Merge remote-tracking branch 'origin/main' into feat/sketch-tools-return-ids

# Conflicts:
#	crates/engine/src/cmd/mod.rs
#	crates/engine/src/cmd/sketch.rs
#	crates/engine/src/cmd/sketch_create.rs
#	crates/engine/src/cmd/sketch_modify.rs
#	crates/engine/src/lib.rs
#	docs/book/src/guide/sketching.md
This commit is contained in:
CypherNaugh_0x committed 2026-10-11 13:07:50 +02:00
commit b93d4905ac
181 files changed
+29350 -1572

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
# Assembly physical properties
The Browser's component **Properties** action measures the selected assembly placement,
including its nested components. Select the root design to measure every instance in the
assembly. The window shows material-aware mass, volume, surface area, center of mass and
the world bounding box. Pending occurrence moves are included without capturing them.
The same measurements are available through commands:
```json
{"command":"component.properties","params":{"component":"Bracket"}}
{"command":"component.properties","params":{"component":"root"}}
{"command":"component.properties","params":{"component":"Subassembly","descendants":false}}
{"command":"occurrence.properties","params":{"occurrence":"Bracket:2"}}
```
`component.properties` defaults to the active component and measures its first placement.
`occurrence.properties` measures the chosen instance. A nested occurrence can appear beneath
several instances of its parent; supply `path` (the complete list of occurrence ids from the
root) to choose one of those placements. An ambiguous occurrence without a path returns an
error. Both commands accept `descendants: false` to measure only directly owned bodies.
Results contain a `bodies` list and a `total` object. Each body's entry identifies the original
body name, owning component and occurrence path. Physical material density is resolved from
that original body, so copies keep their material and mass. Values use millimetres, square
millimetres, cubic millimetres and grams; coordinates use the world frame.
Mass and center of mass account for each body's density. Volume and area are summed over
placed bodies, including overlapping bodies and repeated instances. Measurements use the
kernel's tessellation-based body measurement. An empty component reports zero totals and
null center of mass and bounding box. A failed body measurement returns an error instead of
presenting an incomplete assembly total. These commands leave geometry, pending placements
and undo history unchanged.
+16
View File
@@ -11,6 +11,13 @@ component, and **Paste New** creates an independent copy. Move an occurrence wit
triad, then **Capture Position** to keep it or **Revert** to put it back. SolveCraft asks before
the next command if a move wasn't captured. **Ground** fixes an occurrence in place.
Paste New copies nested component definitions, sketches, feature histories and generated
dimension parameters. Repeated child instances remain shared within the new copy. Materials,
appearances and wholly internal joints/motion records receive copied references. Design-wide
user parameters remain shared; retained external links and omitted cross-boundary motion
records are reported. Unsupported destructive links refuse the entire copy. See
[individual-instance and copy details](https://github.com/bherbruck/solvecraft/blob/main/docs/occurrence-workflows.md).
**Joints** (`joint.create`, J) connect two components by joint origins that snap to faces, edges,
circles and vertices: rigid, revolute, slider, cylindrical, pin-slot, planar and ball, with
offsets, flip and limits. **As-built Joint** keeps the current position, **Rigid Group** locks
@@ -20,3 +27,12 @@ couples two joints. Contact sets stop motion where bodies would pass through eac
volumes in red.
STEP export writes the component tree as an assembly.
Right-click a component in the Browser and choose **Properties** to inspect
material-aware mass, volume, surface area, centre of mass and world bounds. Descendants and
repeated instances contribute to assembly totals; pending moves are included. A component
uses its first placement; `occurrence.properties` selects a specific instance. Root Properties
measures the complete assembly. Volumes are summed, including overlapping bodies, rather than
measuring their union. The same workflow is available through `component.properties` and
`occurrence.properties`; see
[placement and measurement details](https://github.com/bherbruck/solvecraft/blob/main/docs/assembly-properties.md).
+30
View File
@@ -18,6 +18,32 @@ Extruding into existing material selects **Cut**. In an empty component it selec
choose **New Body** explicitly to keep an addition separate. Changing the default does not alter
operations already saved in a design.
Editing an extrusion retains its signed distances, From/To Object inputs, taper expressions
and explicit body targets. Revolve edits retain world, sketch and explicit-line axes, both
angle expressions and To Object targets. An unchanged **All profiles** selection continues
to include profiles added later. Cancel restores the complete timeline; a successful edit is
one undo step, including downstream parameter changes. Editing a placed component previews the
edited feature before its downstream history. Cylindrical Emboss profile guides follow the
sketch's chosen occurrence frame.
New symmetric revolves split the entered angle evenly around the sketch profile, regardless
of which way the selected axis points. Two Sides measures the second angle backward and the
first angle forward along the sketch-normal sweep direction. Profiles on opposite sides of
an axis each use their own sweep direction. Designs saved before format 11 keep their original
angular placement when opened, edited or copied; creating another revolve uses the new behavior.
To Object follows that same direction for each selected profile, including curved target faces.
Pick a target away from the axis so its angular position is defined.
For cylindrical **Emboss**, select a supported exterior cylinder face and a tangent sketch
profile. **Deboss** cuts radially into the wall. Orthogonal line profiles, including holes and
concave outlines, wrap with exact radial walls; the profile must stay clear of seams and ends.
Complete cylinders and coaxial sleeves are supported. Capture pending component positions
before applying. The feature stores the selected target and author occurrence paths, so edits
and reopening retain the chosen instances. Other curved surfaces and free-form profiles remain
unsupported. A new Emboss without an explicit face infers a unique eligible supported cylinder;
select the face when the target is ambiguous. Older saved features without a face retain their
planar placement.
Fillets and chamfers handle straight edges between planar faces, whole smooth loops, runs of
neighbouring edges with mitred or spherical corners, and closed chains of curved edges (a rolling
ball). See the roadmap's known limitations for the rest.
@@ -28,3 +54,7 @@ be found, the feature warns instead of silently picking another face.
Press **Delete** on anything selected (bodies, faces, sketches, features, planes, components,
canvases). It runs as one undoable step and lists the features that would go with it or fail.
Face Extrude, face Revolve, and Press Pull retain linked generated profiles. When a modified planar face has no construction certificate, these internal profiles use the legacy named-face attachment and projection behavior so upstream edits still update the plane and outline. This compatibility path is private to those modeling tools: newly attached user sketches require a certified face or an explicitly fixed plane. Legacy internal attachments can follow the nearest matching face after topology changes; inspect their result after major upstream edits. Activate the intended occurrence before generating a face profile from a repeated component; capture a separately moved source position before creating a legacy profile across components.
A negative Press Pull across a planar face containing a round through-hole can still fail when the Boolean cutter has coincident curved faces. This operation reports an error and preserves the design atomically; positive face extrusion and Press Pull retain the hole and remain linked.
+9
View File
@@ -17,3 +17,12 @@ Saves are atomic: a crash at any moment leaves either the old file or the new on
replaced version is kept as `<file>.bak`. Unsaved changes are autosaved to a recovery folder,
and the next launch offers to recover them. Older design files are upgraded on open, and files
from a newer version are refused with a message.
Current designs use format 10 for recorded body transfers, explicit 3D curve coordinate
spaces and certified face bindings, alongside semantic configuration styles, associative
free-form offsets and cylindrical emboss selections. Older ownership maps, geometry and
expressions retain their saved meaning. Legacy 3D curves with retained associations receive
their producer's coordinate-space marker without changing any saved points; detached curves
retain world coordinates. A lost cross-component association refreshed by an older build may
need an explicit relink or refresh when its source returns. Loading never guesses a numerical
correction. Association records, coordinate arrays and placements are bounded and checked.
+5 -1
View File
@@ -18,4 +18,8 @@ existing geometry.
Parameters export to and import from CSV or JSON (`parameters.export`, `parameters.import`).
**Configurations** (`config.*`) keep a table of rows, each with its own parameter values and
suppressed features, switched with `config.activate`.
suppressed features, physical materials and body appearances, switched with `config.activate`.
The table's Library picker selects material or appearance values. Choose **Follow material**
to clear an appearance override. Custom looks retain their colour and opacity across
activation, undo and save/reopen. See
[configuration commands and examples](https://github.com/bherbruck/solvecraft/blob/main/docs/configurations.md).
+41 -1
View File
@@ -9,7 +9,47 @@ The SHEET METAL tab builds parts from a sheet of constant thickness under a **sh
- **Unfold / Refold** (`sheet.unfold`, `sheet.refold`) for working on the flat part.
- **Convert** (`sheet.convert`) turns a solid of constant thickness into sheet metal.
- **Create Flat Pattern** (`sheet.flat_pattern`) shows the flat part with its bend lines and a
bend table, and exports it as DXF.
bend table, and exports it as DXF or a bend-table CSV through the save picker.
Bends follow the rule's K-factor, so flat lengths match what a press brake will make. The
oracle checks these against parts built in Fusion.
For a shop drawing or spreadsheet, `sheet.export_bend_table` returns CSV by default; choose
`format: "json"` for structured data. It includes the sheet rule, thickness, bend angles,
radii, allowances and flat centre-line coordinates. Lengths use millimetres and angles use
degrees. Supply `path` to save it, or omit `path` to receive the content through the command
response. `body` defaults to the last sheet body. Exporting does not add a timeline entry or
consume an undo step.
```json
{"command":"sheet.export_bend_table","params":{"format":"csv","path":"bracket-bends.csv"}}
{"command":"sheet.export_dxf","params":{"path":"bracket-flat.dxf"}}
```
DXF cutout geometry preserves lines, circles and circular arcs; other curves are sampled
adaptively. The `OUTLINE`, `BEND_UP` and `BEND_DOWN` layers separate cuts from bend centres.
Base-flange profiles keep their interior holes. Through cuts that cross a sheet edge become
notches in the flat outline; overlapping and repeated cuts remove their combined area once.
The flat preview, DXF and unfolded solid use the same material boundaries. Lines and circular
arcs remain exact; other profile curves use a 0.001 mm chord tolerance.
Cuts can leave separate material pieces, including the centre of a ring cut. These pieces
remain one logical sheet group through Unfold / Refold and export as separate flat outlines.
Large profiles that exceed the geometry processing budget report an error instead of
exporting a partial outline.
Parallel, untapered extrude cuts also preserve shallow pockets through Unfold / Refold.
The pocket floor and side walls remain solid geometry; overlapping cuts from opposite sides
become a through hole wherever they remove the whole thickness. Flat-pattern JSON lists
`pockets` with their side, depth and bottom/top thickness coordinates in millimetres.
DXF pocket boundaries use `POCKET_BOTTOM_Z…_TO_…_MM`, `POCKET_TOP_Z…_TO_…_MM`, or
`POCKET_INTERNAL_Z…_TO_…_MM` layers. These are machining operations, so do not treat every
pocket layer as a through-cut contour when importing the drawing into a CAM tool.
Extrude Intersect on a straight base or an unfolded sheet retains the exact planar material,
including interior holes and detached islands. A completely empty intersection removes the
sheet and its metadata together. Pocket profiles can move with planar panels when forming,
but a pocket crossing a bend zone cannot yet be refolded. Machining folded bend material,
tapered sheet cuts and other unsupported 3D sheet Cut/Intersect operations report an error before changing
the design; they cannot silently restore removed material during a later sheet rebuild.
+37
View File
@@ -20,6 +20,43 @@ ids of what it added (`created: {points, curves, constraints, dimensions}`). Ids
never reused within a sketch, even after a delete, so a script can dimension or constrain the new
geometry right away.
Extend finds intersections with exact ellipses, rational conics and spline spans. It keeps the
original line or circular support and extends only beyond the selected endpoint; conflicting
constraints or an ambiguous overlap leave the sketch unchanged.
Offsets of smooth ellipses, conics and splines follow their source after dimension changes,
dragging and reopening a design. Their stored cubic spline has a whole-span normal-distance
error bound of 0.002 mm. Singular tangents, curvature cusps, possible self-intersections and
excessive subdivisions are refused. Offset these curves individually: mixed chain junctions
currently require separate geometry. `sketch.offset.break` releases an offset for independent
editing, and undo restores its association. Older independently sampled offsets remain independent.
Smooth open and newly created smooth closed offsets can be offset again, including bounded
refinement after a source edit. New closed outputs use a periodic cubic fit with continuous
tangent and curvature at the seam. Break Offset Association preserves that interpolation,
and its closing point remains joined when dragged. Deleting an output also removes its
unused private fit points; deleting a source with a retained dependent is refused.
For explicit closed fit splines, `sketch.spline.fit_point` accepts `periodic: true` and at
least three distinct cyclic samples. It closes the loop automatically. Existing calls and
older saved closed splines retain natural interpolation; older associative closed offsets
also retain their saved natural fit. A legacy seam without a unique normal still refuses
another offset. Periodic intent is stored on each curve and survives save, reopen and Break.
While drawing a fit spline, click its starting point after three distinct samples to close
it smoothly. Right-click finishes an ordinary natural fit. Offset accepts both ellipse
handles and dense fitted curves; the second click sets the side and distance from the curve.
Enable **3D Sketch** in the Sketch Palette to draw lines, fit splines and points off the plane.
New 3D geometry follows its sketch's component placement, including the selected occurrence
and pending position changes. Click a drawn fit point to show its move triad; its arrows move
along world X, Y and Z. Scripts also supply world coordinates to `sketch.line3d`,
`sketch.spline3d`, `sketch.point3d` and `sketch.move3d`. Activate the desired occurrence before
editing an explicit sketch belonging to a component with multiple placements.
Older drawn or detached 3D wires keep their saved world positions. Included and surface-linked
wires with an explicit component marker keep that meaning after the link is broken. Old files
whose links became lost after an incorrectly scoped cross-component refresh may require a
fresh link once the source is available; their stored point values are preserved on opening.
## Constraints and dimensions
The solver is SolveCraft's own (damped Gauss–Newton with degree-of-freedom analysis). Constraints:
+151
View File
@@ -0,0 +1,151 @@
# Design configurations
The configuration table stores named design variants. Add parameter, feature suppression,
physical material, body appearance, component appearance, and semantic face appearance columns
with `config.configure` or `config.column`.
The desktop Configuration Table's **Add Column** menu offers the same targets. Material and
appearance cells have a **Library** picker; their text fields also accept exact saved values.
```json
{"command":"config.configure","params":{"params":["width"],"materials":["Box1"],"appearances":["Box1"]}}
{"command":"config.row","params":{"name":"Aluminum blue","values":{"param:width":"80 mm","material:Box1":"Aluminum","appearance:Box1":"Aluminum - Anodized Blue"}}}
{"command":"config.activate","params":{"row":"Aluminum blue"}}
```
Use the body's actual Browser name in place of `Box1`. `config.table` returns the column keys,
rows, active name, and `matches`: whether the current design still has the active row's values.
Changing an assignment by hand makes `matches` false. Activating another row is undoable.
Material values are names from `material.list` (case insensitive), with `Default` clearing the
body's physical material assignment. Appearance values are names from `appearance.library`,
an empty string or `Default` to clear the body's appearance, or a custom look object:
```json
{"command":"config.row","params":{"name":"Transparent blue","from":"Aluminum blue","values":{"appearance:Box1":{"name":"Custom blue","color":[40,90,186],"opacity":0.4}}}}
```
The table stores custom looks without losing colour or opacity. `color` contains three byte
values, names support up to 128 Unicode characters, and `opacity` must be finite and between
zero and one. Style values are validated when
editing a row and again when activating a saved row. An invalid value leaves the design unchanged.
Clearing a body appearance allows component appearance or material colour to show through;
face appearances keep their existing priority. Physical material changes affect measured mass.
`config.row` supports `from` to copy another row, `rename` to rename an existing row, and
`delete` to remove it. Names must be unique. To remove a style column, use
`config.column` with `material` or `appearance` set to the target body and `delete: true`.
Body style columns target body names. Assignments remain stored when a row suppresses the
feature that produces that body, and become visible when it returns.
## Component and face appearances
**Add Column** offers component appearances and a **Face Appearance** submenu organized by
body and semantic role. You can also select a viewport face before opening the menu and use
**Selected face on ...**. These assignments affect every occurrence sharing the definition.
Component columns use stable component IDs, so renaming a component preserves its rows.
Face columns resolve a definition body through certified lineage, never through a saved display face index.
```json
{"command":"config.configure","params":{"component_appearances":["Part"],"face_appearances":[{"body":"Box1","point":[5,5,10]}]}}
```
Use a point on the current surface to capture a face. The menu carries its already certified target directly, avoiding a second nearest-face pick on thin concentric walls. World occurrence picks are converted
to the shared definition coordinates. `config.table` returns canonical keys and readable
target labels. Use its returned face key when editing a row or deleting a face column:
`config.column` accepts `face_appearance: "<returned key>"` with `delete: true`.
Component columns can be removed with `component_appearance: "Part"` and `delete: true`.
Supported stable face roles are box axis faces, cylinder caps and unsplit side, profile-plane
extrude caps, and one-sided revolve caps. From/nonzero or variable Start Offset/Two Sides extrude caps and
symmetric/Two Sides revolve caps are not yet certified. Mesh faces, ambiguous cap names,
generic index-derived names, and sketch side names based on nearest-curve heuristics are
rejected. Untapered New Body extrusions additionally support line, circle and arc sides
with exact source-edge construction certificates. Ordinary face names and saved sketch or Emboss anchors retain their legacy naming; strict styles resolve separate source metadata and also require the original producing feature. All constructed pieces of the same
sketch curve share one appearance, including split circle seams; distinct coincident
curves are ambiguous and cannot be selected. Unsupported downstream modifiers remove
the certificate rather than transferring paint by proximity. Coplanar split pieces of one supported semantic face share
the configured appearance. If that lineage disappears while its body remains, Apply and
Preview reject the row atomically. There is no nearest-face substitution; later ordinary
topology edits also cannot transfer its paint to a replacement face. A suppressed owning
feature keeps the assignment dormant until it returns.
The Library's **Follow inherited appearance** removes only the selected direct component
or face override. Face paint takes priority over body, component, and physical material;
clearing it reveals inherited or imported paint. Body renames maintain face targets.
Deleting a component or originating feature removes its configured targets and row cells.
Deleting one occurrence preserves the shared definition configuration.
Embedded STEP faces use certificates bound to the exact stored payload, source item and
original STEP face entity. Kernel seam pieces of that same source face share the override.
Replacing the embedded payload invalidates the old face target, even when the replacement
has identical geometry or reuses entity numbers. Body renames and exact rigid placements
preserve source identity; ordinary parameter edits rebuild construction certificates.
Independent component copies duplicate mapped configuration columns, row values, and rules
without retargeting the source. An independent copy of the same embedded STEP payload
preserves its source certificate under the new feature. Copying strict paint on a foreign
body that requires re-export still fails explicitly because that exporter cannot yet
certify the source-to-output face mapping.
Activation evaluates all row parameter expressions together, so column order does not create
temporary dependency cycles. Preview and activation reject new or changed geometry errors
without changing the design. An identical existing error remains visible. A saved row cannot
recreate a deleted parameter: remove its configuration references before deleting it. Deleting
a feature removes its input and suppression columns and any rules referring to that feature.
## Ordered rules and preview
Open **Add or edit rule** below the table. Give the rule a name, choose when it applies, then
choose a driven parameter, driven suppression, numeric range, or allowed values. Numeric
fields accept ordinary design expressions and explicit units. **Edit**, the arrow buttons,
the enable checkbox, and **Delete** update existing rules. Choose **All**, **Any**, or **Not**
to build compound conditions with nested controls, **Add condition**, and **Remove condition**.
**Preview Row** rebuilds a scratch design and shows effective expressions and matched or
skipped rules. Driven and restricted values identify the rule responsible. It leaves the
current geometry, active row, and undo history unchanged. **Apply** or **Activate** publishes
the validated variant as one undoable action.
Rules execute in list order. Each condition sees earlier drives; restrictions from matched
rules all apply to the final values. A range includes its endpoints. Allowed values compare
numeric values with matching dimensions, so `1 cm` equals `10 mm`. An angle never equals a
length. Bare expressions use the target parameter's unit, or the document's unit for feature
length inputs. Equality uses a relative/absolute tolerance of `1e-9` in internal units.
The rule editor's **Length units** selector sets the meaning of bare feature-length
expressions; explicit units override it. Rules capture this unit context when authored. Changing document units
preserves mixed expressions such as `width + 1` without treating `width * 2` as a length
multiplier. Bare saved feature length cells and rule thresholds gain the previous explicit
unit; explicit units and nonliteral source expressions retain their text. A matching active
row rederives its driven values when units change. User parameters retain their own units.
Rules recompute on configured edits, **Apply**, and **Preview Row**. Ordinary parameter
edits can leave the configuration unmatched and do not continuously enforce restrictions.
Cross-unit drives store effective numeric lengths; their saved source expressions reevaluate
on the next Apply or Preview rather than following later ordinary parameter edits live.
Saved source cells are preserved: disabling a drive restores the row's original choice.
```json
{"command":"config.rule","params":{"rule":{"id":"depth-rule","name":"Large parts use deeper stock","condition":{"type":"parameter","parameter":"width","operator":"ge","expression":"80 mm"},"effect":{"type":"drive_parameter","parameter":"depth","expression":"width / 2"}}}}
{"command":"config.rule","params":{"rule":{"id":"width-range","name":"Stock width","condition":{"type":"always"},"effect":{"type":"parameter_range","parameter":"width","minimum":"10 mm","maximum":"100 mm"}}}}
{"command":"config.preview","params":{"row":"Aluminum blue"}}
{"command":"config.rule","params":{"id":"width-range","index":0}}
```
Configure the `depth` column before adding this example drive. Conditions may reference any
existing design parameter; effect targets must be configured columns. `config.rules` lists
rules. `config.rule` replaces a rule with the same ID, deletes with `id` and `delete: true`,
or moves it to a zero-based `index`. Editing a rule validates every saved row before committing;
editing a row validates that row. Invalid geometry, dependency cycles, incompatible units,
or restrictions leave the previous document intact and explain the failure. Delete rules
before removing the last row. Parameter renames update rule targets and expressions; rule
references prevent parameter deletion until removed.
Tables support at most 128 rules; conditions allow eight levels and 64 nodes, and allowed
value lists support up to 128 expressions. These bounds are checked before saved rules are
decoded. Driven appearance/material rules and repeated fixed-point evaluation are outside
the current rule scope.
Newly saved designs use file format 11, including optional durable face attachments. Older designs upgrade on opening without
changing their existing configuration values. Older SolveCraft versions must be updated to
open newly saved designs.
+34
View File
@@ -0,0 +1,34 @@
# Contact sets and joint motion
Contact sets constrain **Drive Joints**, motion-study playback and exported motion samples.
Bodies belonging to different members of an enabled set are checked along the requested
joint motion. A collision between clear start and end poses can therefore stop the motion,
including slider travel through a blocker and revolute travel across one.
```json
{"command":"contact.create","params":{"occurrences":["Base:1","Carriage:1"]}}
{"command":"joint.drive","params":{"joint":"Rail","value":30}}
```
A stopped command returns `stopped_by_contact`, identifying the occurrence pair and the
fraction of the requested motion reached. The first detected collision interval is refined
to leave the bodies just short of penetration, within the tessellated contact tolerance.
Motion links and limits participate in the trajectory checks. Moving a body between
components preserves its placement for contact checks through its body offset.
The trajectory uses bounded samples of cached tessellated geometry. Spacing accounts for
effective joint travel, angular motion, distance from joint pivots and whole-body widths
along sampled face directions. This handles tilted thin plates while keeping curved bodies
practical to drive. It is not exact continuous collision detection: locally thin walls in
a larger body, unsampled face directions and very small geometric details remain limitations.
When a motion or assembly exceeds the sampling, geometry or collision-work budget, the
command returns an error and restores the document. Use smaller drive increments or a
smaller contact set. Mesh bodies in contact sets are currently rejected for swept driving.
An assembly already overlapping at the start retains the recovery behaviour that allows
it to move out of that invalid placement. Disable contact to move freely.
`motion.export` uses the same checks between its requested poses, including sparse exports,
and leaves the source document unchanged. Contact checks interpolate joint values between
those poses; they do not reconstruct intermediate motion-study keyframes omitted by the
requested sample steps.
+66
View File
@@ -0,0 +1,66 @@
# Face-attached sketches
New face-attached sketches store the selected source body, its creating feature, an exact
face certificate, and the source and author occurrence paths. The sketch's picked origin
and orientation are stored in the source face's canonical plane. Editing the source height
or moving its placement therefore updates the sketch plane while preserving its local
geometry and dimensions.
Supported planar sources are exact Box faces, untapered New Body Extrude caps and straight
sketch sides, and planar faces of immutable STEP imports. Extrude caps also identify their
outer boundary and holes by source curve IDs. Reordering profiles cannot substitute another
profile's cap. Curved surfaces cannot host a planar sketch through this workflow.
Edited surfaces without retained construction provenance, ambiguous sources, and unsupported
generators require an explicit fixed plane instead. A nearby or parallel face is never used
to repair a new attachment automatically.
## Create and repair
Select a supported planar face and create a sketch. The desktop selection supplies the exact
body and face index, including its occurrence path. Command callers can use
`sketch.create` with `plane: {face: [x,y,z], body: "world body key", index: face_index}`;
the point is in world coordinates. A point-only face request must find a unique supported
source. An unsupported or ambiguous request fails with an explanation instead of creating
an attachment with weaker identity.
When a source is suppressed, deleted, replaced, or loses its certificate, the sketch reports
a lost attachment. Its saved plane is only a visible repair guide: it does not produce a
healthy solved sketch or let downstream features build at a substitute face.
Use **Redefine Sketch Plane** to select a new supported face explicitly. The draft can be
reviewed before applying it; cancellation leaves the existing attachment intact. Reattachment
keeps existing sketch geometry, IDs, and dimensions. When the selected source changes, its
previous automatically projected boundary becomes ordinary geometry on the new plane;
it is not replaced by a newly projected boundary. Rebinding to the same certified source
retains its live boundary. Manually created projection links retain their own sources.
Choose an explicit fixed plane to detach the sketch. This preserves its current local
geometry and dimensions and converts only its automatically projected face boundary to
ordinary geometry. Manual projection links remain attached to their own sources. A fresh
fixed-plane sketch has no live face auto-projection.
## Occurrences, pending positions, and files
The selected source occurrence and the sketch's author occurrence are separate identities.
Repeated instances therefore cannot silently switch an attachment to the first placement.
A missing author path also requires explicit repair. Reattachment and creation capture
pending positions only on the involved source and author paths. Failed commands restore
those pending positions; undo restores the previous attachment and placement state.
File format 11 saves these optional attachments. Existing designs with face references
without an attachment retain their legacy geometry and lookup behavior when opened; they
are not silently upgraded. Redefining such a sketch onto a supported selected face creates
the stronger attachment. Unsupported legacy geometry can instead be retained on an explicit
fixed plane. Imported attachments also bind the exact STEP payload digest, item entity, and
face entity: replacing the payload cannot reuse an old attachment merely because a face
index or shape looks the same.
## Profiles generated by face modelling commands
Extrude, Revolve, and Press Pull can generate an internal sketch from a selected planar face. Supported
sources use the same certified attachment and live boundary as an ordinary attached sketch.
For modified faces without a construction certificate, these commands retain their historical
named-face and linked-boundary behaviour through a private compatibility path. Initial capture
uses the selected body and face index. These helper sketches do not have the stronger saved
identity guarantee of a certified attachment. This compatibility path does not change the
requirements for creating an ordinary face-attached sketch.
+61
View File
@@ -0,0 +1,61 @@
# Working with individual instances
Each occurrence placement has a full path of occurrence IDs, from the design root to that placement. A child definition reused under several parent instances has a different full path in each parent. Names are labels; paths identify placements across rename and position capture.
Select a placement through `select.set`:
```json
{"items":[{"type":"occurrence","path":[2,4]}]}
```
Properties accepts the leaf occurrence ID and the full path. Move can use world coordinates, including a world rotation pivot:
```json
{"occurrence":4,"path":[2,4],"space":"world","translate":[10,0,0],"capture":false}
```
World movement includes pending parent and child positions. The default space remains parent-local for existing scripts. Capture Position commits pending transforms; Revert Position drops them. Copying an occurrence copies that selected occurrence's effective transform, including its pending position.
An occurrence definition inside a component is shared by every instance of that parent component. Moving, grounding, copying, or deleting that nested definition changes all its parent instances. Selecting its exact path determines the world frame used for movement and Properties; it does not create an independent child definition.
Activate a placement to author shared geometry through its frame:
```json
{"component":3,"occurrence":4,"path":[2,4]}
```
New geometry belongs to the component and appears in every instance. The selected frame determines how world inputs become local component geometry. Planar sketches and new 3D wires display at the active placement during authoring. Component-only activation keeps the first-placement behavior. Format 10 stores an explicit World or Component coordinate marker for 3D wire samples and fit points. Older drawn and detached wires retain their world positions; retained Include and surface producer links keep their component meaning, including lost references. Breaking a link preserves its explicit marker. Activate the desired occurrence before supplying world inputs to an explicit sketch owned by a repeated, nonactive component.
Visibility is an independent view setting for exact placements. Hide a path and all descendants with `browser.visibility`:
```json
{"visible":false,"paths":[[2,4]]}
```
`visible:true` removes that path's own hide setting. A hidden ancestor still hides its descendants. Add `isolate:true` to a visible path list to hide other branches. Show the bodies folder to clear occurrence hides. Selection, activation paths and visibility are session state; the saved document retains occurrence IDs and transforms. Undo follows the existing behavior of clearing selection.
Paths are checked for missing links, repeated IDs, component mismatches and a maximum depth of 64. Descendant expansion rejects more than 100,000 placements or bodies instead of returning incomplete results. Computed body names normally retain their readable occurrence labels; collisions use full occurrence IDs so visibility and body commands still address the correct source.
Placed bodies retain their definition identity separately from display names. Body materials and appearances remain shared, with body overrides taking precedence over component overrides and material colors. Face overrides follow the placed geometry, including pending positions, and painted exports retain these colors.
Paste New copies the reachable component definition graph and its feature history. Repeated children stay shared within the new copy, while the copied definitions, sketches and generated dimension/input parameters are independent of the originals. Materials and body, component and face appearances follow the copied definition identities. Pattern and mirror output names remain explicit, so later body operations follow the copied bodies.
Configuration columns, row values and internal rules are duplicated for copied targets. Certified native face appearances follow the new feature lineage. Selected cylindrical Emboss target and authoring paths inside the copied graph follow the copied occurrences; an incompatible external authoring context is rejected before adoption.
A body reassigned from an external component receives an independent BaseFeature before the first copied feature that modifies it. Copied modifiers then replay once. The command reports these frozen bodies. Public user parameters remain design-wide; retained external sketch, project and feature links are reported. Joints and motion records wholly inside the copied occurrence graph receive new references. Records crossing its boundary are omitted with notices.
Copy evaluates on a scratch document, checks that original bodies remain unchanged, and verifies copied body measurements and sampled material occupancy before adopting it. Unsupported cross-boundary destructive operations, configured foreign faces without certified semantic lineage, reassigned mesh bodies, rolled-back timelines and exceeded work limits return errors without a partial copy. A successful copy selects the new occurrence, preserves your active component and unrelated pending positions, and places the copy under the chosen parent occurrence path. Activate the new occurrence to author features in it. Paste New preserves each 3D wire's World or Component marker and stored coordinates: Component wires follow the copied placement, while World wires retain their physical world positions.
Create Components from Bodies and Move Bodies to Component now add ownership-transfer features at the current timeline position. Earlier joins, cuts and face selections keep their original component frames. At the transfer, geometry converts once into the destination frame; later features authored there operate on the transferred body. Rolling the timeline back before the transfer displays the original owner. Body materials and face identity survive the transfer, and an inherited source-component appearance becomes a body override to preserve its visible look.
Transfers preserve the body's world pose through rotated or translated parents. Pending positions on the involved source and destination paths are captured atomically with the transfer so save/reopen retains that pose; unrelated pending positions remain pending. Undo and checkpoint restoration recover the original pending positions as well as the feature history; redo restores the captured transfer. The operation requires one source and one destination placement. Shared instance definitions with several placements are rejected because a single ownership change cannot preserve several different world poses. A component that supplies transfer history outside its subtree cannot be deleted until that dependent history is removed.
Older files without transfer features keep their saved assignment and offset behavior. No transfer timestamp is inferred from their final ownership map. Paste New freezes externally authored geometry after its successful entry transfer and remaps internal transfers, then replays later modifiers once. All transfer commands validate and evaluate on a scratch document before adoption.
New face-attached sketches capture the selected body's producer, certified face and exact occurrence path, together with the sketch's authoring placement. A supported face follows source edits; a missing or incompatible source reports a lost attachment rather than choosing another nearby face. Opening Edit restores the saved authoring occurrence as view context without creating an undo entry. Older saved point-only face references retain their legacy behavior.
`sketch.create` accepts `plane:{face:[x,y,z],body:"world body name",index:faceIndex,path:[occurrenceIDs]}`. Coordinates and custom planes are world inputs. The optional path must match the selected body. Point-only face picks must resolve uniquely to a supported exact attachment. For an unsupported planar face, explicitly add `fixed:true` to keep its current plane; this creates no live boundary projection. Curved faces cannot become planar attachments through this option.
Use `sketch.redefine` with the sketch ID and a new plane to repair or convert an attachment. Its preview is disposable; Apply records one undo step. An optional `author_path` explicitly repairs a missing author placement. Rebinding a repeated owner from another active component requires that path. Changing the target or converting to a fixed plane detaches only the old automatic face borders, retaining their currently evaluated geometry and entity IDs; unrelated projection links remain live. Pending positions on the involved target and author paths are captured with the edit, while unrelated pending positions remain pending.
Paste New remaps internal certified targets and authoring paths to the copied definitions. Timeline paste reports retained external face targets and refuses translating such attachments until an explicit fixed-plane conversion establishes independent geometry. Rename preserves certified body identity; another producer using the same body name cannot repair a lost attachment.
+19 -19
View File
@@ -2,17 +2,17 @@
Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the toolbar commands of Fusion's Design workspace, ids and names only) and the live command registry (`solvecraft-cli commands`). A command counts as live when SolveCraft registers the same command id. This measures breadth, not depth; see ROADMAP.md and docs/oracle.md for depth.
**In scope (SOLID, SKETCH, ASSEMBLY, SHEET METAL, PLASTIC enclosure subset): 328 / 541 commands live (61%).** SOLID + SKETCH: 185 / 291 (64%). Registered commands: 300.
**In scope (SOLID, SKETCH, ASSEMBLY, SHEET METAL, PLASTIC enclosure subset): 335 / 541 commands live (62%).** SOLID + SKETCH: 188 / 291 (65%). Registered commands: 311.
Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE beyond what solids need, PCB, render, animation, simulation, manufacture, drawings, MANAGE, UTILITIES and the rest of PLASTIC. All Design tabs together: 616 / 1175 (52%).
Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE beyond what solids need, PCB, render, animation, simulation, manufacture, drawings, MANAGE, UTILITIES and the rest of PLASTIC. All Design tabs together: 630 / 1175 (54%).
| Tab | Panel | Live | Total | % |
|---|---|---:|---:|---:|
| SOLID | CREATE | 23 | 35 | 66% |
| SOLID | MODIFY | 19 | 32 | 59% |
| SOLID | ASSEMBLE | 12 | 21 | 57% |
| SOLID | CONFIGURE | 2 | 3 | 67% |
| SOLID | CONSTRUCT | 18 | 20 | 90% |
| SOLID | CONFIGURE | 3 | 3 | 100% |
| SOLID | CONSTRUCT | 19 | 20 | 95% |
| SOLID | INSPECT | 12 | 25 | 48% |
| SOLID | INSERT | 6 | 11 | 55% |
| SOLID | SELECT | 0 | 15 | 0% |
@@ -20,7 +20,7 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| SKETCH | CREATE | 41 | 41 | 100% |
| SKETCH | MODIFY | 12 | 12 | 100% |
| SKETCH | CONSTRAINTS | 15 | 15 | 100% |
| SKETCH | CONFIGURE | 2 | 3 | 67% |
| SKETCH | CONFIGURE | 3 | 3 | 100% |
| SKETCH | INSPECT | 12 | 25 | 48% |
| SKETCH | INSERT | 7 | 13 | 54% |
| SKETCH | ASSEMBLE | 0 | 1 | 0% |
@@ -29,8 +29,8 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| SHEET METAL | CREATE | 15 | 19 | 79% |
| SHEET METAL | MODIFY | 12 | 21 | 57% |
| SHEET METAL | ASSEMBLE | 11 | 20 | 55% |
| SHEET METAL | CONFIGURE | 2 | 3 | 67% |
| SHEET METAL | CONSTRUCT | 18 | 20 | 90% |
| SHEET METAL | CONFIGURE | 3 | 3 | 100% |
| SHEET METAL | CONSTRUCT | 19 | 20 | 95% |
| SHEET METAL | INSPECT | 12 | 25 | 48% |
| SHEET METAL | INSERT | 6 | 11 | 55% |
| SHEET METAL | SELECT | 0 | 15 | 0% |
@@ -42,8 +42,8 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| ASSEMBLY | MOTION | 3 | 3 | 100% |
| ASSEMBLY | MODIFY | 8 | 11 | 73% |
| ASSEMBLY | CONTACT | 2 | 2 | 100% |
| ASSEMBLY | CONFIGURE | 2 | 3 | 67% |
| ASSEMBLY | CONSTRUCT | 18 | 20 | 90% |
| ASSEMBLY | CONFIGURE | 3 | 3 | 100% |
| ASSEMBLY | CONSTRUCT | 19 | 20 | 95% |
| ASSEMBLY | INSPECT | 12 | 25 | 48% |
| ASSEMBLY | SELECT | 0 | 15 | 0% |
| ASSEMBLY | POSITION | 2 | 2 | 100% |
@@ -56,8 +56,8 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| SURFACE | CREATE | 9 | 25 | 36% |
| SURFACE | MODIFY | 17 | 26 | 65% |
| SURFACE | ASSEMBLE | 11 | 20 | 55% |
| SURFACE | CONFIGURE | 2 | 3 | 67% |
| SURFACE | CONSTRUCT | 18 | 20 | 90% |
| SURFACE | CONFIGURE | 3 | 3 | 100% |
| SURFACE | CONSTRUCT | 19 | 20 | 95% |
| SURFACE | INSPECT | 12 | 25 | 48% |
| SURFACE | INSERT | 6 | 11 | 55% |
| SURFACE | SELECT | 0 | 15 | 0% |
@@ -66,8 +66,8 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| MESH | PREPARE | 0 | 4 | 0% |
| MESH | MODIFY | 6 | 30 | 20% |
| MESH | ASSEMBLE | 12 | 21 | 57% |
| MESH | CONFIGURE | 2 | 3 | 67% |
| MESH | CONSTRUCT | 18 | 20 | 90% |
| MESH | CONFIGURE | 3 | 3 | 100% |
| MESH | CONSTRUCT | 19 | 20 | 95% |
| MESH | INSPECT | 12 | 25 | 48% |
| MESH | INSERT | 5 | 10 | 50% |
| MESH | SELECT | 0 | 10 | 0% |
@@ -77,7 +77,7 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| FORM | MODIFY | 5 | 31 | 16% |
| FORM | SYMMETRY | 0 | 6 | 0% |
| FORM | UTILITIES | 0 | 5 | 0% |
| FORM | CONSTRUCT | 18 | 20 | 90% |
| FORM | CONSTRUCT | 19 | 20 | 95% |
| FORM | INSPECT | 12 | 25 | 48% |
| FORM | INSERT | 7 | 13 | 54% |
| FORM | ASSEMBLE | 0 | 1 | 0% |
@@ -87,8 +87,8 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
| PLASTIC | CREATE | 27 | 35 | 77% |
| PLASTIC | MODIFY | 19 | 32 | 59% |
| PLASTIC | ASSEMBLE | 11 | 20 | 55% |
| PLASTIC | CONFIGURE | 2 | 3 | 67% |
| PLASTIC | CONSTRUCT | 18 | 20 | 90% |
| PLASTIC | CONFIGURE | 3 | 3 | 100% |
| PLASTIC | CONSTRUCT | 19 | 20 | 95% |
| PLASTIC | INSPECT | 12 | 26 | 46% |
| PLASTIC | INSERT | 6 | 11 | 55% |
| PLASTIC | SELECT | 0 | 15 | 0% |
@@ -166,10 +166,12 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
- SOLID › ASSEMBLE › New Contact Set
- SOLID › CONFIGURE › Configure
- SOLID › CONFIGURE › Display Configuration Table
- SOLID › CONFIGURE › Create Configuration Rules
- SOLID › CONSTRUCT › Offset Plane
- SOLID › CONSTRUCT › Plane at Angle
- SOLID › CONSTRUCT › Tangent Plane
- SOLID › CONSTRUCT › Midplane
- SOLID › CONSTRUCT › Perpendicular Plane
- SOLID › CONSTRUCT › Plane Through Two Edges
- SOLID › CONSTRUCT › Plane Through Three Points
- SOLID › CONSTRUCT › Plane Along Path
@@ -274,6 +276,7 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
- SKETCH › CONSTRAINTS › Polygon
- SKETCH › CONFIGURE › Configure
- SKETCH › CONFIGURE › Display Configuration Table
- SKETCH › CONFIGURE › Create Configuration Rules
- SKETCH › INSPECT › Measure
- SKETCH › INSPECT › Interference
- SKETCH › INSPECT › Section Analysis
@@ -331,9 +334,7 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
- SOLID › ASSEMBLE › Tangent Constraint
- SOLID › ASSEMBLE › Joint Constraint
- SOLID › ASSEMBLE › As-Built Constraint
- SOLID › CONFIGURE › Create Configuration Rules
- SOLID › CONSTRUCT › User Coordinate System (UCS)
- SOLID › CONSTRUCT › Perpendicular Plane
- SOLID › INSPECT › Validate
- SOLID › INSPECT › Component Connection Analysis
- SOLID › INSPECT › DOF Analysis
@@ -368,7 +369,6 @@ Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE
- SOLID › SELECT › Select Edge Priority
- SOLID › SELECT › Select Component Priority
- SOLID › SELECT › Selection Filters
- SKETCH › CONFIGURE › Create Configuration Rules
- SKETCH › INSPECT › Validate
- SKETCH › INSPECT › Component Connection Analysis
- SKETCH › INSPECT › DOF Analysis