예제 #1
0
    def make_manifold(self, verbose=False):
        """
        Reconstruct a manifold clean surface from input mesh.  Updates
        mesh in-place.

        Requires pymeshfix

        Parameters
        ----------
        verbose : bool, optional
            Controls output printing.  Default False.

        """
        try:
            import pymeshfix
        except:
            raise ImportError('pymeshfix not installed.  Please run: \n' +
                              'pip install pymeshfix')

        # Run meshfix
        import pymeshfix
        meshfix = pymeshfix.MeshFix(self.v, self.f)
        meshfix.repair(verbose)

        # overwrite this object with cleaned mesh
        self.v = meshfix.v
        self.f = meshfix.f
예제 #2
0
    def GetClosedTrimesh(self, v, f, data):

        unzipped_tri = gzip.decompress(data)
        sub_face_id = []
        for i in range(f.shape[0]):
            if (unzipped_tri[i * 3:i * 3 + 3] == b'\x01\x01\x01'):
                sub_face_id.append(f[i, :])

        part_mesh = pymeshfix.MeshFix(v, np.array(sub_face_id))
        part_mesh.repair()
        part_mesh.plot()  # Visualization of cloased meshes

        #		voxels = pv.voxelize(part_mesh, density=part_mesh.length/200)

        #		p = pv.Plotter()
        #		p.add_mesh(voxels, color=True, show_edges=True, opacity=0.5)
        #		p.add_mesh(surface, color="lightblue", opacity=0.5)
        #		p.show()

        closed_v = part_mesh.v  # numpy np.float array
        closed_f = part_mesh.f  # numpy np.int32 array

        closed_mesh = trimesh.Trimesh(vertices=closed_v, faces=closed_f)

        closed_mesh.merge_vertices()
        closed_mesh.remove_degenerate_faces()
        closed_mesh.remove_duplicate_faces()

        # print("Volume: ", closed_mesh.volume)
        # Numpy-stl (mesh) にも同ルーチン有
        return closed_mesh
예제 #3
0
    def surface_from_multiwfn(self,
                              file: Union[str, PathLike],
                              fix_mesh: bool = True) -> "Dispersion":
        """Adds surface from Multiwfn vertex file with connectivity information.

        Args:
            file: Vertex.pdb file
            fix_mesh: Whether to fix holes in the mesh with pymeshfix (recommended)

        Returns:
            self: Self
        """
        # Read the vertices and faces from the Multiwfn output file
        parser = VertexParser(file)
        vertices = np.array(parser.vertices)
        faces = np.array(parser.faces)
        faces = np.insert(faces, 0, values=3, axis=1)

        # Construct surface and fix it with pymeshfix
        surface = pv.PolyData(vertices, faces, show_edges=True)
        if fix_mesh:
            meshfix = pymeshfix.MeshFix(surface)
            meshfix.repair()
            surface = meshfix.mesh

        # Process surface
        self._surface = surface
        self._process_surface()

        return self
예제 #4
0
def repair_mesh(mesh: Trimesh) -> Trimesh:
    """
    Repair the given mesh using pymeshfix.
    """
    mf = pymeshfix.MeshFix(mesh.vertices, mesh.faces)
    mf.repair()

    return Trimesh(mf.v, mf.f)
예제 #5
0
파일: fix.py 프로젝트: mta152/pymeshfix
def WithVTK(plot=True):
    """ Tests VTK interface and mesh repair of Stanford Bunny Mesh """
    mesh = vtki.PolyData(bunny_scan)
    meshfix = pymeshfix.MeshFix(mesh)
    if plot:
        print('Plotting input mesh')
        meshfix.Plot()
    meshfix.Repair()
    if plot:
        print('Plotting repaired mesh')
        meshfix.Plot()

    return meshfix.mesh
