def remesh(surfacefile, numbertriangles=40000, output="remeshed.vtp"): """ Remesh a surface mesh using using voronoi clustering. Source and module at https://pypi.org/project/pyacvd/ :param surfacefile: Surfacefile to be remeshed to a uniform triangulation. :param numbertriangles: Number of triangles that the surface will have after the remeshing. Default:40000 :param output: output file name :return: Nothing """ print("Remeshing surface.") if surfacefile[-3:] == "vtp": reader = vtk.vtkXMLPolyDataReader() elif surfacefile[-3:] == "ply": reader = vtk.vtkPLYReader() else: print("Input is not a ply or vtp file.") return reader.SetFileName(surfacefile) reader.Update() p = reader.GetOutput() surf = pyvista.PolyData(p) clus = pyacvd.Clustering(surf) clus.subdivide(3) clus.cluster(numbertriangles) remesh = clus.create_mesh() writer = vtk.vtkXMLPolyDataWriter() writer.SetFileName(output) writer.SetInputData(remesh) writer.Write()
def test_cow(): # must be an all triangular mesh to sub-divide cow.tri_filter(inplace=True) # mesh is not dense enough for uniform remeshing clus = pyacvd.Clustering(cow) clus.subdivide(3) clus.cluster(20000) clus.plot(off_screen=True) remesh = clus.create_mesh()
def test_cylinder(): cylinder = pv.Cylinder().tri_filter() # cylinder.clean(inplace=True) clus = pyacvd.Clustering(cylinder) clus.subdivide(3) nclus = 500 clus.cluster(nclus) remesh = clus.create_mesh() assert remesh.n_points == nclus
def mono_uniform_remeshing(data): if VERBOSE: print(f"Remeshing: {data['meta_data']['name']}") data = data["poly_data"].clean() clus = pyacvd.Clustering(data) try: while len(clus.mesh.points) < 30000: clus.subdivide(2) except MemoryError as e: print(f"Ups that a little too much memory! {e}") clus.cluster(10000) remesh = clus.create_mesh() return remesh
def get_smooth_and_coarse_mesh_from_voxelization(img, sigma, npoints): """ Converts an image into a triangle mesh with even distributed points. First we use a Gaussian kernel with size (sigma**3) to smooth the input image. Next we apply marching cubes (vtkContourFilter) to obtain a first mesh, which is used as input to a Voronoi-based clustering that is responsible for remeshing. Details can be found here: https://github.com/pyvista/pyacvd Parameters ---------- img: np.array Input image corresponding to the voxelized version of the original average mesh. sigma: float Gaussian kernel size. npoints: int Number of points used to create the Voronoi clustering. The larger this value the more points the final mesh will have. Returns ------- remesh_vtk: vtkPolyData Triangle with even distirbuted points. """ rad = 5 img = np.pad(img, ((rad, rad), (rad, rad), (rad, rad))) d, h, w = img.shape img = skfilters.gaussian(img > 0, sigma=sigma, preserve_range=True) imagedata = vtk.vtkImageData() imagedata.SetDimensions([w, h, d]) imagedata.SetExtent(0, w - 1, 0, h - 1, 0, d - 1) imagedata.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) values = (255 * img).ravel().astype(np.uint8) values = vtknp.numpy_to_vtk(values, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) imagedata.GetPointData().SetScalars(values) cf = vtk.vtkContourFilter() cf.SetInputData(imagedata) cf.SetValue(0, 255.0 / np.exp(1.0)) cf.Update() mesh = cf.GetOutput() pv_temp = pv.PolyData(mesh) cluster = pyacvd.Clustering(pv_temp) cluster.cluster(npoints) remesh = cluster.create_mesh() remesh_vtk = vtk.vtkPolyData() remesh_vtk.SetPoints(remesh.GetPoints()) remesh_vtk.SetVerts(remesh.GetVerts()) remesh_vtk.SetPolys(remesh.GetPolys()) return remesh_vtk
def downsample(inp): # surface = vtk.vtkSurface() # surface.CreateFromPolyData(inp) # # areas = vtk.vtkDoubleArray() # areas = surface.GetTrianglesAreas() # surfaceArea = 0 # # for i in range(0, areas.GetSize()): # surfaceArea += areas.GetValue(i) # # clusterNumber = surfaceArea / 20 mesh = pyvista.PolyData(inp) # Create clustering object clus = pyacvd.Clustering(mesh) # mesh is not dense enough for uniform remeshing # clus.subdivide(3) clus.cluster(3000) Remesh = clus.create_mesh() # print(Remesh) # Remesh = vtk.vtkIsotropicDiscreteRemeshing() # Remesh.SetInput(surface) # Remesh.SetFileLoadSaveOption(0) # Remesh.SetNumberOfClusters(clusterNumber) # Remesh.SetConsoleOutput(0) # Remesh.GetMetric().SetGradation(0) # Remesh.SetDisplay(0) # Remesh.Remesh() # out = vtk.vtkPolyData() # out.SetPoints(Remesh.GetOutput().GetPoints()) # out.SetPolys(Remesh.GetOutput().GetPolys()) return Remesh
# warp each point by the normal vectors for i in range(1, int(args.distance) + 1): print(f'Expanding: {i}') shell = shell.compute_normals() warp = vtk.vtkWarpVector() warp.SetInputData(shell) warp.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, vtk.vtkDataSetAttributes.NORMALS) warp.SetScaleFactor(2) warp.Update() shell = pv.wrap(warp.GetOutput()) expanded_mesh = shell.extract_surface() clus = pyacvd.Clustering(expanded_mesh) clus.subdivide(3) clus.cluster(args.points) shell = clus.create_mesh().extract_surface() uniform = shell p = pv.Plotter(notebook=False, shape=(1, 1)) p.add_mesh(shell) p.add_points(np.asarray(uniform.points), color="r", point_size=8.0, render_points_as_spheres=True) p.add_mesh(expanded_mesh, smooth_shading=True) p.link_views() p.show_bounds() p.show()
# timeout_s = 60) # except ShellException as e: # with open(LOG_DIR / (name + ".log"), "w") as log: # log.write(str(e)) #------------------------------------------------------------------------------- # uniform remeshing #------------------------------------------------------------------------------- print("uniform remeshing") PLY_DIR3 = OUTPUT_DIR / "ply3" / experiment os.makedirs(PLY_DIR3, exist_ok=True) for f in PLY_DIR2.iterdir(): ply = pyvista.read(str(f)) clus = pyacvd.Clustering(ply) clus.subdivide(4) clus.cluster(ply.number_of_points * 11 // 10) remesh = clus.create_mesh(flipnorm=False) remesh.save(PLY_DIR3 / f.name) # remove pyvtk header fd = os.open(PLY_DIR3 / f.name, os.O_RDWR) size = os.path.getsize(PLY_DIR3 / f.name) mm = mmap.mmap(fd, size) mm.readline(), mm.readline(), mm.readline() byte = ("comment " + "s" * (mm.find(b'\n') - mm.tell() - 8)).encode("latin-1") mm.write(byte) mm.flush()
############################################################################### # Using pyacvd # ~~~~~~~~~~~~ # # We can use `pyacvd <https://github.com/pyvista/pyacvd>`_ to create a # more uniform mesh using the mesh generated from ``pyvista``. We can # use the ``pyacvd`` module to generate a more uniform surface mesh # and then tetrahedralize that. # # Here we re-run the above example, except using a more uniform surface import pyacvd n_surf = 1000 clustered = pyacvd.Clustering(sphere) clustered.subdivide(2) clustered.cluster(n_surf) uniform_surf = clustered.create_mesh() # generate interior mesh and plot the surface of it tet = tetgen.TetGen(uniform_surf) tet.tetrahedralize(order=1, mindihedral=20, minratio=1.5) uniform_grid = tet.grid uniform_grid.plot(show_edges=True) ############################################################################### # Plot the cross section of the tetrahedralization cell_center = uniform_grid.cell_centers().points
def test_bunny(): clus = pyacvd.Clustering(bunny) clus.cluster(5000) remesh = clus.create_mesh() assert remesh.n_points == 5000
screenshot='/home/alex/afrl/python/source/pyacvd/docs/images/cow.png') cpos = [(7.927519161395299, 3.54223003919585, -4.1077249997544545), (2.5251427740425236, 0.3910539874485469, 1.9812043586464985), (-0.23846635120392892, 0.9325600395795517, 0.2710453318595791)] cow.plot(show_edges=True, color='w', cpos=cpos, screenshot='/home/alex/afrl/python/source/pyacvd/docs/images/cow_zoom.png') # mesh is not dense enough for uniform remeshing # must be an all triangular mesh to sub-divide cow.tri_filter(inplace=True) cow.subdivide(4, inplace=True) clus = pyacvd.Clustering(cow) clus.cluster(20000) # plot clustered cow mesh cpos = [(7.927519161395299, 3.54223003919585, -4.1077249997544545), (2.5251427740425236, 0.3910539874485469, 1.9812043586464985), (-0.23846635120392892, 0.9325600395795517, 0.2710453318595791)] clus.plot(screenshot='/home/alex/afrl/python/source/pyacvd/docs/images/cow_clus.png', cpos=cpos, cmap='bwr') # remesh remesh = clus.create_mesh() # plot uniformly remeshed cow remesh.plot(color='w', show_edges=True, cpos=cpos, smooth_shading=True,