浏览代码

boundary facets test

Alec Jacobson 6 年之前
父节点
当前提交
418d48ead3
共有 3 个文件被更改,包括 106 次插入22 次删除
  1. 20 19
      include/igl/boundary_facets.cpp
  2. 16 3
      include/igl/boundary_facets.h
  3. 70 0
      tests/include/igl/boundary_facets.cpp

+ 20 - 19
include/igl/boundary_facets.cpp

@@ -15,11 +15,31 @@
 #include <map>
 #include <iostream>
 
+#include "list_to_matrix.h"
+#include "matrix_to_list.h"
+
+template <typename DerivedT, typename DerivedF>
+IGL_INLINE void igl::boundary_facets(
+  const Eigen::MatrixBase<DerivedT>& T,
+  Eigen::PlainObjectBase<DerivedF>& F)
+{
+  assert(T.cols() == 0 || T.cols() == 4 || T.cols() == 3);
+  using namespace std;
+  using namespace Eigen;
+  // Cop out: use vector of vectors version
+  vector<vector<typename DerivedT::Scalar> > vT;
+  matrix_to_list(T,vT);
+  vector<vector<typename DerivedF::Scalar> > vF;
+  boundary_facets(vT,vF);
+  list_to_matrix(vF,F);
+}
+
 template <typename IntegerT, typename IntegerF>
 IGL_INLINE void igl::boundary_facets(
   const std::vector<std::vector<IntegerT> > & T,
   std::vector<std::vector<IntegerF> > & F)
 {
+  // Kept for legacy reasons. Could probably just delete.
   using namespace std;
 
   if(T.size() == 0)
@@ -98,25 +118,6 @@ IGL_INLINE void igl::boundary_facets(
 
 }
 
-#include "list_to_matrix.h"
-#include "matrix_to_list.h"
-
-template <typename DerivedT, typename DerivedF>
-IGL_INLINE void igl::boundary_facets(
-  const Eigen::MatrixBase<DerivedT>& T,
-  Eigen::PlainObjectBase<DerivedF>& F)
-{
-  assert(T.cols() == 0 || T.cols() == 4 || T.cols() == 3);
-  using namespace std;
-  using namespace Eigen;
-  // Cop out: use vector of vectors version
-  vector<vector<typename DerivedT::Scalar> > vT;
-  matrix_to_list(T,vT);
-  vector<vector<typename DerivedF::Scalar> > vF;
-  boundary_facets(vT,vF);
-  list_to_matrix(vF,F);
-}
-
 template <typename DerivedT, typename Ret>
 Ret igl::boundary_facets(
   const Eigen::MatrixBase<DerivedT>& T)

+ 16 - 3
include/igl/boundary_facets.h

@@ -18,15 +18,28 @@ namespace igl
   // BOUNDARY_FACETS Determine boundary faces (edges) of tetrahedra (triangles)
   // stored in T (analogous to qptoolbox's `outline` and `boundary_faces`).
   //
-  // Templates:
-  //   IntegerT  integer-value: e.g. int
-  //   IntegerF  integer-value: e.g. int
   // Input:
   //  T  tetrahedron (triangle) index list, m by 4 (3), where m is the number of tetrahedra
   // Output:
   //  F  list of boundary faces, n by 3 (2), where n is the number of boundary faces
+  //  J  list of indices into T, n by 1
+  //  K  list of indices revealing across from which vertex is this facet
   //
   //
+  template <
+    typename DerivedT, 
+    typename DerivedF,
+    typename DerivedJ,
+    typename DerivedK>
+  IGL_INLINE void boundary_facets(
+    const Eigen::MatrixBase<DerivedT>& T,
+    Eigen::PlainObjectBase<DerivedF>& F,
+    Eigen::PlainObjectBase<DerivedJ>& J,
+    Eigen::PlainObjectBase<DerivedK>& K);
+  template <typename DerivedT, typename DerivedF>
+  IGL_INLINE void boundary_facets(
+    const Eigen::MatrixBase<DerivedT>& T,
+    Eigen::PlainObjectBase<DerivedF>& F);
   template <typename IntegerT, typename IntegerF>
   IGL_INLINE void boundary_facets(
     const std::vector<std::vector<IntegerT> > & T,

+ 70 - 0
tests/include/igl/boundary_facets.cpp

@@ -0,0 +1,70 @@
+#include <test_common.h>
+#include <igl/boundary_facets.h>
+#include <igl/sort.h>
+#include <igl/sortrows.h>
+#include <igl/setxor.h>
+
+
+TEST_CASE("boundary_facets: single_tet", "[igl]")
+{
+  const Eigen::MatrixXi T = 
+    (Eigen::MatrixXi(1,4)<<0,1,2,3).finished();
+  Eigen::MatrixXi F;
+  Eigen::MatrixXi J;
+  Eigen::MatrixXi K;
+  igl::boundary_facets(T,F);
+  REQUIRE( F.rows () == 4 );
+  // sorted! (unoriented)
+  const Eigen::MatrixXi sorted_Fgt = 
+    (Eigen::MatrixXi(4,3) << 
+     0,1,2,
+     0,1,3,
+     0,2,3,
+     1,2,3).finished();
+  Eigen::MatrixXi sorted_F;
+  {
+    Eigen::MatrixXi _1;
+    igl::sort(F,2,true, sorted_F,_1);
+    igl::sortrows(Eigen::MatrixXi(sorted_F),true,sorted_F,_1);
+  }
+  test_common::assert_eq(sorted_Fgt,sorted_F);
+}
+
+TEST_CASE("boundary_facets: single_cube", "[igl]")
+{
+  const Eigen::MatrixXi T = 
+    (Eigen::MatrixXi(6,4)<<
+    0,1,7,5,
+    0,7,4,5,
+    0,1,3,7,
+    0,3,2,7,
+    0,6,4,7,
+    0,2,6,7).finished();
+  const Eigen::MatrixXi Fgt = 
+    (Eigen::MatrixXi(12,3)<<
+    0,5,4,
+    0,1,5,
+    6,7,2,
+    7,3,2,
+    4,6,0,
+    6,2,0,
+    1,7,5,
+    1,3,7,
+    0,3,1,
+    0,2,3,
+    5,7,4,
+    7,6,4).finished();
+  Eigen::MatrixXi F;
+  igl::boundary_facets(T,F);
+  const auto sortF = [](const Eigen::MatrixXi & F)-> Eigen::MatrixXi
+  {
+    Eigen::MatrixXi sorted_F;
+    Eigen::MatrixXi _1;
+    igl::sort(F,2,true, sorted_F,_1);
+    igl::sortrows(Eigen::MatrixXi(sorted_F),true,sorted_F,_1);
+    return sorted_F;
+  };
+  Eigen::MatrixXi sorted_F = sortF(F);
+  Eigen::MatrixXi sorted_Fgt = sortF(Fgt);
+  test_common::assert_eq(sorted_Fgt,sorted_F);
+}