Open FPerezHernandez92 opened 4 months ago
Hi Francisco, I think it is very difficult problem because the original mesh is very irregular and even at the very first step you run into the problem of having the extrusion of the boundary to intersect your mesh mesh:
import vedo
def cap(mesh, value_z):
msh = mesh.boundaries().join().extrude(zshift=value_z).lw(0)
msh.cut_with_plane(origin=(0, 0, value_z), normal=(0, 0, 1))
return msh
name_mesh = "data/example_lower.stl"
mesh = vedo.Mesh(name_mesh)
value_z: int = -20
closed_mesh = cap(mesh, value_z)
vedo.show(mesh, closed_mesh).close()
(note how the purple on the bottom right hits the yellow mesh)
I'm afraid you will need an extra step of cleaning up the mesh before proceeding to close it.
Or you can try with pymeshfix
but it takes a LONG time to process it (1 min):
pip install pymeshfix
then
import vedo # 2024.5.2
import time
import pymeshfix
def close_with_cover_reply(mesh, value_z):
extrude_mesh = mesh.extrude(zshift=value_z, cap=False, res=10)
cut_mesh = extrude_mesh.cut_with_plane(origin=(0, 0, value_z), normal=(0, 0, 1))
extrude_cut_mesh = vedo.merge(mesh, cut_mesh)
extrude_cut_mesh.clean()
cover_mesh = extrude_cut_mesh.copy()
cover_mesh.vertices[:, 2:] = value_z
closed_mesh = vedo.merge(extrude_cut_mesh, cover_mesh)
closed_mesh.clean()
meshfix = pymeshfix.MeshFix(closed_mesh.vertices, closed_mesh.cells)
meshfix.repair()
return vedo.Mesh(meshfix.mesh)
name_mesh = "data/example_lower.stl"
mesh = vedo.Mesh(name_mesh)
value_z: int = -20
st_time = time.time()
closed_mesh = close_with_cover_reply(mesh, value_z)
print(time.time() - st_time, closed_mesh.is_closed(), closed_mesh.is_manifold())
vedo.show(closed_mesh, axes=1)
Thank you very much for your answers. Unfortunately I can't use pymeshfix because it takes too long. I need to solve the problem in a very small amount of time.
Indeed the type of meshes present many difficulties. I have thought of an alternative that could be the one that was done here https://github.com/marcomusy/vedo/issues/1019#issuecomment-1921652457
But my idea would be to make smooth to the edge or to take a subsampling of the edge to lose a little its morphology. The problem would be that with the subsampling I would not be able to use the to_strips function because the number of lines is different. Perhaps in this way I could clean the edge that apparently is the biggest impediment. Would it be an option?
Sorry I overlooked your question..
SInce the main issue seems to be the self-intersecting vertices in the extrusion, you may try to detect them before extrusion with intersect_with_line()
described here
If positive you can delete the face .delete_cells()
and then call .clean()
to remove the point too.
I am working with a kind of mesh that is a bit complicated. At the edges they might have intersections. Therefore, when it comes to extruding and putting a cover, I have problems. For example, I can't generate the cover with "Delaney". Or if I paste a slice the mesh is not closed (I use the is_closed method and it returns False).
example_lower.stl.zip
I have extruded the mesh and then cut the extrusion to have a plane surface.
My problem comes to generate the cover. Option 1. Function "close_with_cover_reply". I have tried to replicate the mesh at the desired Z coordinate. This way I get a closed mesh, but at the cost of obtaining a mesh with twice the number of points, which is not very elegant.
Option 2. Function "close_with_delaney". I tried to get the boundary of the extracted mesh. Then I generate the cover with Delaney, but, apart from the fact that it generates triangles where it does not correspond, the mesh would not be closed.
I wouldn't mind modifying the morphology of the edge, so I could make a smooth of the edge and join it as it is done in @https://github.com/marcomusy/vedo/issues/1019 and then extrude to simplify it, but it is not enough.
I have used the "cap" parameter of the extrude function but it generates a copy of the mesh points, which I am trying to avoid.
My goal would be to have something similar to this and also, the is_closed function would return True:
Thanks for the help and congratulations for the work, I love vedo.