Types - Mesh
API reference for ./geometry/mesh on @huukhanhnguyen/types.
See the Guide for the package's role.
API reference
Signatures are generated from the live package .d.ts - not hand-written.
Mesh
type
Opaque n-gon polygon mesh — design topology stored as faces, triangles only at the doors (render tessellation, STL/GLB writers, GLB import). Flat per-VERTEX attribute arrays parallel to positions (NOTE the difference from shell tables: here vertex i's uv is uvs[2i..2i+1], its normal normals[3i..3i+2], its skin influences skin.indices[4i..4i+3]). Sniff: geometry has positions AND faces — unique among stream shapes (shells have loops, curves have vertices+edges without faces). Closed BY TYPE (the boundary law): only the mesh→mesh op family consumes it; boolean/BOM/tableSource/nesting/watertight filter it out by type.
Kept DISTINCT from the tessellation TriangleMesh wire type (see triangleMesh.ts) on purpose: the stream shape carries the skin BINDING object (SkinBinding, like a face) while the tessellation expands it to skinIndices/skinWeights arrays (+ skeleton), and the tessellation adds the groups bake-time field a stream entity never has. Tessellation always carries triangle indices.
type Mesh
// = {
/** Vertex positions, flat [x,y,z] per vertex. */
positions: number[];
/** N-gon faces: each entry is one CCW outer loop of vertex indices into
* `positions`, length ≥ 3. Non-planar faces allowed; no holes (a hole
* would be a second loop — not stored). A triangle is a 3-gon. */
faces: number[][];
/**
* Sparse flagged edges for interaction/crease (GLB import, etc.).
* Runtime builds a full edge table from `faces`; only flagged edges are
* persisted as `[v1, v2, flags]` triples.
*/
edges?: [number, number, number][];
/** Per-vertex [u,v] texture coordinates (glTF TEXCOORD_0). */
uvs?: number[];
/** Second UV set (glTF TEXCOORD_1) — AO/lightmaps. Parallel to `uvs`. */
uvs2?: number[];
/** Per-vertex [x,y,z] normals (smooth shading). Absent = a renderer
* derives them (render() computes area-weighted vertex normals). */
normals?: number[];
/** Per-vertex [r,g,b] or [r,g,b,a] colors (glTF COLOR_0). */
colors?: number[];
/** Skeletal binding of this mesh's vertices — see SkinBinding
* (indices/weights are 4 entries PER VERTEX here). */
skin?: SkinBinding;
/** Morph targets — see MorphTarget (offsets are per-VERTEX position
* deltas here — already the tessellation layout, no remap at render). */
morphs?: MorphTarget[];
/** `Track.key` reference (2026-08-14) — this mesh's OWN weights channel.
* One track covers every entry in `morphs` at once: its
* `values[i].length` must equal `morphs.length`, in the SAME order —
* glTF packs one node's whole `weights` array into a single channel
* (confirmed against the spec: `node.weights` count MUST match the
* referenced mesh's morph target count), so one track already covers
* it — no per-target track to re-merge at export. Consumer-holds-the-
* reference, same as `SkeletonJoint`'s `*Track` fields. Absent = this
* mesh's morph weights never animate (still usable as a static pose
* via each target's own authored weight elsewhere, out of scope here). */
weightsTrack?: string;
}MorphTarget
type
One morph target: per-point POSITION DELTAS, flat [dx,dy,dz] per point across all loops (same parallel-to-loops convention as uvs). Static shape data — never animated itself; Mesh.weightsTrack is what varies over time (the blend weight of every target here, together).
type MorphTarget
// = {
name?: string;
offsets: number[];
}ScatterTriangle
type
One triangle with its measures precomputed — what area-weighted sampling (scatter, point-cloud seeding) walks. Not an entity: a bare geometric sample, which is why it carries area and normal rather than an id.
type ScatterTriangle
// = {
a: Point;
b: Point;
c: Point;
area: number;
normal: Vector;
}SkinBinding
type
Skin binding for a mesh's points (skeletal deformation) — glTF SKIN semantics. skeleton names a skeletons[] lane entry (chain key) in the same model or component scope; indices/weights hold 4 entries PER POINT (flat across all loops, same parallel-to-loops convention as uvs/normals): point i's influences are indices[4i..4i+3] (joint ordinals into the skeleton's flat joint list) with weights[4i..4i+3]. Written by faceSkeleton or imported from GLB — never hand-authored.
type SkinBinding
// = {
skeleton: string;
indices: number[];
weights: number[];
}