浏览代码

Merge branch 'master' of github.com:libigl/libigl into alecjacobson

Former-commit-id: d9aa0d5fa6087080291de3f931de640a16a46131
Alec Jacobson 8 年之前
父节点
当前提交
cd78d3408b

+ 113 - 0
include/igl/copyleft/tetgen/tetrahedralize.cpp

@@ -100,7 +100,120 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
   return e;
   return e;
 }
 }
 
 
+template <
+  typename DerivedV, 
+  typename DerivedF, 
+  typename DerivedVM, 
+  typename DerivedFM, 
+  typename DerivedTV, 
+  typename DerivedTT, 
+  typename DerivedTF,
+  typename DerivedTM>
+IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  const Eigen::PlainObjectBase<DerivedVM>& VM,
+  const Eigen::PlainObjectBase<DerivedFM>& FM,
+  const std::string switches,
+  Eigen::PlainObjectBase<DerivedTV>& TV,
+  Eigen::PlainObjectBase<DerivedTT>& TT,
+  Eigen::PlainObjectBase<DerivedTF>& TF,
+  Eigen::PlainObjectBase<DerivedTM>& TM)
+{
+  using namespace std;
+  vector<vector<REAL> > vV,vTV;
+  vector<vector<int> > vF,vTT,vTF;
+  vector<int> vTM;
+	
+  matrix_to_list(V,vV);
+  matrix_to_list(F,vF);
+	vector<int> vVM = matrix_to_list(VM);
+	vector<int> vFM = matrix_to_list(FM);
+  int e = tetrahedralize(vV,vF,vVM,vFM,switches,vTV,vTT,vTF,vTM);
+  if(e == 0)
+  {
+    bool TV_rect = list_to_matrix(vTV,TV);
+    if(!TV_rect)
+    {
+      return false;
+    }
+    bool TT_rect = list_to_matrix(vTT,TT);
+    if(!TT_rect)
+    {
+      return false;
+    }
+    bool TF_rect = list_to_matrix(vTF,TF);
+    if(!TF_rect)
+    {
+      return false;
+    }
+    bool TM_rect = list_to_matrix(vTM,TM);
+    if(!TM_rect)
+    {
+      return false;
+    }
+  }
+  return e;
+}
+IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
+  const std::vector<std::vector<REAL > > & V, 
+  const std::vector<std::vector<int> > & F, 
+  const std::vector<int> & VM, 
+	const std::vector<int> & FM,
+  const std::string switches,
+  std::vector<std::vector<REAL > > & TV, 
+  std::vector<std::vector<int > > & TT, 
+  std::vector<std::vector<int> > & TF,
+  std::vector<int> & TM)
+{
+  using namespace std;
+  tetgenio in,out;
+  bool success;
+  success = mesh_to_tetgenio(V,F,in);
+  if(!success)
+  {
+    return -1;
+  }
+	in.pointmarkerlist = new int[VM.size()];
+	for (int i = 0; i < VM.size(); ++i) {
+		in.pointmarkerlist[i] = VM[i];
+	}
+  // These have already been created in mesh_to_tetgenio.
+  // Reset them here.
+	for (int i = 0; i < FM.size(); ++i) {
+		in.facetmarkerlist[i] = FM[i];
+	}
+  try
+  {
+    char * cswitches = new char[switches.size() + 1];
+    std::strcpy(cswitches,switches.c_str());
+    ::tetrahedralize(cswitches,&in, &out);
+    delete[] cswitches;
+  }catch(int e)
+  {
+    cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
+    return 1;
+  }
+  if(out.numberoftetrahedra == 0)
+  {
+    cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
+    return 2;
+  }
+  success = tetgenio_to_tetmesh(out,TV,TT,TF);
+  if(!success)
+  {
+    return -1;
+  }
+	TM.resize(out.numberofpoints);
+	for (int i = 0; i < out.numberofpoints; ++i) {
+		TM[i] = out.pointmarkerlist[i];
+	}
+  //boundary_facets(TT,TF);
+  return 0;
+}
+
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
 template int igl::copyleft::tetgen::tetrahedralize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template int igl::copyleft::tetgen::tetrahedralize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template int igl::copyleft::tetgen::tetrahedralize<Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 1, 0, -1, 1>,Eigen::Matrix<int, -1, 1, 0, -1, 1>,Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 1, 0, -1, 1> >(const Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > &,const Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &,const Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &,const Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &,const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > &,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
 #endif
 #endif

+ 56 - 0
include/igl/copyleft/tetgen/tetrahedralize.h

@@ -67,6 +67,62 @@ namespace igl
         Eigen::PlainObjectBase<DerivedTV>& TV,
         Eigen::PlainObjectBase<DerivedTV>& TV,
         Eigen::PlainObjectBase<DerivedTT>& TT,
         Eigen::PlainObjectBase<DerivedTT>& TT,
         Eigen::PlainObjectBase<DerivedTF>& TF);
         Eigen::PlainObjectBase<DerivedTF>& TF);
