|
@@ -1,8 +1,52 @@
|
|
|
#include <test_common.h>
|
|
|
|
|
|
+#include <vector>
|
|
|
+
|
|
|
#include <igl/boolean/mesh_boolean.h>
|
|
|
#include <igl/boolean/MeshBooleanType.h>
|
|
|
#include <igl/exterior_edges.h>
|
|
|
+#include <igl/is_vertex_manifold.h>
|
|
|
+
|
|
|
+namespace mesh_boolean_test {
|
|
|
+
|
|
|
+ template<typename DerivedF>
|
|
|
+ void assert_no_exterior_edges(
|
|
|
+ const Eigen::PlainObjectBase<DerivedF>& F) {
|
|
|
+ Eigen::MatrixXi Eb;
|
|
|
+ igl::exterior_edges(F, Eb);
|
|
|
+
|
|
|
+ ASSERT_EQ(0, Eb.rows());
|
|
|
+ }
|
|
|
+
|
|
|
+ template<typename DerivedV, typename DerivedF>
|
|
|
+ void assert_is_manifold(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV>& V,
|
|
|
+ const Eigen::PlainObjectBase<DerivedF>& F) {
|
|
|
+ Eigen::MatrixXi B;
|
|
|
+ ASSERT_TRUE(igl::is_vertex_manifold(F, B));
|
|
|
+ ASSERT_TRUE(igl::is_edge_manifold(V, F));
|
|
|
+ }
|
|
|
+
|
|
|
+ template<typename DerivedV, typename DerivedF>
|
|
|
+ void assert_genus_eq(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV>& V,
|
|
|
+ const Eigen::PlainObjectBase<DerivedF>& 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, EMAP;
|
|
|
+ std::vector<std::vector<size_t> > 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;
|
|
|
+ ASSERT_EQ(euler, 2 - 2 * genus);
|
|
|
+ }
|
|
|
|
|
|
TEST(MeshBoolean, TwoCubes) {
|
|
|
Eigen::MatrixXd V1;
|
|
@@ -19,8 +63,39 @@ TEST(MeshBoolean, TwoCubes) {
|
|
|
igl::boolean::MESH_BOOLEAN_TYPE_UNION,
|
|
|
Vo, Fo);
|
|
|
|
|
|
- Eigen::MatrixXi Eb;
|
|
|
- igl::exterior_edges(Fo, Eb);
|
|
|
+ assert_no_exterior_edges(Fo);
|
|
|
+ assert_is_manifold(Vo, Fo);
|
|
|
+ assert_genus_eq(Vo, Fo, 0);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(MeshBoolean, MinusTest) {
|
|
|
+ // Many thanks to Eric Yao for submitting this test case.
|
|
|
+ Eigen::MatrixXd V1, V2, Vo;
|
|
|
+ Eigen::MatrixXi F1, F2, Fo;
|
|
|
+ test_common::load_mesh("boolean_minus_test_cube.obj", V1, F1);
|
|
|
+ test_common::load_mesh("boolean_minus_test_green.obj", V2, F2);
|
|
|
+
|
|
|
+ igl::boolean::mesh_boolean(V1, F1, V2, F2,
|
|
|
+ igl::boolean::MESH_BOOLEAN_TYPE_MINUS,
|
|
|
+ Vo, Fo);
|
|
|
+
|
|
|
+ assert_no_exterior_edges(Fo);
|
|
|
+ assert_is_manifold(Vo, Fo);
|
|
|
+ assert_genus_eq(Vo, Fo, 1);
|
|
|
+}
|
|
|
+
|
|
|
+TEST(MeshBoolean, IntersectWithSelf) {
|
|
|
+ Eigen::MatrixXd V1, Vo;
|
|
|
+ Eigen::MatrixXi F1, Fo;
|
|
|
+ test_common::load_mesh("cube.obj", V1, F1);
|
|
|
+
|
|
|
+ igl::boolean::mesh_boolean(V1, F1, V1, F1,
|
|
|
+ igl::boolean::MESH_BOOLEAN_TYPE_INTERSECT,
|
|
|
+ Vo, Fo);
|
|
|
+
|
|
|
+ assert_no_exterior_edges(Fo);
|
|
|
+ assert_is_manifold(Vo, Fo);
|
|
|
+ assert_genus_eq(Vo, Fo, 0);
|
|
|
+}
|
|
|
|
|
|
- ASSERT_EQ(0, Eb.rows());
|
|
|
}
|