def repair_holes(vertices, faces_):
    # trimesh has a hole fixing function, but it just deals with
    # 3 or 4 vertices holes.
    meshfix = pymeshfix.MeshFix(vertices, faces_)
    meshfix.repair()
    vertices = meshfix.v  # numpy np.float array
    faces_ = meshfix.f  # numpy np.int32 array

    # The return mesh has a solid angle of -1 instead of 1.
    # Correcting this.
    mesh_ = trimesh.Trimesh(vertices=vertices, faces=faces_)
    trimesh.repair.fix_normals(mesh_, multibody=False)
    return mesh_.vertices, mesh_.faces
예제 #7
0
def test_repair_vtk():
    meshin = vtki.PolyData(bunny_scan)
    meshfix = pymeshfix.MeshFix(meshin)
    meshfix.repair()

    # check arrays and output mesh
    assert np.any(meshfix.v)
    assert np.any(meshfix.f)
    meshout = meshfix.mesh
    assert meshfix.mesh.n_points

    # test for any holes
    pdata = meshout.extract_edges(non_manifold_edges=False, feature_edges=False,
                                  manifold_edges=False)
    assert pdata.n_points == 0
예제 #8
0
def test_repairVTK():
    meshin = vtki.PolyData(bunny_scan)
    meshfix = pymeshfix.MeshFix(meshin)
    meshfix.Repair()

    # check arrays and output mesh
    assert np.any(meshfix.v)
    assert np.any(meshfix.f)
    meshout = meshfix.mesh
    assert meshfix.mesh.GetNumberOfPoints()

    # test for any holes
    pdata = meshout.ExtractEdges(non_manifold_edges=False,
                                 feature_edges=False,
                                 manifold_edges=False)
    assert pdata.GetNumberOfPoints() == 0
예제 #9
0
파일: bunny.py 프로젝트: zeta1999/pymeshfix
import pyvista as pv
import pymeshfix as mf
from pyvista import examples

################################################################################
bunny = examples.download_bunny()

# Define a camera position that shows the holes in the mesh
cpos = [(-0.2, -0.13, 0.12), (-0.015, 0.10, -0.0), (0.28, 0.26, 0.9)]

# Show mesh
bunny.plot(cpos=cpos)

################################################################################
# Genereate a meshfix mesh ready for fixing and extract the holes
meshfix = mf.MeshFix(bunny)
holes = meshfix.extract_holes()

################################################################################
# Render the mesh and outline the holes
p = pv.Plotter()
p.add_mesh(bunny, color=True)
p.add_mesh(holes, color='r', line_width=8)
p.camera_position = cpos
p.enable_eye_dome_lighting()  # helps depth perception
p.show()

