marcomusy / vedo

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

Boolean operations only working with spheres #739

Open mgraugal opened 1 year ago

mgraugal commented 1 year ago

I've successfully run the example boolean.py, whichs mainly consists on the following lines:

s1 = Sphere(pos=[-0.7, 0, 0], c="red5", alpha=0.5)
s2 = Sphere(pos=[0.7, 0, 0], c="green5", alpha=0.5)

plt.at(0).show(s1, s2, __doc__)

b1 = s1.boolean("intersect", s2).c('magenta')
plt.at(1).show(b1, "intersect", resetcam=False)

b2 = s1.boolean("plus", s2).c("blue").wireframe(True)
plt.at(2).show(b2, "plus", resetcam=False)

b3 = s1.boolean("minus", s2).compute_normals().add_scalarbar(c='white')
plt.at(3).show(b3, "minus", resetcam=False)

Obtaining the following result: Screenshot from 2022-11-23 16-46-59

But when switching from Sphere to other types of shapes (I've tried operation between sphere-cylinder, cylinder-cylinder, cyñinder-box, box, box) the result appears to be always empty.

An example box-box

plt = Plotter(shape=(2, 2), interactive=False, axes=3)

s1 = Box(pos=[-0.4, 0, 0], c="red5", alpha=0.5)
s2 = Box(pos=[0.4, 0, 0], c="green5", alpha=0.5)

plt.at(0).show(s1, s2, __doc__)

b1 = s1.boolean("intersect", s2).c('magenta')
plt.at(1).show(b1, "intersect", resetcam=False)

b2 = s1.boolean("plus", s2).c("blue").wireframe(True)
plt.at(2).show(b2, "plus", resetcam=False)

b3 = s1.boolean("minus", s2).compute_normals().add_scalarbar(c='white')
plt.at(3).show(b3, "minus", resetcam=False)

plt.render()
plt.interactive().close()

Screenshot from 2022-11-23 16-48-16

Any clues why this occurs?

Running on an Ubuntu 18.14 with Intel I7 and nvidia RTX 2060

mgraugal commented 1 year ago

Vedo installed with pip install -U git+https://github.com/marcomusy/vedo.git

marcomusy commented 1 year ago

Hi, the boolean operations tend to work only if the original meshes are sufficiently hi-res in terms of triangles and faces. Check out this discussion: https://discourse.vtk.org/t/compute-the-volume-of-the-intersection-between-two-vtkpolydata-objects/8338/4

mgraugal commented 1 year ago

Thank you very much for your answer! I've just added the triangulate method on the box creation and now it works, although the addition is strange: Screenshot from 2022-11-23 17-18-27

mgraugal commented 1 year ago

Thank you very much for your answer! I've just added the triangulate method on the box creation and now it works, although the addition is strange:

Screenshot from 2022-11-23 17-18-27

marcomusy commented 1 year ago

I think that if the faces are exactly in the same plane the algorithm does not work correctly... but it seems to do it right in other cases provided the faces are sufficiently small:

from vedo import Cube, show
c1 = Cube().subdivide(5, method=1).wireframe()
c2 = Cube().subdivide(5, method=1).pos(0.5,0.4,0.3).rotate_x(20).wireframe()
cc = c1.boolean("plus", c2)
show(cc, axes=1)

Screenshot from 2022-11-24 17-39-59