Skip to content
Shapemetry

Guide

What it is: the RUNTIME parametric kernel - load ModelJSON, build a node graph, evaluate(), emit scene vocabulary for hosts.

Headless and deterministic. Depends on geometry.

Pipeline

ModelJSON → Model.fromJSON({ registry }) → model.evaluate(params?)
         → EvaluateResult { geometry, materials, params, … }
         → scene ObjectData / Material (host-consumed)

Document shapes

type ModelJSON = {
  title: string
  parameters?: (Operation | Group)[]   // header value bindings
  objects?: SceneNode[]                // ObjectNode | BlockNode; key required
  materials?: Operation[]
  layers?: Operation[]
  styles?: …; textStyles?: …; annotationStyles?: …;
  cameras?: LaneNode[]                 // look-at args → CameraObject[]
  animations?: …; components?: …;
  textures?: …; tables?: …; views?: …; sheets?: …;
}

// No nodeType field - discriminate by method vs operations[]
// Data chains (object bodies, component bodies/openings, sheets) use DataStep;
// config lanes use Operation (animation? only). Group is display grouping.
type DataStep  = { method: string; args?: { key: string; input: string }[]; key?: string; … }
type Operation = { method: string; args?: …; key?: string; animation?: … }
type Group     = { operations: (DataStep | Group)[]; key?: string; instances?: … }

type ObjectNodeBase = { key: string; label?: string; enabled?: string; instances?: NodeInstance[] }
type ObjectNode     = ObjectNodeBase & { operations: (Operation | Group)[] }
type BlockNode      = ObjectNodeBase & { objects: SceneNode[] }
type SceneNode      = ObjectNode | BlockNode

// Evaluated camera: projection on `data` (CameraData + optional gizmoSize).
// Placement is CameraObject.instances[i].transformation — there is no `camera` field.
type CameraData   = { fov: number; near?: number; far?: number } | { height: number; near?: number; far?: number }
type CameraObject = BaseObject & { type: "camera"; data: CameraData & { gizmoSize?: number } }

// Evaluated sheet. No PageObject type — paper content is SceneObject[].
type Page = { title: string; objects: SceneObject[]; width: number; height: number }

Args are expression strings evaluated at runtime. Producers concat into the stream; transforms map/reduce; groups nest folds.

Entry points

SpecifierRole
@huukhanhnguyen/modelFull runtime
@huukhanhnguyen/model/computeCompute-only import graph
@huukhanhnguyen/model/nodesDefault method registry
@huukhanhnguyen/model/src/*Live src/ (parashape check-/gen- import the source registries)
import { Model } from '@huukhanhnguyen/model'
import { nodeRegistry } from '@huukhanhnguyen/model/nodes'
const model = Model.fromJSON(json, { registry: nodeRegistry })
const result = model.evaluate()

Method tables (AUTOGEN): REFERENCE.md, DATA.md.

Modules

Last updated: 📖 2 min readEdit on GitHub