Skip to content
Shapemetry

@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

MultiFaceAccessorError

Overrides

Error.constructor

cause?

optional cause?: unknown

Inherited from

Error.cause

message

message: string

Inherited from

Error.message

name

name: string

Inherited from

Error.name

stack?

optional stack?: string

Inherited from

Error.stack

stackTraceLimit

static stackTraceLimit: 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()

static captureStackTrace(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()

static prepareStackTrace(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

const DEFAULT_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

BrepData

tolerance?

number = DEFAULT_CURVE_TOLERANCE

Returns

Point[][]


eachFaceLoops()

eachFaceLoops(geometry, tolerance?): Point[][][]

Per-face loop lists for the body (length = faceCountOf).

Parameters

geometry

BrepData

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?

Transformation

Returns

BrepData


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

BrepData

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

BrepData

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

BrepData

Returns

BrepData[]


faceBoundaryPoints()

faceBoundaryPoints(geometry, tolerance?): Point[]

All boundary points of every face of the body (bounds / inspect).

Parameters

geometry

BrepData

tolerance?

number = DEFAULT_CURVE_TOLERANCE

Returns

Point[]


faceCountOf()

faceCountOf(geometry): number

Face count of this body (faces.length — may span several shells).

Parameters

geometry

BrepData

Returns

number


faceDataFromLoops()

faceDataFromLoops(loops, uvMatrix?): BrepData | null

faceFromLoops as a one-face BrepData document.

Parameters

loops

Point[][]

uvMatrix?

Transformation

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?

Transformation

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?

Transformation

Returns

BrepData


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

BrepData

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

BrepData

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

BrepData

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

BrepData

Returns

boolean


isClosedWrap()

isClosedWrap(geometry): boolean

True when ONE wrap closes a volume — a solid root, or a shell that closes.

Parameters

geometry

BrepData

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

Transformation

Returns

Frame


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

BrepData

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

BrepData


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

BrepData

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

BrepData

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

BrepData

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

BrepData

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

BrepData

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

BrepData

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

uvMatrix?

Transformation

Returns

BrepData

Last updated: 📖 13 min readEdit on GitHub