Boolean operations are defined on geometry (e.g., via winding numbers).
Voxel/grids approaches embrace that but typically lose the link to original faces.
Even classical mesh Booleans face the hard question: how do we transfer materials, UVs, normals, colors, or other attributes through cuts and re-meshing?
Solidean’s answer is Tracking IDs: a minimal, exact, high-performance mechanism that gives every output face a provenance back to the inputs.
The Idea
- Each input face can carry a 64-bit Tracking ID (with a reserved bit pattern for “untracked”).
- During Booleans, an input face may be split into many output faces (possibly across multiple operations).
- Every output face corresponds to a geometric subset of exactly one input face. The geometry establishes the subset, the Tracking ID preserves the link.
This avoids baking attribute logic into the kernel, keeps the engine fast, and lets you define how attributes travel.
Enabling Tracking
-
Per-surface, assign IDs via:
-
Export IDs alongside geometry via:
-
Read IDs from the blob using
DataSlot::PrimitiveIDs.
ID structure (conceptual):
flags (2 bits) | surface_id (30 bits) | primitive_id (32 bits)- Flags include:
- is-inverted: winding flipped relative to the source primitive
- is-subset: face is a proper subset (e.g., a cut piece)
Why this beats “transport during the op”
- Performance: no attribute payload is carried inside the kernel; only small IDs.
- Simplicity: no registration of attribute schemas or user callbacks.
- Composability: works across any number of operations (iterated Booleans, mixed pipelines).
- Flexibility: you decide how to map provenance to attributes in user code.
Practical Transfer Strategies
Per-Face Attributes (materials, face colors, metadata)
- Export triangles (unrolled or indexed) with IDs.
- For each output face:
- Read its
id.surface_id()to identify the source mesh/surface. - Read
id.primitive_id()to index the source face. - Copy the face attribute (e.g., material index, RGB, tag).
- Read its
See the guide: Transporting per-face attributes.
Per-Vertex / Per-Edge / UV / Normals
Unify these as per-halfedge (a.k.a. per-(vertex, face)) attributes:
- For each vertex of each output face, compute its barycentric coordinates in the source triangle (since the output face is a subset, this mapping is well-defined).
- Interpolate the attribute from source triangle vertices/halfedges (UVs, colors, smooth normals).
This policy is simple, fast, and robust.
Variants and Control
- Choose an ID layout that suits your pipeline:
- Assign distinct
surface_ids per input asset (e.g., 0 for “workpiece”, 1..N for tools). - Use
TrackIDRaworTrackPrimitiveIDsto align with existing asset indices.
- Assign distinct
- With indexed exports, you can also export topology (e.g., halfedges) if your attribute policies operate on mesh adjacency.
What about multiple Booleans?
No problem.
Tracking lives on faces, and faces always come from some input face, possibly after several splits.
Your transfer logic remains identical, regardless of how many steps produced the result.
Summary
- Tracking IDs provide provable provenance for every output face.
- They keep the kernel lean and maximize performance.
- They enable attribute transport after the fact, on your terms.
- They scale from simple per-face copies to robust, barycentric per-vertex/halfedge interpolation.
Use them whenever your pipeline needs materials, UVs, normals, or any custom attribute to survive exact Booleans.