@layergen/mesh-repair
v0.2.0
Published
Pure-Node mesh-repair primitives extracted from layergen's web-worker. Used by both the browser repair tool and the @layergen/mcp server.
Readme
@layergen/mesh-repair
Pure-Node mesh-repair primitives. Single source of truth for layergen's mesh-fixing logic (BVH-checked 3D ear-clipping, footprint-aware base plates, tri-tri intersection detection, etc.) — imported directly by both:
src/stlOpsWorker.js— the browser repair tool's web worker@layergen/mcp— the Node-side MCP server's repair tools
Anyone fixing a bug or adding a feature here automatically improves both surfaces. No copy-paste, no auto-generation, no drift.
What it does
Operates on raw Float32Array positions and Uint32Array indices (or
non-indexed buffers) — no DOM, no three.js dependency in the core, no
worker globals. Just CPU-bound geometry math that runs identically on
any modern Node or browser environment.
three.js IS used by geometry.js for STL load/save and addBasePlate
(BoxGeometry primitive); those are isolated from raw.js.
Layout
packages/mesh-repair/
├── package.json
├── src/
│ ├── index.js # public API (re-exports)
│ ├── raw.js # the *Raw primitives (typed-array in/out)
│ ├── score.js # analyzeMeshRaw — print-readiness scoring
│ └── geometry.js # STL I/O + addBasePlate (uses three.js)
└── test/
├── smoke.test.mjs # raw functions on a synthetic broken cube
└── geometry.test.mjs # STL round-trip + base-plate clampingPublic API
import {
// Analysis
analyzeMeshRaw, // { score, verdict, issues, fixes, stats }
// High-level pipeline
aggressiveRepairRaw, // merge → remove-shells → fill-holes → remove-non-manifold
// Individual ops
mergeVerticesRaw,
removeFloatingShellsRaw,
fillHolesRaw,
removeNonManifoldRaw,
decimateRaw,
autoOrientRaw,
countBoundariesQuick,
makeNormalsConsistent,
// STL I/O + base plate
loadStlBytes,
exportStlBytes,
computeBoundingBox,
addBasePlate,
} from "@layergen/mesh-repair";All raw operations follow the same shape:
const { positions, indices, meta } = mergeVerticesRaw(
positionsIn, // Float32Array, flat xyzxyz...
indicesIn, // Uint32Array (or null for non-indexed)
precision, // function-specific args
// optional progress callback (defaults to no-op)
// (pct, msg) => console.log(`${pct}%`, msg),
);indices may be null in the output — that means the function de-indexed
the mesh (one tri = 9 floats in positions). Check meta for op-specific
diagnostics like meta.removedTriangles, meta.keptShells, etc.
Editing
Just edit src/raw.js, src/score.js, or src/geometry.js directly.
Both the web worker and the MCP server pick up changes on next bundle /
next install. No more extract-raw.mjs — the dedup landing
(2026-05-01) made the worker import from this package, eliminating the
copy-paste flow.
Testing
cd packages/mesh-repair
npm install # earcut + three (only deps)
npm test11 tests cover STL round-trip, base-plate sub-mm clamping, and every *Raw function on a synthetic cube-with-hole.
