@huukhanhnguyen/model / nodeMethods/brepFace
nodeMethods/brepFace
MultiFaceAccessorError
Named error when a one-face accessor is used on a multi-face wrap.
Extends
Error
Constructors
Constructor
new MultiFaceAccessorError(
accessor,faceCount):MultiFaceAccessorError
Parameters
accessor
string
faceCount
number
Returns
Overrides
Error.constructor
cause?
optionalcause?:unknown
Inherited from
Error.cause
message
message:
string
Inherited from
Error.message
name
name:
string
Inherited from
Error.name
stack?
optionalstack?:string
Inherited from
Error.stack
stackTraceLimit
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from
Error.stackTraceLimit
Methods
captureStackTrace()
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`The first line of the trace will be prefixed with ${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.
The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();Parameters
targetObject
object
constructorOpt?
Function
Returns
void
Inherited from
Error.captureStackTrace
prepareStackTrace()
staticprepareStackTrace(err,stackTraces):any
Parameters
err
Error
stackTraces
CallSite[]
Returns
any
See
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from
Error.prepareStackTrace
DEFAULT_CURVE_TOLERANCE
constDEFAULT_CURVE_TOLERANCE:0.5=0.5
Chord-deviation tolerance (mm) for turning a curved boundary into a polyline. Owned here because this is the lowest module that needs it; render.ts re-exports it so existing importers are unaffected (there is no region.ts — that half of the old note named a file that does not exist).
UNJUSTIFIED: 0.5 mm carries no derivation and no measurement in this repo. It is a display default, so a caller can always pass tighter; but it has not been measured against a deviation target and should be.
classifyShellsToBodies()
classifyShellsToBodies(
shells):BrepData[]
Same as classifyShellsToBodyDocuments, then one scene body per classified solid (tables may span outer + voids).
Parameters
shells
BrepData[]
Returns
BrepData[]
classifyShellsToBodyDocuments()
classifyShellsToBodyDocuments(
shells):string[]
Classify one-shell documents into bodies by containment and orientation. Returns kernel solid-root document STRINGS (multi-shell when a body has voids). brep_classify_shells — N one-shell docs in, solid-root docs out.
Parameters
shells
BrepData[]
Returns
string[]
dataLoops()
dataLoops(
face,tolerance?):Point[][]
faceLoops for a face ENTITY — one-face only (throws on multi-face).
Parameters
face
tolerance?
number = DEFAULT_CURVE_TOLERANCE
Returns
Point[][]
eachFaceLoops()
eachFaceLoops(
geometry,tolerance?):Point[][][]
Per-face loop lists for the body (length = faceCountOf).
Parameters
geometry
tolerance?
number = DEFAULT_CURVE_TOLERANCE
Returns
Point[][][]
emptyFaceGeometry()
emptyFaceGeometry(
_uvMatrix?):BrepData
The EMPTY face — a shell with no faces. The 2D ops use it as their "no result" value (it was {loops: []} before the brep cutover): it carries no loops, so every consumer that iterates the boundary sees nothing.
Parameters
_uvMatrix?
Returns
explodeBodyToFaceData()
explodeBodyToFaceData(
geometry):BrepData[]
THE LOSSLESS EXPLODE: every face of this body as its own one-face document, including cavity faces derived via voidShellDocumentsOf.
Parameters
geometry
Returns
BrepData[]
explodeFaceRows()
explodeFaceRows(
geometry):BrepData[]
Every face of a document as its own one-face document, remapped to be self-contained.
Distinct from explodeToFaceData, which asks the KERNEL and therefore refuses a document holding more than one shell ("Shell.fromJSON expects one shell") — a chain document routinely holds several disconnected shells. This one is pure table surgery through the geometry package's own extractShellTables: no sew, no handle, and edge curves / face surfaces / attributes ride along untouched (a loop-rebuild would flatten a curved face).
Parameters
geometry
Returns
BrepData[]
explodeToFaceData()
explodeToFaceData(
geometry):BrepData[]
THE EXPLODE: every face of a wrap's OUTER shell as its own one-face-shell document, read straight out of the kernel. brep_shell_face_document hands one face back as its own B-Rep document — the face, its outer loop and holes, and only the edges and vertices those loops reference — which is exactly what one face's own wrap document. The shell is opened once for the whole walk and the handle is freed in a finally, so no TypeScript object graph is built and nothing survives the call.
Empty when the wrap carries no faces. VOIDS ARE NOT INCLUDED — this walks the outer shell Shell.* sees. A body's cavities ride on explodeBodyToFaceData.
Parameters
geometry
Returns
BrepData[]
faceBoundaryPoints()
faceBoundaryPoints(
geometry,tolerance?):Point[]
All boundary points of every face of the body (bounds / inspect).
Parameters
geometry
tolerance?
number = DEFAULT_CURVE_TOLERANCE
Returns
Point[]
faceCountOf()
faceCountOf(
geometry):number
Face count of this body (faces.length — may span several shells).
Parameters
geometry
Returns
number
faceDataFromLoops()
faceDataFromLoops(
loops,uvMatrix?):BrepData|null
faceFromLoops as a one-face BrepData document.
Parameters
loops
Point[][]
uvMatrix?
Returns
BrepData | null
faceFromLoops()
faceFromLoops(
loops,uvMatrix?):BrepData|null
Flat polygon loops (outer first, then holes) → a one-face-shell Shell. The supporting plane is fitted from the outer loop by Newell's method inside Face.fromLoop, so the carrier comes back tagged form: plane and every downstream brep op takes its analytic path.
Returns null when the outer loop has fewer than 3 distinct points — callers skip such degenerate input rather than emitting a broken face.
Parameters
loops
Point[][]
uvMatrix?
Returns
BrepData | null
faceGeometryFromLoops()
faceGeometryFromLoops(
loops,uvMatrix?):BrepData
faceFromLoops that always yields a geometry, degenerate input becoming the EMPTY face. For producers whose old { loops } literal could not fail: a loop with fewer than 3 distinct points used to make an unrenderable face, and now makes an unrenderable empty one.
Parameters
loops
Point[][]
uvMatrix?
Returns
faceLoops()
faceLoops(
geometry,tolerance?):Point[][]
ONE-FACE boundary loops — outer first, then holes. The inverse of faceFromLoops for a planar face built from polygons.
Throws MultiFaceAccessorError when the wrap has more than one face (silent flatten would mis-read holes / per-face topology). Use faceLoopsAt or eachFaceLoops for multi-face wraps.
Parameters
geometry
tolerance?
number = DEFAULT_CURVE_TOLERANCE
Returns
Point[][]
faceLoopsAt()
faceLoopsAt(
geometry,faceIndex,tolerance?):Point[][]
Boundary loops of one face inside a wrap (outer-shell index). Empty when the index is out of range.
Parameters
geometry
faceIndex
number
tolerance?
number = DEFAULT_CURVE_TOLERANCE
Returns
Point[][]
facesToSolid()
facesToSolid(
faces):BrepData|null
Scene faces → ONE solid DOCUMENT (TOLERANCE SEW). Survives ONLY for migration and explicit import doors — not hot eval/boolean paths. Prefer solidDocumentOf on an already-wrapped document, and measureFaceSet when the sew was only ever wanted for a measurement.
When faces is a single wrap that already closes, it is handed straight back through the loader (no sew, cavities kept). Multi-document bags sew every wrap's outer shell into one kernel shell and load that.
Returns null when the faces do not close a volume — brep_load refuses an open sheet, which is the same answer.
Parameters
faces
BrepData[]
Returns
BrepData | null
isCavityShell()
isCavityShell(
geometry):boolean
True when this shell bounds a CAVITY rather than material — the question a connected-component split has to ask before it treats each component as a body, because a hollow solid's cavity is a component too.
The test is the WINDING, not containment: a cavity's faces wind inward and its signed volume is negative, a material lump's wind outward. That is the same fact derive_shell_roles (crates/geometry/src/brep/topo/serialize.rs) sorts a document's shells by, and it is the ONLY thing that tells a cavity apart from a SECOND LUMP — voidShellDocuments cannot, because the kernel parks both in the void slot ("N disjoint lumps are one valid body", same file).
An OPEN shell (a roof plane) bounds no volume at all and is never one. Asking isClosedWrap first is also what keeps signedVolume on a document the solid door has already accepted, so a throw from it is a real kernel failure rather than a swallowed open sheet.
Parameters
geometry
Returns
boolean
isClosedFaceSet()
isClosedFaceSet(
faces):boolean
True when a face set closes a VOLUME — asked of the kernel: one wrap is its own answer (brep_load refuses an open sheet), a multi-document bag is tolerance-sewn first and the sewn shell reports its own watertightness. EMPTY set is not a solid.
Parameters
faces
BrepData[]
Returns
boolean
isClosedSolid()
isClosedSolid(
data):boolean
True when one wrap is a closed solid (solid root or closed shell).
Parameters
data
Returns
boolean
isClosedWrap()
isClosedWrap(
geometry):boolean
True when ONE wrap closes a volume — a solid root, or a shell that closes.
Parameters
geometry
Returns
boolean
isShellBrep()
isShellBrep(
doc):boolean
True when a value is scene tables or a one-shell kernel document.
Parameters
doc
unknown
Returns
boolean
isSolidBrep()
isSolidBrep(
doc):boolean
Does this KERNEL document carry more than one shell? Scene BrepData tables store no partition — use voidShellDocumentsOf / BrepData.classifyShells when the body may have cavities.
Parameters
doc
unknown
Returns
boolean
matrixToFrame()
matrixToFrame(
matrix):Frame
Row-major 4×4 plane→world matrix → its frame. Columns are u, v, normal, origin.
Parameters
matrix
Returns
measureFaceSet()
measureFaceSet(
faces):SolidMeasurements|null
Kernel measurements for a face SET: one wrap is measured as itself. Several closed shells recombine via classifyShells (outer + voids = one body). Mixed/open bags fall back to tolerance sew. Null when no volume.
Parameters
faces
BrepData[]
Returns
SolidMeasurements | null
measureWrap()
measureWrap(
geometry):SolidMeasurements|null
Kernel measurements for ONE wrap, or null when it bounds no volume.
Parameters
geometry
Returns
SolidMeasurements | null
mergeBrepData()
mergeBrepData(
documents):BrepData
Concatenate brep documents into ONE body (ARCHITECTURE.md's Objects section, BrepObject). Face ORDER is source order so face-indexed attributes stay parallel, exactly as mergeMeshData keeps them for a mesh buffer.
Tables concatenate; every index is offset by the running table length — BrepEdge.start/end by the vertex count, BrepLoop.orientedEdges[].edge and a face's uvCurves[].edge by the edge count, BrepFace.outerLoop / innerLoops by the loop count.
The shell partition is NOT stored: it derives by connectivity (BrepData.classifyShells) at the doors that need it.
Single-source fast path: the same document reference, untouched.
Parameters
documents
BrepData[]
Returns
noteKernelHandle()
noteKernelHandle(
delta):void
Handle bookkeeping for the welded-mesh arena in nodeMethods/solid/mesh.ts.
Parameters
delta
-1 | 1
Returns
void
outstandingKernelHandles()
outstandingKernelHandles():
number
Kernel arena handles this package is holding right now. Every acquirer releases in a finally, so this reads 0 between evaluations; the leak gate asserts exactly that.
Returns
number
planeFrameOf()
planeFrameOf(
geometry):Frame|null
The frame DERIVED from the face's own plane form tag, or null when the carrier is not a tagged plane (a curved face has no single frame).
uvMatrix is AUTHORED meta and is never synthesized — this is the fallback consumers use when it is absent, computed on read and never stored, so a face that was never given a uvMatrix keeps behaving exactly as its geometry implies.
Parameters
geometry
Returns
Frame | null
shellDocumentAfter()
shellDocumentAfter(
geometry, ...operations):BrepData|null
The wrap's OUTER SHELL put through operations — an open sheet is a legitimate operand here. Null when the wrap carries no faces.
Parameters
geometry
operations
...HandleOperation[]
Returns
BrepData | null
shellDocumentOf()
shellDocumentOf(
geometry):string|null
Kernel JSON for one-shell BrepData.* doors — the OUTER shell of this body. Multi-shell bodies (cavities) extract the outer via BrepData.outerShellDocument; one-component bodies pass toKernelDocument through.
Parameters
geometry
Returns
string | null
solidDocumentAfter()
solidDocumentAfter(
geometry, ...operations):BrepData|null
The wrap as a kernel SOLID, put through operations, written back out as a document. Null when the wrap bounds no volume. The operand document is never mutated: every op answers a fresh document string.
Parameters
geometry
operations
...HandleOperation[]
Returns
BrepData | null
solidDocumentOf()
solidDocumentOf(
geometry):string|null
Kernel JSON for a solid load — the whole body, partition derived. Multi-document bags must recombine via classifyShellsToBodyDocuments first.
Parameters
geometry
Returns
string | null
voidShellDocumentsOf()
voidShellDocumentsOf(
geometry):BrepData[]
Void (cavity) shells of a body, derived from connectivity. Empty when the body has one shell or the solid door refuses (open sheet).
Parameters
geometry
Returns
BrepData[]
withSewnShell()
withSewnShell<
T>(faces,read):T|null
Sews every wrap's outer shell into ONE kernel shell document and runs read on it. Null when the bag carries no faces.
Type Parameters
T
T
Parameters
faces
BrepData[]
read
(shell) => T
Returns
T | null
wrapDataListOf()
wrapDataListOf(
doc):BrepData[]
Kernel document → one-body array (including cavities).
Parameters
doc
unknown
Returns
BrepData[]
wrapDataOf()
wrapDataOf(
doc,uvMatrix?):BrepData
Kernel or scene document → one BrepData body.
Parameters
doc
unknown