+      
+			// Mesh the interior of a surface mesh (V,F) using tetgen
+      //
+      // Inputs:
+      //   V  #V by 3 vertex position list
+      //   F  #F list of polygon face indices into V (0-indexed)
+			//   M  #V list of markers for vertices
+      //   switches  string of tetgen options (See tetgen documentation) e.g.
+      //     "pq1.414a0.01" tries to mesh the interior of a given surface with
+      //       quality and area constraints
+      //     "" will mesh the convex hull constrained to pass through V (ignores F)
+      // Outputs:
+      //   TV  #V by 3 vertex position list
+      //   TT  #T by 4 list of tet face indices
+      //   TF  #F by 3 list of triangle face indices
+			//   TM  #V list of markers for vertices
+      // Returns status:
+      //   0 success
+      //   1 tetgen threw exception
+      //   2 tetgen did not crash but could not create any tets (probably there are
+      //     holes, duplicate faces etc.)
+      //   -1 other error
+      IGL_INLINE int tetrahedralize(
+        const std::vector<std::vector<REAL > > & V, 
+        const std::vector<std::vector<int> > & F, 
+				const std::vector<int> & VM,
+				const std::vector<int> & FM,
+        const std::string switches,
+        std::vector<std::vector<REAL > > & TV, 
+        std::vector<std::vector<int > > & TT, 
+        std::vector<std::vector<int> > & TF,
+				std::vector<int> & TM);
+      
+      // Wrapper with Eigen types
+      // Templates:
+      //   DerivedV  real-value: i.e. from MatrixXd
+      //   DerivedF  integer-value: i.e. from MatrixXi
+      template <
+        typename DerivedV, 
+        typename DerivedF, 
+				typename DerivedVM,
+				typename DerivedFM,
+        typename DerivedTV, 
+        typename DerivedTT, 
+        typename DerivedTF, 
+        typename DerivedTM>
+      IGL_INLINE int tetrahedralize(
+        const Eigen::PlainObjectBase<DerivedV>& V,
+        const Eigen::PlainObjectBase<DerivedF>& F,
+        const Eigen::PlainObjectBase<DerivedVM>& VM,
+        const Eigen::PlainObjectBase<DerivedFM>& FM,
+        const std::string switches,
+        Eigen::PlainObjectBase<DerivedTV>& TV,
+        Eigen::PlainObjectBase<DerivedTT>& TT,
+        Eigen::PlainObjectBase<DerivedTF>& TF,
+        Eigen::PlainObjectBase<DerivedTM>& TM);
     }
     }
   }
   }
 }
 }

+ 2 - 2
include/igl/png/render_to_png.cpp

@@ -17,7 +17,7 @@ IGL_INLINE bool igl::png::render_to_png(
   const bool alpha,
   const bool alpha,
   const bool fast)
   const bool fast)
 {
 {
-  unsigned char * data = new unsigned char[width*height];
+  unsigned char * data = new unsigned char[4*width*height];
   glReadPixels(
   glReadPixels(
     0,
     0,
     0,
     0,
@@ -35,7 +35,7 @@ IGL_INLINE bool igl::png::render_to_png(
       data[4*(i+j*width)+3] = 255;
       data[4*(i+j*width)+3] = 255;
     }
     }
   }
   }
-  bool ret = stbi_write_png(png_file.c_str(), width, height, 4, data, width*sizeof(unsigned char));
+  bool ret = stbi_write_png(png_file.c_str(), width, height, 4, data, 4*width*sizeof(unsigned char));
   delete [] data;
   delete [] data;
   return ret;
   return ret;
 }
 }

+ 101 - 0
include/igl/triangle/triangulate.cpp

@@ -129,6 +129,107 @@ IGL_INLINE void igl::triangle::triangulate(
 
 
 }
 }
 
 