################################################################################
# Repair the mesh
meshfix.repair(verbose=True)
예제 #10
0
    def make(self, key):
        print("----------Working on " + str(key['segment_id']) + ":----------")

        split_significance_threshold = 200

        global_time = time.time()

        #get the mesh with the error segments filtered away
        start_time = time.time()

        mesh, face_indexes = get_mesh_minus_errors_and_spines(key)

        new_key = dict(segmentation=key["segmentation"],
                       segment_id=key["segment_id"])
        """
        Handle the poosibility that there is no mesh
        """
        if len(mesh.faces) < 50:
            print(
                f"There were only {len(mesh.faces)} faces in mesh so not doing skeletonization"
            )
            new_key["n_edges"] = 0
            new_key["edges"] = np.array([]).astype(float)
            new_key["n_bodies"] = 0
            new_key["n_bodies_stitched"] = 0
            new_key["largest_mesh_perc"] = 0
            new_key["largest_mesh_distance_perc"] = 0
            new_key["n_faces_in_filtered"] = len(face_indexes)
            new_key["faces_in_filtered"] = face_indexes

            self.insert1(new_key, skip_duplicates=True)
        else:

            print(
                f"Step 1: Retrieving Mesh and removing error segments: {time.time() - start_time}"
            )

            # 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()
            """ 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

                #send the data through the hole patching function from pymesh:
                cleaned_verts, cleaned_triangles = clean_from_arrays_celii(
                    m.vertices,
                    m.faces,
                    verbose=True,
                    joincomp=True,
                    remove_smallest_components=False,
                    clean=False)
                #cleaned_mesh = make_trimesh_object(m.vertices,m.faces)

                path_and_filename, filename, file_loc = write_Whole_Neuron_Off_file(
                    str(new_key["segment_id"]) + "_piece_" + str(h),
                    cleaned_verts, cleaned_triangles)

                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_2.mls"
                output_mesh = meshlab_fix_manifold_path_specific_mls(
                    path_and_filename, key["segment_id"], meshlab_script)

                meshlab_script_2 = str(
                    pathlib.Path.cwd()) + "/" + "remove_intersecting_faces.mls"
                output_mesh = meshlab_fix_manifold_path_specific_mls(
                    output_mesh, key["segment_id"], meshlab_script_2)

                print("About to run pymeshfix")
                start_time_py = time.time()
                loaded_mesh = trimesh.load_mesh(output_mesh, process=False)
                meshfix = pymeshfix.MeshFix(loaded_mesh.vertices,
                                            loaded_mesh.faces)
                meshfix.repair(verbose=False,
                               joincomp=True,
                               remove_smallest_components=False)
                print(
                    f"Total time for pymeshfix = {time.time() - start_time_py}"
                )

                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 4: Meshlab fixing non-manifolds: {time.time() - start_time}"
                )

                print(path_and_filename)

                #send to be skeletonized
                start_time = time.time()

                mls_mesh = trimesh.load_mesh(path_and_filename + ".off")

                if len(mls_mesh.faces) < 20:
                    print(
                        "Number of faces are less than 20 so not generating skeleton"
                    )
                    continue

                return_value = cm.calcification(path_and_filename)
                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("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_2.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(path_and_filename +
                                                   "_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
            new_key["n_faces_in_filtered"] = len(face_indexes)
            new_key["faces_in_filtered"] = face_indexes

            #print("new_key=" + str(new_key))

            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")
예제 #11
0
    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")
예제 #12
0
    def open_mesh(self):
        """ add a mesh to the pyqt frame """
        global int_surface, ext_surface, mesh_vol, mesh
        global x_range, y_range, z_range, Vol_centroid
        global open_mesh_run
        global mesh_name

        # track pre-processing starting time
        open_mesh_start = time.time()

        # open file
        file_info = QtWidgets.QFileDialog.getOpenFileName()
        file_path = file_info[0]
        
        # determine file type and if conversion needed
        _, file_name = os.path.split(file_path)
        mesh_name, mesh_type = os.path.splitext(file_name)

        # read mesh & transform according to principal axes
        print(file_path)
        pre = trimesh.load(file_path)
        orient = pre.principal_inertia_transform
        pre = pre.apply_transform(orient)
        post_file_path = 'data/'+ mesh_name + '_oriented.stl'
        pre.export(post_file_path)
        ext_surface = pv.read(post_file_path)

        # scale meshes accordingly
        if mesh_name == 'elephant':
            ext_surface.points *= 12  # Elephant
        elif mesh_name == 'Bracket S24D1':
            ext_surface.points /= 10  # Bracket
        elif mesh_name == 'knight':
            ext_surface.points /= 2 # Knight

        # create internal offset
        thickness = 0.1 # inches
        grid = pv.create_grid(ext_surface).triangulate()
        solid = grid.clip_surface(ext_surface)
        solid.compute_implicit_distance(ext_surface, inplace=True)
        imp_dis_max = max(solid['implicit_distance'])

        shell_threshold = imp_dis_max - thickness
        shell = solid.clip_scalar('implicit_distance', value = shell_threshold)
        int_surface = shell.extract_geometry()

        meshfix = mf.MeshFix(int_surface)
        meshfix.repair(verbose=True)

        mesh = solid.clip_surface(int_surface, invert=False)
        
        # print mesh info
        print("Mesh Name:", mesh_name)
        print("Mesh Type:", mesh_type[1:])

        # find mesh centroid and translate the mesh so that's the origin
        Vol_centroid = np.array([0,0,0])
        self.skewed_centroid_action.setCheckable(True)

        # reset plotter
        self.reset_plotter(Vol_centroid)

        # find the max and min of x,y,z axes of mesh
        ranges = mesh.bounds
        x_range = abs(ranges[0] - ranges[1])
        y_range = abs(ranges[2] - ranges[3])
        z_range = abs(ranges[4] - ranges[5])
        print("x:", float(format(x_range, ".2f")), "in")
        print("y:", float(format(y_range, ".2f")), "in")
        print("z:", float(format(z_range, ".2f")), "in")

        # mesh volume
        mesh_vol = float(format(mesh.volume, ".2f"))
        print("Mesh Volume:", mesh_vol, "in^3")

        # track pre-processing ending time & duration
        open_mesh_end = time.time()
        open_mesh_run = open_mesh_end - open_mesh_start
        print("Pre-Processing run time: %g seconds" % (open_mesh_run))

        print("Mesh Cells:", mesh.n_cells)
예제 #13
0
import pyvista as pv
import pymeshfix as mf
from pyvista import examples

mesh = examples.download_torso()
print(mesh)

################################################################################

cpos = [(-1053., -1251., 83.), (2., -15., -276.), (0.12, 0.18, 1)]

mesh.plot(color=True, show_edges=True, cpos=cpos)

################################################################################
# Appy a triangle filter to ensure the mesh is simply polyhedral
meshfix = mf.MeshFix(mesh.tri_filter())
holes = meshfix.extract_holes()

################################################################################
# Outline the holes in the mesh
p = pv.Plotter()
p.add_mesh(mesh)
p.add_mesh(holes, color='r', line_width=8)
p.enable_eye_dome_lighting()  # helps with depth perception
p.camera_position = cpos
p.show()

################################################################################
# Emphasize the hole near the ear - this needs to be repaired so that the mesh
# is absolutely water tight.
cpos_ear = [(180., -206., 17.), (107., -122.9, -11.9), (-0.13, 0.22, 0.96)]
예제 #14
0
    def SimplifyMeshSubj(self):
        '''Function to simplify a mesh from a subject folder, the simplification also cleans problems and
        suppresses small disconnected objects. The meshes created are displayed for the user to check that
        there aren´t any problems, close the window of the displayed mesh for the script to continue.
        The function doesn´t return outputs, it saves the new faces
        and vertices in .npy files in the subject folder.

        Function call:
        SimplifyMeshSubj()'''
        ###### Mesh simplification

        warnings.filterwarnings("ignore")

        proceed = True

        if os.path.isfile(os.path.join(self.Subj_folder, 'vertices_simple.npy')) and\
                os.path.isfile(os.path.join(self.Subj_folder,'faces_simple.npy')):
            print(
                'Simplified mesh already exists, do you want to re-calculate?')
            proceed_ = input("Yes(y)/No(n): ")

            if proceed_ == 'y' or proceed_ == 'Y':
                proceed = True
            else:
                proceed = False

        if proceed:
            # Plots the original surf
            # Plot the final reduced mesh

            if self.quiet == 0:
                print('Loaded mesh. Close window to proceed!')
                mlab.triangular_mesh(self.vertices_full[:, 0],
                                     self.vertices_full[:, 1],
                                     self.vertices_full[:, 2], self.faces_full)
                mlab.show()

            ######## GM ########
            print('Simplifying cortical surface')
            ####### Initial Mesh cleaning (fixes problems and deletes disconnected components)
            repaired = fix.MeshFix(self.vertices_full, self.faces_full)
            repaired.repair()
            vertices_simple = repaired.v
            faces_simpl = repaired.f

            ######## Mesh decimation ########
            x = vertices_simple[:, 0]
            y = vertices_simple[:, 1]
            z = vertices_simple[:, 2]
            mesh = mlab.pipeline.triangular_mesh_source(
                x, y, z, faces_simpl)  # creates mesh structure
            dec = mlab.pipeline.quadric_decimation(
                mesh)  # Creates the decimation filter
            dec.filter.target_reduction = self.reductions_ratio  # Set the decimation value (reduces to 25%,changed due to post-fixing)
            new_nodes = np.array(
                dec.outputs[0]._get_output()._get_points())  # Get the nodes
            new_faces = np.array(
                dec.outputs[0]._get_output()._get_polys()._get_data()).astype(
                    int)  # get the faces
            bad_index = range(
                0, len(new_faces), 4
            )  # values to discard (probably reference to the number of nodes in the face)
            new_faces = np.delete(new_faces,
                                  bad_index)  # obtain the real face values
            new_faces = np.reshape(new_faces,
                                   (-1, 3))  # generate the faces matrix

            ####### Final Mesh cleaning (fixes problems and deletes disconnected components)
            repaired = fix.MeshFix(new_nodes, new_faces)
            repaired.repair()
            vertices_simple = repaired.v
            faces_simple = repaired.f
            if self.quiet == 0:
                # Plot the final reduced mesh
                print('Check the mesh! Close the window to proceed!')
                mlab.triangular_mesh(vertices_simple[:, 0], vertices_simple[:,
                                                                            1],
                                     vertices_simple[:, 2], faces_simple)
                mlab.show()

            print('Done!')

            # Calculates normals!
            print('Calculating faces normals!')
            # Calculates faces normals with trimesh
            meshTRIM_simply = trimesh.Trimesh(vertices_simple, faces_simple)
            trimesh.repair.fix_inversion(meshTRIM_simply, multibody=True)
            trimesh.repair.fix_normals(meshTRIM_simply, multibody=True)

            #Updates attributes of the class!
            self.vertices_simple = meshTRIM_simply.vertices
            self.faces_simple = np.int32(meshTRIM_simply.faces)
            s_snorm = meshTRIM_simply.face_normals

            # Saves nodes and faces!
            np.save(os.path.join(self.Subj_folder, 'vertices_simple.npy'),
                    self.vertices_simple)

            np.save(os.path.join(self.Subj_folder, 'faces_simple.npy'),
                    self.faces_simple)

            print('Done!')

            print('Calculating faces/normals areas!')
            self.Area_calc()
            print('Done!')

            print('Calculates normals in each node!')
            self.normals_simple = self.triangles2nodes(data_2_remap=s_snorm,
                                                       normalize=True)
            np.save(os.path.join(self.Subj_folder, 'normals_simple.npy'),
                    self.normals_simple)

            print('Done!')

            print(
                'Calculates dot products of normals (convenient for EMOD calculation)!'
            )

            n = self.normals_simple.shape[0]
            normals_vector = np.zeros(np.int(0.5 * n * (n - 1) + n))

            finish_vector = 1
            init_vector = 0
            final_node = 1

            for i in self.normals_simple:
                nodes2use = self.normals_simple[0:final_node, ]
                dot_norm = np.dot(nodes2use, i)

                normals_vector[init_vector:finish_vector] = dot_norm
                init_vector = finish_vector
                finish_vector = init_vector + dot_norm.shape[0] + 1
                final_node = final_node + 1

            np.save(os.path.join(self.Subj_folder, 'dot_normals_half.npy'),
                    np.float32(normals_vector))

            print('Done!')

            print(
                'Calculates products of areas (convenient for EMOD calculation)!'
            )

            n = self.area_nodes_simple.shape[0]
            areas_vector = np.zeros(np.int(0.5 * n * (n - 1) + n))
            single_areas_vector = np.zeros(np.int(0.5 * n * (n - 1) + n))

            finish_vector = 1
            init_vector = 0
            final_node = 1

            for i in progressbar.progressbar(self.area_nodes_simple):
                nodes2use = self.area_nodes_simple[0:final_node, ]
                dot_norm = nodes2use * i
                dot_norm_single = i * np.ones(np.shape(nodes2use))

                areas_vector[init_vector:finish_vector] = dot_norm
                single_areas_vector[
                    init_vector:finish_vector] = dot_norm_single
                init_vector = finish_vector
                finish_vector = init_vector + dot_norm.shape[0] + 1
                final_node = final_node + 1

            np.save(os.path.join(self.Subj_folder, 'dot_areas_half.npy'),
                    np.float32(areas_vector))
            np.save(
                os.path.join(self.Subj_folder, 'dot_areas_single_half.npy'),
                np.float32(single_areas_vector))

            print('Done!')

            print(
                'Saved simplified mesh and its attributes in subject folder!')

        else:
            self.vertices_simple = np.load(
                os.path.join(self.Subj_folder, 'vertices_simple.npy'))
            self.faces_simple = np.load(
                os.path.join(self.Subj_folder, 'faces_simple.npy'))
            self.normals_simple = np.load(
                os.path.join(self.Subj_folder, 'normals_simple.npy'))
            self.area_nodes_simple = np.load(
                os.path.join(self.Subj_folder, 'area_per_node.npy'))
            self.area_faces_simple = np.load(
                os.path.join(self.Subj_folder, 'area_per_face.npy'))
예제 #15
0
파일: torso.py 프로젝트: zeta1999/pymeshfix

mesh = examples.download_torso()
print(mesh)

################################################################################

cpos = [(-1053., -1251., 83.),
        (2., -15., -276.),
        (0.12, 0.18, 1)]

mesh.plot(color=True, show_edges=True, cpos=cpos)

################################################################################
# Appy a triangle filter to ensure the mesh is simply polyhedral
meshfix = mf.MeshFix(mesh.triangulate())
holes = meshfix.extract_holes()

################################################################################
# Outline the holes in the mesh
p = pv.Plotter()
p.add_mesh(mesh)
p.add_mesh(holes, color='r', line_width=8)
p.enable_eye_dome_lighting() # helps with depth perception
p.camera_position = cpos
p.show()

################################################################################
# Emphasize the hole near the ear - this needs to be repaired so that the mesh
# is absolutely water tight.
cpos_ear = [(180., -206., 17.),
예제 #16
0
파일: fix.py 프로젝트: mta152/pymeshfix
    """ Functional Test: vtk and native """
    out_file = 'repaired.ply'
    Native()
    outmesh = vtki.PolyData(out_file)
    os.remove(out_file)
    assert outmesh.GetNumberOfPoints()

    # test for any holes
    pdata = outmesh.ExtractEdges(non_manifold_edges=False,
                                 feature_edges=False,
                                 manifold_edges=False)
    assert pdata.GetNumberOfPoints() == 0

    # test vtk
    meshin = vtki.PolyData(bunny_scan)
    meshfix = pymeshfix.MeshFix(meshin)
    meshfix.Repair()

    # check arrays and output mesh
    assert np.any(meshfix.v)
    assert np.any(meshfix.f)
    meshout = meshfix.mesh
    assert meshfix.mesh.GetNumberOfPoints()

    # test for any holes
    pdata = meshout.ExtractEdges(non_manifold_edges=False,
                                 feature_edges=False,
                                 manifold_edges=False)
    assert pdata.GetNumberOfPoints() == 0

    print('PASS')
예제 #17
0
파일: cow.py 프로젝트: bygreencn/pymeshfix
import numpy as np

################################################################################
cow = examples.download_cow()

# Add holes and cast to triangulated PolyData
cow['random'] = np.random.rand(cow.n_cells)
holy_cow = cow.threshold(0.9, invert=True).extract_geometry().tri_filter()
print(holy_cow)

################################################################################

# A nice camera location of the cow
cpos = [(6.56, 8.73, 22.03), (0.77, -0.44, 0.0), (-0.13, 0.93, -0.35)]

meshfix = mf.MeshFix(holy_cow)
holes = meshfix.extract_holes()

# Render the mesh and outline the holes
p = pv.Plotter()
p.add_mesh(holy_cow, color=True)
p.add_mesh(holes, color='r', line_width=8)
p.camera_position = cpos
p.enable_eye_dome_lighting()  # helps depth perception
p.show()

################################################################################
# Repair the holey cow

meshfix.repair(verbose=True)
예제 #18
0
    def make(self, key):
        global_time = time.time()
        #get the mesh with the error segments filtered away
        start_time = time.time()
        new_key = remove_error_segments(key)
        print(f"Step 1: Retrieving Mesh and removing error segments: {time.time() - start_time}")
        
        #where i deal with the error segments
        if new_key["vertices"].size<2:
            start_time = time.time()
            print("All faces were error segments, inserting dummy entry")
            #create the key with None
            new_key["n_vertices"] = 0
            new_key["n_triangles"] = 0
            new_key["vertices"] = np.array([]).astype(float)
            new_key["triangles"] = np.array([]).astype(float)
            new_key["n_edges"] = 0
            new_key["edges"] = np.array([]).astype(float)
            self.insert1(new_key,skip_duplicates=True)
            
            #insert dummy dictionary into correspondence table
#             new_correspondence_dict = dict(segmentation=key["segmentation"],
#                                            segment_id=key["segment_id"],
#                                            time_updated=str(datetime.datetime.now()),
#                                            n_correspondence = 0,
#                                            correspondence=np.array([]).astype(float))
            
#             #if all goes well then write to correspondence database
#             ta3p100.NeuronRawSkeletonCorrespondence.insert1(new_correspondence_dict,skip_duplicates=True)
            
            
            print(f"Step 2: Inserting dummy dictionary: {time.time() - start_time}")
            print(f"Total time: {time.time() - global_time}")
            print("\n\n")
        
        else:
        
            #print("Step 2: Remove all error semgents")
            start_time = time.time()
            #pass the vertices and faces to pymeshfix to become watertight
            meshfix = pymeshfix.MeshFix(new_key["vertices"],new_key["triangles"])
            meshfix.repair(verbose=False,joincomp=True,remove_smallest_components=False)
            print(f"Step 2: 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
            #start_time = time.time()
            
            ##****** this needs to be changed for reading them in******
            bone_array = read_skeleton_revised(output_mesh[:-4]+"_skeleton.cgal")
            #correspondence_array = read_skeleton_revised(output_mesh[:-4]+"_correspondance.cgal")
            #print(bone_array)
            if len(bone_array) <= 0:
                raise Exception('No skeleton generated for ' + str(new_key["segment_id"]))
            
#             if len(correspondence_array) <= 0:
#                 raise Exception('No CORRESPONDENCE 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"] = bone_array.shape[0]
            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)
            
            #create a new dictionary key to be inserted into correspondence table
            """
            time_updated      :timestamp    # the time at which the component labels were updated
            ---
            n_correspondence   :int unsigned #number of mappings from skeleton vert to original surface vert 
            correspondence     :longblob #array storing mapping of every skeleton vert to original surface vert  
            """
#             #insert dummy dictionary into correspondence table
#             new_correspondence_dict = dict(segmentation=key["segmentation"],
#                                            segment_id=key["segment_id"],
#                                            time_updated=str(datetime.datetime.now()),
#                                            n_correspondence = correspondence_array.shape[0],
#                                            correspondence=correspondence_array)
            
#             #if all goes well then write to correspondence database
#             ta3p100.NeuronRawSkeletonCorrespondence.insert1(new_correspondence_dict,skip_duplicates=True)
            
            
            os.system("rm "+str(path_and_filename)+"*")
            print(f"Step 6: Inserting both dictionaries: {time.time() - start_time}")
            print(f"Total time: {time.time() - global_time}")
            print("\n\n")