Expand description
Assembly constraint state, lifecycle, and solver mapping.
§The assembly block
Constraints are kernel history state: a top-level assembly block on the
history request — { constraints: [ { type, inputParams, persistentData, enabled, open } ], idCounter } — that round-trips through the saved
document. The pre-purge envelope keys (assemblyConstraints /
assemblyConstraintIdCounter) are NOT read (no-backwards-compat).
§Lifecycle, run at the tail of every history execution
- VALIDATE (
lifecycle): disabled →status:'disabled'; unknown type → an error entry without aborting the rest; duplicate detection across the overlapping family {touch_align, distance, angle, concentric, perpendicular, tangent} via order-independent selection-pair signatures. - MAP (
mapping): each element ref resolves throughsolvers/assembly_resolveto an analytic frame in the owning component’s LOCAL space. Unresolvable/unsupported selections fail that constraint only (status fromcrate::ResolveError::status); the solve continues. - SOLVE: ONE
crate::solve_assemblycall over every mapped constraint; per-mate residuals/statuses + solver diagnostics merge into each constraint’spersistentData; distance/angle first-solve initialization commits intoinputParamsonly on success. - WRITE BACK: solved poses re-pose the scene components in place
(
crate::feature_pipeline::component) and are exported as genericinputParams.transformJSON updates for the owning ACOMP features (the pose-authority contract; applied byassembly_apply_document_jsonwith no compile-time dependency on the ACOMP feature).
§Pose self-consistency (why an unapplied write-back cannot corrupt)
Mate-local frames are computed as record.transform⁻¹ · world_frame, and
each body’s solver pose IS record.transform — so even when the record’s
absolute pose is stale (the app has not yet folded a pose update back into
the ACOMP feature), the solve is self-consistent: reconstructed world frames
equal the actual world geometry, satisfied constraints produce no motion,
and a re-executed component simply re-solves to the same poses. The
write-back matters for PERSISTENCE (save/load) and cache fingerprints, not
for per-run geometric correctness.
Structs§
- Assembly
State - The document’s
assemblyblock: the ordered constraint list plus the persistent id counter (monotonic, never reused — mirrors the feature counter’s contract). - Constraint
Entry - One persisted constraint:
{ type, inputParams, persistentData, enabled, open }.inputParamscarriesid,elements(selection ref strings) and the type-specific params;persistentDatais the solver-state merge target (status/message/diagnostics/orientation cache). - Constraint
Type Def - One constraint type’s static definition.
- Retired
Session - A replaced session and the solids only it owned, to drop where it costs nothing (another thread). Dropping it is all there is to do with it.
- Session
Transfer - An owned, self-contained copy of a thread’s assembly session: the session
and a clone of every solid its scene names, keyed by the handle it had
THERE. It shares nothing with the thread it came from, so that thread may
free or reuse every handle afterwards (
assembly_session_import).
Constants§
- CONSTRAINT_
TYPES - Spec §4 table order — also the panel’s
+dropdown order. - FIXED_
IS_ NOT_ A_ CONSTRAINT - The refusal for a
fixedconstraint (kernel ABI, app command, batch): Fixed is the component instance’s own setting, never a constraint.
Functions§
- assembly_
add_ constraint_ impl - assembly_
add_ constraint_ json - Add a constraint of
constraint_typewith the giveninputParamsJSON (elements etc.;idis minted from the type’s short name + the persistent counter when absent). Auto-solves; returns{id, report}. - assembly_
apply_ document_ impl - assembly_
apply_ document_ json - Fold the session’s solved state into a history DOCUMENT: replaces the
top-level
assemblyblock and writes each pending pose / grounded flag into the owning feature’sinputParams(matched byinputParams.id— generic JSON, no dependency on the ACOMP feature shape). The app calls this on its document before persisting or re-running (the pose-authority write-back). - assembly_
apply_ inferred_ constraints_ json - Scan and CREATE: every accepted candidate becomes a constraint, then ONE
solve runs for the whole batch (each inferred constraint is already
satisfied at the pose it was read from, so a healthy assembly does not
move). Returns
{ok, created: [id…], report, solve}. - assembly_
component_ entities_ json - Every NAMED face and edge of one component, resolved like
assembly_resolve_refs_json(component-local frames). Entities without an analytic frame are skipped: a mate could never have referenced them. An unknown component is an empty list. - assembly_
dof_ json - The last solve’s DOF/diagnostics summary (
{ok, dof, rank, redundant, status, strategy, iterations, maxResidual, ...}or{ok:false, error}). - assembly_
drag_ solve_ impl - assembly_
drag_ solve_ json - The live-drag dry run against the session (
lifecycle::drag_solve). Request{poses: {componentId: {translate, rotateEulerDeg}}, unfix?: [id], reference?: {componentId: pose}, explain?: bool}— the dragged components at their dragged poses, and the last good live poses to re-base mechanical mates at. Reply{ok: true, poses: {componentId: {translate, rotateEulerDeg}}, blocking: [constraintId]}for every movable body (blocking: withexplain, the constraints that would not let the dragged components reach the drag pose; empty otherwise);Errwhen the mates cannot hold at this drag. Nothing in the session (the state, the scene, the pending write-backs, the report) changes. - assembly_
flip_ plan_ json - What Flip would do to constraint
id, read from the live session:{ok: true, patch, seed, elements: [{component, fixed, anchor, direction, geom}], value, angleAxis}(world frame, pick order), or{ok: false, reason}for a type with no other solution. Read-only: the caller writes the patch and the seeded pose as one edit (constraints::flip_rule). - assembly_
frame_ solve_ impl - assembly_
frame_ solve_ json - One frame of a motion study against the session (
lifecycle::frame_solve). Request{overrides: {constraintId: {value?: number, enabled?: bool}}, reference?: {componentId: {translate, rotateEulerDeg}}}:valuedrives a distance or angle constraint to it (model units or degrees; an angle may run past 360),enabledswitches a constraint off or on for the frame, andreferenceis the previous frame’s poses (the warm start). Reply{ok: true, poses: {componentId: {translate, rotateEulerDeg}}}for every movable body;Errwhen the mates cannot hold the frame or an override names a constraint the session lacks or drives one that is not a distance or angle. Nothing in the session changes. - assembly_
infer_ constraints_ json - SCAN the live scene for constraints its component placement implies, without
creating anything.
options_jsonissuper::infer::InferOptions({}for the defaults). NeverErr: a missing session or a bad options object comes back as{ok: false, error}— aJsValueerror aborts a native build. - assembly_
inferable_ types_ json - The inferable constraint types, joined to the catalogue:
[{type, label, icon, longName, detects, defaultOn}]. Session-free — the dialog can list what the button offers before any document is open. - assembly_
move_ constraint_ impl - assembly_
move_ constraint_ json - Reorder a constraint to
index(clamped). Auto-solves; returns the report. - assembly_
overlay_ json - Overlay geometry for the viewport graphics lane: per enabled constraint,
the resolved WORLD anchor points/directions/geometry classes (post-solve),
the status, the evaluated value, and (multi-element types) the element
role groups —
[{id, type, status, message, anchors, directions, geoms, value, unit, target, groups}]. Constraints whose selections do not resolve emit status/message only (no anchors). - assembly_
pose_ updates_ json - The pending generic feature write-backs:
{"poses": {componentId: transformParam}, "isFixed": {componentId: bool}}. The transform param is{translate, rotateEulerDeg (deg, intrinsic XYZ)}— exactly the shape the ACOMP feature’sinputParams.transformreader expects. - assembly_
rebase_ mechanical_ impl - Refresh the mechanical mates’ stored references at the released poses of
a live drag (
lifecycle::rebase_mechanical). Request{poses: {componentId: {translate, rotateEulerDeg}}}. Reply: the updatedassemblyblock JSON when a mechanical mate was refreshed, elsenull. The caller writes the block in the SAME undo step as the poses, so the next run maps a multi-turn drag from where it ended. - assembly_
remove_ constraint_ impl - assembly_
remove_ constraint_ json - Delete a constraint. Auto-solves; returns the solve report.
- assembly_
resolve_ refs_ json - Resolve selection refs against the live session WITHOUT touching any
constraint:
refs_jsonis["ACOMP2:Part_PZ", …]; the reply is one row per ref,{ref, ok: true, component, geom, point, direction, radius}in the owning component’s local frame, or{ref, ok: false, status, error}. Read-only — the replace-component lane snapshots a mate’s references before the swap with it. - assembly_
run_ solve_ impl - assembly_
run_ solve_ json - Manual solve (the panel’s Solve button). Returns the solve report.
- assembly_
session_ export - Copy this thread’s session for another thread (
Nonewithout one). - assembly_
session_ import - Install a
SessionTransferas this thread’s session: every solid is registered HERE under a fresh handle and the scene is re-pointed at it. Returns what it replaced (the previous session and the solids a previous import owned) for the caller to drop. - assembly_
session_ serial - Which session this thread holds (see
SESSION_SERIAL); 0 = none yet. - assembly_
set_ constraint_ enabled_ impl - assembly_
set_ constraint_ enabled_ json - Enable/disable a constraint. Auto-solves; returns the solve report.
- assembly_
set_ constraint_ open_ impl - assembly_
set_ constraint_ open_ json - Persist a constraint row’s dialog expansion state (view state — no solve).
- assembly_
state_ json - The current
assemblyblock (post-solve) as JSON — the panel’s list source and the state the app folds back into its document. - assembly_
statuses_ json - Per-constraint status rows:
[{id, type, enabled, open, status, message, satisfied, error}]. - assembly_
update_ constraint_ impl - assembly_
update_ constraint_ json - Replace a constraint’s
inputParams(the dialog commit). Auto-solves; returns the solve report. - constraint_
hidden_ params - The constraint-form params to HIDE for the current
values(the feature dialogs’feature_hidden_paramshook): a Distance or Angle shows itsminimum/maximumonly withlimiton, and its single target only withlimitoff (the target is ignored while the range rules). - constraint_
schema_ catalogue numberparams are expression-capable against the part’s expression scope (the dialog engine’s established convention).- constraint_
type - Look up a type definition by its canonical
typestring. - transform_
to_ pose_ params - The generic
inputParams.transformpose write-back JSON:{translate, rotateEulerDeg}with degrees in the intrinsicXYZorder (R = Rx·Ry·Rz—features::common::compose_trs_matrix). This is the write-side half of the ACOMP feature’s reader contract (assembly_component.rsreads exactlytransform.translate+transform.rotateEulerDeg; a mismatched key would silently zero the pose on the next history run).