#include #include #include #include #include #include #include #include namespace { template void assert_no_exterior_edges( const Eigen::PlainObjectBase& F) { Eigen::MatrixXi Eb; igl::exterior_edges(F, Eb); REQUIRE (Eb.rows() == 0); } template void assert_is_manifold( const Eigen::PlainObjectBase& V, const Eigen::PlainObjectBase& F) { Eigen::MatrixXi B; REQUIRE (igl::is_vertex_manifold(F, B)); REQUIRE (igl::is_edge_manifold(F)); } template void assert_genus_eq( const Eigen::PlainObjectBase& V, const Eigen::PlainObjectBase& F, const int genus) { const int num_vertices = V.rows(); const int num_faces = F.rows(); Eigen::Matrix< typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> E, uE; Eigen::Matrix< typename DerivedF::Scalar, Eigen::Dynamic, 1> EMAP; std::vector > uE2E; igl::unique_edge_map(F, E, uE, EMAP, uE2E); const int num_edges = uE.rows(); const int euler = num_vertices - num_edges + num_faces; REQUIRE (2 - 2 * genus == euler); } } TEST_CASE("MeshBoolean: TwoCubes", "[igl/copyleft/boolean]") { Eigen::MatrixXd V1; Eigen::MatrixXi F1; igl::read_triangle_mesh(test_common::data_path("two-boxes-bad-self-union.ply"), V1, F1); Eigen::MatrixXd V2(0, 3); Eigen::MatrixXi F2(0, 3); Eigen::MatrixXd Vo; Eigen::MatrixXi Fo; igl::copyleft::cgal::mesh_boolean(V1, F1, V2, F2, igl::MESH_BOOLEAN_TYPE_UNION, Vo, Fo); assert_no_exterior_edges(Fo); assert_is_manifold(Vo, Fo); assert_genus_eq(Vo, Fo, 0); } TEST_CASE("MeshBoolean: MinusTest", "[igl/copyleft/boolean]") { // Many thanks to Eric Yao for submitting this test case. Eigen::MatrixXd V1, V2, Vo; Eigen::MatrixXi F1, F2, Fo; igl::read_triangle_mesh(test_common::data_path("boolean_minus_test_cube.obj"), V1, F1); igl::read_triangle_mesh(test_common::data_path("boolean_minus_test_green.obj"), V2, F2); igl::copyleft::cgal::mesh_boolean(V1, F1, V2, F2, igl::MESH_BOOLEAN_TYPE_MINUS, Vo, Fo); assert_no_exterior_edges(Fo); assert_is_manifold(Vo, Fo); assert_genus_eq(Vo, Fo, 1); } TEST_CASE("MeshBoolean: IntersectWithSelf", "[igl/copyleft/boolean]") { Eigen::MatrixXd V1, Vo; Eigen::MatrixXi F1, Fo; igl::read_triangle_mesh(test_common::data_path("cube.obj"), V1, F1); igl::copyleft::cgal::mesh_boolean(V1, F1, V1, F1, igl::MESH_BOOLEAN_TYPE_INTERSECT, Vo, Fo); assert_no_exterior_edges(Fo); assert_is_manifold(Vo, Fo); assert_genus_eq(Vo, Fo, 0); }