[Constraint 2.0 / A] Datum registry — named points, axes, planes #9

Closed
opened 2026-08-03 16:30:10 +00:00 by Mark · 0 comments
Owner

Foundation: Datum registry — addressable points/axes/planes independent of modules

Why this comes first: the current target= field only resolves to a module/instance name. To put a hole's center onto the world coordinate origin, or an axis onto a non-existent point in space, we need datums — named, addressable geometric anchors that exist regardless of which part they're attached to.

Spec additions to src/lib/scad/constraints.ts:

export interface DatumPoint { kind: "datum-point"; id: string; name: string; expr: [Expr, Expr, Expr]; }
export interface DatumAxis  { kind: "datum-axis";  id: string; name: string; origin: DatumPoint; dir: [Expr, Expr, Expr]; }
export interface DatumPlane { kind: "datum-plane"; id: string; name: string; origin: DatumPoint; normal: [Expr, Expr, Expr]; }
export type Datum = DatumPoint | DatumAxis | DatumPlane;

New annotation kinds:

  • // @sf:datum-point name=hinge_axis_pt expr=[x,y,z] — x/y/z may be literal numbers or other shared-param names (the simple version of #? expressions).
  • // @sf:datum-axis name=hinge_axis origin=hinge_axis_pt dir=[1,0,0]
  • // @sf:datum-plane name=top_of_plate origin=hinge_axis_pt normal=[0,0,1]

Storage: New Datum[] field on the project manifest (.scadforge.json). The parser extracts them; the solver consults the registry whenever target=$<datum_name> appears in any other annotation.

UI (workbench):

  • "Place mode (C)" button (ConstraintPanel.tsx) currently lets user click two faces. Extend to: click two points in the viewport → name the result → persist to manifest.
  • Add a Datums tab in the constraint panel listing project datums with delete/rename.

Parsing/serialization rules:

  • name must be unique within project (enforce in solver, error in UI).
  • expr uses the expression grammar introduced by sub-issue #? (formulas). Until then, accept only numbers.

Files to change:

  • src/lib/scad/constraints.ts (+~200 LOC: types, parser cases, serializer)
  • src/lib/scad/parser.ts (resetAnnotationIds() interaction)
  • src/lib/scad/solver.ts (datum lookup during resolve)
  • src/lib/vfs.ts (new ProjectDatum persisted entry alongside VfsFile)
  • src/components/workbench/ConstraintPanel.tsx (Datum tab + Place-point-Datum mode toggle in ConstraintPopovers.tsx)
  • src/pages/landing/HeroScene.tsx etc. — no change unless marketing mock references datums

Acceptance:

  • A fresh project has zero datums; user can create three (point, axis, plane) via the UI.
  • Persists across reload (manifest round-trip).
  • Exports correctly: serialized datums appear as // @sf:datum-* in the exported .scad zip.
  • Lint clean, tsc clean, build clean.

Out of scope (deferred to later sub-issues): addressing datums from target=, expression values inside expr=[…], formula-driven re-solve on datum change.

Labels: enhancement


Part of epic #8.

## Foundation: Datum registry — addressable points/axes/planes independent of modules **Why this comes first:** the current `target=` field only resolves to a *module/instance name*. To put a hole's center onto the world coordinate origin, or an axis onto a non-existent point in space, we need datums — named, addressable geometric anchors that exist regardless of which part they're attached to. **Spec additions to `src/lib/scad/constraints.ts`:** ```ts export interface DatumPoint { kind: "datum-point"; id: string; name: string; expr: [Expr, Expr, Expr]; } export interface DatumAxis { kind: "datum-axis"; id: string; name: string; origin: DatumPoint; dir: [Expr, Expr, Expr]; } export interface DatumPlane { kind: "datum-plane"; id: string; name: string; origin: DatumPoint; normal: [Expr, Expr, Expr]; } export type Datum = DatumPoint | DatumAxis | DatumPlane; ``` **New annotation kinds:** - `// @sf:datum-point name=hinge_axis_pt expr=[x,y,z]` — `x/y/z` may be literal numbers or other shared-param names (the simple version of #? expressions). - `// @sf:datum-axis name=hinge_axis origin=hinge_axis_pt dir=[1,0,0]` - `// @sf:datum-plane name=top_of_plate origin=hinge_axis_pt normal=[0,0,1]` **Storage:** New `Datum[]` field on the project manifest (`.scadforge.json`). The parser extracts them; the solver consults the registry whenever `target=$<datum_name>` appears in any other annotation. **UI (workbench):** - "Place mode (C)" button (`ConstraintPanel.tsx`) currently lets user click two faces. Extend to: click **two points** in the viewport → name the result → persist to manifest. - Add a Datums tab in the constraint panel listing project datums with delete/rename. **Parsing/serialization rules:** - `name` must be unique within project (enforce in solver, error in UI). - `expr` uses the expression grammar introduced by sub-issue #? (formulas). Until then, accept only numbers. **Files to change:** - `src/lib/scad/constraints.ts` (+~200 LOC: types, parser cases, serializer) - `src/lib/scad/parser.ts` (`resetAnnotationIds()` interaction) - `src/lib/scad/solver.ts` (datum lookup during resolve) - `src/lib/vfs.ts` (new `ProjectDatum` persisted entry alongside `VfsFile`) - `src/components/workbench/ConstraintPanel.tsx` (Datum tab + Place-point-Datum mode toggle in `ConstraintPopovers.tsx`) - `src/pages/landing/HeroScene.tsx` etc. — no change unless marketing mock references datums **Acceptance:** - A fresh project has zero datums; user can create three (point, axis, plane) via the UI. - Persists across reload (manifest round-trip). - Exports correctly: serialized datums appear as `// @sf:datum-*` in the exported `.scad` zip. - Lint clean, tsc clean, build clean. **Out of scope (deferred to later sub-issues):** addressing datums from `target=`, expression values inside `expr=[…]`, formula-driven re-solve on datum change. **Labels:** enhancement --- Part of epic #8.
Mark 2026-08-04 03:26:54 +00:00
Sign in to join this conversation.
No description provided.