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);
  }

}
Example #2
0
bool Polygon::convertToInequalityConstraints(Eigen::MatrixXd& A, Eigen::VectorXd& b) const
{
  Eigen::MatrixXd V(nVertices(), 2);
  for (unsigned int i = 0; i < nVertices(); ++i)
    V.row(i) = vertices_[i];

  // Create k, a list of indices from V forming the convex hull.
  // TODO: Assuming counter-clockwise ordered convex polygon.
  // MATLAB: k = convhulln(V);
  Eigen::MatrixXi k;
  k.resizeLike(V);
  for (unsigned int i = 0; i < V.rows(); ++i)
    k.row(i) << i, (i+1) % V.rows();
  Eigen::RowVectorXd c = V.colwise().mean();
  V.rowwise() -= c;
  A = Eigen::MatrixXd::Constant(k.rows(), V.cols(), NAN);

  unsigned int rc = 0;
  for (unsigned int ix = 0; ix < k.rows(); ++ix) {
    Eigen::MatrixXd F(2, V.cols());
    F.row(0) << V.row(k(ix, 0));
    F.row(1) << V.row(k(ix, 1));
    Eigen::FullPivLU<Eigen::MatrixXd> luDecomp(F);
    if (luDecomp.rank() == F.rows()) {
      A.row(rc) = F.colPivHouseholderQr().solve(Eigen::VectorXd::Ones(F.rows()));
      ++rc;
    }
  }

  A = A.topRows(rc);
  b = Eigen::VectorXd::Ones(A.rows());
  b = b + A * c.transpose();

  return true;
}
Example #3
0
// Converts a representative vector per face in the full set of vectors that describe
// an N-RoSy field
void representative_to_nrosy(
    const Eigen::MatrixXd& V,
    const Eigen::MatrixXi& F,
    const Eigen::MatrixXd& R,
    const int N,
    Eigen::MatrixXd& Y)
{
    using namespace Eigen;
    using namespace std;
    MatrixXd B1, B2, B3;

    igl::local_basis(V,F,B1,B2,B3);

    Y.resize(F.rows()*N,3);
    for (unsigned i=0; i<F.rows(); ++i)
    {
        double x = R.row(i) * B1.row(i).transpose();
        double y = R.row(i) * B2.row(i).transpose();
        double angle = atan2(y,x);

        for (unsigned j=0; j<N; ++j)
        {
            double anglej = angle + 2*M_PI*double(j)/double(N);
            double xj = cos(anglej);
            double yj = sin(anglej);
            Y.row(i*N+j) = xj * B1.row(i) + yj * B2.row(i);
        }
    }
}
void HomogeneousPoint3fIntegralImage::compute(const Eigen::MatrixXi &indices, const HomogeneousPoint3fVector &points) {
  if (cols() != indices.cols() || rows() != indices.rows())
    resize(indices.rows(), indices.cols());
  clear();
  
  HomogeneousPoint3fAccumulator *acc = data();
  const int *pointIndex = indices.data();
  int s = rows() * cols();
  // fill the accumulators with the points
  for (int i=0; i<s; i++, acc++, pointIndex++){
    if (*pointIndex<0)
      continue;
    const HomogeneousPoint3f& point = points[*pointIndex];
    acc->operator += (point);
  }

  // fill by column
  #pragma omp parallel for
  for (int c=0; c<cols(); c++){
    for (int r=1; r<rows(); r++){
      coeffRef(r,c) += coeffRef(r-1,c);
    }
  }

  // fill by row
  #pragma omp parallel for
  for (int r=0; r<rows(); r++){
    for (int c=1; c<cols(); c++){
      coeffRef(r,c) += coeffRef(r,c-1);
    }
  }
}
Example #5
0
// Receive a matrix from MATLAB
IGL_INLINE void igl::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixXi& M)
{
  if (*mlengine == 0)
    mlinit(mlengine);
  
  unsigned long m = 0;
  unsigned long n = 0;
  std::vector<double> t;
  
  mxArray *ary = engGetVariable(*mlengine, name.c_str());
  if (ary == NULL)
  {
    m = 0;
    n = 0;
    M = Eigen::MatrixXi(0,0);
  }
  else
  {
    m = mxGetM(ary);
    n = mxGetN(ary);
    M = Eigen::MatrixXi(m,n);
    
    double *pM = mxGetPr(ary);
    
    int c = 0;
    for(int j=0; j<M.cols();++j)
      for(int i=0; i<M.rows();++i)
        M(i,j) = int(pM[c++])-1;
  }
  
  mxDestroyArray(ary);
}
Example #6
0
void color_intersections(
  const Eigen::MatrixXd & V,
  const Eigen::MatrixXi & F,
  const Eigen::MatrixXd & U,
  const Eigen::MatrixXi & G,
  Eigen::MatrixXd & C,
  Eigen::MatrixXd & D)
{
  using namespace igl;
  using namespace igl::cgal;
  using namespace Eigen;
  MatrixXi IF;
  const bool first_only = false;
  intersect_other(V,F,U,G,first_only,IF);
  C.resize(F.rows(),3);
  C.col(0).setConstant(0.4);
  C.col(1).setConstant(0.8);
  C.col(2).setConstant(0.3);
  D.resize(G.rows(),3);
  D.col(0).setConstant(0.4);
  D.col(1).setConstant(0.3);
  D.col(2).setConstant(0.8);
  for(int f = 0;f<IF.rows();f++)
  {
    C.row(IF(f,0)) = RowVector3d(1,0.4,0.4);
    D.row(IF(f,1)) = RowVector3d(0.8,0.7,0.3);
  }
}
Example #7
0
void PixelMapper::mergeProjections(Eigen::MatrixXf& depthImage, Eigen::MatrixXi& indexImage,
				   Eigen::MatrixXf* depths, Eigen::MatrixXi* indices, int numImages){
  assert (numImages>0);
  int rows=depths[0].rows();
  int cols=depths[0].cols();
  depthImage.resize(indexImage.rows(), indexImage.cols());
  depthImage.fill(std::numeric_limits<float>::max());
  indexImage.resize(rows, cols);
  indexImage.fill(-1);

  #pragma omp parallel for
  for (int c=0; c<cols; c++){
    int* destIndexPtr = &indexImage.coeffRef(0,c);
    float* destDepthPtr = &depthImage.coeffRef(0,c);
    int* srcIndexPtr[numImages];
    float* srcDepthPtr[numImages];
    for (int i=0; i<numImages; i++){
      srcIndexPtr[i] = &indices[i].coeffRef(0,c);
      srcDepthPtr[i] = &depths[i].coeffRef(0,c);
    }
    for (int r=0; r<rows; r++){
      for (int i=0; i<numImages; i++){
	if (*destDepthPtr>*srcDepthPtr[i]){
	  *destDepthPtr = *srcDepthPtr[i];
	  *destIndexPtr = *srcIndexPtr[i];
	}
	srcDepthPtr[i]++;
	srcIndexPtr[i]++;
      }
      destDepthPtr++;
      destIndexPtr++;
    }
  }

}
Example #8
0
IGL_INLINE bool igl::decimate(
  const Eigen::MatrixXd & V,
  const Eigen::MatrixXi & F,
  const size_t max_m,
  Eigen::MatrixXd & U,
  Eigen::MatrixXi & G,
  Eigen::VectorXi & J,
  Eigen::VectorXi & I)
{
  // Original number of faces
  const int orig_m = F.rows();
  // Tracking number of faces
  int m = F.rows();
  typedef Eigen::MatrixXd DerivedV;
  typedef Eigen::MatrixXi DerivedF;
  DerivedV VO;
  DerivedF FO;
  igl::connect_boundary_to_infinity(V,F,VO,FO);
  bool ret = decimate(
    VO,
    FO,
    shortest_edge_and_midpoint,
    max_faces_stopping_condition(m,orig_m,max_m),
    U,
    G,
    J,
    I);
  const Eigen::Array<bool,Eigen::Dynamic,1> keep = (J.array()<orig_m);
  igl::slice_mask(Eigen::MatrixXi(G),keep,1,G);
  igl::slice_mask(Eigen::VectorXi(J),keep,1,J);
  Eigen::VectorXi _1,I2;
  igl::remove_unreferenced(Eigen::MatrixXd(U),Eigen::MatrixXi(G),U,G,_1,I2);
  igl::slice(Eigen::VectorXi(I),I2,1,I);
  return ret;
}
Example #9
0
TEST(readOBJ, simple) {
    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    test_common::load_mesh("cube.obj", V, F);
    ASSERT_EQ(8, V.rows());
    ASSERT_EQ(12, F.rows());
}
IGL_INLINE void igl::covariance_scatter_matrix(
  const Eigen::MatrixXd & V, 
  const Eigen::MatrixXi & F,
  const ARAPEnergyType energy,
  Eigen::SparseMatrix<double>& CSM)
{
  using namespace igl;
  using namespace Eigen;
  // number of mesh vertices
  int n = V.rows();
  assert(n > F.maxCoeff());
  // dimension of mesh
  int dim = V.cols();
  // Number of mesh elements
  int m = F.rows();

  // number of rotations
  int nr;
  switch(energy)
  {
    case ARAP_ENERGY_TYPE_SPOKES:
      nr = n;
      break;
    case ARAP_ENERGY_TYPE_SPOKES_AND_RIMS:
      nr = n;
      break;
    case ARAP_ENERGY_TYPE_ELEMENTS:
      nr = m;
      break;
    default:
      fprintf(
        stderr,
        "covariance_scatter_matrix.h: Error: Unsupported arap energy %d\n",
        energy);
      return;
  }

  SparseMatrix<double> KX,KY,KZ;
  arap_linear_block(V,F,0,energy,KX);
  arap_linear_block(V,F,1,energy,KY);
  SparseMatrix<double> Z(n,nr);
  if(dim == 2)
  {
    CSM = cat(1,cat(2,KX,Z),cat(2,Z,KY)).transpose();
  }else if(dim == 3)
  {
    arap_linear_block(V,F,2,energy,KZ);
    SparseMatrix<double>ZZ(n,nr*2);
    CSM = 
      cat(1,cat(1,cat(2,KX,ZZ),cat(2,cat(2,Z,KY),Z)),cat(2,ZZ,KZ)).transpose();
  }else
  {
    fprintf(
     stderr,
     "covariance_scatter_matrix.h: Error: Unsupported dimension %d\n",
     dim);
    return;
  }

}
IGL_INLINE bool igl::mesh_to_polyhedron(
  const Eigen::MatrixXd & V,
  const Eigen::MatrixXi & F,
  Polyhedron & poly)
{
  typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
  // Postcondition: hds is a valid polyhedral surface.
  CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B(poly.hds());
  B.begin_surface(V.rows(),F.rows());
  typedef typename HalfedgeDS::Vertex   Vertex;
  typedef typename Vertex::Point Point;
  assert(V.cols() == 3 && "V must be #V by 3");
  for(int v = 0;v<V.rows();v++)
  {
    B.add_vertex(Point(V(v,0),V(v,1),V(v,2)));
  }
  assert(F.cols() == 3 && "F must be #F by 3");
  for(int f=0;f<F.rows();f++)
  {
    B.begin_facet();
    for(int c = 0;c<3;c++)
    {
      B.add_vertex_to_facet(F(f,c));
    }
    B.end_facet();
  }
  if(B.error())
  {
    B.rollback();
    return false;
  }
  B.end_surface();
  return poly.is_valid();
}
// Parse right hand side arguments for a matlab mex function.
//
// Inputs:
//   nrhs  number of right hand side arguments
//   prhs  pointer to right hand side arguments
// Outputs:
//   V  n by dim list of mesh vertex positions
//   F  m by dim list of mesh face indices
//   s  1 by dim bone source vertex position
//   d  1 by dim bone dest vertex position
// "Throws" matlab errors if dimensions are not sane.
void parse_rhs(
  const int nrhs, 
  const mxArray *prhs[], 
  Eigen::MatrixXd & V,
  Eigen::MatrixXi & F,
  Eigen::VectorXd & s,
  Eigen::VectorXd & d)
{
  using namespace std;
  if(nrhs < 4)
  {
    mexErrMsgTxt("nrhs < 4");
  }
  const int dim = mxGetN(prhs[0]);
  if(dim != 3)
  {
    mexErrMsgTxt("Mesh vertex list must be #V by 3 list of vertex positions");
  }
  if(dim != (int)mxGetN(prhs[1]))
  {
   mexErrMsgTxt("Mesh facet size must equal dimension");
  }
  if(dim != (int)mxGetN(prhs[2]))
  {
   mexErrMsgTxt("Source dim must equal vertex dimension");
  }
  if(dim != (int)mxGetN(prhs[3]))
  {
   mexErrMsgTxt("Dest dim must equal vertex dimension");
  }
  // set number of mesh vertices
  const int n = mxGetM(prhs[0]);
  // set vertex position pointers
  double * Vp = mxGetPr(prhs[0]);
  // set number of faces
  const int m = mxGetM(prhs[1]);
  // set face index list pointer
  double * Fp = mxGetPr(prhs[1]);
  // set source and dest pointers
  double * sp = mxGetPr(prhs[2]);
  double * dp = mxGetPr(prhs[3]);
  // resize output to transpose
  V.resize(n,dim);
  copy(Vp,Vp+n*dim,V.data());
  // resize output to transpose
  F.resize(m,dim);
  // Q: Is this doing a cast?
  // A: Yes.
  copy(Fp,Fp+m*dim,F.data());
  // http://stackoverflow.com/a/4461466/148668
  transform(F.data(),F.data()+m*dim,F.data(),
    bind2nd(std::plus<double>(),-1.0));
  // resize output to transpose
  s.resize(dim);
  copy(sp,sp+dim,s.data());
  d.resize(dim);
  copy(dp,dp+dim,d.data());
}
Example #13
0
TEST(readOBJ, simple) {
    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    // wait... so this is actually testing test_common::load_mesh not readOBJ
    // directly...
    test_common::load_mesh("cube.obj", V, F);
    ASSERT_EQ(8, V.rows());
    ASSERT_EQ(12, F.rows());
}
Example #14
0
IGL_INLINE void igl::exterior_edges(
  const Eigen::MatrixXi & F,
  Eigen::MatrixXi & E)
{
  using namespace Eigen;
  using namespace std;
  assert(F.cols() == 3);
  const size_t m = F.rows();
  MatrixXi all_E,sall_E,sort_order;
  // Sort each edge by index
  all_edges(F,all_E);
  sort(all_E,2,true,sall_E,sort_order);
  // Find unique edges
  MatrixXi uE;
  VectorXi IA,EMAP;
  unique_rows(sall_E,uE,IA,EMAP);
  VectorXi counts = VectorXi::Zero(uE.rows());
  for(size_t a = 0;a<3*m;a++)
  {
    counts(EMAP(a)) += (sort_order(a)==0?1:-1);
  }

  E.resize(all_E.rows(),2);
  {
    int e = 0;
    const size_t nue = uE.rows();
    // Append each unique edge with a non-zero amount of signed occurances
    for(size_t ue = 0; ue<nue; ue++)
    {
      const int count = counts(ue);
      size_t i,j;
      if(count == 0)
      {
        continue;
      }else if(count < 0)
      {
        i = uE(ue,1);
        j = uE(ue,0);
      }else if(count > 0)
      {
        i = uE(ue,0);
        j = uE(ue,1);
      }
      // Append edge for every repeated entry
      const int abs_count = abs(count);
      for(size_t k = 0;k<abs_count;k++)
      {
        E(e,0) = i;
        E(e,1) = j;
        e++;
      }
    }
    E.conservativeResize(e,2);
  }
}
Example #15
0
int main(int argc, char *argv[])
{
  using namespace Eigen;
  using namespace std;

  // Load a quad mesh generated by a conjugate field
  igl::readOFF(TUTORIAL_SHARED_PATH "/inspired_mesh_quads_Conjugate.off", VQC, FQC);

  // Convert it in a triangle mesh
  FQCtri.resize(2*FQC.rows(), 3);
  FQCtri <<  FQC.col(0),FQC.col(1),FQC.col(2),
             FQC.col(2),FQC.col(3),FQC.col(0);
  igl::slice( VQC, FQC.col(0).eval(), 1, PQC0);
  igl::slice( VQC, FQC.col(1).eval(), 1, PQC1);
  igl::slice( VQC, FQC.col(2).eval(), 1, PQC2);
  igl::slice( VQC, FQC.col(3).eval(), 1, PQC3);

  // Planarize it
  igl::planarize_quad_mesh(VQC, FQC, 100, 0.005, VQCplan);

  // Convert the planarized mesh to triangles
  igl::slice( VQCplan, FQC.col(0).eval(), 1, PQC0plan);
  igl::slice( VQCplan, FQC.col(1).eval(), 1, PQC1plan);
  igl::slice( VQCplan, FQC.col(2).eval(), 1, PQC2plan);
  igl::slice( VQCplan, FQC.col(3).eval(), 1, PQC3plan);

  // Launch the viewer
  igl::viewer::Viewer viewer;
  key_down(viewer,'2',0);
  viewer.data.invert_normals = true;
  viewer.data.show_lines = false;
  viewer.callback_key_down = &key_down;
  viewer.launch();
}
Example #16
0
 // construct
 WorldParamsPrior(const std::vector<distrib::MultiGaussian>& ctrlpts_, const std::vector<Eigen::MatrixXi>& ctrlptMasks_,
                  const std::vector<Eigen::MatrixXd>& ctrlptMins_, const std::vector<Eigen::MatrixXd>& ctrlptMaxs_,
                  const Eigen::VectorXd& ctrlptCoupledSds_, const Eigen::VectorXd& ctrlptUncoupledSds_,
                  const std::vector<distrib::MultiGaussian>& properties_, const std::vector<Eigen::VectorXi>& propMasks_,
                  const std::vector<Eigen::VectorXd>& propMins_, const std::vector<Eigen::VectorXd>& propMaxs_,
                  const std::vector<BoundaryClass>& classes_)
     : ctrlptMasks(ctrlptMasks_),
       ctrlptMins(ctrlptMins_),
       ctrlptMaxs(ctrlptMaxs_),
       ctrlptCoupledSds(ctrlptCoupledSds_),
       ctrlptUncoupledSds(ctrlptUncoupledSds_),
       ctrlptPrior(ctrlpts_),
       propMasks(propMasks_),
       propMins(propMins_),
       propMaxs(propMaxs_),
       propertyPrior(properties_),
       classes(classes_)
 {
   for (uint l = 0; l < propMasks.size(); l++)
   {
     for (uint p = 0; p < propMasks_[l].size(); p++)
     {
       if (!propMasks_[l](p))
       {
         propertyPrior[l].sigma.row(p).setZero();
         propertyPrior[l].sigma.col(p).setZero();
         propertyPrior[l].sigma(p, p) = 1;
       }
     }
   }
   for (uint l = 0; l < ctrlptMasks_.size(); l++)
   {
     Eigen::MatrixXi masks = ctrlptMasks_[l];
     masks.resize(masks.rows() * masks.cols(), 1);
     for (uint p = 0; p < masks.rows(); p++)
     {
       if (!masks(p))
       {
         ctrlptPrior[l].sigma.row(p).setZero();
         ctrlptPrior[l].sigma.col(p).setZero();
         ctrlptPrior[l].sigma(p, p) = 1;
       }
     }
   }
   WorldParams minParams; 
   WorldParams maxParams;
   minParams.rockProperties = propMins;
   maxParams.rockProperties = propMaxs;
   minParams.controlPoints = ctrlptMins;
   maxParams.controlPoints = ctrlptMaxs;
   thetaMin = deconstruct(minParams);
   thetaMax = deconstruct(maxParams);
   VLOG(1) << "Theta min:" << thetaMin.transpose();
   VLOG(1) << "Theta max:" << thetaMax.transpose();
 }
