Browse Source

merge into single call, use map for copying, segment markers exposed

Former-commit-id: 3cae90f26019c1f1344237b279e00ba914d6de1a
Alec Jacobson 8 năm trước cách đây
mục cha
commit
08e3c26b1f
2 tập tin đã thay đổi với 110 bổ sung150 xóa
  1. 76 132
      include/igl/triangle/triangulate.cpp
  2. 34 18
      include/igl/triangle/triangulate.h

+ 76 - 132
include/igl/triangle/triangulate.cpp

@@ -42,128 +42,75 @@ extern "C"
 #  define VOID IGL_PREVIOUSLY_DEFINED_VOID
 #endif
 
+template <
+ typename DerivedV,
+ typename DerivedE,
+ typename DerivedH,
+ typename DerivedV2,
+ typename DerivedF2>
 IGL_INLINE void igl::triangle::triangulate(
-  const Eigen::MatrixXd& V,
-  const Eigen::MatrixXi& E,
-  const Eigen::MatrixXd& H,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedE> & E,
+  const Eigen::MatrixBase<DerivedH> & H,
   const std::string flags,
-  Eigen::MatrixXd& V2,
-  Eigen::MatrixXi& F2)
+  Eigen::PlainObjectBase<DerivedV2> & V2,
+  Eigen::PlainObjectBase<DerivedF2> & F2)
 {
-  using namespace std;
-  using namespace Eigen;
-
-  // Prepare the flags
-  string full_flags = flags + "pzB";
-
-  // 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(V.rows(),sizeof(int));
-   for (unsigned i=0;i<V.rows();++i)
-     in.pointmarkerlist[i] = 1;
-
-  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] = 1;
-
-  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;
-
-  // 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];
-
-  // 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);
-
+  Eigen::VectorXi VM,EM,VM2,EM2;
+  return triangulate(V,E,H,VM,EM,flags,V2,F2,VM2,EM2);
 }
 
-// Allows use of markers
+template <
+ typename DerivedV,
+ typename DerivedE,
+ typename DerivedH,
+ typename DerivedVM,
+ typename DerivedEM,
+ typename DerivedV2,
+ typename DerivedF2,
+ typename DerivedVM2,
+ typename DerivedEM2>
 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 Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedE> & E,
+  const Eigen::MatrixBase<DerivedH> & H,
+  const Eigen::MatrixBase<DerivedVM> & VM,
+  const Eigen::MatrixBase<DerivedEM> & EM,
   const std::string flags,
