Parametron

ParaShape Entities — API reference

Two layers: computation values (bare PascalCase namespaces — the function substrate, where math lives) and scene entities (camelCase *Entity namespaces — bound + rendered). Functions are primary; nodes are a curated visual projection of function-calls.

A scene entity is a plain JSON record — NOT a class instance. It has no methods; it is pure data ({ id, geometry, visible?, layer?, material?, label?, sourceKey? }) that the graph passes around, serializes, and watches. There is NO type tag — an entity's KIND is discriminated by the SHAPE of its geometry field (point = [x,y,z]; curve = a NurbsCurveJSON with controlPoints; face = { loops, uvMatrix }). Sniff with the guards isPoint / isCurve / isFace (or entityKind(e)) from schema/graph.ts. This reference documents each kind as that data shape (its fields), plus the free computation functions (Namespace.*, value → value, called in expressions) and the producers / transforms (operations) that produce or process it. Signatures read name(args) → returnType. Operation args are abbreviated — see REFERENCE.md for full args. Tables are generated from src/nodesRegistry/catalog.ts + schema/types.ts.

Data, not an object with methods. The Shape tables are the stored JSON data — there is no c.length / pointEntity.geometry instance access. You compute only via free functions Namespace.fn(value, …) (Curve.length(c), Point.distance(from, to)). Because entities carry no methods, they need no class — they are JSON, the graph is pure functions transforming geometry-as-JSON, and the data stays uniform, serializable, and watchable.


curveEntity · kind = curve geometry · CurveJSON

A 1-D wire or a closed loop (a closed loop is still a Curve), backed by a NURBS curve. No type tag — isCurve(e) is true when e.geometry has controlPoints.

ShapeCurveJSON = { id: string, geometry: NurbsCurveJSON, visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }

fieldtypenotes
geometryNurbsCurveJSON{ degree, knots, controlPoints, weights } (kernel shape); kind is sniffed from this
idstringidentity
material? layer? visible? label?render metadata
sourceKey?stringkey of the container child node that produced it (provenance)

Computation functionsCurve.* (value → value, in expressions)

  • Curve.length(curve) → number
  • Curve.closestPoint(curve, point) → point
  • Curve.pointAt(curve, parameter) → point
  • Curve.tangentAt(curve, parameter) → vector
  • Curve.pointAtLength(curve, distance) → point
  • Curve.startPoint(curve) → point
  • Curve.endPoint(curve) → point
  • Curve.divide(curve, count) → point[]

Producersreturn: "curveEntity" (add a Curve to the stream)

polyline · spline · rectangle · polygon · arcCenterStartEnd · arcThreePoints · arcTangentEnd · circle · ellipseArc · nurbsCurve · cubicBezier · quadraticBezier · textCurve · (generic:) clone (clone references another node and adds an independent deep copy — new ids; grouping = a container, { key, operations: [...] })

Transforms that target it (derived namespace CurveEntity + generic Instance)

curveSplit · curveFillet · curveChamfer (curve corner rounding/bevel) · curveFill (closed curves → flat faces; nested ring = hole) · curveOffset · curveThicken · curveUnion · curveSubtract · curveIntersect (2D closed-curve boolean — closed curves → closed curve; binary, needs curve) · curveSelfUnion (no-operand reduce n→1 — fuse the own closed curves into one region) · curveReverse · (generic:) move · rotate · resize · mirror · arrayLinear · arrayRadial · arrayCurve · arrayDistances · applyMaterial · applyLayer · visible · name


faceEntity · kind = face geometry · FaceJSON

A flat 3-D polygon: a filled region (holes via extra loops). A solid is Face[] — a box = 6 Faces, no dedicated solid entity. Curved producers tessellate a kernel NURBS surface to Face[] (each triangle a polygon). No type tag — isFace(e) is true when e.geometry has loops.

ShapeFaceJSON = { id: string, geometry: { loops: [x,y,z][][], uvMatrix?: number[16] }, visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }

fieldtypenotes
geometry.loops[x,y,z][][]3-D WORLD loops: outer loop first, then holes (a flat polygon)
geometry.uvMatrix?number[16]row-major 4×4 plane→world frame, for UV + 2D projection
idstringidentity
material? layer? visible? label?render metadata
sourceKey?stringkey of the container child node that produced it (provenance)

