Reputation: 31
I have a "doughnut" or "toroidal" shape mesh, meaning that it has a hole in the middle but it is a closed mesh. These holes are due to the topology of the mesh and not because of an error or missing polygons. I need to fill this holes so I have a complete surface. Can I achieve this using pymeshlab, trimesh or other libraries in python? I have tried with different libraries with filling holes methods but since this is a closed surface those methods does not work.
Here is an example of my mesh.
And here is an example of how my mesh should look after I fill this topology holes on the mesh
Here are some of the functions I have tried
Using trimesh:
stl_file = os.path.join(stl_folder, filename)
mesh = trimesh.load(stl_file)
filled_mesh = mesh_creator.fillMesh(mesh)
filled_mesh.export(stl_file)
Using VTK
fillHolesFilter = vtk.vtkFillHolesFilter()
fillHolesFilter.SetInputConnection(reader.GetOutputPort())
fillHolesFilter.SetHoleSize(1000.0)
fillHolesFilter.Update()
But these gives me the exact same mesh, whitouth filling the holes.
Upvotes: 1
Views: 517
Reputation: 133
As Neil Butcher already said in his comment under your post, shrinkwrapping seem to be the go-to technique for you.
PyMeshLab provides an implementation of the algorithm described in the 2022 paper "Alpha wrapping with an offset". Check the PyMeshLab documentation for more info.
The code would look like this:
import pymeshlab
ms = pymeshlab.MeshSet()
ms.load_new_mesh("your_mesh.stl")
alpha = 1e-2 # size (fraction) of the 'ball'
offset = 1e-3 # distance (fraction) that is added to the surface
ms.generate_alpha_wrap(alpha, offset)
ms.save_current_mesh("dest_mesh.stl")
The same algorithm is also implemented in CGAL. Check the CGAL documentation here. CGAL has a Python wrapper. If you prefer to use it, the code would look like something like this:
from CGAL.CGAL_Polyhedron_3 import Polyhedron_3
from CGAL.CGAL_Alpha_wrap_3 import alpha_wrap_3
P = Polyhedron_3("your_mesh.stl")
Q = Polyhedron_3() # destination mesh
alpha = 1e-2 # size (abs) of the 'ball'
offset = 1e-3 # distance (abs) that is added to the surface
alpha_wrap_3(P, alpha, offset, Q)
Q.write_to_file("dest_mesh.stl")
Alternatively, Open3D also provides some surface reconstruction algorithms that you may want to check.
Cheers!
Upvotes: 1