-  Eigen::MatrixXd& V2,
-  Eigen::MatrixXi& F2,
-  Eigen::VectorXi& M2)
+  Eigen::PlainObjectBase<DerivedV2> & V2,
+  Eigen::PlainObjectBase<DerivedF2> & F2,
+  Eigen::PlainObjectBase<DerivedVM2> & VM2,
+  Eigen::PlainObjectBase<DerivedEM2> & EM2)
 {
   using namespace std;
   using namespace Eigen;
 
+  assert( (VM.size() == 0 || V.rows() == VM.size()) && 
+    "Vertex markers must be empty or same size as V");
+  assert( (EM.size() == 0 || E.rows() == EM.size()) && 
+    "Segment markers must be empty or same size as E");
+  assert(V.cols() == 2);
+  assert(E.size() == 0 || E.cols() == 2);
+  assert(H.size() == 0 || H.cols() == 2);
+
   // Prepare the flags
-  string full_flags = flags + "pz";
+  string full_flags = flags + "pz" + (EM.size() || VM.size() ? "B" : "");
+
+  typedef Map< Matrix<double,Dynamic,Dynamic,RowMajor> > MapXdr;
+  typedef Map< Matrix<int,Dynamic,Dynamic,RowMajor> > MapXir;
 
   // 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.pointlist = (double*)calloc(V.size(),sizeof(double));
+  {
+    MapXdr inpl(in.pointlist,V.rows(),V.cols());
+    inpl = V.template cast<double>();
+  }
 
   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.pointmarkerlist = (int*)calloc(VM.size(),sizeof(int));
+  for(unsigned i=0;i<VM.rows();++i) in.pointmarkerlist[i] = VM.size()?VM(i):1;
 
   in.trianglelist = NULL;
   in.numberoftriangles = 0;
@@ -171,25 +118,25 @@ IGL_INLINE void igl::triangle::triangulate(
   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.numberofsegments = E.size()?E.rows():0;
+  in.segmentlist = (int*)calloc(E.size(),sizeof(int));
+  {
+    MapXir insl(in.segmentlist,E.rows(),E.cols());
+    insl = E.template cast<int>();
+  }
   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);
+  for (unsigned i=0;i<E.rows();++i) in.segmentmarkerlist[i] = EM.size()?EM(i):1;
+
+  in.numberofholes = H.size()?H.rows():0;
+  in.holelist = (double*)calloc(H.size(),sizeof(double));
+  {
+    MapXdr inhl(in.holelist,H.rows(),H.cols());
+    inhl = H.template cast<double>();
+  }
   in.numberofregions = 0;
 
   // Prepare the output struct
   triangulateio out;
-
   out.pointlist = NULL;
   out.trianglelist = NULL;
   out.segmentlist = NULL;
@@ -200,19 +147,15 @@ IGL_INLINE void igl::triangle::triangulate(
   ::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];
+  V2 = MapXdr(out.pointlist,out.numberofpoints,2).cast<typename DerivedV2::Scalar>();
+  F2 = MapXir(out.trianglelist,out.numberoftriangles,3).cast<typename DerivedF2::Scalar>();
+  if(VM.size())
+  {
+    VM2 = MapXir(out.pointmarkerlist,out.numberofpoints,1).cast<typename DerivedVM2::Scalar>();
+  }
+  if(EM.size())
+  {
+    EM2 = MapXir(out.segmentmarkerlist,out.numberofsegments,1).cast<typename DerivedEM2::Scalar>();
   }
 
   // Cleanup in
@@ -221,7 +164,6 @@ IGL_INLINE void igl::triangle::triangulate(
   free(in.segmentlist);
   free(in.segmentmarkerlist);
   free(in.holelist);
-
   // Cleanup out
   free(out.pointlist);
   free(out.trianglelist);
@@ -232,4 +174,6 @@ IGL_INLINE void igl::triangle::triangulate(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::triangle::triangulate<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -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> >&);
 #endif

+ 34 - 18
include/igl/triangle/triangulate.h

@@ -1,6 +1,7 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 //
 // Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
+// Copyright (C) 2017 Alec Jacobson
 //
 // This Source Code Form is subject to the terms of the Mozilla Public License
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -26,16 +27,20 @@ namespace igl
     //   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
     //
-    // TODO: expose the option to prevent Steiner points on the boundary
-    //
+    template <
+      typename DerivedV,
+      typename DerivedE,
+      typename DerivedH,
+      typename DerivedV2,
+      typename DerivedF2>
     IGL_INLINE void triangulate(
-      const Eigen::MatrixXd& V,
-      const Eigen::MatrixXi& E,
-      const Eigen::MatrixXd& H,
+      const Eigen::MatrixBase<DerivedV> & V,
+      const Eigen::MatrixBase<DerivedE> & E,
+      const Eigen::MatrixBase<DerivedH> & H,
       const std::string flags,
-      Eigen::MatrixXd& V2,
-      Eigen::MatrixXi& F2);
-		
+      Eigen::PlainObjectBase<DerivedV2> & V2,
+      Eigen::PlainObjectBase<DerivedF2> & F2);
+        
 		// Triangulate the interior of a polygon using the triangle library.
     //
     // Inputs:
@@ -51,16 +56,27 @@ namespace igl
     //
     // 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);
+    template <
+      typename DerivedV,
+      typename DerivedE,
+      typename DerivedH,
+      typename DerivedVM,
+      typename DerivedEM,
+      typename DerivedV2,
+      typename DerivedF2,
+      typename DerivedVM2,
+      typename DerivedEM2>
+    IGL_INLINE void triangulate(
+      const Eigen::MatrixBase<DerivedV> & V,
+      const Eigen::MatrixBase<DerivedE> & E,
+      const Eigen::MatrixBase<DerivedH> & H,
+      const Eigen::MatrixBase<DerivedVM> & VM,
+      const Eigen::MatrixBase<DerivedEM> & EM,
+      const std::string flags,
+      Eigen::PlainObjectBase<DerivedV2> & V2,
+      Eigen::PlainObjectBase<DerivedF2> & F2,
+      Eigen::PlainObjectBase<DerivedVM2> & VM2,
+      Eigen::PlainObjectBase<DerivedEM2> & EM2);
   }
 }