Skip to content

Face Source Tracking

Face Source Tracking

boolean_chain_with_face_source runs a boolean chain and additionally reports, for every output triangle, which input mesh and which original face it came from. The result is (V, F, S) where S[i] = [mesh_id, face_id]:

  • mesh_id — the position of the source mesh in the input list.
  • face_id — the row index of the original face in that mesh.

Tracking uses Manifold's native mesh-relation machinery (OriginalID and the output run / face IDs).

split_by_source turns the tags into one submesh per input, perfect for colouring each contribution differently.

Run it (requires compas_viewer):

python docs/examples/example_boolean_face_source.py
from compas.datastructures import Mesh
from compas.geometry import Box
from compas.geometry import Cylinder
from compas.geometry import Frame
from compas.geometry import Sphere
from compas_viewer import Viewer

from compas_manifold.booleans import boolean_chain_with_face_source
from compas_manifold.booleans import split_by_source

cube = Box(2).to_vertices_and_faces(triangulated=True)
sphere = Sphere(0.8, point=[1, 1, 1]).to_vertices_and_faces(u=32, v=32, triangulated=True)
cyl = Cylinder(0.4, 4.0, Frame([0, 0, 0], [1, 0, 0], [0, 1, 0])).to_vertices_and_faces(u=32, triangulated=True)

V, F, S = boolean_chain_with_face_source([cube, sphere, cyl], ["difference", "difference"])

# Separate the tagged result into one mesh per source input.
parts = split_by_source(V, F, S)

colors = {0: (0.8, 0.3, 0.3), 1: (0.3, 0.7, 0.4), 2: (0.3, 0.4, 0.8)}

# =============================================================================
# Visualize
# =============================================================================

viewer = Viewer()
for mesh_id, (Vp, Fp) in parts.items():
    mesh = Mesh.from_vertices_and_faces(Vp.tolist(), Fp.tolist())
    viewer.scene.add(
        mesh,
        facecolor=colors.get(mesh_id, (0.5, 0.5, 0.5)),
        lineswidth=1,
        show_points=False,
    )
viewer.show()