Commit Graph
63 Commits
Author SHA1 Message Date
bherbruckandClaude Opus 5.5 6090e89b3f Release under the SolidCraft name: binaries, assets and installers (#383)
* Release under the SolidCraft name: binaries, assets and installers

The desktop binary is now `solidcraft` and the CLI `solidcraft-cli` (the two app packages
are renamed; their folders move with the rest of the rename later). Every release asset is
named solidcraft-<ver>-… / SolidCraft-<ver>-windows-x64.exe, and the installers show the
SolidCraft product name.

Kept so existing installs keep updating (docs/compatibility.md):
- `solvecraft-cli` alias binary in every package, forwarding to solidcraft-cli with a
  deprecation note on stderr (tests/legacy_alias.rs).
- Linux app ID ai.storyteller.solvecraft (Flatpak ID, desktop entry, Wayland app_id).
- MSI UpgradeCode, so the MSI upgrades in place.
- deb Replaces/Conflicts/Provides and rpm Obsoletes/Provides solvecraft.
- An old-named .zsync copy so earlier AppImages find updates; a legacy .flatpakrepo copy.
- .solvecraft file associations; SOLVECRAFT_* fallbacks in the packaging scripts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

* MSI: register the legacy .solvecraft extension without a duplicate open verb

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 16:05:35 -04:00
Vitali M.andVitali M. 6efbd6ff14 Place a dimension that would over-constrain the sketch as a driven one (#366)
Sketch Dimension refused a dimension the sketch couldn't take, with
"that dimension would over-constrain the sketch; add it as a driven
(reference) dimension with driven: true", which the tool gave no way to
do. It now places it as a driven dimension instead: while placing, the
preview shows it in parentheses in the driven colour, and the click adds
it at once (it has no parameter and no value to edit), with a status line
saying why. Other refusals, such as an unsupported pick, are reported as
before, since the driven dimension is refused too.

Refs #320

Co-authored-by: Vitali M. <[email protected]>
2026-10-12 14:54:34 -04:00
Nathan Dane 4eaadf3099 fix(macos): package the app as SolidCraft (#347) (#354) 2026-10-12 14:37:35 -04:00
bherbruckandClaude Opus 5.5 d15869ab85 CI: shard tests across 4 runners; heavy tests on main and nightly (#350)
* CI: build tests once and run them in 4 nextest shards

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

* CI: quote the shard arguments

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

* CI: extract the test archive into the checkout; skip the heaviest tests on pull requests

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

* Docs: CI shards and the tests pull requests skip

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 14:30:35 -04:00
7db66bb824 Pick a horizontal or vertical dimension from where its text is placed (#345)
Between two points, or on a line, that don't line up with an axis, the
Sketch Dimension tool only offered the distance between them: an auto
dimension ignored where its text went. Now the placement picks what it
measures: across from the two (between the perpendiculars through them)
the distance between them, as before; past that, above or below them the
horizontal distance, beside them the vertical one. With no text, an
explicit type, or two ends already on an axis, nothing changes.

The tool previews the dimension from the cursor, so the choice follows
the pointer while placing it.

Fixes #257

Co-authored-by: Vitali M. <[email protected]>
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 14:18:11 -04:00
Iraklis KourtisandClaude Opus 5.5 a9efae864d fix(doc): designs saved before format 14 keep their piece names (#136)
Pieces a cut splits a body into are named after their faces since names
follow history (lineage::order_lumps), so they keep their body names when
an upstream edit moves the cut. The kernel's shell order named them
before, and the two orders can differ: a slot along X through a 40x30x10
block swaps Body1 and Body1 (1). A design saved by an older build stores
body names meaning the old order (fillet and chamfer bodies, targets,
participants, materials, appearances, joints), so it would act on the
other piece.

Each feature now says which order names its pieces
(Feature::shell_piece_order). The v13 to v14 step sets it on every saved
feature, so an older design evaluates as it was saved; features made from
now on, in new or old designs, name their pieces after their faces.

The corpus gains split-body-pieces, saved by v0.3.2: a fillet, a chamfer
and an appearance refer to the two pieces by body name. Without the
setting the two pieces swap names (the corpus test fails); with it they
stay as saved. Migration tests that compared an upgraded design with the
original now expect the setting on its features.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
2026-10-12 11:52:53 -04:00
Iraklis KourtisandClaude Opus 5.5 08cf526fe2 feat(doc): persistent names follow the kernel's exact face history (#136)
Why: every reference a user makes to a face or edge (fillet and chamfer
edges, sketches on faces, shell/draft/offset faces, joints, appearances)
is stored as a name and found again after any upstream edit. Those names
were re-derived by sampling points of each face and voting, and pieces
of a split face were numbered by where their centres lay. After an
upstream edit that splits, merges, mirrors or shrinks a face, a fillet
or sketch could silently re-attach to the wrong face, and nothing told
the user. The kernel now reports exact history for its operations, so
names follow it and fail loudly instead of guessing.

- crates/doc/src/lineage.rs: a feature's kernel histories composed into
  one lineage over nameable operands (bodies before the feature, moved
  copies, shell cavities, tools named by role: sketch curve, cap, box
  side, imported face). Instrumented: extrude/revolve/sweep/loft tools,
  join/cut/intersect, lumps after a cut, fillet/chamfer, shell, draft,
  split face/body, pattern/mirror (bodies and features), combine,
  boundary fill, move/scale, offset/delete face, thread, import.
- crates/doc/src/history_names.rs: names from lineage; split pieces told
  apart by the faces only they touch (F2:top#[F2:side:l4,F4:side:l4]),
  merged faces answer to every name (aliases), lump bodies ordered by
  their faces' names instead of shell order.
- crates/doc/src/name_lookup.rs, piece_names.rs: references resolve by
  exact name, alias or bounding faces, else nearest piece with a
  warning; names worked out from geometry (operations without history)
  are reported when only geometry decided.
- Format 14: names stored by older formats get a legacy mark and are
  found as the build that saved them found them (some geometric names
  name a face history names differently: a tube's outer wall was named
  after its inner circle). New corpus file saved by 9a979cf.
- kernel: Body::lumps carries each piece's history over the whole.
- Adversarial tests: split, merge, mirrored twins, shrink to a sliver,
  moving cut with body pieces, history-less bodies, certified sketch.
- docs/book/src/dev/naming.md describes the real mechanism and why.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
2026-10-12 11:52:53 -04:00
4d4b3a715f Create construction planes along drawn 3D sketch paths (#240)
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 11:44:19 -04:00
e6e0a7ebb5 Snap 3D bridge lines to points on other sketch planes (#229)
* Snap 3D bridge drawing to points on visible sketch planes

* Keep cross-sketch point picks out of sketch tools

`pick()` returned every visible sketch's points while 3D drawing was on,
so `sketch_point_at` and the sketch tools could take another sketch's
point as an active-sketch local point plus id (flattening it or making a
bad coincident reference). `pick()` is local again; the bridge snap uses
`pick_3d` explicitly and hover mirrors it for feedback. `sketch_point_at`
also ignores foreign points defensively.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(sketch3d): check local point scope with a sketch tool active

Main's Project preselection fix now offers other sketches' points to idle
selection, so assert the local scope where it still applies.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* style: rustfmt

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 11:25:39 -04:00
bherbruckandClaude Opus 5.5 3b8028a040 Retire legacy reference data and the external command catalog (#302)
- Remove xtask/data/fusion-catalog.tsv and xtask/data/fusion-ids.tsv.
- Remove the legacy command-id table (crates/engine/src/legacy_ids.rs) and its use in
  find_command and in the shortcut, recents and pinned-command loaders. Only SolidCraft's
  dotted ids name commands; any other id is an unknown command.
- Boundary Fill's id becomes solid.boundary_fill.
- Replace the parity report with SolidCraft's own feature checklist: `cargo xtask features`
  writes docs/features.md from the command registry.
- docs/oracle.md, docs/step-import.md (corpus section) and docs/iges-import.md: reference
  results are being rebuilt on analytic and open-source (FreeCAD) values; see #292.
  `cargo xtask oracle` and `cargo xtask step-corpus [--iges]` write these placeholders.
- AGENTS.md, CLAUDE.md, CONTRIBUTING.md, README.md, ROADMAP.md and the book describe
  SolidCraft as independent, with reference tests on analytic values and open-source tools,
  and agents do not drive or extract data from commercial CAD products.


Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 11:19:15 -04:00
59fabc16ac Reject ambiguous origin and construction plane names (#247)
* Reject ambiguous origin and construction plane names

* Reserve origin plane names for construction planes; suggest the other alias

A construction plane can no longer be created with or renamed to XY, XZ, YZ, Top, Front or
Right, so a plane argument can't become ambiguous in new designs. For older designs that
already hold such a plane, the ambiguity error now also names the origin plane's other
alias (XY for Top...). The existing tests build those legacy names directly.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 11:05:57 -04:00
e12758ff91 Public reference tests: analytic and FreeCAD expected values (#310)
The oracle no longer uses Fusion measurements. tests/oracle/<case>/ now holds the 76 recipes
(our own format, with recorded measurements and tool-specific fields removed) and an
expected.json per case:

- 55 analytic cases: closed-form values from tools/oracle-analytic/ (stdlib Python, formulas
  in each case's "method").
- 21 FreeCAD cases: the same recipe built with FreeCAD's public scripting API by
  tools/freecad-oracle/ (an external program, not a dependency), with a reference.stl for 20.

solvecraft-cli oracle compares body count, volume, area, centre of mass, bbox, face counts
where the geometry fixes them, and, against reference.stl, the sampled Hausdorff distance and
the principal moments (spatial.rs from #301). cargo xtask oracle reads tests/oracle, writes
docs/oracle.md with the source of each value, and supports known_failure marks for tracked
bugs. CI runs it on every PR; a manual workflow regenerates the FreeCAD values. step-corpus,
seam normalisation and the through-all emulation, which only existed to compare with Fusion,
are removed.

75/76 pass; 75-sm-bracket-holes is a known failure (#296).


Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 10:43:43 -04:00
bherbruckandClaude Opus 5.5 611422e4df Alias navigation preset uses Shift+Alt with LMB/MMB/RMB (Fixes #304) (#306)
Navigation presets are now a table of bindings (button, required modifier
keys, camera mode) instead of string matches. The Alias preset binds
Shift+Alt+left to orbit, Shift+Alt+middle to pan and Shift+Alt+right to
zoom. A left press with a binding's keys is latched until release, so that
drag neither box-selects nor drags sketch geometry; plain left drags behave
as before. Shift only requests snapping when the binding without Shift
still orbits.

The scenario harness sends Alt with ui.drag/ui.click, and camera checks can
assert panned/zoomed since the last camera step. The user guide notes Alt+drag
grabs by KDE and GNOME and how to free them.


Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 10:33:53 -04:00
62847173f4 Honor design units in sketch dimensions and measurements (#241)
* Honor design units in sketch dimensions and measurements

* fix: apply document units to specialized length controls

* Accept explicit units in length fields; document design-unit dimension values

Length fields in a design-unit control now evaluate what is typed as a
length expression: a bare number stays in the design's units, while an
explicit unit ("10 mm", "0.5 in", "1 in + 5 mm") is converted.
Document that a bare numeric sketch.dimension value from scripts, the
control channel or MCP is read in the design's units.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 10:08:11 -04:00
lillith df4c8a2994 Reconstruct constant-section meshes as parametric solids 2026-10-12 10:06:42 -04:00
lillith 874315db8e fix(sketch): apply Project to complete preselection 2026-10-12 10:05:52 -04:00
lillith 56b499e951 Reject invalid explicit axis origins instead of using zero 2026-10-12 09:51:58 -04:00
bherbruck ff9653a353 Merge current main into wheel zoom smoothing option 2026-10-11 20:36:16 -04:00
bherbruck 6dd202d277 Fix desktop launch, app icons and keyboard parameter editing 2026-10-11 19:09:47 -04:00
lillith 16bf3ba593 feat(ui): allow disabling wheel zoom smoothing 2026-10-12 01:07:23 +02:00
lillith 8601e38d4b fix(ui): restore free Shift-middle orbit 2026-10-12 00:30:05 +02:00
bherbruck d8beaedfa4 Open Parameters directly and prepare SolidCraft 0.3.0 2026-10-11 17:49:47 -04:00
bherbruck 4af2d06007 Integrate PRs #159, #166 and #174 for 0.3.0 2026-10-11 17:23:30 -04:00
bherbruck 81ef51c6ce Integrate current project documentation 2026-10-11 17:23:13 -04:00
bherbruck 26b7b7336f Integrate current project documentation 2026-10-11 17:23:12 -04:00
bherbruck 8539ac1b40 Resolve #166 minimum Rust version and renamed docs 2026-10-11 17:23:12 -04:00
bherbruck 78aa2aacfb Resolve #159 against current sketch preselection 2026-10-11 17:23:12 -04:00
bherbruck 71cda4e7ee Use plain open-source CAD wording 2026-10-11 17:15:59 -04:00
bherbruck 7f98dd1c47 Describe SolidCraft as independent parametric CAD 2026-10-11 17:12:16 -04:00
bherbruck af536a7907 Rename displayed product to SolidCraft and add header bug reporting 2026-10-11 16:16:48 -04:00
bherbruck da56d180bf Merge pull request #180 from 0xlillith/fix/sketch-point-constraint-preselection
fix: apply Coincident, Midpoint and point Symmetry to preselection
2026-10-11 15:32:20 -04:00
lillith cc2ee6a0f9 fix: apply point constraints to sketch preselection 2026-10-11 20:52:48 +02:00
lillith 1adb2cd69f fix: accept two line picks for sketch coincidence 2026-10-11 20:34:04 +02:00
lillith 36f49811ab chore: align advertised Rust version with egui requirements 2026-10-11 19:37:06 +02:00
lillith f2f8a0df57 docs: explain browser saves and local downloads 2026-10-11 19:17:55 +02:00
lillith 09bf9cafdf fix: apply horizontal and vertical constraints to preselection 2026-10-11 18:51:34 +02:00
bherbruck ab05b24dee Prepare 0.2.0 usability release and refresh desktop demo 2026-10-11 10:55:55 -04:00
bherbruck 0167c358bb Merge upstream profile picks and flush-pad fixes with adaptive identities 2026-10-11 09:43:16 -04:00
bherbruck ce46faa19d Merge pull request #117 from CypherNaught-0x/feat/profiles-by-curve-ids
Profiles can be picked by the curves around them, and point picks are stored that way
2026-10-11 09:28:43 -04:00
bherbruck 4e595deff2 feat: preserve adaptive sketch profiles and curved modeling workflows 2026-10-11 09:06:25 -04:00
CypherNaugh_0x 4c466466a2 Merge origin/main into feat/profiles-by-curve-ids 2026-10-11 14:53:08 +02:00
bherbruck 43a02625a2 feat: add smooth interactive axis view and diagonal snapping 2026-10-11 08:51:24 -04:00
bherbruck b02c5c01f9 Merge pull request #123 from CypherNaught-0x/feat/sketch-tools-return-ids
Sketch commands return the ids of the geometry they create
2026-10-11 08:17:05 -04:00
bherbruck 180c655ded Merge pull request #129 from 0xlillith/fix/sketch-point-alignment
fix: allow horizontal and vertical alignment of sketch points
2026-10-11 08:16:27 -04:00
CypherNaugh_0x 680c82365e Merge remote-tracking branch 'origin/main' into feat/sketch-tools-return-ids
# Conflicts:
#	crates/engine/src/cmd/sketch_modify.rs
2026-10-11 13:30:48 +02:00
bherbruck f9d61590f3 Merge pull request #120 from CypherNaught-0x/feat/timeline-inspect
timeline.inspect shows a feature's editable fields; the timeline.edit format is documented
2026-10-11 07:11:49 -04:00
CypherNaugh_0x b93d4905ac 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
2026-10-11 13:07:50 +02:00
CypherNaugh_0x 184e301c46 Merge remote-tracking branch 'origin/main' into feat/profiles-by-curve-ids
# Conflicts:
#	crates/doc/src/lib.rs
#	crates/sketch/src/lib.rs
2026-10-11 13:07:46 +02:00
CypherNaugh_0x cc22672041 Sketch commands return the ids of the points, curves, constraints and dimensions they create as created: {points, curves, constraints, dimensions}, worked out in Session::execute from the sketch before and after, so a script can dimension and constrain new geometry right away; ids stay stable and are not reused after a delete (undo rewinds the counters with the design). The MCP execute tool describes the field 2026-10-11 12:23:57 +02:00
CypherNaugh_0x adb1e5fec5 timeline.inspect returns a feature's definition in the shape timeline.edit's set takes, so agents no longer guess field names: timeline.edit had no documented format ({"extent": {"distance": …}} worked, but only by trying). The new read-only command (feature: id or name) returns type, definition (the editable fields and their current values; bookkeeping and large payloads such as sketch geometry and imported STEP text are left out and listed under omitted), inputs (label, parameter name, expression, unit) and the feature's error and warning. timeline.edit's params doc points to it, and the book's Solid features chapter documents the edit format with the fields of the common features. Tests: inspect, edit by the field names it shows, inspect again (extrude, fillet, sketch); no undo step; hostile feature arguments are refused 2026-10-11 12:23:30 +02:00