Skip to content
Shapemetry

@huukhanhnguyen/model / nodeMethods/utils

nodeMethods/utils

clusterFaces()

clusterFaces(faces, tolerance?): BrepData[][]

Union-find over brep data documents that share a boundary vertex (within tolerance, world units/mm) — derives the connected partition of a flat BrepData[]; the partition is never stored. Used by packages/collision (a part-boundary tolerance, deliberately coarser than nodeMethods/solid/mesh.ts's internal connectedFaceGroups, which uses a much tighter 1e-6 mesh-weld tolerance for a different purpose).

Parameters

faces

BrepData[]

tolerance?

number = 1e-3

Returns

BrepData[][]


computedCount()

computedCount(value, minimum, op, name?): number

A count the author normally COMPUTES (divide(curve, length / spacing), a sweep's step count) rather than writes as a literal.

The registry declares these args as number, so a fraction is permitted by the contract and flooring it is the operation's own definition — asking for 7.3 segments means 7 whole segments, and no tolerance is broken. That is what separates this from wholeCount, where flooring or clamping would substitute a DIFFERENT model than the one authored (polygon(sides: 2) is not a triangle, arrayLinear(copies: 2.7) is not 2 copies).

What it still refuses is a value that cannot mean a count at all: NaN (a failed expression), infinite, or below the minimum the maths needs.

Parameters

value

number

minimum

number

op

string

name?

string = "count"

Returns

number


dataId()

dataId(): string

Returns

string


facesToIndices()

facesToIndices(faces): number[]

Flatten polygon faces to a TRIANGLE index buffer. Tessellated output is always 3-gons; an n-gon fans from its first vertex.

Parameters

faces

number[][]

Returns

number[]


flattenPoints()

flattenPoints(points): Float64Array

Door codec: a point list as the flat [x, y, z, ...] buffer every geometry wasm door takes. A 2-long point reads z as 0 — the 2D-input case curve.ts feeds; a Point always has its third slot.

Parameters

points

readonly readonly number[][]

Returns

Float64Array


meshPointAt()

meshPointAt(positions, index): Point

Door codec: one corner of a flat triangulation (types' TriangleMesh) as a Point. The nested point spelling exists only at doors that speak points (faceGeometryFromLoops, pin predicates) — never as a sibling mesh type.

Parameters

positions

readonly number[]

index

number

Returns

Point


newellSum()

newellSum(loop): Vector

Parameters

loop

Point[]

Returns

Vector


pointInPolygon2d()

pointInPolygon2d(p, polygon): boolean

Ray-cast point-in-polygon (even-odd rule) in 2D.

Parameters

p

[number, number]

polygon

[number, number][]

Returns

boolean


projectToPlane2d()

projectToPlane2d(p, origin, u, v): [number, number]

Project a 3D world point onto a 2D plane basis (orthonormal u/v axes through origin) — a dot-product projection, not a matrix solve.

Parameters

p

Point

origin

Point

u

Vector

v

Vector

Returns

[number, number]


signedDistanceToPlane()

signedDistanceToPlane(point, planePoint, normal): number

Signed distance from point to the plane through planePoint with unit normal — positive on the +normal side, negative on the -normal side.

Parameters

point

Point

planePoint

Point

normal

Vector

Returns

number


weldKey()

weldKey(point, scale?): string

Quantize a point into a stable string key for vertex-welding (Map/Set dedup by position) — two points within 1/scale of each other collide to the SAME key. Default 1e6 = 1e-6 world-unit tolerance; pass a different scale for a looser/tighter weld.

Parameters

point

readonly number[]

scale?

number = 1e6

Returns

string


wholeCount()

wholeCount(value, minimum, op, name?): number

A whole-number argument (a copy count, a side count, a division count) that drives a loop — checked instead of clamped.

Measured 2026-08-15: the ops taking one either did not check at all (arrayLinear) or clamped with Math.max(minimum, Math.round(value)) (polygon, divide, pointsInLoops). Both shapes turn a bad argument into a believable answer:

  • Math.max(3, Math.round(NaN)) is NaN, not 3 — the clamp does not clamp, the loop below it never runs, and the op returns an empty or unchanged result. NaN is the value an argument takes when its expression fails to evaluate, so this is a case real documents reach.
  • a clamp that DOES fire silently substitutes a different model than the one authored: polygon(sides: 2) drew a triangle, divide(count: 0) returned two points.

minimum states what the maths needs (a polygon needs 3 sides, a division needs 1 segment). It is a rejection threshold, never a substitution.

Parameters

value

number

minimum

number

op

string

name?

string = "count"

Returns

number

Last updated: 📖 4 min readEdit on GitHub