Beispiel #1
0
IGL_INLINE void igl::flipped_triangles(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedX> & X)
{
  assert(V.cols() == 2 && "V should contain 2D positions");
  std::vector<typename DerivedX::Scalar> flip_idx;
  for (int i = 0; i < F.rows(); i++)
  {
    // https://www.cs.cmu.edu/~quake/robust.html
    typedef Eigen::Matrix<typename DerivedV::Scalar,1,2> RowVector2S;
    RowVector2S v1_n = V.row(F(i,0));
    RowVector2S v2_n = V.row(F(i,1));
    RowVector2S v3_n = V.row(F(i,2));
    Eigen::Matrix<typename DerivedV::Scalar,3,3> T2_Homo;
    T2_Homo.col(0) << v1_n(0),v1_n(1),1.;
    T2_Homo.col(1) << v2_n(0),v2_n(1),1.;
    T2_Homo.col(2) << v3_n(0),v3_n(1),1.;
    double det = T2_Homo.determinant();
    assert(det == det && "det should not be NaN");
    if (det < 0)
    {
      flip_idx.push_back(i);
    }
  }
  igl::list_to_matrix(flip_idx,X);
}
Beispiel #2
0
IGL_INLINE void igl::cylinder(
  const int axis_devisions,
  const int height_devisions,
  Eigen::PlainObjectBase<DerivedV> & V,
  Eigen::PlainObjectBase<DerivedF> & F)
{
  V.resize(axis_devisions*height_devisions,3);
  F.resize(2*(axis_devisions*(height_devisions-1)),3);
  int f = 0;
  typedef typename DerivedV::Scalar Scalar;
  for(int th = 0;th<axis_devisions;th++)
  {
    Scalar x = cos(2.*igl::PI*Scalar(th)/Scalar(axis_devisions));
    Scalar y = sin(2.*igl::PI*Scalar(th)/Scalar(axis_devisions));
    for(int h = 0;h<height_devisions;h++)
    {
      Scalar z = Scalar(h)/Scalar(height_devisions-1);
      V(th+h*axis_devisions,0) = x;
      V(th+h*axis_devisions,1) = y;
      V(th+h*axis_devisions,2) = z;
      if(h > 0)
      {
        F(f,0) = ((th+0)%axis_devisions)+(h-1)*axis_devisions;
        F(f,1) = ((th+1)%axis_devisions)+(h-1)*axis_devisions;
        F(f,2) = ((th+0)%axis_devisions)+(h+0)*axis_devisions;
        f++;
        F(f,0) = ((th+1)%axis_devisions)+(h-1)*axis_devisions;
        F(f,1) = ((th+1)%axis_devisions)+(h+0)*axis_devisions;
        F(f,2) = ((th+0)%axis_devisions)+(h+0)*axis_devisions;
        f++;
      }
    }
  }
  assert(f == F.rows());
}
inline void igl::PlanarizerShapeUp<DerivedV, DerivedF>::planarize(Eigen::PlainObjectBase<DerivedV> &Vout)
{
  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> planarity;
  Vout = Vin;
  
  for (int iter =0; iter<maxIter; ++iter)
  {
    igl::quad_planarity(Vout, Fin, planarity);
    typename DerivedV::Scalar nonPlanarity = planarity.cwiseAbs().maxCoeff();
    //std::cerr<<"iter #"<<iter<<": max non-planarity: "<<nonPlanarity<<std::endl;
    if (nonPlanarity<threshold)
      break;
    assembleP();
    Vv = solver.solve(Q.transpose()*P);
    if(solver.info()!=Eigen::Success)
    {
      std::cerr << "Linear solve failed - PlanarizerShapeUp.cpp" << std::endl;
      assert(0);
    }
    for (int i =0;i<numV;++i)
      Vout.row(i) << Vv.segment(3*i,3).transpose();
  }
  // set the mean of Vout to the mean of Vin
  Eigen::Matrix<typename DerivedV::Scalar, 1, 3> oldMean, newMean;
  oldMean = Vin.colwise().mean();
  newMean = Vout.colwise().mean();
  Vout.rowwise() += (oldMean - newMean);
  
};
IGL_INLINE void igl::sort_vectors_ccw(
  const Eigen::PlainObjectBase<DerivedS>& P,
  const Eigen::PlainObjectBase<DerivedS>& N,
  Eigen::PlainObjectBase<DerivedI> &order)
{
  int half_degree = P.cols()/3;
  //local frame
  Eigen::Matrix<typename DerivedS::Scalar,1,3> e1 = P.head(3).normalized();
  Eigen::Matrix<typename DerivedS::Scalar,1,3> e3 = N.normalized();
  Eigen::Matrix<typename DerivedS::Scalar,1,3> e2 = e3.cross(e1);

  Eigen::Matrix<typename DerivedS::Scalar,3,3> F; F<<e1.transpose(),e2.transpose(),e3.transpose();

  Eigen::Matrix<typename DerivedS::Scalar,Eigen::Dynamic,1> angles(half_degree,1);
  for (int i=0; i<half_degree; ++i)
  {
    Eigen::Matrix<typename DerivedS::Scalar,1,3> Pl = F.colPivHouseholderQr().solve(P.segment(i*3,3).transpose()).transpose();
//    assert(fabs(Pl(2))/Pl.cwiseAbs().maxCoeff() <1e-5);
    angles[i] = atan2(Pl(1),Pl(0));
  }

  igl::sort( angles, 1, true, angles, order);
  //make sure that the first element is always  at the top
  while (order[0] != 0)
  {
    //do a circshift
    int temp = order[0];
    for (int i =0; i< half_degree-1; ++i)
      order[i] = order[i+1];
    order(half_degree-1) = temp;
  }
}
  bool is_orientable(
      const Eigen::PlainObjectBase<DerivedF>& F,
      const Eigen::PlainObjectBase<DeriveduE>& uE,
      const std::vector<std::vector<uE2EType> >& uE2E) {
    const size_t num_faces = F.rows();
    const size_t num_edges = uE.rows();
    auto edge_index_to_face_index = [&](size_t ei) {
      return ei % num_faces;
    };
    auto is_consistent = [&](size_t fid, size_t s, size_t d) {
      if ((size_t)F(fid, 0) == s && (size_t)F(fid, 1) == d) return true;
      if ((size_t)F(fid, 1) == s && (size_t)F(fid, 2) == d) return true;
      if ((size_t)F(fid, 2) == s && (size_t)F(fid, 0) == d) return true;

      if ((size_t)F(fid, 0) == d && (size_t)F(fid, 1) == s) return false;
      if ((size_t)F(fid, 1) == d && (size_t)F(fid, 2) == s) return false;
      if ((size_t)F(fid, 2) == d && (size_t)F(fid, 0) == s) return false;
      throw "Invalid face!!";
    };
    for (size_t i=0; i<num_edges; i++) {
      const size_t s = uE(i,0);
      const size_t d = uE(i,1);
      int count=0;
      for (const auto& ei : uE2E[i]) {
        const size_t fid = edge_index_to_face_index(ei);
        if (is_consistent(fid, s, d)) count++;
        else count--;
      }
      if (count != 0) {
        return false;
      }
    }
    return true;
  }