+// Allows use of markers
+IGL_INLINE void igl::triangle::triangulate(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& E,
+  const Eigen::MatrixXd& H,
+  const Eigen::VectorXi& VM,
+  const Eigen::VectorXi& EM,
+  const std::string flags,
+  Eigen::MatrixXd& V2,
+  Eigen::MatrixXi& F2,
+  Eigen::VectorXi& M2)
+{
+  using namespace std;
+  using namespace Eigen;
+
+  // Prepare the flags
+  string full_flags = flags + "pz";
+
+  // Prepare the input struct
+  triangulateio in;
+
+  assert(V.cols() == 2);
+
+  in.numberofpoints = V.rows();
+  in.pointlist = (double*)calloc(V.rows()*2,sizeof(double));
+  for (unsigned i=0;i<V.rows();++i)
+    for (unsigned j=0;j<2;++j)
+      in.pointlist[i*2+j] = V(i,j);
+
+  in.numberofpointattributes = 0;
+  in.pointmarkerlist = (int*)calloc(VM.rows(),sizeof(int));
+
+   for (unsigned i=0;i<VM.rows();++i) {
+     in.pointmarkerlist[i] = VM(i);
+   }
+
+  in.trianglelist = NULL;
+  in.numberoftriangles = 0;
+  in.numberofcorners = 0;
+  in.numberoftriangleattributes = 0;
+  in.triangleattributelist = NULL;
+
+  in.numberofsegments = E.rows();
+  in.segmentlist = (int*)calloc(E.rows()*2,sizeof(int));
+  for (unsigned i=0;i<E.rows();++i)
+    for (unsigned j=0;j<2;++j)
+      in.segmentlist[i*2+j] = E(i,j);
+  in.segmentmarkerlist = (int*)calloc(E.rows(),sizeof(int));
+  for (unsigned i=0;i<E.rows();++i)
+    in.segmentmarkerlist[i] = EM(i);
+
+  in.numberofholes = H.rows();
+  in.holelist = (double*)calloc(H.rows()*2,sizeof(double));
+  for (unsigned i=0;i<H.rows();++i)
+    for (unsigned j=0;j<2;++j)
+      in.holelist[i*2+j] = H(i,j);
+  in.numberofregions = 0;
+
+  // Prepare the output struct
+  triangulateio out;
+
+  out.pointlist = NULL;
+  out.trianglelist = NULL;
+  out.segmentlist = NULL;
+  out.segmentmarkerlist = NULL;
+  out.pointmarkerlist = NULL;
+
+  // Call triangle
+  ::triangulate(const_cast<char*>(full_flags.c_str()), &in, &out, 0);
+
+  // Return the mesh
+  V2.resize(out.numberofpoints,2);
+  for (unsigned i=0;i<V2.rows();++i)
+    for (unsigned j=0;j<2;++j)
+      V2(i,j) = out.pointlist[i*2+j];
+
+  F2.resize(out.numberoftriangles,3);
+  for (unsigned i=0;i<F2.rows();++i)
+    for (unsigned j=0;j<3;++j)
+      F2(i,j) = out.trianglelist[i*3+j];
+
+  M2.resize(out.numberofpoints);
+  for (unsigned int i = 0; i < out.numberofpoints; ++i) {
+    M2(i) = out.pointmarkerlist[i];
+  }
+
+  // Cleanup in
+  free(in.pointlist);
+  free(in.pointmarkerlist);
+  free(in.segmentlist);
+  free(in.segmentmarkerlist);
+  free(in.holelist);
+
+  // Cleanup out
+  free(out.pointlist);
+  free(out.trianglelist);
+  free(out.segmentlist);
+  free(out.segmentmarkerlist);
+  free(out.pointmarkerlist);
+}
+
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
 #endif
 #endif

+ 26 - 0
include/igl/triangle/triangulate.h

@@ -35,6 +35,32 @@ namespace igl
       const std::string flags,
       const std::string flags,
       Eigen::MatrixXd& V2,
       Eigen::MatrixXd& V2,
       Eigen::MatrixXi& F2);
       Eigen::MatrixXi& F2);
+		
+		// Triangulate the interior of a polygon using the triangle library.
+    //
+    // Inputs:
+    //   V #V by 2 list of 2D vertex positions
+    //   E #E by 2 list of vertex ids forming unoriented edges of the boundary of the polygon
+    //   H #H by 2 coordinates of points contained inside holes of the polygon
+		//   M #V list of markers for input vertices
+    //   flags  string of options pass to triangle (see triangle documentation)
+    // Outputs:
+    //   V2  #V2 by 2  coordinates of the vertives of the generated triangulation
+    //   F2  #F2 by 3  list of indices forming the faces of the generated triangulation
+		//   M2  #V2 list of markers for output vertices
+    //
+    // TODO: expose the option to prevent Steiner points on the boundary
+    //
+		IGL_INLINE void triangulate(
+			const Eigen::MatrixXd& V,
+			const Eigen::MatrixXi& E,
+			const Eigen::MatrixXd& H,
+			const Eigen::VectorXi& VM,
+			const Eigen::VectorXi& EM,
+			const std::string flags,
+			Eigen::MatrixXd& V2,
+			Eigen::MatrixXi& F2,
+			Eigen::VectorXi& M2);
   }
   }
 }
 }