def test_intersecting_cubes(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([2, 2, 2])) mesh_2 = generate_box_mesh(np.array([1, 1, 1]), np.array([3, 3, 3])) mesh = merge_meshes((mesh_1, mesh_2)) outer_hull = compute_outer_hull(mesh) self.assertTrue(outer_hull.is_closed()) self.assert_valid_attributes(mesh, outer_hull)
def test_nested_mesh(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([-1, -1, -1]), np.array([2, 2, 2])); mesh = boolean(mesh_1, mesh_2, "intersection", "igl"); self.assert_array_equal(mesh_1.bbox, mesh.bbox); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assert_array_equal(mesh_2.bbox, mesh.bbox); mesh = boolean(mesh_1, mesh_2, "difference", "igl"); self.assertEqual(0, mesh.num_vertices); self.assertEqual(0, mesh.num_faces); mesh = boolean(mesh_2, mesh_1, "difference", "igl"); self.assertEqual(16, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assert_array_equal(mesh_2.bbox, mesh.bbox); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(2, mesh.num_components); mesh = boolean(mesh_1, mesh_2, "symmetric_difference", "igl"); self.assertEqual(16, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assert_array_equal(mesh_2.bbox, mesh.bbox); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(2, mesh.num_components);
def test_nested_mesh(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh( np.array([-1, -1, -1]), np.array([2, 2, 2])) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") self.assert_array_equal(mesh_1.bbox, mesh.bbox) mesh = boolean(mesh_1, mesh_2, "union", "igl") self.assert_array_equal(mesh_2.bbox, mesh.bbox) mesh = boolean(mesh_1, mesh_2, "difference", "igl") self.assertEqual(0, mesh.num_vertices) self.assertEqual(0, mesh.num_faces) mesh = boolean(mesh_2, mesh_1, "difference", "igl") self.assertEqual(16, mesh.num_vertices) self.assertEqual(24, mesh.num_faces) self.assert_array_equal(mesh_2.bbox, mesh.bbox) self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(2, mesh.num_components) mesh = boolean(mesh_1, mesh_2, "symmetric_difference", "igl") self.assertEqual(16, mesh.num_vertices) self.assertEqual(24, mesh.num_faces) self.assert_array_equal(mesh_2.bbox, mesh.bbox) self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(2, mesh.num_components)
def test_simple_intersection(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([2, 2, 2])) mesh_2 = generate_box_mesh(np.array([1, 1, 1]), np.array([3, 3, 3])) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") self.assertEqual(8, mesh.num_vertices) self.assertEqual(12, mesh.num_faces) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components) mesh = boolean(mesh_1, mesh_2, "union", "igl") self.assertEqual(20, mesh.num_vertices) self.assertEqual(36, mesh.num_faces) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components) mesh = boolean(mesh_1, mesh_2, "difference", "igl") self.assertEqual(14, mesh.num_vertices) self.assertEqual(24, mesh.num_faces) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components) mesh = boolean(mesh_1, mesh_2, "symmetric_difference", "igl") self.assertEqual(22, mesh.num_vertices) self.assertEqual(48, mesh.num_faces) self.assertFalse(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components)
def test_intersecting_cubes(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([2, 2, 2])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]), np.array([3, 3, 3])); mesh = merge_meshes((mesh_1, mesh_2)); outer_hull = compute_outer_hull(mesh); self.assertTrue(outer_hull.is_closed()); self.assert_valid_attributes(mesh, outer_hull);
def test_corner_corner_touch(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([1, 1, 1]), np.array([4, 4, 4])) mesh = merge_meshes((mesh_1, mesh_2)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) self.assert_no_self_intersect(output_mesh) self.assert_even_adj_faces(output_mesh)
def test_face_face_touch_with_different_area(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([-1, -1, 1]), np.array([2, 2, 2])) mesh = merge_meshes((mesh_1, mesh_2)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh)
def test_simple_intersection(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([2, 2, 2])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]), np.array([4, 4, 4])); mesh = merge_meshes((mesh_1, mesh_2)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_face_face_touch_with_different_area(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([-1, -1, 1]), np.array([2, 2, 2])) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") self.assertEqual(0, mesh.num_vertices) self.assertEqual(0, mesh.num_faces) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(0, mesh.num_components)
def test_corner_corner_touch(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]), np.array([4, 4, 4])); mesh = merge_meshes((mesh_1, mesh_2)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_face_face_touch_with_different_area(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([-1, -1, 1]), np.array([2, 2, 2])); mesh = merge_meshes((mesh_1, mesh_2)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_face_face_touch(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([0, 0, 1]), np.array([1, 1, 2])) mesh = merge_meshes((mesh_1, mesh_2)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) # Since the overlapping faces would be kept so valid nested outer hulls # can be extracted, the resolved mesh would be actually self-intersecting. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh)
def test_multiple_components(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([2, 2, 2]), np.array([3, 3, 3])) mesh = merge_meshes((mesh_1, mesh_2)) outer_hulls = compute_outer_hull(mesh, all_layers=True) self.assertEqual(1, len(outer_hulls)) outer_hull = outer_hulls[0] self.assertTrue(outer_hull.is_closed()) self.assertEqual(2, outer_hull.num_components) self.assert_valid_attributes(mesh, outer_hull)
def test_eps_corner_intersection(self): eps = np.finfo(np.float64).eps mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh( np.array([1, 1, 1]) - eps, np.array([3, 3, 3])) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") self.assertEqual(8, mesh.num_vertices) self.assertEqual(12, mesh.num_faces) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components)
def test_no_intersection(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([3, 3, 3]), np.array([4, 4, 4])) mesh = merge_meshes((mesh_1, mesh_2)) intersecting_faces = detect_self_intersection(mesh) self.assertEqual(0, len(intersecting_faces)) output_mesh = resolve_self_intersection(mesh) self.assertEqual(mesh.num_vertices, output_mesh.num_vertices) self.assertEqual(mesh.num_faces, output_mesh.num_faces) self.assert_even_adj_faces(output_mesh)
def test_cross_union(self): mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) mesh_2 = generate_box_mesh(np.array([-1, -2, -1]), np.array([1, 2, 1])) mesh_3 = generate_box_mesh(np.array([-1, -1, -2]), np.array([1, 1, 2])) mesh = merge_meshes((mesh_1, mesh_2, mesh_3)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) # The output mesh contains duplicated faces due to input overlaps. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh)
def test_cross_union(self): mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) mesh_2 = generate_box_mesh(np.array([-1, -2, -1]), np.array([1, 2, 1])) mesh_3 = generate_box_mesh(np.array([-1, -1, -2]), np.array([1, 1, 2])) mesh = boolean(mesh_1, mesh_2, "union", "igl") mesh = boolean(mesh, mesh_3, "union", "igl") self.assert_array_equal( np.array([[-2, -2, -2], [2, 2, 2]], dtype=float), mesh.bbox) self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(1, mesh.num_components)
def test_eps_face_intersection(self): eps = np.finfo(np.float64).eps mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) mesh_2 = generate_box_mesh(np.array([0, 0, 1 - eps]), np.array([1, 1, 2])) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") bbox = mesh.bbox self.assert_array_equal(np.array([0, 0, 1 - eps]), bbox[0]) self.assert_array_equal(np.array([1, 1, 1]), bbox[1]) self.assertTrue(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components)
def test_multiple_components(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([2, 2, 2]), np.array([3, 3, 3])); mesh = merge_meshes((mesh_1, mesh_2)); outer_hulls = compute_outer_hull(mesh, all_layers=True); self.assertEqual(1, len(outer_hulls)); outer_hull = outer_hulls[0]; self.assertTrue(outer_hull.is_closed()); self.assertEqual(2, outer_hull.num_components); self.assert_valid_attributes(mesh, outer_hull);
def test_face_face_touch(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([0, 0, 1]), np.array([1, 1, 2])); mesh = merge_meshes((mesh_1, mesh_2)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); # Since the overlapping faces would be kept so valid nested outer hulls # can be extracted, the resolved mesh would be actually self-intersecting. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_no_intersection(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([3, 3, 3]), np.array([4, 4, 4])); mesh = merge_meshes((mesh_1, mesh_2)); intersecting_faces = detect_self_intersection(mesh); self.assertEqual(0, len(intersecting_faces)); output_mesh = resolve_self_intersection(mesh); self.assertEqual(mesh.num_vertices, output_mesh.num_vertices); self.assertEqual(mesh.num_faces, output_mesh.num_faces); self.assert_even_adj_faces(output_mesh);
def test_cross_union(self): mesh_1 = generate_box_mesh( np.array([-2, -1, -1]), np.array([2, 1, 1])); mesh_2 = generate_box_mesh( np.array([-1, -2, -1]), np.array([1, 2, 1])); mesh_3 = generate_box_mesh( np.array([-1, -1, -2]), np.array([1, 1, 2])); mesh = merge_meshes((mesh_1, mesh_2, mesh_3)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); # The output mesh contains duplicated faces due to input overlaps. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_face_face_touch_with_different_area(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([-1, -1, 1]), np.array([2, 2, 2])); mesh = boolean( mesh_1, mesh_2, "intersection", "igl"); self.assertEqual(0, mesh.num_vertices); self.assertEqual(0, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(0, mesh.num_components);
def test_eps_corner_intersection(self): eps = np.finfo(np.float64).eps; mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]) - eps, np.array([3, 3, 3])); mesh = boolean( mesh_1, mesh_2, "intersection", "igl"); self.assertEqual(8, mesh.num_vertices); self.assertEqual(12, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def test_intersection_with_self(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh = boolean(mesh_1, mesh_1, "intersection", "igl"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertTrue(1, mesh.num_components);
def test_eps_face_intersection(self): eps = np.finfo(np.float64).eps; mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([0, 0, 1-eps]), np.array([1, 1, 2])); mesh = boolean( mesh_1, mesh_2, "intersection", "igl"); bbox = mesh.bbox; self.assert_array_equal(np.array([0, 0, 1-eps]), bbox[0]); self.assert_array_equal(np.array([1, 1, 1]), bbox[1]); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def test_intersection_with_self(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])) mesh = boolean(mesh_1, mesh_1, "intersection", "igl") self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertTrue(1, mesh.num_components)
def test_nested_cubes(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([3, 3, 3])) mesh_2 = generate_box_mesh(np.array([1, 1, 1]), np.array([2, 2, 2])) mesh = merge_meshes((mesh_1, mesh_2)) outer_hulls = compute_outer_hull(mesh, all_layers=True) self.assertEqual(2, len(outer_hulls)) outer_hull = outer_hulls[0] interior_mesh = outer_hulls[1] self.assertTrue(outer_hull.is_closed()) self.assertEqual(1, outer_hull.num_components) self.assert_valid_attributes(mesh, outer_hull) self.assertEqual(8, interior_mesh.num_vertices) self.assert_array_equal(([1, 1, 1], [2, 2, 2]), interior_mesh.bbox)
def test_cross_union(self): mesh_1 = generate_box_mesh( np.array([-2, -1, -1]), np.array([2, 1, 1])); mesh_2 = generate_box_mesh( np.array([-1, -2, -1]), np.array([1, 2, 1])); mesh_3 = generate_box_mesh( np.array([-1, -1, -2]), np.array([1, 1, 2])); mesh = boolean(mesh_1, mesh_2, "union", "igl"); mesh = boolean(mesh, mesh_3, "union", "igl"); self.assert_array_equal( np.array([[-2, -2, -2], [2, 2, 2]], dtype=float), mesh.bbox); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(1, mesh.num_components);
def test_single_hex(self): hex_mesh = generate_box_mesh(np.zeros(3), np.ones(3), 1, using_simplex=False) tet_mesh = hex_to_tet(hex_mesh, True, 0) self.assert_array_equal(hex_mesh.bbox, tet_mesh.bbox) self.assertEqual(24, tet_mesh.num_voxels)
def test_boundary_pts_geogram(self): mesh = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) pts = np.array([[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]) if "geogram" in BVH.available_engines: sq_dist, face_idx, closest_pts = distance_to_mesh( mesh, pts, "geogram") self.assert_array_equal(sq_dist, np.zeros(2))
def test_single_hex(self): hex_mesh = generate_box_mesh( np.zeros(3), np.ones(3), 1, using_simplex=False); tet_mesh = hex_to_tet(hex_mesh, True, 0); self.assert_array_equal(hex_mesh.bbox, tet_mesh.bbox); self.assertEqual(24, tet_mesh.num_voxels);
def test_diag_box(self): mesh = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) N = 5 slices = slice_mesh(mesh, [1, 1, 1], N) self.assertEqual(N, len(slices)) slices = merge_meshes(slices) self.assert_bbox_is_embedded(slices.bbox, mesh.bbox)
def test_boundary_pts_cgal(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); pts = np.array([ [0.0, 0.0, 0.0], [1.0, 1.0, 1.0] ]); sq_dist, face_idx, closest_pts = distance_to_mesh(mesh, pts, "cgal"); self.assert_array_equal(sq_dist, np.zeros(2));
def test_nested_cubes(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([3, 3, 3])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]), np.array([2, 2, 2])); mesh = merge_meshes((mesh_1, mesh_2)); outer_hulls = compute_outer_hull(mesh, all_layers=True); self.assertEqual(2, len(outer_hulls)); outer_hull = outer_hulls[0]; interior_mesh = outer_hulls[1]; self.assertTrue(outer_hull.is_closed()); self.assertEqual(1, outer_hull.num_components); self.assert_valid_attributes(mesh, outer_hull); self.assertEqual(8, interior_mesh.num_vertices); self.assert_array_equal(([1, 1, 1], [2, 2, 2]), interior_mesh.bbox);
def test_symmetric_connectivity(self): bbox_min = np.zeros(3) bbox_max = np.ones(3) mesh = generate_box_mesh(bbox_min, bbox_max, keep_symmetry=True) self.assertEqual(15, mesh.num_vertices) self.assertEqual(24, mesh.num_faces) self.assertEqual(24, mesh.num_voxels) self.assert_bbox_matches(mesh, bbox_min, bbox_max)
def test_2D(self): bbox_min = np.zeros(2) bbox_max = np.ones(2) * 100.5 mesh = generate_box_mesh(bbox_min, bbox_max) self.assertEqual(4, mesh.num_vertices) self.assertEqual(2, mesh.num_faces) self.assert_bbox_matches(mesh, bbox_min, bbox_max)
def test_3D(self): bbox_min = np.zeros(3) bbox_max = np.ones(3) mesh = generate_box_mesh(bbox_min, bbox_max) self.assertEqual(8, mesh.num_vertices) self.assertEqual(12, mesh.num_faces) self.assertEqual(6, mesh.num_voxels) self.assert_bbox_matches(mesh, bbox_min, bbox_max)
def test_simple_cube(self): mesh = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) outer_hulls = compute_outer_hull(mesh, all_layers=True) self.assertEqual(1, len(outer_hulls)) outer_hull = outer_hulls[0] self.assertTrue(outer_hull.is_closed()) self.assertEqual(mesh.num_vertices, outer_hull.num_vertices) self.assertEqual(mesh.num_faces, outer_hull.num_faces) self.assert_valid_attributes(mesh, outer_hull)
def test_diag_box(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); N = 5; slices = slice_mesh(mesh, [1, 1, 1], N); self.assertEqual(N, len(slices)); slices = merge_meshes(slices); self.assert_bbox_is_embedded(slices.bbox, mesh.bbox);
def test_intersection_with_slighly_rotated_self(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) rot = Quaternion.fromAxisAngle(np.array([1.0, 1.0, 1.0]), 0.0001) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces) mesh = boolean(mesh_1, mesh_2, "intersection", "igl") self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertTrue(1, mesh.num_components)
def test_3D(self): bbox_min = np.zeros(3); bbox_max = np.ones(3); mesh = generate_box_mesh( bbox_min, bbox_max); self.assertEqual(8, mesh.num_vertices); self.assertEqual(12, mesh.num_faces); self.assertEqual(6, mesh.num_voxels); self.assert_bbox_matches(mesh, bbox_min, bbox_max);
def test_2D(self): bbox_min = np.zeros(2); bbox_max = np.ones(2) * 100.5; mesh = generate_box_mesh( bbox_min, bbox_max); self.assertEqual(4, mesh.num_vertices); self.assertEqual(2, mesh.num_faces); self.assert_bbox_matches(mesh, bbox_min, bbox_max);
def test_rotation_180(self): mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) rot = Quaternion.fromAxisAngle(np.array([1.0, 1.0, 0.0]), math.pi / 2.0) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces) mesh = boolean(mesh_1, mesh_2, "union", "cgal") self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(1, mesh.num_components)
def test_simple_cube(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); outer_hulls = compute_outer_hull(mesh, all_layers=True); self.assertEqual(1, len(outer_hulls)); outer_hull = outer_hulls[0]; self.assertTrue(outer_hull.is_closed()); self.assertEqual(mesh.num_vertices, outer_hull.num_vertices); self.assertEqual(mesh.num_faces, outer_hull.num_faces); self.assert_valid_attributes(mesh, outer_hull);
def test_symmetric_connectivity(self): bbox_min = np.zeros(3); bbox_max = np.ones(3); mesh = generate_box_mesh( bbox_min, bbox_max, keep_symmetry=True); self.assertEqual(15, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assertEqual(24, mesh.num_voxels); self.assert_bbox_matches(mesh, bbox_min, bbox_max);
def test_simple_intersection(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([2, 2, 2])); mesh_2 = generate_box_mesh( np.array([1, 1, 1]), np.array([3, 3, 3])); mesh = boolean( mesh_1, mesh_2, "intersection", "igl"); self.assertEqual(8, mesh.num_vertices); self.assertEqual(12, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "union", "igl"); self.assertEqual(20, mesh.num_vertices); self.assertEqual(36, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "difference", "igl"); self.assertEqual(14, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "symmetric_difference", "igl"); self.assertEqual(22, mesh.num_vertices); self.assertEqual(48, mesh.num_faces); self.assertFalse(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def test_rotate_union_120_degrees(self): # TODO: Bug mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) rot = Quaternion.fromAxisAngle(np.array([1.0, 0.0, 0.0]), float(2 * math.pi) / 3) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces) mesh = boolean(mesh_1, mesh_2, "union", "igl") self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(1, mesh.num_components)
def test_edge_edge_touch(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); mesh_2 = generate_box_mesh( np.array([0, 1, 1]), np.array([1, 2, 2])); mesh = boolean( mesh_1, mesh_2, "intersection", "igl"); self.assertEqual(0, mesh.num_vertices); self.assertEqual(0, mesh.num_faces); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(0, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "union", "igl"); self.assertEqual(14, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assertFalse(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "difference", "igl"); self.assert_array_equal(mesh_1.bbox, mesh.bbox); self.assertTrue(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components); mesh = boolean( mesh_1, mesh_2, "symmetric_difference", "igl"); self.assertEqual(14, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assertFalse(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def test_union_with_45_rotated_self(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); rot = Quaternion.fromAxisAngle(np.array([1.0, 1.0, 1.0]), math.pi/4.0); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertTrue(1, mesh.num_components);
def test_rotation_180(self): mesh_1 = generate_box_mesh( np.array([-2, -1, -1]), np.array([2, 1, 1])); rot = Quaternion.fromAxisAngle( np.array([1.0, 1.0, 0.0]), math.pi / 2.0); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "cgal"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(1, mesh.num_components);
def test_rotate_union_120_degrees(self): # TODO: Bug mesh_1 = generate_box_mesh( np.array([-2, -1, -1]), np.array([2, 1, 1])); rot = Quaternion.fromAxisAngle( np.array([1.0, 0.0, 0.0]), float(2*math.pi) / 3); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(1, mesh.num_components);
def test_rotate_120(self): mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) rot = Quaternion.fromAxisAngle(np.array([1.0, 0.0, 0.0]), float(2 * math.pi) / 3) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces) mesh = merge_meshes((mesh_1, mesh_2)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) # The output mesh contains degenerated face. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh)
def test_simple(self): input_mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); path = np.array([ [0, 0, 0], [1, 1, 1] ]); output_mesh = minkowski_sum(input_mesh, path); self.assertTrue(output_mesh.is_closed()); self.assertTrue(output_mesh.is_oriented()); self.assertTrue(output_mesh.num_boundary_edges == 0); input_bbox_min, input_bbox_max = input_mesh.bbox; output_bbox_min, output_bbox_max = output_mesh.bbox; self.assert_array_equal(input_bbox_min, output_bbox_min); self.assert_array_equal([1, 1, 1], output_bbox_max - input_bbox_max);
def test_subdiv(self): bbox_min = np.zeros(3); bbox_max = np.ones(3); mesh = generate_box_mesh( bbox_min, bbox_max, subdiv_order=1); self.assertEqual(27, mesh.num_vertices); self.assertEqual(48, mesh.num_faces); self.assertEqual(48, mesh.num_voxels); # All tets belongs to the same cell. cell_index = mesh.get_attribute("cell_index"); self.assertEqual(0, np.amax(cell_index)); self.assertEqual(0, np.amin(cell_index)); self.assert_bbox_matches(mesh, bbox_min, bbox_max);
def test_cube(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); queries = np.array([ [-1, 0, 0], [0.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.5, 0.5], ]); winding_numbers = compute_winding_number(mesh, queries); self.assertEqual(len(queries), len(winding_numbers)); self.assertAlmostEqual(0.0, norm(winding_numbers - np.array([0, 0.125, 0.25, 0.5, 1])));
def test_samples(self): bbox_min = np.zeros(3); bbox_max = np.ones(3); mesh = generate_box_mesh( bbox_min, bbox_max, num_samples=2); self.assertEqual(27, mesh.num_vertices); self.assertEqual(48, mesh.num_faces); self.assertEqual(48, mesh.num_voxels); # There is a total of 8 cells. cell_index = mesh.get_attribute("cell_index"); self.assertEqual(0, np.amin(cell_index)); self.assertEqual(7, np.amax(cell_index)); self.assert_bbox_matches(mesh, bbox_min, bbox_max);
def test_union_with_rotated_self(self): #TODO: bug mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); rot = Quaternion.fromAxisAngle(np.array([1, 1, 0], dtype=float), math.pi * 0.5); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.5, 0.5, 0.5]), mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(1, mesh.num_components);