Example #17
0
std::array<Eigen::MatrixXi, 4> FillGroup(const Eigen::MatrixXi& m)
{
  std::array<Eigen::MatrixXi, 4> patterns;
  patterns[0] = m;

  // Found in this awesome answer http://stackoverflow.com/a/3488737/505049
  patterns[1] = m.transpose().colwise().reverse().eval();  // Rotate 90 CW
  patterns[2] = m.transpose().colwise().reverse().transpose().colwise().reverse().eval();  // Rotate 180. Not in the S.O. post
  patterns[3] = m.transpose().rowwise().reverse().eval();  // Rotate 270 CW
  return patterns;
}
Example #18
0
void update_visualization(igl::opengl::glfw::Viewer & viewer)
{
  using namespace Eigen;
  using namespace std;
  Eigen::Vector4d plane(
    0,0,1,-((1-slice_z)*V.col(2).minCoeff()+slice_z*V.col(2).maxCoeff()));
  MatrixXd V_vis;
  MatrixXi F_vis;
  VectorXi J;
  {
    SparseMatrix<double> bary;
    // Value of plane's implicit function at all vertices
    const VectorXd IV = 
      (V.col(0)*plane(0) + 
        V.col(1)*plane(1) + 
        V.col(2)*plane(2)).array()
      + plane(3);
    igl::marching_tets(V,T,IV,V_vis,F_vis,J,bary);
  }
  VectorXd W_vis;
  igl::slice(W,J,W_vis);
  MatrixXd C_vis;
  // color without normalizing
  igl::parula(W_vis,false,C_vis);


  const auto & append_mesh = [&C_vis,&F_vis,&V_vis](
    const Eigen::MatrixXd & V,
    const Eigen::MatrixXi & F,
    const RowVector3d & color)
  {
    F_vis.conservativeResize(F_vis.rows()+F.rows(),3);
    F_vis.bottomRows(F.rows()) = F.array()+V_vis.rows();
    V_vis.conservativeResize(V_vis.rows()+V.rows(),3);
    V_vis.bottomRows(V.rows()) = V;
    C_vis.conservativeResize(C_vis.rows()+F.rows(),3);
    C_vis.bottomRows(F.rows()).rowwise() = color;
  };
  switch(overlay)
  {
    case OVERLAY_INPUT:
      append_mesh(V,F,RowVector3d(1.,0.894,0.227));
      break;
    case OVERLAY_OUTPUT:
      append_mesh(V,G,RowVector3d(0.8,0.8,0.8));
      break;
    default:
      break;
  }
  viewer.data().clear();
  viewer.data().set_mesh(V_vis,F_vis);
  viewer.data().set_colors(C_vis);
  viewer.data().set_face_based(true);
}
Example #19
0
void PrintPattern(const Eigen::MatrixXi& M)
{
    for(int r=0; r< M.rows(); ++r) {
        for(int c=0; c<M.cols(); ++c) {
            const int v = M(r,c);
            const char b = (v == -1) ? 'x' : '0'+v;
            std::cout << b << ' ';
        }
        std::cout << std::endl;
    }
}
Example #20
0
IGL_INLINE void igl::GeneralPolyVectorFieldFinder<DerivedV, DerivedF>::getGeneralCoeffConstraints(const Eigen::VectorXi &isConstrained,
                                                       const Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &cfW,
                                                       int k,
                                                       const Eigen::VectorXi &rootsIndex,
                                                       Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic,1> &Ck)
{
  int numConstrained = isConstrained.sum();
  Ck.resize(numConstrained,1);
  // int n = rootsIndex.cols();

  Eigen::MatrixXi allCombs;
  {
    Eigen::VectorXi V = Eigen::VectorXi::LinSpaced(n,0,n-1);
    igl::nchoosek(V,k+1,allCombs);
  }

  int ind = 0;
  for (int fi = 0; fi <numF; ++fi)
  {
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b1 = B1.row(fi);
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b2 = B2.row(fi);
    if(isConstrained[fi])
    {
      std::complex<typename DerivedV::Scalar> ck(0);

      for (int j = 0; j < allCombs.rows(); ++j)
      {
        std::complex<typename DerivedV::Scalar> tk(1.);
        //collect products
        for (int i = 0; i < allCombs.cols(); ++i)
        {
          int index = allCombs(j,i);

          int ri = rootsIndex[index];
          Eigen::Matrix<typename DerivedV::Scalar, 1, 3> w;
          if (ri>0)
            w = cfW.block(fi,3*(ri-1),1,3);
          else
            w = -cfW.block(fi,3*(-ri-1),1,3);
          typename DerivedV::Scalar w0 = w.dot(b1);
          typename DerivedV::Scalar w1 = w.dot(b2);
          std::complex<typename DerivedV::Scalar> u(w0,w1);
          tk*= u;
        }
        //collect sum
        ck += tk;
      }
      Ck(ind) = ck;
      ind ++;
    }
  }


}
Example #21
0
void relabelFaces(Eigen::MatrixXi& aggregated,
                  const Eigen::MatrixXd& vertices,
                  const Eigen::MatrixXi& faces,
                  Eigen::Vector3i& vertexOffset,
                  int& offset) {
  for (int i = 0; i < faces.rows(); i++) {
    aggregated.row(offset++) = vertexOffset + Eigen::Vector3i(faces.row(i));
  }
  int numVerts = vertices.rows();
  vertexOffset += Eigen::Vector3i(numVerts, numVerts, numVerts);
}
IGL_INLINE void igl::remove_unreferenced(
  const Eigen::PlainObjectBase<DerivedV> &V,
  const Eigen::PlainObjectBase<DerivedF> &F,
  Eigen::PlainObjectBase<DerivedNV> &NV,
  Eigen::PlainObjectBase<DerivedNF> &NF,
  Eigen::PlainObjectBase<DerivedI> &I)
{

  // Mark referenced vertices
  Eigen::MatrixXi mark = Eigen::MatrixXi::Zero(V.rows(),1);
  
  for(int i=0; i<F.rows(); ++i)
  {
    for(int j=0; j<F.cols(); ++j)
    {
      if (F(i,j) != -1)
        mark(F(i,j)) = 1;
    }
  }
  
  // Sum the occupied cells 
  int newsize = mark.sum();
  
  NV.resize(newsize,V.cols());
  I.resize(V.rows(),1);
  
  // Do a pass on the marked vector and remove the unreferenced vertices
  int count = 0;
  for(int i=0;i<mark.rows();++i)
  {
    if (mark(i) == 1)
    {
      NV.row(count) = V.row(i);
      I(i) = count;
      count++;
    }
    else
    {
      I(i) = -1;
    }
  }

  NF.resize(F.rows(),F.cols());

  // Apply I on F
  for (int i=0; i<F.rows(); ++i)
  {
    Eigen::RowVectorXi t(F.cols());
    for (int j=0; j<F.cols(); ++j)
      t(j) = I(F(i,j));

    NF.row(i) = t;
  }
}
/*!
*  \brief      Convert cv::Mat to integer Eigen matrix
*  \author     Sascha Kaden
*  \param[in]  image
*  \param[out] Eigen matrix
*  \date       2016-12-18
*/
cv::Mat eigenToCV(Eigen::MatrixXi eigenMat) {
    cv::Mat cvMat(eigenMat.rows(), eigenMat.cols(), CV_32SC1, eigenMat.data());

    if (Eigen::RowMajorBit)
        cv::transpose(cvMat, cvMat);

    cv::Mat dst;
    cvMat.convertTo(dst, CV_8UC1);
    cv::cvtColor(dst, dst, CV_GRAY2BGR);

    return dst;
}
Example #24
0
void init_C(const Eigen::MatrixXi & F)
{
  using namespace Eigen;
  using namespace igl;
  using namespace std;
  C.resize(F.rows(),3);
  for(int c = 0;c<F.rows();c++)
  {
    C(c,0) = C(c,1) = C(c,2) = (double)c/F.rows();
    //jet((double)c/F.rows(),C(c,0),C(c,1),C(c,2));
  }
}
Example #25
0
int main(int argc, char *argv[])
{
  using namespace Eigen;
  using namespace std;
  igl::readOBJ(TUTORIAL_SHARED_PATH "/bump-domain.obj",V,F);
  U=V;
  // Find boundary vertices outside annulus
  typedef Matrix<bool,Dynamic,1> VectorXb;
  VectorXb is_outer = (V.rowwise().norm().array()-1.0)>-1e-15;
  VectorXb is_inner = (V.rowwise().norm().array()-0.15)<1e-15;
  VectorXb in_b = is_outer.array() || is_inner.array();
  igl::colon<int>(0,V.rows()-1,b);
  b.conservativeResize(stable_partition( b.data(), b.data()+b.size(),
   [&in_b](int i)->bool{return in_b(i);})-b.data());
  bc.resize(b.size(),1);
  for(int bi = 0;bi<b.size();bi++)
  {
    bc(bi) = (is_outer(b(bi))?0.0:1.0);
  }


  // Pseudo-color based on selection
  MatrixXd C(F.rows(),3);
  RowVector3d purple(80.0/255.0,64.0/255.0,255.0/255.0);
  RowVector3d gold(255.0/255.0,228.0/255.0,58.0/255.0);
  for(int f = 0;f<F.rows();f++)
  {
    if( in_b(F(f,0)) && in_b(F(f,1)) && in_b(F(f,2)))
    {
      C.row(f) = purple;
    }else
    {
      C.row(f) = gold;
    }
  }

  // Plot the mesh with pseudocolors
  igl::viewer::Viewer viewer;
  viewer.data.set_mesh(U, F);
  viewer.core.show_lines = false;
  viewer.data.set_colors(C);
  viewer.core.trackball_angle = Eigen::Quaternionf(0.81,-0.58,-0.03,-0.03);
  viewer.core.trackball_angle.normalize();
  viewer.callback_pre_draw = &pre_draw;
  viewer.callback_key_down = &key_down;
  viewer.core.is_animating = true;
  viewer.core.animation_max_fps = 30.;
  cout<<
    "Press [space] to toggle animation."<<endl<<
    "Press '.' to increase k."<<endl<<
    "Press ',' to decrease k."<<endl;
  viewer.launch();
}
Example #26
0
void parse_rhs(
  const int nrhs, 
  const mxArray *prhs[], 
  Eigen::MatrixXd & V,
  Eigen::MatrixXi & F,
  Eigen::MatrixXd & P,
  Eigen::MatrixXd & N,
  int & num_samples)
{
  using namespace std;
  if(nrhs < 5)
  {
    mexErrMsgTxt("nrhs < 5");
  }

  const int dim = mxGetN(prhs[0]);
  if(dim != 3)
  {
    mexErrMsgTxt("Mesh vertex list must be #V by 3 list of vertex positions");
  }
  if(dim != (int)mxGetN(prhs[1]))
  {
   mexErrMsgTxt("Mesh facet size must be 3");
  }
  if(mxGetN(prhs[2]) != dim)
  {
    mexErrMsgTxt("Point list must be #P by 3 list of origin locations");
  }
  if(mxGetN(prhs[3]) != dim)
  {
    mexErrMsgTxt("Normal list must be #P by 3 list of origin normals");
  }
  if(mxGetN(prhs[4]) != 1 || mxGetM(prhs[4]) != 1)
  {
    mexErrMsgTxt("Number of samples must be scalar.");
  }


  V.resize(mxGetM(prhs[0]),mxGetN(prhs[0]));
  copy(mxGetPr(prhs[0]),mxGetPr(prhs[0])+V.size(),V.data());
  F.resize(mxGetM(prhs[1]),mxGetN(prhs[1]));
  copy(mxGetPr(prhs[1]),mxGetPr(prhs[1])+F.size(),F.data());
  F.array() -= 1;
  P.resize(mxGetM(prhs[2]),mxGetN(prhs[2]));
  copy(mxGetPr(prhs[2]),mxGetPr(prhs[2])+P.size(),P.data());
  N.resize(mxGetM(prhs[3]),mxGetN(prhs[3]));
  copy(mxGetPr(prhs[3]),mxGetPr(prhs[3])+N.size(),N.data());
  if(*mxGetPr(prhs[4]) != (int)*mxGetPr(prhs[4]))
  {
    mexErrMsgTxt("Number of samples should be non negative integer.");
  }
  num_samples = (int) *mxGetPr(prhs[4]);
}
Example #27
0
TEST(CSGTree, extrusion) {
    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    test_common::load_mesh("extrusion.obj", V, F);
    igl::copyleft::cgal::CSGTree tree(V, F);
    igl::copyleft::cgal::CSGTree inter(tree, tree, "i"); // returns error

    Eigen::MatrixXd V2 = inter.cast_V<Eigen::MatrixXd>();
    Eigen::MatrixXi F2 = inter.F();

    ASSERT_EQ(V.rows(), V2.rows());
    ASSERT_EQ(F.rows(), F2.rows());
}
Example #28
0
bool key_down(igl::viewer::Viewer& viewer, unsigned char key, int modifier)
{
  using namespace std;
  using namespace Eigen;

  // Plot the original quad mesh
  if (key == '1')
  {
    // Draw the triangulated quad mesh
    viewer.data.set_mesh(VQC, FQCtri);

    // Assign a color to each quad that corresponds to its planarity
    VectorXd planarity;
    igl::quad_planarity( VQC, FQC, planarity);
    MatrixXd Ct;
    igl::jet(planarity, 0, 0.01, Ct);
    MatrixXd C(FQCtri.rows(),3);
    C << Ct, Ct;
    viewer.data.set_colors(C);

    // Plot a line for each edge of the quad mesh
    viewer.data.add_edges(PQC0, PQC1, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC1, PQC2, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC2, PQC3, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC3, PQC0, Eigen::RowVector3d(0,0,0));
  }

  // Plot the planarized quad mesh
  if (key == '2')
  {
    // Draw the triangulated quad mesh
    viewer.data.set_mesh(VQCplan, FQCtri);

    // Assign a color to each quad that corresponds to its planarity
    VectorXd planarity;
    igl::quad_planarity( VQCplan, FQC, planarity);
    MatrixXd Ct;
    igl::jet(planarity, 0, 0.01, Ct);
    MatrixXd C(FQCtri.rows(),3);
    C << Ct, Ct;
    viewer.data.set_colors(C);

    // Plot a line for each edge of the quad mesh
    viewer.data.add_edges(PQC0plan, PQC1plan, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC1plan, PQC2plan, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC2plan, PQC3plan, Eigen::RowVector3d(0,0,0));
    viewer.data.add_edges(PQC3plan, PQC0plan, Eigen::RowVector3d(0,0,0));
  }

  return false;
}
Example #29
0
void velocity_filter_ACM(
  const Eigen::MatrixXd & V0, 
  Eigen::MatrixXd & V1, 
  const Eigen::MatrixXi & F0, 
  double outer,
  double inner,
  int numinfinite)
{
  using namespace Eigen;
  using namespace std;

  Matrix3Xi F0_t(3,F0.rows());
  for (int k=0; k<F0.rows();k++){
      F0_t(0,k) = F0(k,0);
      F0_t(1,k) = F0(k,1);
      F0_t(2,k) = F0(k,2);
  }

  VectorXd qstart(3*V0.rows());
  VectorXd qend(3*V0.rows());
  for (int k=0; k<V0.rows();k++){
      qstart(3*k) = V0(k,0);
      qstart(3*k+1) = V0(k,1);
      qstart(3*k+2) = V0(k,2);
  }
  for (int k=0; k<V0.rows();k++){
      qend(3*k) = V1(k,0);
      qend(3*k+1) = V1(k,1);
      qend(3*k+2) = V1(k,2);
  }
  VectorXd invmasses(3*V0.rows());
  for (int k=0; k<3*numinfinite; k++){
      invmasses(k) = 0.0;
  }
  for (int k=3*numinfinite; k<3*V0.rows(); k++){
      invmasses(k) = 1.0;
  }

  int sim_status = VelocityFilter::velocityFilter(qstart, qend, F0_t, invmasses, outer, inner);
  cout << "simultaion_status = " << sim_status << endl;

  for (int k=0; k<V0.rows(); k++){
      V1(k,0) = qend(3*k);
      V1(k,1) = qend(3*k+1);
      V1(k,2) = qend(3*k+2);
  }

  return;
}
Example #30
0
int main(int argc, char *argv[])
{
  using namespace Eigen;
  using namespace std;

  cout<<"Usage:"<<endl;
  cout<<"[space]  toggle showing input mesh, output mesh or slice "<<endl;
  cout<<"         through tet-mesh of convex hull."<<endl;
  cout<<"'.'/','  push back/pull forward slicing plane."<<endl;
  cout<<endl;

  // Load mesh: (V,T) tet-mesh of convex hull, F contains facets of input
  // surface mesh _after_ self-intersection resolution
  igl::readMESH(TUTORIAL_SHARED_PATH "/big-sigcat.mesh",V,T,F);

  // Compute barycenters of all tets
  igl::barycenter(V,T,BC);

  // Compute generalized winding number at all barycenters
  cout<<"Computing winding number over all "<<T.rows()<<" tets..."<<endl;
  igl::winding_number(V,F,BC,W);

  // Extract interior tets
  MatrixXi CT((W.array()>0.5).count(),4);
  {
    size_t k = 0;
    for(size_t t = 0;t<T.rows();t++)
    {
      if(W(t)>0.5)
      {
        CT.row(k) = T.row(t);
        k++;
      }
    }
  }
  // find bounary facets of interior tets
  igl::boundary_facets(CT,G);
  // boundary_facets seems to be reversed...
  G = G.rowwise().reverse().eval();

  // normalize
  W = (W.array() - W.minCoeff())/(W.maxCoeff()-W.minCoeff());

  // Plot the generated mesh
  igl::opengl::glfw::Viewer viewer;
  update_visualization(viewer);
  viewer.callback_key_down = &key_down;
  viewer.launch();
}