def test_empty_mesh(self): """ What happens when we call functions on an empty mesh? """ mesh = Mesh(np.zeros((0, 3), np.float32), np.zeros((0, 3), int)) mesh.simplify(1.0) assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.simplify(0.1) assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.laplacian_smooth(0) assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.laplacian_smooth(2) assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.stitch_adjacent_faces() assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.serialize(fmt='obj') assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.serialize(fmt='drc') assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0 mesh.compress() concatenate_meshes((mesh, mesh)) assert len(mesh.vertices_zyx) == len(mesh.normals_zyx) == len( mesh.faces) == 0
def test_mismatches(self): mesh_1, mesh_2, mesh_3 = self.mesh_1, self.mesh_2, self.mesh_3 mesh_1.recompute_normals() # let's really mess up mesh 3 -- give it the wrong number of normals mesh_3.recompute_normals() mesh_3.normals_zyx = mesh_3.normals_zyx[:-1] try: _combined_mesh = concatenate_meshes((mesh_1, mesh_2, mesh_3)) except RuntimeError: pass else: assert False, "Expected a RuntimeError, but did not see one."
def test_concatenate(self): mesh_1, mesh_2, mesh_3, mesh_4 = self.mesh_1, self.mesh_2, self.mesh_3, self.mesh_4 vertexes_1, vertexes_2, vertexes_3 = self.vertexes_1, self.vertexes_2, self.vertexes_3 faces_1, faces_2, faces_3 = self.faces_1, self.faces_2, self.faces_3 combined_mesh = concatenate_meshes((mesh_1, mesh_2, mesh_3, mesh_4)) assert (combined_mesh.vertices_zyx == np.concatenate( (vertexes_1, vertexes_2, vertexes_3))).all() expected_faces = np.concatenate((faces_1, faces_2, faces_3)) expected_faces[len(faces_1):] += len(vertexes_1) expected_faces[len(faces_1) + len(faces_2):] += len(vertexes_2) assert (combined_mesh.faces == expected_faces).all()
def test_concatenate(tiny_meshes): mesh_1, mesh_2, mesh_3, mesh_4 = tiny_meshes vertexes_1, vertexes_2, vertexes_3 = mesh_1.vertices_zyx, mesh_2.vertices_zyx, mesh_3.vertices_zyx faces_1, faces_2, faces_3 = mesh_1.faces, mesh_2.faces, mesh_3.faces combined_mesh = concatenate_meshes((mesh_1, mesh_2, mesh_3, mesh_4)) assert (combined_mesh.vertices_zyx == np.concatenate( (vertexes_1, vertexes_2, vertexes_3))).all() expected_faces = np.concatenate((faces_1, faces_2, faces_3)) expected_faces[len(faces_1):] += len(vertexes_1) expected_faces[len(faces_1) + len(faces_2):] += len(vertexes_2) assert (combined_mesh.faces == expected_faces).all()
def test_normals_guarantees(self): """ Member functions have guarantees about whether normals are present or absent after the function runs. - simplify(): Always present afterwards - laplacian_smooth(): Always present afterwards - stitch_adjacent_faces(): Present afterwards IFF they were present before. """ data_box = np.array(self.data_box) FACTOR = 2 data_box *= FACTOR mesh_orig = Mesh.from_binary_vol(self.binary_vol, data_box) mesh = copy.deepcopy(mesh_orig) assert mesh.normals_zyx.shape[0] > 1 # Verify normals are always present after simplification, # Regardless of whether or not they were present before, # or if simplification was even performed. mesh.simplify(1.0) assert mesh.normals_zyx.shape[0] > 1 mesh.simplify(0.5) assert mesh.normals_zyx.shape[0] > 1 mesh.drop_normals() mesh.simplify(0.5) assert mesh.normals_zyx.shape[0] > 1 # Verify normals are always present after smoothing, # Regardless of whether or not they were present before, # or if smoothing was even performed. mesh = copy.deepcopy(mesh_orig) mesh.laplacian_smooth(0) assert mesh.normals_zyx.shape[0] > 1 mesh.laplacian_smooth(2) assert mesh.normals_zyx.shape[0] > 1 mesh.drop_normals() mesh.laplacian_smooth(2) assert mesh.normals_zyx.shape[0] > 1 # Verify that the presence or absence of normals is the SAME after stitching, # Whether or not stitching had any effect. # no stitching, keep normals mesh = copy.deepcopy(mesh_orig) stitching_performed = mesh.stitch_adjacent_faces() assert not stitching_performed assert mesh.normals_zyx.shape[0] > 1 # no stitching, no normals in the first place mesh.drop_normals() stitching_performed = mesh.stitch_adjacent_faces() assert not stitching_performed assert mesh.normals_zyx.shape[0] == 0 # stitching, generate normals mesh = copy.deepcopy(mesh_orig) duplicated_mesh = concatenate_meshes([mesh, mesh]) assert duplicated_mesh.normals_zyx.shape[0] > 1 stitching_performed = duplicated_mesh.stitch_adjacent_faces() assert stitching_performed assert duplicated_mesh.normals_zyx.shape[0] > 1 # stitching, no normals in the first place mesh = copy.deepcopy(mesh_orig) duplicated_mesh = concatenate_meshes([mesh, mesh]) duplicated_mesh.drop_normals() stitching_performed = duplicated_mesh.stitch_adjacent_faces() assert stitching_performed assert duplicated_mesh.normals_zyx.shape[0] == 0