Browse Source

enable mixed polygons using convention that negative indices are ignored (#2338)

* enable mixed polygons using convention that negative indices are ignored

* add unit tests

---------

Co-authored-by: Bryn Lloyd <[email protected]>
Bryn Lloyd 1 year ago
parent
commit
293e79ff86

+ 2 - 2
include/igl/copyleft/tetgen/mesh_to_tetgenio.cpp

@@ -65,10 +65,10 @@ IGL_INLINE void igl::copyleft::tetgen::mesh_to_tetgenio(
     f->numberofholes = 0;
     f->numberofholes = 0;
     f->holelist = NULL;
     f->holelist = NULL;
     tetgenio::polygon * p = &f->polygonlist[0];
     tetgenio::polygon * p = &f->polygonlist[0];
-    p->numberofvertices = F.cols();
+    p->numberofvertices = (F.row(i).array() >= 0).count();
     p->vertexlist = new int[p->numberofvertices];
     p->vertexlist = new int[p->numberofvertices];
     // loop around face
     // loop around face
-    for(int j = 0;j < F.cols(); j++)
+    for(int j = 0;j < p->numberofvertices; j++)
     {
     {
       p->vertexlist[j] = F(i,j);
       p->vertexlist[j] = F(i,j);
     }
     }

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

@@ -51,6 +51,11 @@ namespace igl
       ///     holes, duplicate faces etc.)
       ///     holes, duplicate faces etc.)
       ///   -1 other error
       ///   -1 other error
       ///
       ///
+      /// \note The polygons F can contain polygons with different number of vertices.
+      /// Trailing unused columns are filled with -1. For example, triangles and
+      /// segments can be specified using a #F x 3 matrix: for segments the third 
+      /// column contains -1.
+      ///
       /// \note Tetgen mixes integer region ids in with other region data `attr
       /// \note Tetgen mixes integer region ids in with other region data `attr
       /// = (int) in->regionlist[i + 3];`. So it's declared safe to use integer
       /// = (int) in->regionlist[i + 3];`. So it's declared safe to use integer
       /// types for `TR` since this also assumes that there's a single tet
       /// types for `TR` since this also assumes that there's a single tet

+ 41 - 0
tests/include/igl/copyleft/tetgen/tetrahedralize.cpp

@@ -101,3 +101,44 @@ TEST_CASE("tetrahedralize: schoenhardt", "[igl/copyleft/tetgen]")
   igl::copyleft::tetgen::tetrahedralize(V,F,"pQ",TV,TT,TF);
   igl::copyleft::tetgen::tetrahedralize(V,F,"pQ",TV,TT,TF);
   REQUIRE (V.rows() <= TV.rows());
   REQUIRE (V.rows() <= TV.rows());
 }
 }
+
+TEST_CASE("tetrahedralize: quad_face", "[igl/copyleft/tetgen]")
+{
+  const Eigen::MatrixXd V = (Eigen::MatrixXd(5,3)<<
+    -1.0,0.0,0.0,
+    0.0,-1.0,0.0,
+    1.0,0.0,0.0,
+    0.0,1.0,0.0,
+    0.0,0.0,1.0).finished();
+  const Eigen::MatrixXi F = (Eigen::MatrixXi(5,4)<<
+    0,1,2,3,
+    0,1,4,-1,
+    1,2,4,-1,
+    2,3,4,-1,
+    3,0,4,-1).finished();
+  Eigen::MatrixXd TV;
+  Eigen::MatrixXi TT,TF;
+  igl::copyleft::tetgen::tetrahedralize(V,F,"pQ",TV,TT,TF);
+  REQUIRE (TT.rows() == 2);
+}
+
+TEST_CASE("tetrahedralize: embedded_segment", "[igl/copyleft/tetgen]")
+{
+  const Eigen::MatrixXd V = (Eigen::MatrixXd(6,3)<<
+    -0.5,0.5,0.0,
+    0.0,-1.0,0.0,
+    0.5,0.5,0.0,
+    0.0,0.0,1.0,
+    0.0,0.0,0.2,
+    0.0,0.0,0.9).finished();
+  const Eigen::MatrixXi F = (Eigen::MatrixXi(5,3)<<
+    0,1,2,
+    1,3,2,
+    0,2,3,
+    1,0,3,
+    4,5,-1).finished();
+  Eigen::MatrixXd TV;
+  Eigen::MatrixXi TT,TF;
+  igl::copyleft::tetgen::tetrahedralize(V,F,"pQ",TV,TT,TF);
+  REQUIRE (TT.rows() == 7);
+}