def process_mesh( cv:CloudVolume, label:int, mesh: Mesh, num_lod:int = 1, draco_compression_level:int = 1, ) -> Tuple[MultiLevelPrecomputedMeshManifest, Mesh]: mesh.vertices /= cv.meta.resolution(cv.mesh.meta.mip) grid_origin = np.floor(np.min(mesh.vertices, axis=0)) chunk_shape = np.ceil(np.max(mesh.vertices, axis=0) - grid_origin) manifest = MultiLevelPrecomputedMeshManifest( segment_id=label, chunk_shape=chunk_shape, grid_origin=grid_origin, num_lods=int(num_lod), lod_scales=[ 1 ] * int(num_lod), vertex_offsets=[[0,0,0]], num_fragments_per_lod=[1], fragment_positions=[[[0,0,0]]], fragment_offsets=[0], # needs to be set when we have the final value ) vqb = int(cv.mesh.meta.info["vertex_quantization_bits"]) mesh.vertices = to_stored_model_space( mesh.vertices, manifest, lod=0, vertex_quantization_bits=vqb, frag=0 ) quantization_range = np.max(mesh.vertices, axis=0) - np.min(mesh.vertices, axis=0) quantization_range = np.max(quantization_range) # mesh.vertices must be integer type or mesh will display # distored in neuroglancer. mesh = DracoPy.encode( mesh.vertices, mesh.faces, quantization_bits=vqb, compression_level=draco_compression_level, quantization_range=quantization_range, quantization_origin=np.min(mesh.vertices, axis=0), create_metadata=True, ) manifest.fragment_offsets = [ len(mesh) ] return (manifest, mesh)
def test_duplicate_vertices(): verts = np.array( [ [0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [2, 0, 0], [2, 1, 0], [3, 0, 0], [3, 1, 0], [3, 0, 0], [4, 0, 0], [4, 1, 0], [4, 0, 0], # duplicate in x direction [5, 0, 0], [5, 1, 0], [5, 0, 0], [6, 0, 0], [6, 1, 0], [6, 1, 2], [7, 0, 0], [7, 1, 0], [4, 0, 0] ], dtype=np.float32) faces = np.array( [[0, 1, 2], [2, 3, 4], [4, 5, 6], [7, 8, 9], [9, 10, 11], [10, 11, 12], [12, 13, 14], [14, 15, 16], [15, 16, 17], [15, 18, 19], [18, 19, 20]], dtype=np.uint32) mesh = Mesh(verts, faces, segid=666) def deduplicate(mesh, x, offset_x=0): return mesh.deduplicate_chunk_boundaries( (x, 100, 100), is_draco=False, offset=(offset_x, -1, -1) # so y=0,z=0 isn't a chunk boundary ) # test that triple 4 isn't affected mesh2 = deduplicate(mesh, x=4) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] # pop off the last 4 mesh.vertices = mesh.vertices[:-1] mesh.faces = mesh.faces[:-1] # test that 4 is now affected mesh2 = deduplicate(mesh, x=4) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] - 1 mesh2 = deduplicate(mesh, x=3) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] - 1 mesh2 = deduplicate(mesh, x=4, offset_x=-1) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] - 1 mesh2 = deduplicate(mesh, x=5) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] - 1 mesh2 = deduplicate(mesh, x=1) assert not np.all(mesh.vertices == mesh2.vertices) assert mesh2.vertices.shape[0] == mesh.vertices.shape[0] - 3