Kernel boundary — booleans / offset / triangulation run in 2D, so toPolyShape(face) projects the 3-D loops to a 2-D PolyShape (fitting a plane when uvMatrix is absent) and fromPolyShape(shapes, uvMatrix) samples each result loop to polygon vertices and unprojects back to 3-D.

Computation functionsFace.* (value → value, over a face geometry value)

  • Face.area(face) → number
  • Face.normal(face) → vector
  • Face.centroid(face) → point
  • Face.contains(face, point) → binary

Producersreturn: "faceEntity"

extrude · sweep · loft · revolve · patchFromCurve · patchFromCorners · (generic:) clone (loft / revolve / patchFromCurve / patchFromCorners build a kernel NurbsSurface internally, then tessellate → Face[] via nurbsToFaces.)

Transforms that target it (derived namespace FaceEntity + generic Instance)

3-D solid boolean (binary, needs solid): solidUnion · solidSubtract · solidIntersect · solidSelfUnion (no-operand reduce n→1 — fuse all own solids into one) · faceExtrude (face push) · faceOffset (face inset/outset) · edgeFillet (edge rounding) · edgeChamfer (edge bevel) · faceLattice · faceReverse · (generic:) move · rotate · resize · mirror · arrayLinear · arrayRadial · arrayCurve · arrayDistances · applyMaterial · applyLayer · visible · name (solid ops auto-flatten a nested input — a loaded model can be boolean'd directly.)


pointEntity · kind = point geometry · PointJSON

A position marker — the render-only visualization of a coordinate. No type tag — isPoint(e) is true when e.geometry is an array [x,y,z].

ShapePointJSON = { id: string, geometry: [x,y,z], visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }

fieldtypenotes
geometry[x, y, z]the position (kind is sniffed from this being an array)
idstringidentity
material? layer? visible? label?render metadata
sourceKey?stringkey of the container child node that produced it (provenance)

Computation functionsPoint.*

  • Point.distance(from, to) → number
  • Point.midpoint(from, to) → point
  • Point.interpolate(from, to, fraction) → point
  • Point.translate(point, offset) → point

Producersreturn: "pointEntity"

pointEntity · (generic:) clone

Transforms that target it (generic Instance only)

(generic:) move · rotate · resize · mirror · arrayLinear · arrayRadial · arrayCurve · arrayDistances · applyMaterial · applyLayer · visible · name


Vector · computation value only (no scene entity)

A 3-D direction/magnitude [x, y, z]. A pure value — used by math, never rendered, so it has no *Entity namespace (and like all entities, no type tag).

Computation functionsVector.*

  • Vector.length(vector) → number
  • Vector.normalize(vector) → vector
  • Vector.dot(left, right) → number
  • Vector.cross(left, right) → vector
  • Vector.angle(from, to) → number
  • Vector.add(left, right) → vector
  • Vector.subtract(left, right) → vector
  • Vector.scale(vector, factor) → vector
  • Vector.between(from, to) → vector


Registry reference (auto-generated)

Generated from the SSOT registries (src/schema/types.ts, src/nodesRegistry/catalog.ts, src/schema.ts) by scripts/gen-reference.mjs (pnpm gen:docs). The per-entity narrative above is hand-written; the blocks below mirror the registries exactly. Do not hand-edit between the AUTOGEN markers — the docsSync test fails on drift.

Types

<!-- AUTOGEN:types -->
TypeKindShapeNote
curveEntitysceneEntity{ id: string, geometry: NurbsCurveJSON, visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }1D wire — line / arc / bezier / nurbs curve. NO type tag — kind is sniffed from the geometry shape (curve geometry = NurbsCurveJSON, has controlPoints).
faceEntitysceneEntity{ id: string, geometry: { loops: [x,y,z][][], uvMatrix?: number[16] }, visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }Flat bounded region; a solid is faceEntity[]. NO type tag — kind is sniffed from the geometry shape (face geometry has loops). loops = 3D world polygons, outer loop first then holes; uvMatrix = row-major 4×4 plane→world frame for UV / 2D projection.
pointEntitysceneEntity{ id: string, geometry: [x,y,z], visible?: boolean, layer?: string, material?: string, label?: string, sourceKey?: string }Point marker — render-only, from the pointEntity generator. NO type tag — kind is sniffed from the geometry shape (point geometry = [x,y,z]).
groupEntitysceneEntity{ id: string, definition: string, transformation: number[16], material?: string, layer?: string, name?: string, visible?: boolean }ONE placement of a GroupDefinition (SketchUp component model). definition = id of the shared content { id: string, entities: EntityJSON[] } in the model's runtime definitions map — child entities stored ONCE, the definition itself is NOT a scene entity. transformation = column-major 4×4 (translation at indices 12,13,14). A node's value is groupEntity[]: N placements, 1 shared definition. Kind = has definition (no geometry).
entitynamespace(curveEntity|faceEntity|pointEntity|groupEntity)[]Generic ops over any scene entity (move/rotate/array/mirror…). An entity has NO type tag — kind is discriminated by its geometry shape (a groupEntity by its definition field).
materialnamespaceMaterialJSONMaterial record — a static materials[] lane entry, referenced by name (applyMaterial).
layernamespaceLayerJSONLayer record — a static layers[] lane entry, referenced by name (applyLayer).
numbervaluenumberUnitless number
lengthvaluenumber (mm)Distance (mm)
anglevaluenumber (deg)Degrees
binaryvalue0 | 10 or 1 — multiply with a dimension to collapse it
stringvaluestringText (single-quoted literal)
colorvalue#rrggbb#rrggbb hex string
vectorvalue[x,y,z]Direction [x, y, z] or [x, y] (z defaults to 0)
pointvalue[x,y,z]Position [x, y, z] or [x, y] (z defaults to 0)
planevalue{point:[x,y,z],normal:[nx,ny,nz]}Infinite plane: a point on the plane + unit normal. Build via Plane.fromPointNormal.
axisvalue{origin:[x,y,z],direction:[dx,dy,dz]}Directed half-line: origin + unit direction (magnitude dropped). Build via Axis.fromPointDirection / Axis.fromTwoPoints.
curvevalueNurbsCurveJSON { degree, knots, controlPoints, weights }Curve geometry value (NURBS) — the geometry of a curveEntity. Use with Curve.* functions; a curveEntity arg unwraps to this.
facevalue{ loops: [x,y,z][][], uvMatrix?: number[16] }Face geometry value — the geometry of a faceEntity. Use with Face.* functions; a faceEntity arg unwraps to this.
surfacevalueNurbsSurfaceJSON { degreeU, degreeV, knotsU, knotsV, controlPoints, weights }NURBS surface value (computation only — not a scene entity). Use with Surface.* functions; a curved generator tessellates one to faceEntity[].
functionvalue(args) => valueLambda expression
modelvalueModelJSON (embedded)Embedded sub-model. loadModel's input holds the full instanced ModelJSON; its value is the live built sub-model, consumed by placeModel via the loadModel key.
objectvalueobjectParameter group
groupvalueobjectVisual group
areavaluenumberArea unit
volumevaluenumberVolume unit
massvaluenumberMass unit
currencyvaluenumberCurrency
fontvalueFontDataOpentype-parsed font object (fetch + parse happens async in Phase 1 via store.loadFonts, fed by the document's static fonts[] lane). Consumed synchronously by the text generator's font arg, which names a fonts[] record.
fnvalueFunctionCallback function: (entity, index) => value. Accepted alongside a static value for per-entity variation.
<!-- /AUTOGEN:types -->

Nodes

<!-- AUTOGEN:nodes -->

Producers — by return (the entity kind produced; concat into the stream)

curveEntity

  • curveEntity.polyline — Polyline
    • 0 : point[] — Ordered vertices [x,y,z] (z optional, defaults 0).
    • 1 : binary — true closes the loop back to the first point; false leaves it open.
  • curveEntity.spline — Spline
    • 0 : point[] — Control points [x,y,z] the smooth curve passes through/near.
    • 1 : number — Curve smoothness: 1 = polyline, 2 = quadratic, 3 = cubic (most common).
  • curveEntity.rectangle — Rectangle
    • 0 : point — One corner of the rectangle.
    • 1 : point — Opposite corner. The axis with the smallest difference from Point 1 becomes the rectangle's plane (XY/XZ/YZ) — no separate rotate needed to place it on a different plane.
  • curveEntity.polygon — Polygon
    • 0 : point — Polygon center [x,y] in the XY plane.
    • 1 : length — Circumradius — distance from center to each vertex.
    • 2 : number — Number of edges, minimum 3.
  • curveEntity.arcCenterStartEnd — Arc (Center)
    • 0 : point — Arc center [x,y]; the radius = distance from center to start.
    • 1 : point — Where the arc begins; sets the radius.
    • 2 : point — Direction the arc sweeps toward (snapped onto the radius).
  • curveEntity.arcThreePoints — Arc (3 Points)
    • 0 : point — First endpoint the arc passes through.
    • 1 : point — Point on the arc between start and end (defines the bulge).
    • 2 : point — Last endpoint the arc passes through.
  • curveEntity.arcTangentEnd — Arc (Tangent)
    • 0 : axis — Start point + leaving tangent direction, as an axis (magnitude irrelevant).
    • 1 : point — Where the arc ends.
  • curveEntity.circle — Circle
    • 0 : point — Circle center [x,y] in the XY plane.
    • 1 : length — Circle radius.
  • curveEntity.ellipseArc — Ellipse Arc
    • 0 : point — Ellipse center [x,y].
    • 1 : vector — Major-axis vector; its length is the X radius.
    • 2 : vector — Minor-axis vector (perpendicular to xAxis); its length is the Y radius.
    • 3 : angle — Sweep in degrees: 360 = full closed ellipse, under 360 = open arc.
  • curveEntity.cubicBezier — Cubic Bezier
    • 0 : point — Start point (on curve).
    • 1 : point — First tangent control point.
    • 2 : point — Second tangent control point.
    • 3 : point — End point (on curve).
  • curveEntity.quadraticBezier — Quadratic Bezier
    • 0 : point — Start point (on curve).
    • 1 : point — Tangent control (pulled toward, not on curve).
    • 2 : point — End point (on curve).
  • curveEntity.nurbsCurve — NURBS Curve
    • 0 : point[] — Control points [x,y,z] of the hull; the curve is pulled toward them, not through.
    • 1 : number — Polynomial degree (clamped to points.length-1): 1 = polyline, 3 = smooth cubic.
    • 2 : number[] — Knot vector (length = points.length + degree + 1, non-decreasing). Empty = auto clamped-uniform.
    • 3 : number[] — Per-point weight, > 0 (length = points.length). Empty = uniform 1; higher pulls the curve toward that point.
  • curveEntity.textCurve — Text
    • 0 : string — The string to render as outline curves; single-quote the literal.
    • 1 : font — Font reference; leave '' to use the built-in fallback font.
    • 2 : length — Cap height of the glyphs in model units.

entity

  • entity.clone — Clone
    • 0 : entity[] — Node to copy — returns an independent deep copy with fresh ids.
  • entity.entities — Entities
    • 0 : entity[] — Ready-made scene entities as a literal EntityJSON[] (faces/curves/points/groups, UV kept) — emitted verbatim with fresh ids. The static-geometry producer: imports, bakes, AI-authored fixed geometry.
  • entity.placeModel — Place Model
    • 0 : model — Model ID to place — emits an independent placement with fresh ids.

faceEntity

  • faceEntity.extrude — Extrude
    • 0 : point[] | curveEntity[] | faceEntity[] — Closed loop becomes a solid with caps; open becomes walls. Accepts points, curves, or faces.
    • 1 : length — Extrusion distance along the profile's normal.
    • 2 : binary — 1 = closed profiles get top/bottom caps (a solid); 0 = walls only (open shell).
  • faceEntity.sweep — Sweep
    • 0 : curveEntity — Path the profile is swept along (open or closed curve).
    • 1 : curveEntity — Closed cross-section curve carried along the path; yields a solid tube.
    • 2 : binary — Close the two ends of the swept tube (false = open duct).
  • faceEntity.loft — Loft
    • 0 : curveEntity[] — Ordered cross-section curves the skin passes through (2 or more).
    • 1 : number — Smoothness across sections: 1 = straight (ruled) between curves, 3 = smooth.
  • faceEntity.revolve — Revolve
    • 0 : curveEntity[] — Profile curve(s) spun about the axis; a closed profile yields a solid.
    • 1 : axis — Revolution axis (origin on the axis, direction = spin axis).
    • 2 : angle — Sweep in degrees: 360 = full solid, under 360 = partial.
  • faceEntity.patchFromCurve — Patch From Curve
    • 0 : curveEntity[] — Boundary curves enclosing the region to fill with a smooth surface.
  • faceEntity.patchFromCorners — Patch From Corners
    • 0 : point — First corner [x,y,z]; corners wind in order 0→1→2→3.
    • 1 : point — Second corner [x,y,z].
    • 2 : point — Third corner [x,y,z], diagonal from corner 0.
    • 3 : point — Fourth corner [x,y,z].

pointEntity

  • pointEntity.pointEntity — Render Points
    • 0 : point[] — Marker positions [x,y,z] to visualize (render-only, not construction geometry).

Transforms — by namespace (the entity kind acted on; process the stream)

CurveEntity

  • curveOffset — Offset Curve (namespace: CurveEntity, shape: reduce)
    • 0 : length — Offset amount: positive = outward, negative = inward.
  • curveThicken — Thicken Curve (namespace: CurveEntity, shape: reduce)
    • 0 : length — Strip width (the curve is offset half this to each side).
    • 1 : string — How outer corners are joined: 'round' (arc), 'miter' (sharp point), 'square' (clipped).
    • 2 : string — How open ends are capped: 'round' (semicircle), 'square' (half-width), 'butt' (flush).
  • curveUnion — Curve Union (namespace: CurveEntity, shape: reduce)
    • 0 : curveEntity — The closed curve to merge with this one (2D boolean).
  • curveSubtract — Curve Subtract (namespace: CurveEntity, shape: reduce)
    • 0 : curveEntity — The closed curve to cut away from this one (2D boolean).
  • curveIntersect — Curve Intersect (namespace: CurveEntity, shape: reduce)
    • 0 : curveEntity — The closed curve to keep only the overlap with (2D boolean).
  • curveSelfUnion — Curve Self Union (namespace: CurveEntity, shape: reduce)
    • (no args)
  • curveFill — Fill (namespace: CurveEntity, shape: map)
    • (no args)
  • curveExtrude — Extrude (namespace: CurveEntity, shape: multiply)
    • 0 : length — Extrusion distance along the profile's normal.
    • 1 : binary — 1 = closed profiles get top/bottom caps (a solid); 0 = walls only (open shell).
  • curveReverse — Reverse (namespace: CurveEntity, shape: map)
    • 0 : binary — true flips direction (curve order / face normal); false leaves it.
  • curveSplit — Curve Split (namespace: CurveEntity, shape: multiply)
    • 0 : number — Normalized split position from start (0) to end (1).
  • curveFillet — Curve Fillet (namespace: CurveEntity, shape: map)
    • 0 : length — Arc radius rounding each selected corner (curved).
    • 1 : function — Predicate over a corner vertex and its index selecting which to round; default = all.
  • curveChamfer — Curve Chamfer (namespace: CurveEntity, shape: map)
    • 0 : length — Straight setback from each selected corner (flat cut, not an arc).
    • 1 : function — Predicate over a corner vertex and its index selecting which to cut; default = all.

FaceEntity

  • solidUnion — Solid Union (namespace: FaceEntity, shape: reduce)
    • 0 : faceEntity[] — The closed solid (Face[]) to fuse with this one (3D CSG).
  • solidSubtract — Solid Subtract (namespace: FaceEntity, shape: reduce)
    • 0 : faceEntity[] — The closed solid (Face[]) to carve out of this one (3D CSG).
  • solidIntersect — Solid Intersect (namespace: FaceEntity, shape: reduce)
    • 0 : faceEntity[] — The closed solid (Face[]); keeps only the volume shared by both (3D CSG).
  • solidSelfUnion — Solid Self Union (namespace: FaceEntity, shape: reduce)
    • (no args)
  • faceLattice — Lattice (namespace: FaceEntity, shape: map)
    • 0 : length — Strut/wall thickness of the lattice shell.
    • 1 : binary — Close the open border edges of the lattice with caps.
  • faceExtrude — Face Extrude (namespace: FaceEntity, shape: map)
    • 0 : length — Distance to push the selected faces along their normal (negative = inward).
    • 1 : function — Predicate over a face's points and normal selecting which faces to push; default = all.
  • edgeFillet — Edge Fillet (namespace: FaceEntity, shape: map)
    • 0 : function — Predicate over an edge's two endpoints selecting which edges to round; default = all.
    • 1 : length — Rolling-ball arc radius of the rounded edge (curved).
    • 2 : number — Number of facets across the arc; higher = smoother.
  • edgeChamfer — Edge Chamfer (namespace: FaceEntity, shape: map)
    • 0 : function — Predicate over an edge's two endpoints selecting which edges to cut; default = all.
    • 1 : length — Flat-cut setback from the edge (a straight 45°-style bevel, not an arc).
  • faceReverse — Reverse (namespace: FaceEntity, shape: map)
    • 0 : binary — true flips direction (curve order / face normal); false leaves it.
  • faceOffset — Offset Face (namespace: FaceEntity, shape: map)
    • 0 : length — Inset (positive) or outset (negative) distance.

Instance

  • arrayLinear — Linear Array (namespace: Instance, shape: multiply)
    • 0 : vector — Per-copy step — magnitude IS the spacing (unlike Array Along Distances, where direction is normalized).
    • 1 : number — Copies to add — the original stays, so 1 duplicates once.
  • arrayRadial — Radial Array (namespace: Instance, shape: multiply)
    • 0 : axis — Rotation axis: origin = pivot point, direction = spin axis.
    • 1 : number — Copies to add around the axis — original + copies spaced evenly over 360°.
  • arrayCurve — Array Along Curve (namespace: Instance, shape: multiply)
    • 0 : curveEntity — Path curve the copies are distributed along.
    • 1 : number — Copies to add along the curve — original at the start, spaced evenly.
    • 2 : angle — Extra rotation in degrees applied to each copy about the curve tangent.
  • arrayDistances — Array by Distances (namespace: Instance, shape: multiply)
    • 0 : vector — Direction to array along — magnitude ignored, see Distances for spacing.
    • 1 : length[] — Gap after each copy, in order, along Direction. Copy count = number of distances (a partition — no separate Copies arg).
  • mirror — Mirror (namespace: Instance, shape: multiply)
    • 0 : plane — Mirror plane (point on plane + normal).
    • 1 : binary — 1 keeps the original and adds the reflection; 0 flips in place.
  • move — Move (namespace: Instance, shape: map)
    • 0 : vector — Displacement to apply.
  • rotate — Rotate (namespace: Instance, shape: map)
    • 0 : axis — Rotation axis (origin = pivot point, direction = axis; magnitude irrelevant).
    • 1 : angle | fn — Rotation angle in degrees (CCW about the axis), or a callback (entity, index) => number, per entity.
  • resize — Resize (namespace: Instance, shape: map)
    • 0 : length | fn — Target width along X, or a callback (entity, index) => number, per entity.
    • 1 : length | fn — Target depth along Y, or a callback (entity, index) => number, per entity.
    • 2 : length | fn — Target height along Z, or a callback (entity, index) => number, per entity.
  • applyMaterial — Material (namespace: Instance, shape: map)
    • 0 : material | fn — A materials[] record name to assign (single-quote literals), or a callback (entity, index) => string, per entity.
  • applyLayer — Layer (namespace: Instance, shape: map)
    • 0 : string | fn — Layer name to assign (single-quote literals), or a callback (entity, index) => string, per entity.
  • visible — Visible (namespace: Instance, shape: map)
    • 0 : binary | fn — true shows, false hides the entities; or a callback (entity, index) => boolean, per entity.
  • name — Name (namespace: Instance, shape: map)
    • 0 : string | fn — Display/export name tag (single-quote literals), or a callback (entity, index) => string, per entity.

Group

  • groupExplode — Explode (namespace: Group, shape: structural)
    • 0 : binary — Dissolve this node's nested groups (a placed sub-model / clone) into raw geometry — SketchUp Explode. 1 = recursive; 0 = one level.
  • looseToGroup — Loose to Groups (namespace: Group, shape: structural)
    • (no args)
  • makeGroup — Make Group (namespace: Group, shape: structural)
    • (no args)

Parameters — value bindings (header lane)

angle

  • angle.angle — Angle
    • 0 : angle

boolean

  • boolean.boolean — Boolean
    • 0 : binary

color

  • color.color — Color
    • 0 : color

length

  • length.length — Length
    • 0 : length

loadModel

  • loadModel.loadModel — Load Model
    • 0 : model — The embedded instanced ModelJSON (installed by the editor — upload, URL, or catalog pick). Built once and cached; place copies with the placeModel operation.

number

  • number.number — Number
    • 0 : number

text

  • text.text — Text
    • 0 : string
<!-- /AUTOGEN:nodes -->

Model schema (TypeScript)

<!-- AUTOGEN:schema -->
type expression = string // any JS expression: arithmetic, parameter key refs, Math.* calls, ternary, arrow functions; literal text single-quoted ('Oak')

type ValueMethod = "angle" | "arrayLength" | "boolean" | "color" | "function" | "length" | "loadModel" | "number" | "text"

type EntityMethod = "applyLayer" | "applyMaterial" | "arcCenterStartEnd" | "arcTangentEnd" | "arcThreePoints" | "arrayCurve" | "arrayDistances" | "arrayLinear" | "arrayRadial" | "circle" | "clone" | "cubicBezier" | "curveChamfer" | "curveExtrude" | "curveFill" | "curveFillet" | "curveIntersect" | "curveOffset" | "curveReverse" | "curveSelfUnion" | "curveSplit" | "curveSubtract" | "curveThicken" | "curveUnion" | "edgeChamfer" | "edgeFillet" | "ellipseArc" | "entities" | "extrude" | "faceExtrude" | "faceLattice" | "faceOffset" | "faceReverse" | "groupExplode" | "loft" | "looseToGroup" | "makeGroup" | "mirror" | "move" | "name" | "nurbsCurve" | "patchFromCorners" | "patchFromCurve" | "placeModel" | "pointEntity" | "polygon" | "polyline" | "quadraticBezier" | "rectangle" | "resize" | "revolve" | "rotate" | "solidIntersect" | "solidSelfUnion" | "solidSubtract" | "solidUnion" | "spline" | "sweep" | "textCurve" | "visible"

type Method = ValueMethod | EntityMethod

type ModelJSON = {
    id?: string
    title: string
    camera?: CameraJSON
    materials?: {
        name: string
        baseColor?: string
        texture?: string
        tileWidth?: number
        tileHeight?: number
        colorFactor?: number
        opacity?: number
        roughness?: number
        metallic?: number
    }[]
    layers?: ({
        name: string
        color?: unknown[]
        lineStyle?: "solid" | "dashed" | "dotted"
    })[]
    fonts?: {
        name: string
        url: string
    }[]
    parameters?: NodeJSON[]
    operations?: NodeJSON[]
    unit: {
        length: "mm" | "cm" | "m" | "in" | "ft" /* default: "mm" */
        area?: "mm2" | "cm2" | "m2" | "in2" | "ft2"
        volume?: "mm3" | "cm3" | "m3" | "in3" | "ft3" | "L"
        mass?: "mg" | "g" | "kg" | "lb" | "oz"
    } /* default: {"length":"mm"} */
}

type CameraJSON = {
    type?: "perspective" | "orthographic"
    position: unknown[]
    target: unknown[]
    zoom?: number
}

type NodeJSON = OperationJSON | ContainerJSON

type OperationJSON = {
    key?: string
    label?: expression
    enabled?: expression
    method: Method
    args?: ArgumentJSON[]
    animation?: {
        keyframes: {
            time: number
            value: number
        }[]
        loop?: boolean
    }
}

type ContainerJSON = {
    key?: string
    label?: expression
    enabled?: expression
    operations: (OperationJSON | ContainerJSON)[]
}

type ArgumentJSON = {
    key: string
    input: string | Record<string, unknown>
    label?: string
    min?: expression
    max?: expression
    step?: expression
    options?: OptionJSON[]
}

type OptionJSON = {
    label: string
    input: expression
}

// JS globals in expression scope — using as node key shadows the global
const JS_RESERVED = ["Math","Number","String","Boolean","Array","Object","isNaN","parseFloat","parseInt"] as const

// ECMAScript reserved words & special identifiers — forbidden as node keys
const JS_KEYWORDS = ["break","case","catch","continue","debugger","default","delete","do","else","finally","for","function","if","in","instanceof","new","return","switch","this","throw","try","typeof","var","void","while","with","class","const","enum","export","extends","import","let","static","super","yield","async","await","implements","interface","package","private","protected","public","of","null","true","false","undefined","NaN","Infinity","arguments","eval"] as const
<!-- /AUTOGEN:schema -->

Sources of truth: src/nodesRegistry/catalog.ts (producers + transforms; the namespace shown next to a transform is derived catalog/display metadata, not a persisted field — OperationJSON carries no namespace), schema/types.ts (type registry), schema.ts (model contract). The auto-generated blocks above mirror them; the narrative is hand-written.

📖 20 min read