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_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_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_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_face_corner_touch_off_center(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) rot = Quaternion.fromData(np.array([1, 1, 1], dtype=float), np.array([0, 0, 1], dtype=float)) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.6, 0.6, 1.0]), mesh_1.faces) 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_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)
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_face_edge_touch(self): mesh_1 = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) rot = Quaternion.fromData(np.array([1, 0, 1], dtype=float), np.array([0, 0, 1], dtype=float)) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.5, 0.5, 1.0]), mesh_1.faces) mesh = boolean(mesh_1, mesh_2, "union", "igl") self.assertEqual(17, mesh.num_vertices) self.assertEqual(30, mesh.num_faces) self.assertFalse(mesh.is_manifold()) self.assertTrue(mesh.is_closed()) self.assertEqual(1, mesh.num_components)
def test_rotation_union_stress_2(self): # TODO: Bug N = 3 mesh_1 = generate_box_mesh(np.array([-2, -1, -1]), np.array([2, 1, 1])) mesh = mesh_1 for i in range(N): rot = Quaternion.fromAxisAngle(np.array([1.0, 1.0, 0.0]), float(i * 2 * math.pi) / N) mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces) mesh = boolean(mesh, mesh_2, "union", "igl") self.assertTrue(mesh.is_closed()) self.assertTrue(mesh.is_manifold()) self.assertEqual(1, mesh.num_components)
def test_edge_edge_orthogonal_touch(self): eps = np.finfo(float).eps 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([-1, -1, 0.5], dtype=float) + np.array( [-math.sqrt(2) / 4.0 + eps, math.sqrt(2) / 4.0 + eps, 0.0], dtype=float), 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_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);
def test_intersect_with_rotated_self(self): 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 = merge_meshes((mesh_1, mesh_2)) output_mesh = resolve_self_intersection(mesh) self.assert_self_intersect(mesh) # The output mesh contains degenerated triangles, which cause CGAL # assertion failure. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh)
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_face_corner_touch_off_center(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); rot = Quaternion.fromData( np.array([1, 1, 1], dtype=float), np.array([0, 0, 1], dtype=float)); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.6, 0.6, 1.0]), mesh_1.faces); 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_rotation_union_stress_2(self): # TODO: Bug N = 3; mesh_1 = generate_box_mesh( np.array([-2, -1, -1]), np.array([2, 1, 1])); mesh = mesh_1; for i in range(N): rot = Quaternion.fromAxisAngle( np.array([1.0, 1.0, 0.0]), float(i*2*math.pi) / N); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T, mesh_1.faces); mesh = boolean(mesh, mesh_2, "union", "igl"); self.assertTrue(mesh.is_closed()); self.assertTrue(mesh.is_manifold()); self.assertEqual(1, mesh.num_components);
def test_edge_edge_orthogonal_touch(self): eps = np.finfo(float).eps; 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([-1, -1, 0.5], dtype=float)+ np.array([-math.sqrt(2)/4.0 + eps, math.sqrt(2)/4.0+eps, 0.0], dtype=float), 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_intersect_with_rotated_self(self): 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 = merge_meshes((mesh_1, mesh_2)); output_mesh = resolve_self_intersection(mesh); self.assert_self_intersect(mesh); # The output mesh contains degenerated triangles, which cause CGAL # assertion failure. #self.assert_no_self_intersect(output_mesh); self.assert_even_adj_faces(output_mesh);
def test_face_edge_touch(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); rot = Quaternion.fromData( np.array([1, 0, 1], dtype=float), np.array([0, 0, 1], dtype=float)); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.5, 0.5, 1.0]), mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assertEqual(17, mesh.num_vertices); self.assertEqual(30, mesh.num_faces); self.assertFalse(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def test_face_corner_touch_off_center(self): mesh_1 = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); rot = Quaternion.fromData( np.array([1, 1, 1], dtype=float), np.array([0, 0, 1], dtype=float)); mesh_2 = form_mesh( np.dot(rot.to_matrix(), mesh_1.vertices.T).T + np.array([0.6, 0.6, 1.0]), mesh_1.faces); mesh = boolean(mesh_1, mesh_2, "union", "igl"); self.assertEqual(16, mesh.num_vertices); self.assertEqual(26, mesh.num_faces); self.assertFalse(mesh.is_manifold()); self.assertTrue(mesh.is_closed()); self.assertEqual(1, mesh.num_components);
def separate(vertex, faces, d_max=2): new_faces = list() for face in faces: p1 = vertex[face[0]] p2 = vertex[face[1]] p3 = vertex[face[2]] if not (distance(p1, p2) > d_max or distance(p2, p3) > d_max or distance(p1, p3) > d_max): new_faces.append(face) mesh = form_mesh(np.array(vertex), np.array(new_faces)) meshs = separate_mesh(mesh) max_v = 0 for i in range(len(meshs)): if meshs[i].num_vertices > max_v: max_v = meshs[i].num_vertices mesh = meshs[i] pcloud_2d = cloud2D(mesh.vertices) face = Delaunay(pcloud_2d) face = [(p[0], p[1], p[2]) for p in face.simplices] return parseToList(mesh.vertices), face
def add_base(support_mesh, print_dir, support_length): Z_dir = np.array([0.0, 0.0, 1.0]); vertices = support_mesh.vertices.reshape((-1, 3), order="C"); faces = support_mesh.faces.reshape((-1, 3), order="C"); height = np.dot(print_dir, vertices.T).ravel(); projection = vertices - np.outer(height, print_dir); if np.all(print_dir == Z_dir): rot = Quaternion().to_matrix(); else: rot = Quaternion.fromData(print_dir, Z_dir).to_matrix(); projection = np.dot(rot, projection.T); bbox_min = np.amin(projection, axis=1) - Z_dir * 0.15; bbox_max = np.amax(projection, axis=1) + Z_dir * 0.15; base = generate_box_mesh(bbox_min, bbox_max); base_vertices = np.dot(rot.T, base.vertices.T).T\ + print_dir * np.amin(height); num_support_vertices = support_mesh.num_vertices; vertices = np.vstack([vertices, base_vertices]); faces = np.vstack([faces, base.faces + num_support_vertices]); return form_mesh(vertices, faces);