Modules | TS

Intersect

Exact mesh intersections, self-intersections, and scalar field isocontours.

The Intersect module computes geometric intersections between meshes and scalar fields. All intersection computations are geometrically and topologically exact, using exact arithmetic.

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

Overview

The Intersect module computes intersection geometry without modifying the input meshes:

  • Mesh-mesh intersections: Curves where two or more meshes intersect
  • Self-intersections: Curves where a mesh intersects itself
  • Scalar field intersections: Contour curves at threshold values

Curves are returned as Curves objects with paths (an OffsetBlockedBuffer of index sequences) and points (an NDArrayFloat32 of coordinates).

To embed intersection curves into mesh topology (splitting faces along curves), use the Cut module.

Supported Input

Intersection computation supports a wide range of input geometry:

  • Open and closed meshes — boundaries are handled correctly
  • Non-manifold edges — edges shared by 3 or more faces
  • Coplanar faces — overlapping faces from the same or different meshes
  • Self-intersecting geometry — meshes that intersect themselves are detected and curves are extracted
  • Crossing intersection curves — where curves from different mesh pairs meet on a face, crossings can be resolved. Controlled via the IntersectOpts interface — see Intersection Modes.
For detecting where a single mesh intersects itself, use tf.selfIntersectionCurves.

Intersection Modes

The IntersectOpts interface controls intersection computation:

interface IntersectOpts {
  mode?: "sos" | "primitives";
  resolveCrossings?: boolean;
  resolveSelfCrossings?: boolean;
}
FieldDescription
mode"sos" (Simulation of Simplicity — fast, no degenerate cases) or "primitives" (handles shared edges/vertices/coplanar faces).
resolveCrossingsResolve crossings between different contours on the same face.
resolveSelfCrossingsResolve self-crossings within a single contour.

Each function sets appropriate defaults — see individual function documentation below and in Cut.

Intersection Curves

Between Two Meshes

const curves = tf.intersectionCurves(mesh0, mesh1);
const curves = tf.intersectionCurves(mesh0, mesh1, { mode: "primitives" });

Default: mode: "sos", resolveCrossings: false, resolveSelfCrossings: false. With two meshes only one contour exists, so crossing resolution flags have no effect.

N-Mesh Intersection Curves

Compute all pairwise intersection curves from an array of meshes:

const curves = tf.intersectionCurves([mesh0, mesh1, mesh2]);
const curves = tf.intersectionCurves([mesh0, mesh1, mesh2], {
  mode: "primitives", resolveCrossings: true,
});

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

Self-Intersection Curves

Find where a mesh intersects itself:

const curves = tf.selfIntersectionCurves(mesh);
const curves = tf.selfIntersectionCurves(mesh, { mode: "primitives" });

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

To embed self-intersection curves into mesh topology, use tf.embeddedSelfIntersectionCurves from the Cut module.

With Transformations

mesh1.transformation = tf.translation([5, 0, 0]);
const curves = tf.intersectionCurves(mesh0, mesh1);

Using Curves

for (let i = 0; i < curves.length; i++) {
  const pathIds = curves.paths.at(i);
  // Access points: curves.points
}

Isocontours

Extract isocontour curves from scalar fields on meshes.

To cut meshes into regions using isocontours, use tf.isobands from the Cut module.

Single Isocontour

const scalars = tf.distance(tf.point(mesh.points), plane);
const curves = tf.isocontours(mesh, scalars, 0.0);

Multiple Isocontours

const thresholds = new Float32Array([0.0, 0.5, 1.0]);
const curves = tf.isocontours(mesh, scalars, thresholds);

Async

All intersect functions are available as async variants via tf.async for off-main-thread execution:

const curves = await tf.async.intersectionCurves(mesh0, mesh1);
const self   = await tf.async.selfIntersectionCurves(mesh);
const iso    = await tf.async.isocontours(mesh, scalars, 0.0);
For implementation details, exact arithmetic, and low-level intersection access, see the C++ Intersect documentation.