Skip to content
Shapemetry

Model - View chain

API reference for src/lanes/views/viewChain, src/schema/viewChain on @huukhanhnguyen/model, reachable from ..

See the Guide for the ModelJSON / evaluate pipeline.

API reference

Signatures are generated from the live package .d.ts - not hand-written.

chainView

function

Test/UI helper: build a chain View from a record-shaped description.

chainView(key: string, record?: { label?: string; family?: ViewFamily; camera?: CameraBase; window?: ViewWindow; filter?: ViewFilterRule[]; style?: string; }): View

clearViewArg

function

clearViewArg(node: Operation, key: string): void

findSectionPlane

function

A sectionPlane entity by its producing node key (sourceKey, stamped by tessellateScene) — authoring-time + viewSection.plane resolve. Falls back to the first section plane in the scene. Same helper views.ts re-exports.

findSectionPlane(entities: Entity[], key: string): SectionEntity | undefined

FoldedView

type

SavedView (@huukhanhnguyen/types) plus the head method that produced it — everything else is exactly that type: camera folds the projection POSE (absent for a headless preset and for viewDetail, which frames 2D content 1); window folds the head's crop rectangle; source is viewDetail-only, the components[] key whose flat content IS this view's drawing (views.ts resolves it through ResolveViewOptions.resolveDetail); placeable is true when the head is plan/section/elevation (paper-placeable).

type FoldedView
// = SavedView & { /** Head method when present (undefined = headless). */ headMethod?: ViewHeadMethod; }

foldViewChain

function

Config-fold a views[] chain into a resolved definition.

foldViewChain(view: View, options?: FoldViewOptions): FoldedView

FoldViewOptions

type

type FoldViewOptions
// = {
    /** Evaluate one expression arg. Default = empty-context parse/eval
     *  (literals and param-free formulas). Model.evaluateView passes a
     *  scope-backed evaluator so cut/pose track live parameters. */
    evaluateArg?: (input: string) => unknown;
    /** enabled expression evaluator; default truthy unless evaluates falsy. */
    isEnabled?: (node: Operation) => boolean;
    /** For viewSection.plane — the scene's entity stream, searched for the
     *  named sectionPlane entity (findSectionPlane). */
    sectionEntities?: Entity[];
    /** For view3d's `camera` arg — resolve a `camera` cameras[] entry by key
     *  (fail-soft: a missing/unresolvable key falls through to the inline
     *  pose args, same as an absent arg). Undefined when the caller has no
     *  cameras lane (e.g. a standalone test). */
    resolveCamera?: (key: string) => EvaluatedCamera | undefined;
}

isViewPlaceable

function

True when the chain has a paper-placeable head (plan/section/elevation).

isViewPlaceable(view: View): boolean

operationsFromRecordView

function

Inverse of the fold: a resolved view definition (family + pose + crop) back into the chain operations that produce it. The authoring UI and tests build fixtures through it, so a fixture can still think in projection terms.

family picks the head — it is NOT inferred from camera fields any more (the type tag it used to read is gone, and a pose alone cannot say whether an author meant a plan or a 3D bookmark). Everything else about the head is still derived from the pose: which principal elevation it faces, whether a plan is cut, where the section plane sits.

operationsFromRecordView(record: { family?: ViewFamily; camera?: CameraBase; window?: ViewWindow; filter?: ViewFilterRule[]; style?: string; }): (Operation | Container)[]

setViewArg

function

setViewArg(node: Operation, key: string, input: string): void

setViewStyleStep

function

Set/replace the viewStyle step (last wins; creates one when missing).

setViewStyleStep(view: View, styleName: string | undefined): void

VIEW_EYE_DISTANCE_MM

const

Stable eye-to-cut distance for plan/section heads that synthesize a camera from a cut height / cut point (matches the views camera/style EYE_DISTANCE_MM so offline migration round-trips).

const VIEW_EYE_DISTANCE_MM = 1000

VIEW_FAMILY_OF

const

Head methods → family. SSOT in schema (SPEC §5.3).

const VIEW_FAMILY_OF: { readonly viewPlan: "plan"

VIEW_FILTER_METHOD

const

const VIEW_FILTER_METHOD: "viewFilter"

VIEW_HEAD_METHODS

const

Head methods → family. Lookup only — never camera-field inference.

The FAMILY is view semantics and lives here, but the method NAMES are type-pinned to the lane's one vocabulary declaration (schema/vocabulary/laneMethods.ts, which the catalog derives its nodeType "view" entries from): a head naming a method that table does not declare stops compiling (step 7, 2026-07-27).

const VIEW_HEAD_METHODS: Set<string>

VIEW_METHODS

const

Every declared view method — heads AND steps, straight off the vocabulary table, so a method added to the catalog is legal here the same moment.

const VIEW_METHODS: Set<string>

VIEW_PLACEABLE_METHODS

const

Paper placement accepts every HEAD; only a HEADLESS chain (a filter/style preset, which frames nothing) is unplaceable.

view3d joined the set 2026-07-27. It used to be excluded on the theory that a perspective bookmark cannot be drawn — but the drawing pipeline projects in PARALLEL from whatever direction the camera looks (views.ts's basisFromForward handles an arbitrary forward vector), and a parallel projection down an oblique direction is exactly an AXONOMETRIC drawing: the isometric that every drawing set carries next to its plans. So a placed view3d renders as an axonometric; its fov/zoom are ignored on paper, since a drawing has no perspective.

const VIEW_PLACEABLE_METHODS: Set<string>

VIEW_STEP_METHODS

const

const VIEW_STEP_METHODS: Set<string>

VIEW_STYLE_METHOD

const

const VIEW_STYLE_METHOD: "viewStyle"

viewArgInput

function

Arg get/set on a view operation node.

viewArgInput(node: Operation, key: string): string | undefined

viewExprJson

function

viewExprJson(value: unknown): string

viewExprNumber

function

Expression-literal helpers for authoring ops (UI + tests + migration).

viewExprNumber(n: number): string

viewExprPoint

function

viewExprPoint(p: [number, number, number]): string

viewExprString

function

viewExprString(s: string): string

viewExprWindow

function

viewExprWindow(w: [number, number, number, number]): string

ViewHeadMethod

type

type ViewHeadMethod
// = keyof typeof VIEW_FAMILY_OF

viewHeadOf

function

First head operation in a view chain (skipping containers / disabled not checked).

viewHeadOf(view: View): Operation | undefined

viewStyleNameLiteral

function

Style name from the last viewStyle step (literal or any — no eval).

viewStyleNameLiteral(view: View): string | undefined
Last updated: 📖 3 min readEdit on GitHub