Beispiel #6
0
IGL_INLINE bool igl::list_to_matrix(const std::vector<std::vector<T > > & V,Eigen::PlainObjectBase<Derived>& M)
{
  // number of rows
  int m = V.size();
  if(m == 0)
  {
    M.resize(0,0);
    return true;
  }
  // number of columns
  int n = igl::min_size(V);
  if(n != igl::max_size(V))
  {
    return false;
  }
  assert(n != -1);
  // Resize output
  M.resize(m,n);

  // Loop over rows
  for(int i = 0;i<m;i++)
  {
    // Loop over cols
    for(int j = 0;j<n;j++)
    {
      M(i,j) = V[i][j];
    }
  }

  return true;
}
Beispiel #7
0
IGL_INLINE void igl::volume(
  Eigen::PlainObjectBase<DerivedL>& L,
  Eigen::PlainObjectBase<Derivedvol>& vol)
{
  using namespace Eigen;
  const int m = L.rows();
  typedef typename Derivedvol::Scalar ScalarS;
  vol.resize(m,1);
  for(int t = 0;t<m;t++)
  {
    const ScalarS u = L(t,0);
    const ScalarS v = L(t,1);
    const ScalarS w = L(t,2);
    const ScalarS U = L(t,3);
    const ScalarS V = L(t,4);
    const ScalarS W = L(t,5);
    const ScalarS X = (w - U + v)*(U + v + w);
    const ScalarS x = (U - v + w)*(v - w + U);
    const ScalarS Y = (u - V + w)*(V + w + u);
    const ScalarS y = (V - w + u)*(w - u + V);
    const ScalarS Z = (v - W + u)*(W + u + v);
    const ScalarS z = (W - u + v)*(u - v + W);
    const ScalarS a = sqrt(x*Y*Z); 
    const ScalarS b = sqrt(y*Z*X); 
    const ScalarS c = sqrt(z*X*Y); 
    const ScalarS d = sqrt(x*y*z); 
    vol(t) = sqrt(
       (-a + b + c + d)*
       ( a - b + c + d)*
       ( a + b - c + d)*
       ( a + b + c - d))/
       (192.*u*v*w);
  }
}
Beispiel #8
0
IGL_INLINE void igl::face_areas(
  const Eigen::MatrixBase<DerivedL>& L,
  const typename DerivedL::Scalar doublearea_nan_replacement,
  Eigen::PlainObjectBase<DerivedA>& A)
{
  using namespace Eigen;
  assert(L.cols() == 6);
  const int m = L.rows();
  // (unsigned) face Areas (opposite vertices: 1 2 3 4)
  Matrix<typename DerivedA::Scalar,Dynamic,1> 
    A0(m,1), A1(m,1), A2(m,1), A3(m,1);
  Matrix<typename DerivedA::Scalar,Dynamic,3> 
    L0(m,3), L1(m,3), L2(m,3), L3(m,3);
  L0<<L.col(1),L.col(2),L.col(3);
  L1<<L.col(0),L.col(2),L.col(4);
  L2<<L.col(0),L.col(1),L.col(5);
  L3<<L.col(3),L.col(4),L.col(5);
  doublearea(L0,doublearea_nan_replacement,A0);
  doublearea(L1,doublearea_nan_replacement,A1);
  doublearea(L2,doublearea_nan_replacement,A2);
  doublearea(L3,doublearea_nan_replacement,A3);
  A.resize(m,4);
  A.col(0) = 0.5*A0;
  A.col(1) = 0.5*A1;
  A.col(2) = 0.5*A2;
  A.col(3) = 0.5*A3;
}
IGL_INLINE void igl::internal_angles(
  const Eigen::PlainObjectBase<DerivedL>& L,
  Eigen::PlainObjectBase<DerivedK> & K)
{
  typedef typename DerivedL::Index Index;
  assert(L.cols() == 3 && "Edge-lengths should come from triangles");
  const Index m = L.rows();
  K.resize(m,3);
  //for(int d = 0;d<3;d++)
  //{
  //  const auto & s1 = L.col(d).array();
  //  const auto & s2 = L.col((d+1)%3).array();
  //  const auto & s3 = L.col((d+2)%3).array();
  //  K.col(d) = ((s3.square() + s2.square() - s1.square())/(2.*s3*s2)).acos();
  //}
  // Minimum number of iterms per openmp thread
  #ifndef IGL_OMP_MIN_VALUE
  #  define IGL_OMP_MIN_VALUE 1000
  #endif
  #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
  for(Index f = 0;f<m;f++)
  {
    for(size_t d = 0;d<3;d++)
    {
      const auto & s1 = L(f,d);
      const auto & s2 = L(f,(d+1)%3);
      const auto & s3 = L(f,(d+2)%3);
      K(f,d) = acos((s3*s3 + s2*s2 - s1*s1)/(2.*s3*s2));
    }
  }
}
Beispiel #10
0
IGL_INLINE void igl::mat_min(
  const Eigen::DenseBase<DerivedX> & X,
  const int dim,
  Eigen::PlainObjectBase<DerivedY> & Y,
  Eigen::PlainObjectBase<DerivedI> & I)
{
  assert(dim==1||dim==2);

  // output size
  int n = (dim==1?X.cols():X.rows());
  // resize output
  Y.resize(n);
  I.resize(n);

  // loop over dimension opposite of dim
  for(int j = 0;j<n;j++)
  {
    typename DerivedX::Index PHONY,i;
    typename DerivedX::Scalar  m;
    if(dim==1)
    {
      m = X.col(j).minCoeff(&i,&PHONY);
    }else
    {
      m = X.row(j).minCoeff(&PHONY,&i);
    }
    Y(j) = m;
    I(j) = i;
  }
}
void igl::crouzeix_raviart_massmatrix(
    const Eigen::PlainObjectBase<DerivedV> & V, 
    const Eigen::PlainObjectBase<DerivedF> & F, 
    const Eigen::PlainObjectBase<DerivedE> & E,
    const Eigen::PlainObjectBase<DerivedEMAP> & EMAP,
    Eigen::SparseMatrix<MT> & M)
{
  using namespace Eigen;
  using namespace std;
  assert(F.cols() == 3);
  // Mesh should be edge-manifold
  assert(is_edge_manifold(F));
  // number of elements (triangles)
  int m = F.rows();
  // Get triangle areas
  VectorXd TA;
  doublearea(V,F,TA);
  vector<Triplet<MT> > MIJV(3*m);
  for(int f = 0;f<m;f++)
  {
    for(int c = 0;c<3;c++)
    {
      MIJV[f+m*c] = Triplet<MT>(EMAP(f+m*c),EMAP(f+m*c),TA(f)*0.5);
    }
  }
  M.resize(E.rows(),E.rows());
  M.setFromTriplets(MIJV.begin(),MIJV.end());
}
IGL_INLINE void igl::project_to_line_segment(
  const Eigen::PlainObjectBase<DerivedP> & P,
  const Eigen::PlainObjectBase<DerivedS> & S,
  const Eigen::PlainObjectBase<DerivedD> & D,
  Eigen::PlainObjectBase<Derivedt> & t,
  Eigen::PlainObjectBase<DerivedsqrD> & sqrD)
{
  project_to_line(P,S,D,t,sqrD);
  const int np = P.rows();
  // loop over points and fix those that projected beyond endpoints
#pragma omp parallel for if (np>10000)
  for(int p = 0;p<np;p++)
  {
    const Eigen::PlainObjectBase<DerivedS> Pp = P.row(p);
    if(t(p)<0)
    {
      sqrD(p) = (Pp-S).squaredNorm();
      t(p) = 0;
    }else if(t(p)>1)
    {
      sqrD(p) = (Pp-D).squaredNorm();
      t(p) = 1;
    }
  }
}
Beispiel #13
0
IGL_INLINE void igl::slice_into(
  const Eigen::PlainObjectBase<DerivedX> & X,
  const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  Eigen::PlainObjectBase<DerivedX> & Y)
{

  int xm = X.rows();
  int xn = X.cols();
  assert(R.size() == xm);
  assert(C.size() == xn);
#ifndef NDEBUG
  int ym = Y.size();
  int yn = Y.size();
  assert(R.minCoeff() >= 0);
  assert(R.maxCoeff() < ym);
  assert(C.minCoeff() >= 0);
  assert(C.maxCoeff() < yn);
#endif

  // Build reindexing maps for columns and rows, -1 means not in map
  Eigen::Matrix<int,Eigen::Dynamic,1> RI;
  RI.resize(xm);
  for(int i = 0;i<xm;i++)
  {
    for(int j = 0;j<xn;j++)
    {
      Y(R(i),C(j)) = X(i,j);
    }
  }
}
IGL_INLINE void igl::slice(
  const MatX& X,
  const Eigen::PlainObjectBase<DerivedR> & R,
  const int dim,
  MatY& Y)
{
  Eigen::Matrix<typename DerivedR::Scalar,Eigen::Dynamic,1> C;
  switch(dim)
  {
    case 1:
      // boring base case
      if(X.cols() == 0)
      {
        Y.resize(R.size(),0);
        return;
      }
      igl::colon(0,X.cols()-1,C);
      return slice(X,R,C,Y);
    case 2:
      // boring base case
      if(X.rows() == 0)
      {
        Y.resize(0,R.size());
        return;
      }
      igl::colon(0,X.rows()-1,C);
      return slice(X,C,R,Y);
    default:
      assert(false && "Unsupported dimension");
      return;
  }
}
Beispiel #15
0
IGL_INLINE bool igl::writeOBJ(
  const std::string str,
  const Eigen::PlainObjectBase<DerivedV>& V,
  const Eigen::PlainObjectBase<DerivedF>& F)
{
  std::ofstream s(str.c_str());

  if(!s.is_open())
  {
    fprintf(stderr,"IOError: writeOBJ() could not open %s\n",str.c_str());
    return false;
  }

  for(int i=0;i<(int)V.rows();++i)
  {
    s << "v " << V(i,0) << " " << V(i,1) << " " << V(i,2) << std::endl;
  }
  
  for(int i=0;i<(int)F.rows();++i)
  {
    s << "f " << F(i,0)+1 << " " << F(i,1)+1 << " " << F(i,2)+1 << std::endl;
  }
  
  s.close();
  return true;
}
IGL_INLINE void igl::polyvector_field_singularities_from_matchings(
                                                                   const Eigen::PlainObjectBase<DerivedV> &V,
                                                                   const Eigen::PlainObjectBase<DerivedF> &F,
                                                                   const std::vector<bool> &V_border,
                                                                   const std::vector<std::vector<VFType> > &VF,
                                                                   const Eigen::MatrixXi &TT,
                                                                   const Eigen::MatrixXi &E2F,
                                                                   const Eigen::MatrixXi &F2E,
                                                                   const Eigen::PlainObjectBase<DerivedM> &match_ab,
                                                                   const Eigen::PlainObjectBase<DerivedM> &match_ba,
                                                                   Eigen::PlainObjectBase<DerivedS> &singularities,
                                                                   Eigen::PlainObjectBase<DerivedS> &singularity_indices)
{
  igl::polyvector_field_singularities_from_matchings(V, F, V_border, VF, TT, E2F, F2E, match_ab, match_ba, singularities);

  singularity_indices.setZero(singularities.size(), 1);

  //get index from first vector only
  int vector_to_match = 0;
  for (int i =0; i<singularities.size(); ++i)
  {
    int vi = singularities[i];

    // Eigen::VectorXi mvi,fi;
    // igl::polyvector_field_one_ring_matchings(V, F, VF, E2F, F2E, TT, match_ab, match_ba, vi, vector_to_match, mvi, fi);
    Eigen::VectorXi fi;
    Eigen::MatrixXi mvi;
    igl::polyvector_field_one_ring_matchings(V, F, VF, E2F, F2E, TT, match_ab, match_ba, vi, mvi, fi);

    singularity_indices[i] = (mvi(mvi.rows()-1,vector_to_match) - vector_to_match);
  }

}
Beispiel #17
0
void igl::sort_triangles(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedFF> & FF,
  Eigen::PlainObjectBase<DerivedI> & I)
{
  using namespace Eigen;
  using namespace igl;
  using namespace std;
  // Put model, projection, and viewport matrices into double arrays
  Matrix4d MV;
  Matrix4d P;
  glGetDoublev(GL_MODELVIEW_MATRIX,  MV.data());
  glGetDoublev(GL_PROJECTION_MATRIX, P.data());
  if(V.cols() == 3)
  {
    Matrix<typename DerivedV::Scalar, DerivedV::RowsAtCompileTime,4> hV;
    hV.resize(V.rows(),4);
    hV.block(0,0,V.rows(),V.cols()) = V;
    hV.col(3).setConstant(1);
    return sort_triangles(hV,F,MV,P,FF,I);
  }else
  {
    return sort_triangles(V,F,MV,P,FF,I);
  }
}
Beispiel #18
0
IGL_INLINE void igl::min(
  const Eigen::SparseMatrix<AType> & A,
  const int dim,
  Eigen::PlainObjectBase<DerivedB> & B,
  Eigen::PlainObjectBase<DerivedI> & I)
{
  const int n = A.cols();
  const int m = A.rows();
  B.resize(dim==1?n:m);
  B.setConstant(std::numeric_limits<typename DerivedB::Scalar>::max());
  I.resize(dim==1?n:m);
  for_each(A,[&B,&I,&dim](int i, int j,const typename DerivedB::Scalar v)
    {
      if(dim == 2)
      {
        std::swap(i,j);
      }
      // Coded as if dim == 1, assuming swap for dim == 2
      if(v < B(j))
      {
        B(j) = v;
        I(j) = i;
      }
    });
  Eigen::VectorXi Z;
  find_zero(A,dim,Z);
  for(int j = 0;j<I.size();j++)
  {
    if(Z(j) != (dim==1?m:n) && 0 < B(j))
    {
      B(j) = 0;
      I(j) = Z(j);
    }
  }
}
Beispiel #19
0
IGL_INLINE void igl::per_face_normals(
  const Eigen::MatrixBase<DerivedV>& V,
  const Eigen::MatrixBase<DerivedF>& F,
  const Eigen::MatrixBase<DerivedZ> & Z,
  Eigen::PlainObjectBase<DerivedN> & N)
{
  N.resize(F.rows(),3);
  // loop over faces
  int Frows = F.rows();
#pragma omp parallel for if (Frows>10000)
  for(int i = 0; i < Frows;i++)
  {
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v1 = V.row(F(i,1)) - V.row(F(i,0));
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v2 = V.row(F(i,2)) - V.row(F(i,0));
    N.row(i) = v1.cross(v2);//.normalized();
    typename DerivedV::Scalar r = N.row(i).norm();
    if(r == 0)
    {
      N.row(i) = Z;
    }else
    {
      N.row(i) /= r;
    }
  }
}
Beispiel #20
0
IGL_INLINE void igl::in_element(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::MatrixXi & Ele,
  const Eigen::PlainObjectBase<DerivedQ> & Q,
  const AABB<DerivedV,DIM> & aabb,
  Eigen::SparseMatrix<Scalar> & I)
{
  using namespace std;
  using namespace Eigen;
  using namespace igl;
  const int Qr = Q.rows();
  std::vector<Triplet<Scalar> > IJV;
  IJV.reserve(Qr);
#pragma omp parallel for if (Qr>10000)
  for(int e = 0;e<Qr;e++)
  {
    // find all
    const auto R = aabb.find(V,Ele,Q.row(e),false);
    for(const auto r : R)
    {
#pragma omp critical
      IJV.push_back(Triplet<Scalar>(e,r,1));
    }
  }
  I.resize(Qr,Ele.rows());
  I.setFromTriplets(IJV.begin(),IJV.end());
}
Beispiel #21
0
IGL_INLINE void igl::find(
  const Eigen::DenseBase<DerivedX>& X,
  Eigen::PlainObjectBase<DerivedI> & I,
  Eigen::PlainObjectBase<DerivedJ> & J,
  Eigen::PlainObjectBase<DerivedV> & V)
{
  const int nnz = X.count();
  I.resize(nnz,1);
  J.resize(nnz,1);
  V.resize(nnz,1);
  {
    int k = 0;
    for(int j = 0;j<X.cols();j++)
    {
      for(int i = 0;i<X.rows();i++)
      {
        if(X(i,j))
        {
          I(k) = i;
          J(k) = j;
          V(k) = X(i,j);
          k++;
        }
      }
    }
  }
}
Beispiel #22
0
IGL_INLINE void igl::matlab::parse_rhs_double(
    const mxArray *prhs[], 
    Eigen::PlainObjectBase<DerivedV> & V)
{
  using namespace std;
  using namespace Eigen;
  // set number of mesh vertices
  const int n = mxGetM(prhs[0]);
  // set vertex position pointers
  double * Vp = mxGetPr(prhs[0]);
  const int dim = mxGetN(prhs[0]);

  typedef typename DerivedV::Scalar Scalar;
  Matrix<Scalar, DerivedV::ColsAtCompileTime, DerivedV::RowsAtCompileTime, RowMajor> VT;
  Scalar * V_data;
  if(DerivedV::IsRowMajor)
  {
    VT.resize(dim,n);
    V_data = VT.data();
  }else
  {
    V.resize(n,dim);
    V_data = V.data();
  }
  copy(Vp,Vp+n*dim,V_data);
  if(DerivedV::IsRowMajor)
  {
    V = VT.transpose();
  }
}
Beispiel #23
0
IGL_INLINE void igl::unique_edge_map(
  const Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedE> & E,
  Eigen::PlainObjectBase<DeriveduE> & uE,
  Eigen::PlainObjectBase<DerivedEMAP> & EMAP,
  std::vector<std::vector<uE2EType> > & uE2E)
{
  using namespace Eigen;
  using namespace std;
  // All occurances of directed edges
  all_edges(F,E);
  const size_t ne = E.rows();
  // This is 2x faster to create than a map from pairs to lists of edges and 5x
  // faster to access (actually access is probably assympotically faster O(1)
  // vs. O(log m)
  Matrix<typename DerivedEMAP::Scalar,Dynamic,1> IA;
  unique_simplices(E,uE,IA,EMAP);
  uE2E.resize(uE.rows());
  // This does help a little
  for_each(uE2E.begin(),uE2E.end(),[](vector<uE2EType > & v){v.reserve(2);});
  assert((size_t)EMAP.size() == ne);
  for(uE2EType e = 0;e<(uE2EType)ne;e++)
  {
    uE2E[EMAP(e)].push_back(e);
  }
}
Beispiel #24
0
IGL_INLINE void igl::randperm(
  const int n,
  Eigen::PlainObjectBase<DerivedI> & I)
{
  Eigen::VectorXi II;
  igl::colon(0,1,n-1,II);
  I = II;
  std::random_shuffle(I.data(),I.data()+n);
}
Beispiel #25
0
IGL_INLINE int igl::unproject_to_zero_plane(
  const Eigen::PlainObjectBase<Derivedwin> & win,
  Eigen::PlainObjectBase<Derivedobj> & obj)
{
  return unproject_to_zero_plane(win(0),win(1),
      &obj.data()[0],
      &obj.data()[1],
      &obj.data()[2]);
}
Beispiel #26
0
IGL_INLINE void igl::jet(
  const Eigen::PlainObjectBase<DerivedZ> & Z,
  const bool normalize,
  Eigen::PlainObjectBase<DerivedC> & C)
{
  const double min_z = (normalize?Z.minCoeff():0);
  const double max_z = (normalize?Z.maxCoeff():-1);
  return jet(Z,min_z,max_z,C);
}
Beispiel #27
0
IGL_INLINE void igl::sort(
  const Eigen::PlainObjectBase<DerivedX>& X,
  const int dim,
  const bool ascending,
  Eigen::PlainObjectBase<DerivedY>& Y,
  Eigen::PlainObjectBase<DerivedIX>& IX)
{
  // get number of rows (or columns)
  int num_inner = (dim == 1 ? X.rows() : X.cols() );
  // Special case for swapping
  if(num_inner == 2)
  {
    return igl::sort2(X,dim,ascending,Y,IX);
  }
  using namespace Eigen;
  // get number of columns (or rows)
  int num_outer = (dim == 1 ? X.cols() : X.rows() );
  // dim must be 2 or 1
  assert(dim == 1 || dim == 2);
  // Resize output
  Y.resize(X.rows(),X.cols());
  IX.resize(X.rows(),X.cols());
  // idea is to process each column (or row) as a std vector
  // loop over columns (or rows)
  for(int i = 0; i<num_outer;i++)
  {
    // Unsorted index map for this column (or row)
    std::vector<size_t> index_map(num_inner);
    std::vector<double> data(num_inner);
    for(int j = 0;j<num_inner;j++)
    {
      if(dim == 1)
      {
        data[j] = (double) X(j,i);
      }else
      {
        data[j] = (double) X(i,j);
      }
    }
    // sort this column (or row)
    igl::sort( data, ascending, data, index_map);
    // Copy into Y and IX
    for(int j = 0;j<num_inner;j++)
    {
      if(dim == 1)
      {
        Y(j,i) = data[j];
        IX(j,i) = index_map[j];
      }else
      {
        Y(i,j) = data[j];
        IX(i,j) = index_map[j];
      }
    }
  }
}
IGL_INLINE void igl::reorient_facets_raycast(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedFF> & FF,
  Eigen::PlainObjectBase<DerivedI> & I)
{
  const int rays_total = F.rows()*100;
  const int rays_minimum = 10;
  const bool facet_wise = false;
  const bool use_parity = false;
  const bool is_verbose = false;
  Eigen::VectorXi C;
  reorient_facets_raycast(
    V,F,rays_total,rays_minimum,facet_wise,use_parity,is_verbose,I,C);
  // Conservative in case FF = F
  FF.conservativeResize(F.rows(),F.cols());
  for(int i = 0;i<I.rows();i++)
  {
    if(I(i))
    {
      FF.row(i) = (F.row(i).reverse()).eval();
    }else
    {
      FF.row(i) = F.row(i);
    }
  }
}
Beispiel #29
0
IGL_INLINE void igl::components(
  const Eigen::SparseMatrix<AScalar> & A,
  Eigen::PlainObjectBase<DerivedC> & C,
  Eigen::PlainObjectBase<Derivedcounts> & counts)
{
  using namespace Eigen;
  using namespace std;
  assert(A.rows() == A.cols() && "A should be square.");
  const size_t n = A.rows();
  Array<bool,Dynamic,1> seen = Array<bool,Dynamic,1>::Zero(n,1);
  C.resize(n,1);
  typename DerivedC::Scalar id = 0;
  vector<typename Derivedcounts::Scalar> vcounts;
  // breadth first search
  for(int k=0; k<A.outerSize(); ++k)
  {
    if(seen(k))
    {
      continue;
    }
    queue<int> Q;
    Q.push(k);
    vcounts.push_back(0);
    while(!Q.empty())
    {
      const int f = Q.front();
      Q.pop();
      if(seen(f))
      {
        continue;
      }
      seen(f) = true;
      C(f,0) = id;
      vcounts[id]++;
      // Iterate over inside
      for(typename SparseMatrix<AScalar>::InnerIterator it (A,f); it; ++it)
      {
        const int g = it.index();
        if(!seen(g) && it.value())
        {
          Q.push(g);
        }
      }
    }
    id++;
  }
  assert((size_t) id == vcounts.size());
  const size_t ncc = vcounts.size();
  assert((size_t)C.maxCoeff()+1 == ncc);
  counts.resize(ncc,1);
  for(size_t i = 0;i<ncc;i++)
  {
    counts(i) = vcounts[i];
  }
}
IGL_INLINE int igl::ray_sphere_intersect(
  const Eigen::PlainObjectBase<Derivedo> & ao,
  const Eigen::PlainObjectBase<Derivedd> & d,
  const Eigen::PlainObjectBase<Derivedc> & ac,
  r_type r, 
  t_type & t0,
  t_type & t1)
{
  Eigen::Vector3d o = ao-ac;
  // http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
  //Compute A, B and C coefficients
  double a = d.dot(d);
  double b = 2 * d.dot(o);
  double c = o.dot(o) - (r * r);

  //Find discriminant
  double disc = b * b - 4 * a * c;
    
  // if discriminant is negative there are no real roots, so return 
  // false as ray misses sphere
  if (disc < 0)
  {
    return 0;
  }

  // compute q as described above
  double distSqrt = sqrt(disc);
  double q;
  if (b < 0)
  {
    q = (-b - distSqrt)/2.0;
  } else
  {
    q = (-b + distSqrt)/2.0;
  }

  // compute t0 and t1
  t0 = q / a;
  double _t1 = c/q;
  if(_t1 == t0)
  {
    return 1;
  }
  t1 = _t1;
  // make sure t0 is smaller than t1
  if (t0 > t1)
  {
    // if t0 is bigger than t1 swap them around
    double temp = t0;
    t0 = t1;
    t1 = temp;
  }
  return 2;
}