def test_pickling_empty(self): mesh = Mesh(np.zeros((0, 3), np.float32), np.zeros((0, 3), np.uint32)) pickled = pickle.dumps(mesh) unpickled = pickle.loads(pickled) assert len(unpickled.vertices_zyx) == 0 assert len(unpickled.faces) == 0
def test_smoothing_hexagon(self): """ Try 'smoothing' a simple 2D hexagon, which is an easy case to understand. """ # This map is correctly labeled with the vertex indices _ = -1 hexagon = [[[_, _, _, _, _, _, _], [_, _, 0, _, 1, _, _], [_, _, _, _, _, _, _], [_, 2, _, 3, _, 4, _], [_, _, _, _, _, _, _], [_, _, 5, _, 6, _, _], [_, _, _, _, _, _, _]]] hexagon = 1 + np.array(hexagon) original_vertices_zyx = np.transpose(hexagon.nonzero()) faces = [[3, 1, 4], [3, 4, 6], [3, 6, 5], [3, 5, 2], [3, 2, 0], [3, 0, 1]] mesh = Mesh(original_vertices_zyx, faces) #mesh.serialize('/tmp/hexagon.obj') mesh.laplacian_smooth(1) #mesh.serialize('/tmp/hexagon-smoothed.obj') # Since vertex 3 is exactly centered between the rest, # it's location never changes. assert (mesh.vertices_zyx[3] == original_vertices_zyx[3]).all()
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_stitch(): vertices = np.zeros((10, 3), np.float32) vertices[:, 0] = np.arange(10) # Make 3 and 6 duplicates of 2 and 4, respectively vertices[3] = vertices[2] vertices[6] = vertices[4] faces = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [7, 8, 4]] # <- duplicate face (different vertex order, and 4=6) # After mapping away from dupe vertices remapped_faces = [[0, 1, 2], [2, 4, 5], [4, 7, 8], [7, 8, 4]] # duplicated face (different vertex order) remapped_faces = np.array(remapped_faces) # After dropping dupe rows remapped_faces[(remapped_faces > 6)] -= 1 remapped_faces[(remapped_faces > 3)] -= 1 # Drop last face (duplicated) remapped_faces = remapped_faces[:-1, :] reduced_vertices = list(vertices) del reduced_vertices[9] # wasn't referenced to begin with del reduced_vertices[6] # was duplicated del reduced_vertices[3] # was duplicated reduced_vertices = np.asarray(reduced_vertices) mesh = Mesh(vertices, faces) mesh.stitch_adjacent_faces() assert (mesh.faces == remapped_faces).all() assert (mesh.vertices_zyx == reduced_vertices).all()
def setUp(self): self.vertexes_1 = np.array([[0, 0, 0], [0, 1, 0], [0, 1, 1]]) self.faces_1 = np.array([[2, 1, 0]]) self.vertexes_2 = np.array([[0, 0, 1], [0, 2, 0], [0, 2, 2]]) self.faces_2 = np.array([[2, 1, 0], [1, 2, 0]]) self.vertexes_3 = np.array([[1, 0, 1], [1, 2, 0], [1, 2, 2]]) self.faces_3 = np.array([[1, 2, 0]]) self.mesh_1 = Mesh(self.vertexes_1, self.faces_1) self.mesh_2 = Mesh(self.vertexes_2, self.faces_2) self.mesh_3 = Mesh(self.vertexes_3, self.faces_3) self.mesh_4 = Mesh(np.zeros((0, 3), np.float32), np.zeros((0, 3), np.uint32)) # Empty mesh
def test_smoothing_trivial(self): vertices_zyx = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 0.0, 2.0]]) # This "face" is actually straight line, # which makes it easy to see what's going on faces = np.array([[0, 1, 2]]) mesh = Mesh(vertices_zyx, faces) average_vertex = vertices_zyx.sum(axis=0) / 3 mesh.laplacian_smooth(1) assert (mesh.vertices_zyx == average_vertex).all()
def tiny_meshes(): vertexes_1 = np.array([[0, 0, 0], [0, 1, 0], [0, 1, 1]]) faces_1 = np.array([[2, 1, 0]]) vertexes_2 = np.array([[0, 0, 1], [0, 2, 0], [0, 2, 2]]) faces_2 = np.array([[2, 1, 0], [1, 2, 0]]) vertexes_3 = np.array([[1, 0, 1], [1, 2, 0], [1, 2, 2]]) faces_3 = np.array([[1, 2, 0]]) mesh_1 = Mesh(vertexes_1, faces_1) mesh_2 = Mesh(vertexes_2, faces_2) mesh_3 = Mesh(vertexes_3, faces_3) mesh_4 = Mesh(np.zeros((0, 3), np.float32), np.zeros( (0, 3), np.uint32)) # Empty mesh return mesh_1, mesh_2, mesh_3, mesh_4