Geometry content: authoring, cooking and loading¶
This page is the workflow guide for cooked curves and surfaces: the
Ludus::GeometryFormat cooked layout, the Ludus::GeometryContent codecs and
the editor-private authoring adapters added in phase G5 of the
curves and surfaces architecture. The architecture page
owns the rationale and the full contract; ADR 0024
owns the frozen domains, statuses and format boundary. This page shows how the
pieces fit together for an author and a runtime.
Pipeline¶
JSON source -- ParseGeometrySource --> GeometrySource (validated, owned)
GeometrySource -- CookGeometry --------> LUGEO blob bytes (GeometryFormat layout)
LUGEO blob -- LoadGeometry ----------> GeometryLoad { PreparedPath | PreparedTrack | PreparedSurface }
PreparedX -- borrow a view ---------> allocation-free sampling (FoundationGeometry)
A cooker never links the renderer, and a runtime loader never links a cooker;
both include the header-only Ludus::GeometryFormat contract.
Source schema¶
A geometry source is hand-readable JSON, parsed through the checked Content JSON facilities. Version 1 holds one geometry kind. The shared members are:
version— the source schema version;1.mode—cubic-path,hermite-path,catmull-rom-path,scalar-trackorpatch-surface. The waypoint modes are authored through the editor adapter, which converts them to cubic spans before cooking.revision— owner-assigned snapshot revision copied into the prepared owner.origin— the float64 chunk origin subtracted before narrowing to float32.assetScale— the declared asset scale forrelativePositionError.closed— whether the path or surface boundary is closed (enablesWrap).precision—strictorvisual.tolerance— every ADR 0024ToleranceProfilefield (units in that record).limits— the preparationWorkLimits(maxSpans,maxLeaves,maxDepth,maxSubdivisions,maxIterations,maxPreparedBytes,maxPatches).
A cubic-path adds spans, each { id, kind: line|cubic, domainWidth, control:
[[x,y,z] x 4] }. A scalar-track adds keys, each { id, time, value, inSlope,
outSlope, interpolation: step|linear|hermite } with strictly increasing times.
Author IDs are unique within a source.
Unknown fields or versions, duplicate IDs and invalid constraints (coincident waypoints, non-monotone key times, out-of-range tolerances) return a structured diagnostic with a concrete repair suggestion. They are never assertions.
Cooked blob¶
CookGeometry validates and dry-runs the FoundationGeometry preparation, so a
cook never emits a blob that cannot load, then serialises the LUGEO blob field by
field in little-endian order and records three SHA-256 digests (source,
dependency and payload). Identical source bytes produce identical blob bytes. The
cook is cooperatively cancellable through the Cancellation hook; cancellation
yields Cancelled and leaves no partial output.
The blob header carries the cache key the architecture lists: the source and
dependency digests, the format and cooker versions, the schema version, the
precision profile and every tolerance. LoadGeometry validates the magic, both
versions, the enum tags, every count against the format limits, each section's
count x element bytes byte product, alignment, offset range and non-overlap, the
tolerance profile, strictly increasing track-key times, control finiteness and
the recomputed payload digest before it exposes any prepared owner. Every failure
leaves the output unchanged.
Catalog registration¶
Cooked geometry is a cooked-geometry resource kind in the content catalog. The
catalog schema version is extended to 2; a version-1 catalog still parses and
rejects the new kind, and a catalog without geometry round-trips as version 1.
Editor authoring¶
The editor-private adapters are Qt-free and build on the existing owners. A
CurveDocument records semantic edits as undoable commands on the shared
DocumentHistory: moving an automatic handle visibly converts it to manual, a
drag coalesces into one undo step, and the monotonic revision keys the preview.
A debounced live build supersedes stale requests by a semantic identity that
excludes cosmetic state. An async prepare job pumps {Pending, Ready, Failed}
over an immutable cooked snapshot carrying the document, revision, generation and
profile identity, with cancellation; the transactional preview publishes a Ready
candidate at a declared frame or tick boundary, keeps the last valid view active
with a stale indicator while an edit is invalid or preparing, never erases the
active view on a failed replacement, rejects a late completion whose identity no
longer matches, and holds at most the active load plus one candidate. On
publication a cursor reloads under a consumer-chosen CursorReloadPolicy (retain
parameter, retain absolute distance, retain normalized distance, or project world
position); the choice is explicit, never implicit.
Where this lives¶
modules/content/geometry_format—Ludus::GeometryFormat(header-only).modules/geometry/content—Ludus::GeometryContent.apps/editorludus_editor_geometry_model— the editor-private adapters.
See the evidence ledger for the G5 gate results and validation record.