def basic_mesh(): verts = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1]]) faces = np.array([[0, 1, 2], [2, 3, 1], [3, 4, 2]]) mesh = trimesh_io.Mesh(verts, faces, process=False) assert np.all(mesh.vertices == verts) yield mesh
def build_basic_mesh(): verts = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1]], dtype=np.float32) faces = np.array([[0, 1, 2], [2, 3, 1], [3, 4, 2]], np.uint32) mesh = trimesh_io.Mesh(verts, faces, process=False) assert np.all(mesh.vertices == verts) yield mesh
def coord_space_mesh( root_id, client, cv=None, return_l2dict=False, nan_rounds=10, require_complete=False, ): if cv is None: cv = client.info.segmentation_cloudvolume(progress=False) lvl2_eg = client.chunkedgraph.level2_chunk_graph(root_id) eg, l2dict_mesh, l2dict_r_mesh, x_ch = build_spatial_graph( lvl2_eg, cv, client=client, method="service", require_complete=require_complete, ) mesh_loc = trimesh_io.Mesh( vertices=x_ch, faces=[[0, 0, 0]], # Some functions fail if no faces are set. link_edges=eg, ) sk_utils.fix_nan_verts_mesh(mesh_loc, nan_rounds) if return_l2dict: return mesh_loc, l2dict_mesh, l2dict_r_mesh else: return mesh_loc
def test_basic_mesh_actor(cube_verts_faces): verts, faces = cube_verts_faces mesh = trimesh_io.Mesh(verts, faces, process=False) mesh_actor = trimesh_vtk.mesh_actor(mesh) mesh_actor.GetMapper().Update() pd = mesh_actor.GetMapper().GetInput() verts_out, faces_out, tmp = trimesh_vtk.poly_to_mesh_components(pd) assert (np.all(verts == verts_out)) assert (np.all(faces_out == faces))
def mesh_by_inds(mesh, inds): assert len(inds) > 0, "empty inds" new_verts = mesh.vertices[inds] ind_map = np.empty((max(inds) + 1, ), dtype=inds.dtype) ind_map[inds] = np.arange(len(inds)) explicit_faces = mesh.faces.reshape((-1, 3)) face_inds = np.all(np.isin(explicit_faces, inds), axis=1) new_faces = ind_map[explicit_faces[face_inds]].ravel() return trimesh_io.Mesh(vertices=new_verts, faces=new_faces)
def build_basic_cube_mesh(): verts = np.array( [[-1., -1., 1.], [-1., -1., -1.], [1., -1., -1.], [1., -1., 1.], [-1., 1., 1.], [-1., 1., -1.], [1., 1., -1.], [1., 1., 1.]], dtype=np.float32) faces = np.array( [[4, 5, 1], [5, 6, 2], [6, 7, 3], [7, 4, 0], [0, 1, 2], [7, 6, 5], [0, 4, 1], [1, 5, 2], [2, 6, 3], [3, 7, 0], [3, 0, 2], [4, 7, 5]], np.uint32) mesh = trimesh_io.Mesh(verts, faces, process=False) assert np.all(mesh.vertices == verts) yield mesh
def chunk_index_mesh( root_id, client=None, datastack_name=None, cv=None, return_l2dict=False, ): """Download a mesh with chunk index vertices Parameters ---------- root_id : int Root id to download. client : CAVEclient, optional Preset CAVEclient, by default None. datastack_name : str or None, optional Datastack to use to initialize a CAVEclient, by default None. cv : cloudvolume.CloudVolume or None, optional Cloudvolume instance, by default None. return_l2dict : bool, optional If True, returns both a l2id to vertex dict and the reverse, by default False. Returns ------- mesh : trimesh_io.Mesh Chunk graph represented as a mesh, with vertices at chunk index locations and edges in the link_edges attribute. l2dict_mesh : dict l2 id to mesh vertex index dictionary. Only returned if return_l2dict is True. l2dict_r_mesh : dict Mesh vertex index to l2 id dictionary. Only returned if return_l2dict is True. """ if client is None: client = CAVEclient(datastack_name) if cv is None: cv = cloudvolume.CloudVolume( client.info.segmentation_source(), use_https=True, progress=False, bounded=False, fill_missing=True, secrets={"token": client.auth.token}, ) lvl2_eg = client.chunkedgraph.level2_chunk_graph(root_id) eg, l2dict_mesh, l2dict_r_mesh, x_ch = build_spatial_graph(lvl2_eg, cv) mesh_chunk = trimesh_io.Mesh( vertices=x_ch, faces=[[0, 0, 0]], # Some functions fail if no faces are set. link_edges=eg, ) if return_l2dict: return mesh_chunk, l2dict_mesh, l2dict_r_mesh else: return mesh_chunk
def maskmesh(mesh, mask): """Applies a mask to a mesh Returns a mesh where the remaining vertices survived the mask. Only keeps the faces that connect vertices that survive the mask. """ newvertices = mesh.vertices[mask] # mapping mask indices to their matching values in the masked result indexmap = np.empty((len(mesh.vertices), ), dtype=np.uint32) indexmap[mask] = np.arange(len(newvertices)) # masking faces and mapping their index values facemask = mask[mesh.faces].min(axis=1) newfaces = indexmap[mesh.faces[facemask]] return trimesh_io.Mesh(newvertices, newfaces)
def attach_new_pt(mesh, new_pt, boundary=None): new_verts = np.vstack((mesh.vertices, new_pt)) new_i = len(mesh.vertices) boundary_edges = find_mesh_boundary_edges(mesh) if boundary is not None: bset = set(boundary) boundary_edges = [ edge for edge in boundary_edges if (edge[0] in bset) and (edge[1] in bset) ] new_faces = np.array(assemble_consistent_faces(boundary_edges, new_i)) new_faces = flip_if_mostly_inwards(new_faces, new_verts, new_pt) all_new_faces = np.vstack((mesh.faces, new_faces)) return trimesh_io.Mesh(vertices=new_verts, faces=all_new_faces)
def build_full_cell_mesh(): filepath = 'test/test_files/648518346349499581.h5' vertices, faces, normals, link_edges, node_mask = trimesh_io.read_mesh_h5( filepath) mesh = trimesh_io.Mesh(vertices, faces) yield mesh
def make(self, key): global_time = time.time() #get the mesh with the error segments filtered away start_time = time.time() print(str(key['segment_id']) + ":") my_dict = (pinky.Mesh & pinky.Neurite.proj() & pinky.CurrentSegmentation & key).fetch1() print( f"Step 1: Retrieving Mesh and removing error segments: {time.time() - start_time}" ) new_key = dict(segmentation=key["segmentation"], segment_id=key["segment_id"]) # Don't need these attributes #vertices=key["vertices"], # triangles=new_key["triangles"],n_vertices=key["n_vertices"], # n_triangles=key["n_triangles"]) start_time = time.time() #pass the vertices and faces to pymeshfix to become watertight mesh = trimesh_io.Mesh(vertices=my_dict["vertices"], faces=my_dict["triangles"]) count, labels = trimesh_io.trimesh.graph.csgraph.connected_components( mesh.edges_sparse, directed=False, return_labels=True) label_counter = Counter(labels) new_key["n_bodies"] = count values = np.array(labels) list_counter = Counter(labels) max_counter = max(list_counter.values()) max_label = -1 for label_key, label_number in list_counter.items(): if label_number == max_counter: max_label = label_key print("max label = " + str(max_label)) searchval = max_label ii = np.where(values == searchval)[0] new_key["largest_mesh_perc"] = len(ii) / len(labels) print("n_bodies = " + str(new_key["n_bodies"])) print("largest mesh perc = " + str(new_key["largest_mesh_perc"])) print( f"Step 2a: Getting the number of splits: {time.time() - start_time}" ) start_time = time.time() #pass the vertices and faces to pymeshfix to become watertight meshfix = pymeshfix.MeshFix(my_dict["vertices"], my_dict["triangles"]) meshfix.repair(verbose=False, joincomp=True, remove_smallest_components=False) print(f"Step 2b: Pymesh shrinkwrapping: {time.time() - start_time}") #print("Step 2: Writing Off File") start_time = time.time() #write the new mesh to off file path_and_filename, filename, file_loc = write_Whole_Neuron_Off_file( str(new_key["segment_id"]), meshfix.v, meshfix.f) print( f"Step 3: Writing shrinkwrap off file: {time.time() - start_time}") #Run the meshlabserver scripts start_time = time.time() output_mesh = meshlab_fix_manifold(key) print( f"Step 4: Meshlab fixing non-manifolds: {time.time() - start_time}" ) print(output_mesh[:-4]) #send to be skeletonized start_time = time.time() return_value = cm.calcification(output_mesh[:-4]) if return_value > 0: raise Exception('skeletonization for neuron ' + str(new_key["segment_id"]) + ' did not finish... exited with error code: ' + str(return_value)) #print(f"Step 5: Generating Skeleton: {time.time() - start_time}") #read in the skeleton files into an array bone_array = read_skeleton_revised(output_mesh[:-4] + "_skeleton.cgal") #print(bone_array) if len(bone_array) <= 0: raise Exception('No skeleton generated for ' + str(new_key["segment_id"])) print( f"Step 5: Generating and reading Skeleton: {time.time() - start_time}" ) start_time = time.time() new_key["n_edges"] = len(bone_array) new_key["edges"] = bone_array #new_key["branches"] = [] #print(key) #if all goes well then write to database self.insert1(new_key, skip_duplicates=True) #raise Exception("done with one neuron") os.system("rm " + str(path_and_filename) + "*") print(f"Step 6: Inserting dictionary: {time.time() - start_time}") print(f"Total time: {time.time() - global_time}") print("\n\n")
def scale_mesh(mesh, old_res, new_res): verts = (mesh.vertices / old_res) * new_res return trimesh_io.Mesh(vertices=verts, faces=mesh.faces)
def center_mesh(mesh): centroid = np.mean(mesh.vertices, axis=0) return trimesh_io.Mesh(vertices=mesh.vertices - centroid, faces=mesh.faces)
def get_lvl2_skeleton(client, root_id, convert_to_nm=False, refine_branch_points=False, root_point=None, point_radius=200, invalidation_d=3, verbose=False, auto_remesh=False): """Get branch points of the level 2 skeleton for a root id. Parameters ---------- datastack : str Datastack name root_id : int Root id of object to skeletonize invalidation_d : int, optional Invalidation distance in chunk increments Returns ------- Branch point locations Branch point locations in mesh space (nms) """ if verbose: import time t0 = time.time() cv = cloudvolume.CloudVolume(client.info.segmentation_source(), use_https=True, progress=False, bounded=False) lvl2_eg = get_lvl2_graph(root_id, client) if verbose: t1 = time.time() print('\nTime to return graph: ', t1 - t0) eg, l2dict, l2dict_reversed, x_ch = build_spatial_graph(lvl2_eg, cv) mesh_chunk = trimesh_io.Mesh(vertices=x_ch, faces=[], link_edges=eg) if root_point is not None: if verbose: t2 = time.time() lvl2_root_chid, lvl2_root_loc = get_closest_lvl2_chunk( root_point, root_id, client=client, cv=cv, radius=point_radius, return_point=True) root_mesh_index = l2dict[lvl2_root_chid] if verbose: print('\n Time to get root index: ', time.time() - t2) else: root_mesh_index = None lvl2_root_loc = None if verbose: t3 = time.time() sk_ch = skeletonize.skeletonize_mesh(mesh_chunk, invalidation_d=invalidation_d, collapse_soma=False, compute_radius=False, root_index=root_mesh_index, remove_zero_length_edges=False) if verbose: print('\n Time to skeletonize: ', time.time() - t3) if refine_branch_points: if verbose: t4 = time.time() sk_ch, missing_ids = refine_skeleton(sk_ch, l2dict_reversed, cv, convert_to_nm, root_location=lvl2_root_loc) if verbose: print('\n Time to refine branch points, ', time.time() - t4) if len(missing_ids) > 0: if auto_remesh: client.chunkedgraph.remesh_level2_chunks(missing_ids) raise ValueError( f'Regenerating mesh for level 2 ids: {missing_ids}. Try again in a few minutes.' ) else: raise ValueError( f'No mesh found for level 2 ids: {missing_ids}') return sk_ch, l2dict_reversed
def meshsurfacearea(m): """Computes the surface area of a mesh""" temp = trimesh_io.Mesh(m.vertices / 1000., m.faces) return temp.area
def make(self, key): split_significance_threshold = 100 global_time = time.time() #get the mesh with the error segments filtered away start_time = time.time() print(str(key['segment_id']) + ":") my_dict = (pinky.Mesh & pinky.Neurite.proj() & pinky.CurrentSegmentation & key).fetch1() print( f"Step 1: Retrieving Mesh and removing error segments: {time.time() - start_time}" ) new_key = dict(segmentation=key["segmentation"], segment_id=key["segment_id"]) # Don't need these attributes #vertices=key["vertices"], # triangles=new_key["triangles"],n_vertices=key["n_vertices"], # n_triangles=key["n_triangles"]) start_time = time.time() #pass the vertices and faces to pymeshfix to become watertight mesh = trimesh_io.Mesh(vertices=my_dict["vertices"], faces=my_dict["triangles"]) """ OLDER WAY OF JUST GETTING THE LARGEST MESH PIECE count, labels = trimesh_io.trimesh.graph.csgraph.connected_components( mesh.edges_sparse, directed=False, return_labels=True) label_counter = Counter(labels) new_key["n_bodies"] = count values = np.array(labels) list_counter = Counter(labels) max_counter = max(list_counter.values()) max_label = -1 for label_key,label_number in list_counter.items(): if label_number==max_counter: max_label = label_key print("max label = " + str(max_label)) searchval = max_label ii = np.where(values == searchval)[0] new_key["largest_mesh_perc"] = len(ii)/len(labels) print("n_bodies = " + str(new_key["n_bodies"])) print("largest mesh perc = " + str(new_key["largest_mesh_perc"])) """ total_splits = mesh.split(only_watertight=False) print( f"There were {len(total_splits)} after split and significance threshold" ) mesh_pieces = [ k for k in total_splits if len(k.faces) > split_significance_threshold ] print( f"There were {len(mesh_pieces)} after split and significance threshold" ) for g, mh in enumerate(mesh_pieces): print(f"Mesh piece {g} with number of faces {len(mh.faces)}") print( f"Step 2a: Getting the number of splits: {time.time() - start_time}" ) #get the largest mesh piece largest_mesh_index = -1 largest_mesh_size = 0 for t, msh in enumerate(mesh_pieces): if len(msh.faces) > largest_mesh_size: largest_mesh_index = t largest_mesh_size = len(msh.faces) #largest mesh piece largest_mesh_perc = largest_mesh_size / len(mesh.faces) new_key["largest_mesh_perc"] = largest_mesh_perc print("largest mesh perc = " + str(largest_mesh_perc)) largest_mesh_skeleton_distance = -1 paths_used = [] total_edges = np.array([]) for h, m in enumerate(mesh_pieces): print(f"Working on split {h} with face total = {len(m.faces)}") # start_time = time.time() # #pass the vertices and faces to pymeshfix to become watertight # meshfix = pymeshfix.MeshFix(m.vertices,m.faces) # meshfix.repair(verbose=False,joincomp=True,remove_smallest_components=False) # print(f"Step 2b: Pymesh shrinkwrapping: {time.time() - start_time}") # #print("Step 2: Writing Off File") # start_time = time.time() # #write the new mesh to off file # path_and_filename,filename,file_loc = write_Whole_Neuron_Off_file(str(new_key["segment_id"]) + "_piece_" + str(h),meshfix.v,meshfix.f) # print(f"Step 3: Writing shrinkwrap off file: {time.time() - start_time}") #add the path to be deleted later path_and_filename, filename, file_loc = write_Whole_Neuron_Off_file( str(new_key["segment_id"]) + "_piece_" + str(h), m.vertices, m.faces) paths_used.append(path_and_filename) #Run the meshlabserver scripts start_time = time.time() #output_mesh = meshlab_fix_manifold_path(path_and_filename,key["segment_id"]) meshlab_script = str( pathlib.Path.cwd()) + "/" + "pymesh_fix_substitute.mls" output_mesh = meshlab_fix_manifold_path_specific_mls( path_and_filename, key["segment_id"], meshlab_script) print( f"Step 4: Meshlab fixing non-manifolds: {time.time() - start_time}" ) print(output_mesh[:-4]) #send to be skeletonized start_time = time.time() mls_mesh = trimesh.load_mesh(output_mesh) if len(mls_mesh.faces) < 20: print( "Number of faces are less than 20 so not generating skeleton" ) continue return_value = cm.calcification(output_mesh[:-4]) if return_value > 0: print('skeletonization for neuron ' + str(new_key["segment_id"]) + ' did not finish... exited with error code: ' + str(return_value)) print("Trying skeletonization with pymesh") #try to run the same skeletonization but now with skeletonization # start_time = time.time() #pass the vertices and faces to pymeshfix to become watertight meshfix = pymeshfix.MeshFix(mls_mesh.vertices, mls_mesh.faces) meshfix.repair(verbose=False, joincomp=True, remove_smallest_components=False) print( f"Step 2b: Pymesh shrinkwrapping: {time.time() - start_time}" ) if len(meshfix.f) < 20: print( "Number of faces are less than 20 so not generating skeleton" ) continue #print("Step 2: Writing Off File") start_time = time.time() #write the new mesh to off file path_and_filename, filename, file_loc = write_Whole_Neuron_Off_file( str(new_key["segment_id"]) + "_piece_" + str(h), meshfix.v, meshfix.f) print( f"Step 3: Writing shrinkwrap off file: {time.time() - start_time}" ) #add the path to be deleted later paths_used.append(path_and_filename) #Run the meshlabserver scripts start_time = time.time() #output_mesh = meshlab_fix_manifold_path(path_and_filename,key["segment_id"]) meshlab_script = str( pathlib.Path.cwd()) + "/" + "pymesh_fix_substitute.mls" output_mesh = meshlab_fix_manifold_path_specific_mls( path_and_filename, key["segment_id"], meshlab_script) print( f"Step 4: Meshlab fixing non-manifolds: {time.time() - start_time}" ) #print(output_mesh[:-4]) #send to be skeletonized start_time = time.time() mls_mesh = trimesh.load_mesh(output_mesh) if len(mls_mesh.faces) < 20: print( "Number of faces are less than 20 so not generating skeleton" ) continue return_value = cm.calcification(output_mesh[:-4]) if return_value > 0: raise Exception( 'skeletonization for neuron ' + str(new_key["segment_id"]) + ' did not finish EVEN AFTER TRYING PYMESH... exited with error code: ' + str(return_value)) print(f"Step 5: Generating Skeleton: {time.time() - start_time}") #read in the skeleton files into an array bone_array = read_skeleton_revised(output_mesh[:-4] + "_skeleton.cgal") #print(bone_array) if len(bone_array) <= 0: raise Exception('No skeleton generated for ' + str(new_key["segment_id"])) print( f"Step 5: Generating and reading Skeleton: {time.time() - start_time}" ) #get the largest mesh skeleton distance if h == largest_mesh_index: largest_mesh_skeleton_distance = find_skeleton_distance( bone_array) #add the skeleton edges to the total edges if not total_edges.any(): total_edges = bone_array else: total_edges = np.vstack([total_edges, bone_array]) total_edges_stitched = stitch_skeleton_with_degree_check(total_edges) #get the total skeleton distance for the stitched skeleton total_skeleton_distance = find_skeleton_distance(total_edges_stitched) largest_mesh_distance_perc = largest_mesh_skeleton_distance / total_skeleton_distance start_time = time.time() new_key["n_edges"] = len(total_edges_stitched) new_key["edges"] = total_edges_stitched new_key["n_bodies"] = len(total_splits) new_key["n_bodies_stitched"] = len(mesh_pieces) new_key["largest_mesh_perc"] = largest_mesh_perc new_key["largest_mesh_distance_perc"] = largest_mesh_distance_perc self.insert1(new_key, skip_duplicates=True) print(f"Step 6: Inserting dictionary: {time.time() - start_time}") #raise Exception("done with one neuron") for path_and_filename in paths_used: os.system("rm " + str(path_and_filename) + "*") print(f"Total time: {time.time() - global_time}") print("\n\n")