marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
1.98k stars 257 forks source link

Intersection between watertight mesh and plane mesh #1115

Closed omaralvarez closed 1 month ago

omaralvarez commented 1 month ago

I am using cut_with_mesh to obtain the part of a plane mesh that is inside another mesh. What I am using now:

mesh = trimesh2vedo(plane_mesh).cut_with_mesh(trimesh2vedo(mesh))

It looks like this:

Screenshot 2024-05-13 124225

Right now it is crashing silently and I do not know why. I am using the right function to do this?

omaralvarez commented 1 month ago

I have also tested cut_with_box and it does not work either. Could it be due to the mesh not interseting in all sides with the bounding box (mesh just intersects with one side)?

marcomusy commented 1 month ago

It could be! but I cannot tell, you are not giving me enough information.. :) Syntax looks ok though.

omaralvarez commented 1 month ago

Sorry, you are right, I have made a drawing to make it clearer:

Screenshot 2024-05-13 145953

I have the mesh of a plane, and I want to get the area of the part that is inside the box in the drawing (A). plane_mesh is the plane, and mesh is the mesh of the box. I have tested both meshes inside vedo, and the render looks ok. I have also tested cut_with_box with mesh coverted to a vedo Box.

The cut always is empty, not sure why.

I hope that now it is clearer, sorry for the drawing skills.

marcomusy commented 1 month ago

No worries! This seems to work though

from vedo import Cube, Plane, show, settings

settings.use_parallel_projection = True

cube = Cube().rotate_z(10).alpha(0.5)
plane = Plane().scale(0.5).rotate_x(5).shift(dx=0.6)
# cube.subdivide(3, method=1)
# plane.subdivide(3, method=1)

cut_plane = plane.clone().cut_with_mesh(cube).shift(dz=0.01)
cut_plane.c("red5")

show(cube, plane, cut_plane, axes=1)
Screenshot 2024-05-13 at 16 23 32

Note that this doesn´t work if some edges are exactly coincident as then the inside/outside becomes ambiguous.

omaralvarez commented 1 month ago

That may be the problem, the front and back edges are common. The rest should not match. Here is the full code of one of the failing cases:

from vedo import Cube, Mesh, show

box = Box(pos=[0.00073, 0.00279, 0.03353, 0.03529, 0.0, 0.07])

face_mesh = Mesh(
    [[0.00041, 0.035, 0.0],[0.00104, 0.03498, 0.0], [0.00104, 0.03498, 0.07]], 
    [[2, 1, 0]]
)

cut = face_mesh.clone().cut_with_box(box)
cut.c("red5")

show(box, face_mesh, cut)

It's weird because when it is fully inside it works:

screenshot

marcomusy commented 1 month ago

that might be a problem of precision (?)


from vedo import *

box = Box(pos=[0.00073, 0.00279, 0.03353, 0.03529, 0.0, 0.07])

face_mesh = Mesh(
    [[
     [0.00041, 0.035, 0.0],
     [0.00104, 0.03498, 0.0], 
     [0.00104, 0.03498, 0.07]
     ], 
    [[2, 1, 0]]]
)

face_mesh.subdivide(3, method=1)
box.subdivide(3, method=1)
box.alpha(0.5).lighting('off')

cut = face_mesh.clone().cut_with_box(box)
cut.c("red5")

show(box, cut)
omaralvarez commented 1 month ago

You are right. Let me investigate further with your suggested code. Thanks for the help I'll let you know what I find out!

omaralvarez commented 1 month ago

It looks like indeed it was a matter of precision. Subdividing the meshes results look correct. Thank you very much for the help.