mesh_boolean.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <test_common.h>
  2. #include <vector>
  3. #include <igl/boolean/mesh_boolean.h>
  4. #include <igl/boolean/MeshBooleanType.h>
  5. #include <igl/exterior_edges.h>
  6. #include <igl/is_vertex_manifold.h>
  7. namespace mesh_boolean_test {
  8. template<typename DerivedF>
  9. void assert_no_exterior_edges(
  10. const Eigen::PlainObjectBase<DerivedF>& F) {
  11. Eigen::MatrixXi Eb;
  12. igl::exterior_edges(F, Eb);
  13. ASSERT_EQ(0, Eb.rows());
  14. }
  15. template<typename DerivedV, typename DerivedF>
  16. void assert_is_manifold(
  17. const Eigen::PlainObjectBase<DerivedV>& V,
  18. const Eigen::PlainObjectBase<DerivedF>& F) {
  19. Eigen::MatrixXi B;
  20. ASSERT_TRUE(igl::is_vertex_manifold(F, B));
  21. ASSERT_TRUE(igl::is_edge_manifold(V, F));
  22. }
  23. template<typename DerivedV, typename DerivedF>
  24. void assert_genus_eq(
  25. const Eigen::PlainObjectBase<DerivedV>& V,
  26. const Eigen::PlainObjectBase<DerivedF>& F,
  27. const int genus) {
  28. const int num_vertices = V.rows();
  29. const int num_faces = F.rows();
  30. Eigen::Matrix<
  31. typename DerivedF::Scalar,
  32. Eigen::Dynamic,
  33. Eigen::Dynamic>
  34. E, uE, EMAP;
  35. std::vector<std::vector<size_t> > uE2E;
  36. igl::unique_edge_map(F, E, uE, EMAP, uE2E);
  37. const int num_edges = uE.rows();
  38. const int euler = num_vertices - num_edges + num_faces;
  39. ASSERT_EQ(euler, 2 - 2 * genus);
  40. }
  41. TEST(MeshBoolean, TwoCubes) {
  42. Eigen::MatrixXd V1;
  43. Eigen::MatrixXi F1;
  44. test_common::load_mesh("two-boxes-bad-self-union.ply", V1, F1);
  45. Eigen::MatrixXd V2(0, 3);
  46. Eigen::MatrixXi F2(0, 3);
  47. Eigen::MatrixXd Vo;
  48. Eigen::MatrixXi Fo;
  49. igl::boolean::mesh_boolean(V1, F1, V2, F2,
  50. igl::boolean::MESH_BOOLEAN_TYPE_UNION,
  51. Vo, Fo);
  52. assert_no_exterior_edges(Fo);
  53. assert_is_manifold(Vo, Fo);
  54. assert_genus_eq(Vo, Fo, 0);
  55. }
  56. TEST(MeshBoolean, MinusTest) {
  57. // Many thanks to Eric Yao for submitting this test case.
  58. Eigen::MatrixXd V1, V2, Vo;
  59. Eigen::MatrixXi F1, F2, Fo;
  60. test_common::load_mesh("boolean_minus_test_cube.obj", V1, F1);
  61. test_common::load_mesh("boolean_minus_test_green.obj", V2, F2);
  62. igl::boolean::mesh_boolean(V1, F1, V2, F2,
  63. igl::boolean::MESH_BOOLEAN_TYPE_MINUS,
  64. Vo, Fo);
  65. assert_no_exterior_edges(Fo);
  66. assert_is_manifold(Vo, Fo);
  67. assert_genus_eq(Vo, Fo, 1);
  68. }
  69. TEST(MeshBoolean, IntersectWithSelf) {
  70. Eigen::MatrixXd V1, Vo;
  71. Eigen::MatrixXi F1, Fo;
  72. test_common::load_mesh("cube.obj", V1, F1);
  73. igl::boolean::mesh_boolean(V1, F1, V1, F1,
  74. igl::boolean::MESH_BOOLEAN_TYPE_INTERSECT,
  75. Vo, Fo);
  76. assert_no_exterior_edges(Fo);
  77. assert_is_manifold(Vo, Fo);
  78. assert_genus_eq(Vo, Fo, 0);
  79. }
  80. }