Triangular leaky surfaces from `compas.geometry.boolean_union_mesh_mesh`

I was playing with compas.geometry.boolean_union_mesh_mesh, and found imperfect boolean union outcomes. There are triangular voids in non-intersection parts of the geometry.

Presumably, it is a bug in the intersection calculation code, and we look forward to further improvement. :slight_smile:

Examples:

from compas.geometry import Cylinder, Circle, Plane, boolean_union_mesh_mesh
from compas.datastructures import Mesh
from compas.artists import Artist

# Geometries for boolean
cylinder_mesh = Mesh.from_shape(Cylinder(Circle(Plane([0, 0, 0], [0, 0, 1]), 5), 3))
cylinder_mesh_2 = Mesh.from_shape(Cylinder(Circle(Plane([0, 0, 0], [1, 0, 0]), 7), 9 * 0.1))

# Boolean operations
vertices_and_faces = boolean_union_mesh_mesh(cylinder_mesh.to_vertices_and_faces(), cylinder_mesh_2.to_vertices_and_faces())
mesh = Mesh.from_vertices_and_faces(*vertices_and_faces)

# Update the model using the artist
artist = Artist(mesh)
outTemp = artist.draw()
from compas.geometry import Cylinder, Circle, Plane, Sphere, boolean_union_mesh_mesh
from compas.datastructures import Mesh
from compas.artists import Artist

# Geometries for boolean
cylinder_mesh = Mesh.from_shape(Cylinder(Circle(Plane([0, 0, 0], [0, 0, 1]), 5), 3))
sphere_mesh = Mesh.from_shape(Sphere([0, 0, 0], 3))

# Boolean operations for boolean
vertices_and_faces = boolean_union_mesh_mesh(cylinder_mesh.to_vertices_and_faces(), sphere_mesh.to_vertices_and_faces())
mesh = Mesh.from_vertices_and_faces(*vertices_and_faces)

# Update the model using the artist
artist = Artist(mesh)
outTemp = artist.draw()
from compas.geometry import Sphere, Box, Frame, boolean_union_mesh_mesh
from compas.datastructures import Mesh
from compas.artists import Artist

# Geometries for boolean
box_mesh = Mesh.from_shape(Box(Frame.worldXY(), 10, 3, 3))
sphere_mesh = Mesh.from_shape(Sphere([0, 0, 0], 3))

# Boolean operations for boolean
vertices_and_faces = boolean_union_mesh_mesh(box_mesh.to_vertices_and_faces(), sphere_mesh.to_vertices_and_faces())
mesh = Mesh.from_vertices_and_faces(*vertices_and_faces)

# Update the model using the artist 
artist = Artist(mesh)
outTemp = artist.draw()
from compas.geometry import Box, Frame, boolean_union_mesh_mesh
from compas.datastructures import Mesh
from compas.artists import Artist

# Geometries for boolean
box_mesh = Mesh.from_shape(Box(Frame.worldXY(), 10, 3, 3))
box_mesh_2 = Mesh.from_shape(Box(Frame.worldXY(), 3, 3, 10))

# Boolean operations for boolean
vertices_and_faces = boolean_union_mesh_mesh(box_mesh.to_vertices_and_faces(), box_mesh_2.to_vertices_and_faces())
mesh = Mesh.from_vertices_and_faces(*vertices_and_faces)

# Update the model using the artist
artist = Artist(mesh)
outTemp = artist.draw()

are you running this in Rhino?

Yes! I am using Rhino 7 for that!

not sure about the implementations in Rhino, but the base implementation (using CGAL) requires the meshes to be triangulated to be able to apply boolean operations.

the mesh representations of shapes are not automatically triangulated.

just set triangulated=True in from_shape.

from compas.geometry import Cylinder, Circle, Plane, boolean_union_mesh_mesh
from compas.datastructures import Mesh

from compas_view2.app import App

cylinder_1 = Mesh.from_shape(
    Cylinder(Circle(Plane([0, 0, 0], [0, 0, 1]), 5), 3),
    u=64,
    triangulated=True,
)
cylinder_2 = Mesh.from_shape(
    Cylinder(Circle(Plane([0, 0, 0], [1, 0, 0]), 7), 9 * 0.1),
    u=64,
    triangulated=True,
)

vertices_and_faces = boolean_union_mesh_mesh(
    cylinder_1.to_vertices_and_faces(),
    cylinder_2.to_vertices_and_faces(),
)
mesh = Mesh.from_vertices_and_faces(*vertices_and_faces)

viewer = App()
viewer.add(mesh)
viewer.show()

2 Likes

Thanks a lot for the reply! The problem is now solved by adding triangulated=True in from_shape. :slight_smile: