Remesh
The Remesh module provides tools for modifying triangle mesh resolution: reducing face count through decimation, or redistributing vertices through isotropic remeshing.
tf.triangulate from the Geometry module to convert polygon meshes first.parallel: false for sequential execution (e.g. when processing many meshes in parallel externally).Meshtransformation. When a Mesh has a transformation, lengths are measured in the transformed coordinate space. This allows remeshing a scaled or rotated mesh without modifying vertex data.Decimation
Reduce face count using quadric error metrics. The algorithm collapses edges in priority order, placing the new vertex at the position that minimizes geometric error.
Basic Usage
import * as tf from "@polydera/trueform";
const mesh = tf.readStl("model.stl");
// Decimate to 10% of original faces
const decimated = tf.decimated(mesh, 0.1);
With Configuration
const decimated = tf.decimated(mesh, 0.1, {
preserveBoundary: true,
maxAspectRatio: 20.0,
parallel: false,
});
| Parameter | Type | Default | Description |
|---|---|---|---|
m | Mesh | Triangle mesh | |
targetProportion | number | Target face count as fraction of original (0.0–1.0) | |
opts.maxAspectRatio | number | 40 | Maximum triangle aspect ratio after collapse. Negative to disable |
opts.preserveBoundary | boolean | false | If true, boundary edges are never collapsed |
opts.stabilizer | number | 1e-3 | Tikhonov stabilizer for quadric solve |
opts.parallel | boolean | true | Use parallel partitioned collapse |
opts.featureAngle | number | -1 | Feature edge detection angle in degrees. Edges sharper than this are preserved. Negative disables |
opts.featureWeight | number | 100 | Penalty weight for feature edge preservation. Higher = stronger |
Feature Edge Preservation
Preserve sharp creases and corners during decimation:
const decimated = tf.decimated(mesh, 0.1, { featureAngle: 30 });
Returns a new Mesh.
Isotropic Remeshing
Redistribute vertices to achieve uniform edge lengths. Each iteration splits long edges, collapses short edges, flips edges to improve valence, and relaxes vertex positions tangentially.
Basic Usage
import * as tf from "@polydera/trueform";
const mesh = tf.readStl("model.stl");
// Remesh to target edge length
const mel = tf.meanEdgeLength(mesh);
const remeshed = tf.isotropicRemeshed(mesh, 2.0 * mel);
With Configuration
const remeshed = tf.isotropicRemeshed(mesh, 0.02, {
iterations: 5,
relaxationIters: 5,
preserveBoundary: true,
useQuadric: true,
});
| Parameter | Type | Default | Description |
|---|---|---|---|
m | Mesh | Triangle mesh | |
targetLength | number | Target edge length. Longer edges are split, shorter are collapsed | |
opts.iterations | number | 3 | Number of outer iterations (split + collapse + flip + relax) |
opts.relaxationIters | number | 3 | Tangential relaxation iterations per outer iteration |
opts.maxAspectRatio | number | -1 | Maximum aspect ratio after collapse. Negative to disable |
opts.lambda | number | 0.5 | Damping factor for tangential relaxation in (0, 1] |
opts.preserveBoundary | boolean | false | If true, boundary edges are never split or collapsed |
opts.useQuadric | boolean | false | Use quadric error metric for collapse vertex placement |
opts.parallel | boolean | true | Use parallel execution |
opts.featureAngle | number | -1 | Feature edge detection angle in degrees. Edges sharper than this are preserved. Negative disables |
opts.featureWeight | number | 100 | Penalty weight for feature edge preservation. Higher = stronger |
Returns a new Mesh.
Typical Pipeline
A common workflow is to decimate first, then isotropic remesh to improve triangle quality:
import * as tf from "@polydera/trueform";
const mesh = tf.readStl("model.stl");
// Decimate to 5%
const dec = tf.decimated(mesh, 0.05);
// Isotropic remesh to mean edge length of decimated result
const mel = tf.meanEdgeLength(dec);
const result = tf.isotropicRemeshed(dec, mel, { useQuadric: true });
tf.meanEdgeLength to compute a natural target length from the current mesh. This is often the right default for isotropic remeshing after decimation.Async
All remesh functions are available as async variants via tf.async for off-main-thread execution:
const dec = await tf.async.decimated(mesh, 0.1);
const rem = await tf.async.isotropicRemeshed(mesh, 0.02);
