Modules | TS

Cut

Exact mesh arrangements, booleans, and curve embedding.

The Cut module splits meshes along intersection curves, performs boolean operations, and classifies regions. It builds on the Intersect module for computing intersections. All operations are geometrically and topologically exact.

import * as tf from "@polydera/trueform";

Overview

The Cut module provides operations at several levels:

  • Embedded intersection curves: Split a mesh along intersection curves without classifying regions
  • Mesh arrangements: Decompose two or more meshes into classified regions — the complete intersection problem
  • Boolean operations: Select regions from arrangements to produce union, intersection, or difference
  • Polygon arrangements: Decompose a mesh at its self-intersection curves
  • Isocurve embedding: Split meshes along scalar field level sets

All cut operations return faceLabels — an array mapping each output face back to the index of the original face it came from in the source mesh. This enables attribute transfer and provenance tracking. Multi-mesh operations (arrangements and booleans) additionally return labels (or tagLabels) — which input mesh each face belongs to.

All cut operations support an optional { returnCurves: true } option that additionally returns the intersection curves.

Supported Input

Embedding and arrangement operations inherit the same robustness as the Intersect module:

  • Open and closed meshes — boundaries are handled correctly
  • Non-manifold edges — edges shared by 3 or more faces
  • Coplanar faces — overlapping faces are classified
  • Self-intersecting geometry — detected and resolved
  • Crossing intersection curves — where curves from different mesh pairs meet on a face, crossings can be resolved. Controlled via IntersectOpts — see Intersection Modes.

Boolean operations additionally require that intersection curves split the meshes into separate inside/outside regions. Input meshes should be PWN (piecewise winding number) — locally consistent orientation.

To detect where a single mesh's own polygons intersect each other, use tf.embeddedSelfIntersectionCurves or tf.polygonArrangements.

Embedded Intersection Curves

Embed intersection curves between mesh A and mesh B into mesh A:

const { mesh, faceLabels } = tf.embeddedIntersectionCurves(mesh0, mesh1);

// With curves
const { mesh, faceLabels, curves } = tf.embeddedIntersectionCurves(mesh0, mesh1, {
  returnCurves: true,
});

// With explicit mode
const { mesh, faceLabels } = tf.embeddedIntersectionCurves(mesh0, mesh1, {
  mode: "primitives", resolveSelfCrossings: true,
});

Default: mode: "primitives", resolveCrossings: false, resolveSelfCrossings: false.

Self-Intersection

Embed curves where a mesh intersects itself:

const { mesh, faceLabels } = tf.embeddedSelfIntersectionCurves(mesh);

// With curves
const { mesh, faceLabels, curves } = tf.embeddedSelfIntersectionCurves(mesh, {
  returnCurves: true,
});

Default: mode: "primitives", resolveCrossings: true, resolveSelfCrossings: true.

Mesh Arrangements

Decompose intersecting meshes into classified regions:

const { mesh, tagLabels, faceLabels } = tf.meshArrangements([mesh0, mesh1]);

// With curves
const { mesh, tagLabels, faceLabels, curves } = tf.meshArrangements(
  [mesh0, mesh1], { returnCurves: true });

// With explicit mode
const { mesh, tagLabels, faceLabels } = tf.meshArrangements(
  [mesh0, mesh1, mesh2], { mode: "primitives", resolveCrossings: true });

Returns:

  • tagLabels: Which input mesh each face came from (0 or 1)
  • faceLabels: Index of the original face each output face came from

Default: mode: "primitives", resolveCrossings auto (true for 3+ meshes, false for 2), resolveSelfCrossings: false.

Polygon Arrangements

Decompose a single mesh at its self-intersection curves:

const { mesh, faceLabels } = tf.polygonArrangements(mesh);

// With curves
const { mesh, faceLabels, curves } = tf.polygonArrangements(mesh, {
  returnCurves: true,
});

Default: mode: "primitives", resolveCrossings: true, resolveSelfCrossings: true.

Boolean Operations

Boolean operations combine two meshes using set operations:

const { mesh, labels, faceLabels } = tf.booleanUnion(mesh0, mesh1);
const { mesh, labels, faceLabels } = tf.booleanIntersection(mesh0, mesh1);
const { mesh, labels, faceLabels } = tf.booleanDifference(mesh0, mesh1);

Booleans use primitives mode internally with no contour crossing resolution — with two meshes only one contour exists, so crossings cannot occur.

With curves:

const { mesh, labels, faceLabels, curves } = tf.booleanUnion(mesh0, mesh1, {
  returnCurves: true,
});

With transformations:

mesh1.transformation = tf.translation([5, 0, 0]);
const { mesh, labels, faceLabels } = tf.booleanUnion(mesh0, mesh1);

Isobands

Extract regions between consecutive threshold values from scalar fields:

const cutValues = new Float32Array([-1.0, 0.0, 1.0]);
const { mesh, labels, faceLabels } = tf.isobands(mesh, scalars, cutValues);

// Select specific bands
const { mesh, labels, faceLabels } = tf.isobands(mesh, scalars, cutValues, {
  selectedBands: [1, 3],
});

// With curves
const { mesh, labels, faceLabels, curves } = tf.isobands(mesh, scalars, cutValues, {
  returnCurves: true,
});

Async

All cut functions are available as async variants via tf.async, with the same overloads:

const { mesh, labels, faceLabels } = await tf.async.booleanUnion(mesh0, mesh1);
const { mesh, labels, faceLabels, curves } = await tf.async.booleanUnion(mesh0, mesh1, {
  returnCurves: true,
});
const { mesh, faceLabels } = await tf.async.polygonArrangements(mesh);
const { mesh, faceLabels } = await tf.async.embeddedSelfIntersectionCurves(mesh);
For implementation details, see the C++ Cut documentation.