lillith
56b499e951
Reject invalid explicit axis origins instead of using zero
2026-10-12 09:51:58 -04:00
bherbruck
4e39869023
Merge pull request #179 from tbreckle/fix/177-centerline-to-construction
...
fix(sketch): a centerline can be switched straight to construction
2026-10-11 16:46:04 -04:00
bherbruck
af536a7907
Rename displayed product to SolidCraft and add header bug reporting
2026-10-11 16:16:48 -04:00
bherbruck
ef8f6ca6f9
fix: restore shell and cut wall topology in 0.2.1
2026-10-11 15:17:05 -04:00
tbreckle
6dc6372b13
fix(sketch): a centerline can be switched straight to construction
...
sketch.construction set `construction` but left `centerline` on, so the
curve stayed a centerline (drawn dash-dot, still marked as an axis) until
it was first switched back to normal. Making a curve construction now
clears its centerline flag, mirroring sketch.centerline.
2026-10-11 20:40:21 +02:00
lillith
1adb2cd69f
fix: accept two line picks for sketch coincidence
2026-10-11 20:34:04 +02:00
bherbruck
d9d4dd262d
Merge pull request #155 from EmDecay/fix/147-input-channel-caps
...
fix: cap control requests and refuse file reads that never end
2026-10-11 12:39:09 -04:00
Matt
b2cf19c9fb
fix: cap control requests and refuse file reads that never end
...
The control channel read each request with no length cap, so a client sending
gigabytes without a newline made the server thread allocate until the process
was killed. Read lines against the 16 MiB cap the MCP server already uses, now
one shared constant, answer a longer one with an error and close; close a
connection after eight lines that are not JSON, serve at most sixteen
connections at once, and run at most sixty-four queued requests per frame so a
flood cannot starve drawing.
Every file command checked the size with the metadata and then read to the end.
A character device such as /dev/zero reports a length of 0, so the cap passed
and the read was unbounded; a FIFO blocked the calling thread, which over the
control channel is the thread drawing the window. vfs::read now takes the
caller's cap, refuses anything that is not a regular file before opening it,
re-checks on the handle to close the window between the two, and reads no more
than the cap plus the byte that proves it was exceeded. Callers pass the limits
they already had, and the recovery read and the CLI's own reads go through it
too. `solvecraft-cli eval /dev/zero` and a FIFO now fail at once instead of
never returning.
Fixes #147
Co-Authored-By: Claude Opus 5 <[email protected] >
(cherry picked from commit 4156e8acd11c90c435a54a3b0ccc59991db71b12)
2026-10-11 08:22:07 -07: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
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
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
736730c398
Merge pull request #122 from CypherNaught-0x/fix/loft-section-order
...
A loft gives the same body whatever the order of its sections
2026-10-11 07:57:49 -04:00
CypherNaugh_0x
4667c3a600
Fix sketch re-export ordering for rustfmt
2026-10-11 13:57:06 +02: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
CypherNaugh_0x
79753040d5
Merge upstream and update curved-cut regression for fallback diagnostics
2026-10-11 13:25:06 +02:00
bherbruck
7e4dd4fd66
Merge pull request #121 from CypherNaught-0x/fix/fillet-keeps-dimensions
...
Fillet and chamfer keep the dimensions of the corner they replace on a virtual sharp corner
2026-10-11 07:12:48 -04: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
3dc0a6024e
Merge remote-tracking branch 'origin/main' into fix/loft-section-order
...
# Conflicts:
# crates/engine/src/cmd/features_more_tests.rs
2026-10-11 13:03:56 +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
CypherNaugh_0x
c67ad22129
A sketch fillet keeps the dimensions of the corner it rounds: filleting the corner of a spout (a vertical riser and a horizontal top, the top's length dimensioned to the corner and the corner's height from the origin) dropped the height dimension with the corner point and left the length on the shortened straight part, so the top came out a fillet radius too long. Like Fusion, a corner that dimensions or constraints measure to now stays as a virtual sharp corner, a free point held on both curves' extensions (two point-on-curve constraints), with those dimensions kept and a line length to the corner turned into a distance from the line's far end to it; chamfers do the same. sketch.fillet and the chamfers report virtual_corners and moved_to_virtual_corner, and the viewport draws a virtual corner as an open square with dashed extension lines from the curves. Tests: the spout keeps its 80 x 100 size and both dimensions still drive it, the virtual corner survives save/load and undo/redo, a fillet with nothing on its corner leaves no point behind, and nearly straight or folded corners with dimensions never panic
2026-10-11 12:23:22 +02:00
CypherNaugh_0x
2406957039
A loft gives the same body whatever the order of its sections: the ruled side faces were parameterised from the first section to the last, and a loft cut that touches the body along an edge (a fall lofted from a shelled basin's whole outline down to a drain pad) worked for one order and failed for the other, with an Option::unwrap() panic inside the kernel's intersection or "shell not oriented and closed" from the planar fallback. The loft now builds its sections in one canonical order (first-to-last step with a positive largest component), so either order gives the same, working body. Tests: the basin fall cut, joined and as a new body in both orders and with the pad in every corner (engine), and the kernel loft's volume and cut in both orders, including large-below and planes facing down
2026-10-11 12:23:22 +02:00
bherbruck
a6bb8fc924
feat: stabilize face attachments and closed spline workflows
2026-10-11 05:32:46 -04:00
CypherNaugh_0x
848e7aec0e
feat: pick sketch profiles by their bounding curve ids so features keep the same region when parameters move the geometry, matching curves cut into pieces, refusing ambiguous or missing picks instead of taking another region, and storing point picks by curves
2026-10-11 10:17:25 +02:00
bherbruck
c1d819f235
feat: preserve body history and placed modelling workflows
...
Record ownership transfers in the timeline so earlier Join/Cut membership,
world placement, machining data and styles survive component moves, edits,
independent copying, undo and reopening. Preserve pending positions in history
snapshots and keep constructor transfers ordered during feature redefinition.
Retain shallow sheet pockets and exact planar intersection islands through
unfold/refold, with depth-aware flat previews and DXF export. Store explicit
3D wire coordinate spaces and migrate known legacy provenance without moving
saved points or analytic fits.
Infer unique eligible cylindrical Emboss targets, align Revolve manipulators
with actual extent geometry, and discard obsolete preview errors after input
correction. Certify constructed and immutable imported face styles using exact
source metadata while preserving legacy face names. Upgrade designs to format10
with bounded validation and geometry-preserving legacy migration.
2026-10-11 03:59:12 -04:00
bherbruck
0398a813c8
feat: strengthen sketches, feature editing, and independent assemblies
2026-10-11 02:44:31 -04:00
bherbruck
07932d0f42
feat: preserve modeling intent across sketches, assemblies, and fabrication
...
Persist typed sketch dimensions and bounded ordered configuration rules in format 8. Use exact occurrence paths and source identity for editing, movement, appearance, and mass. Preserve sheet material regions through cutting, folding, and exact DXF export; retain nested cavities and material islands.
Validation: cargo xtask ci passed, including 368 engine tests, 178 UI tests, 68 UI scenarios, 136 kernel tests, and the 10-crate wasm check. Actual preview workflows and legacy format-7 origin-corner reopening were inspected.
2026-10-11 01:28:01 -04:00
bherbruck
d71bdb78ec
feat: strengthen modeling, configuration, and assembly workflows
...
Preserve linked sketch identities through deterministic face projection and resizing. Fix origin-corner picking, persistent inline navigation, appearance editing, configuration styles, component properties, contact sweeps, sheet exports, analytic STEP offsets, and bounded rolling-ball fit accuracy.
Validated with full cargo xtask ci, native workflow screenshots, repeated enclosure replays, and analytic geometry regressions.
2026-10-11 00:37:26 -04:00
bherbruck
c1b6478ab5
fix: join additive extrusions and merge coplanar faces
2026-10-10 21:31:19 -04:00
CypherNaugh_0x
e575bded0e
Fix construction-plane references in mirror, section, and sketches ( #99 )
...
Accept construction planes by name or feature ID, preserve parametric mirror references, and reject invalid plane inputs. Retain both mirror-plane and primitive-point regression test modules after resolving the conflict with main.
Validation: cargo xtask ci passed, including 282 engine tests, 138 UI tests, 62 UI scenarios, and WebAssembly.
2026-10-10 19:20:51 -04:00
bherbruck
feaed2e3f6
Merge pull request #97 from CypherNaught-0x/fix/dimension-measured-after-solve
...
sketch.dimension reports the measured value after solving
2026-10-10 18:49:25 -04:00
CypherNaugh_0x
c61b77613a
solid.cylinder, box, sphere, torus and coil place by expressions: base, corner and center take numbers or length expressions per coordinate ("basin_width/2", "10 mm") and follow parameter changes, renames and component frames; before, a point that was not three plain numbers (or an unreadable axis) was silently replaced by the origin (or Z). The features now store the point as expressions (plain numbers still saved as numbers, so existing designs read and write the same) and evaluate it on every recompute; an unreadable or out-of-range point or axis is refused with an error. Tests: primitive points take expressions, follow parameters, renames and a moved component, and bad points are refused
2026-10-10 18:37:22 -04:00
CypherNaugh_0x
ade30e9c4e
Merge origin/main (with #86 ): sketch.dimension reports the solved value in the dimension's unit; the spout test expects the solved 30 and 60 degrees
2026-10-11 00:13:51 +02:00
CypherNaugh_0x
9c09e82cff
sketch.dimension reports measured on the solved sketch: it reported the value the geometry had before the new dimension was solved, so dimensioning a 99.84 mm trough line to 100 answered measured: 99.84 and looked like the dimension had not taken. The command now measures the new dimension again once the sketch is solved (driven dimensions too), through a new solvecraft_sketch::measure_dimension that shares the solver's own measuring. Tests: lengths, a driven distance and a diameter report their solved values
2026-10-11 00:01:19 +02:00
CypherNaugh_0x and Claude Opus 5.5
1227fab860
Extrude's start_offset says which way it goes: along the sketch normal, also with direction: negative (where a positive offset starts on the far side of the sketch from the extrusion)
...
The params doc listed start_offset? with no description, and an extrude in direction negative with a positive start offset surprised a user. The behaviour is unchanged (an offset start plane, as in Fusion); the params doc of solid.extrude and the Extent field doc say so.
Co-Authored-By: Claude Opus 5.5 <[email protected] >
2026-10-10 17:57:34 -04:00
bherbruck
6f16b31771
Fix viewport input leaking through dialogs
...
Use egui pointer ownership for viewport navigation and picking, view-cube
interaction, and sketch-dimension hover. Cover scrolling, model selection,
and cube interaction under floating dialogs, including after they close.
Shield constraint glyph and move-gizmo highlights from overlapping UI too.
Clear strict Clippy warnings and use the same saved path in the recent-file
scenario on Windows and Unix.
Fixes #87
2026-10-10 17:34:14 -04:00
CypherNaugh_0x
ab23fc9906
A failed MCP batch goes back to where it started however long the undo history is: rollback undid as many steps as the undo history had grown, but the history is capped at 200 steps, so once it was full a failed batch reported undone: 0 and left its sketches behind (an empty Sketch1, two sketches named TapHole). New commands edit.checkpoint and edit.restore_checkpoint (forget: true drops one) remember and restore the design, the active sketch and the undo history; batch takes a checkpoint before its first step, restores it on a failure and forgets it on success. Against an app without checkpoints batch falls back to counting undo steps
2026-10-10 17:21:25 -04:00
bherbruck
acf4669f73
fix: select complete circular rims and curved surfaces in 3D
...
Group kernel pieces across circular rims and hidden surface seams for hovering, selection, dialogs, and measurement. Preserve physical references and cover full-item toggling and picking with regression tests.
Fixes #88
2026-10-10 17:13:36 -04:00
bherbruck
d6cdec40da
Fix modelling regressions and reconcile WIP UI work
2026-10-10 15:37:00 -04:00
CypherNaugh_0x
49bd89de13
Parameter and feature edits report the features they restored from the evaluation cache: setting a parameter back (or a timeline.edit back) reused the earlier results for the same inputs, so the geometry changed back but recomputed said 0, which read as "nothing rebuilt". The evaluator now counts cache hits as last_restored, and parameters.change, timeline.edit, timeline.redefine and solid.press_pull on a fillet or chamfer face report it as restored next to recomputed (params docs, the MCP set_parameter description and docs/mcp.md say what each counts). Tests: setting a parameter back and a feature edit back report restored, in the evaluator and through the commands
2026-10-10 15:36:42 -04:00
CypherNaugh_0x
90ce5261b3
An angle dimension between two lines takes the reading nearest its value and reports degrees: without text_at the angle was measured between the lines' directions, so a riser pointing up and an outlet pointing down-left (meeting at 30°, directions 150° apart) asked for 30° swung the outlet round by 120°, which the fillets between them could not follow, and the dimension was refused as over-constraining with a degree of freedom left. Two lines make two angles, θ and 180° − θ; the dimension now takes the one nearer the value (the acute one without a value), and text_at still picks a sector. sketch.dimension reports measured in the dimension's unit (deg for angles, mm for lengths) with a unit field, instead of radians for angles
2026-10-10 14:57:56 -04:00
CypherNaugh_0x
81be4e74b8
browser.visibility hides and shows sketches, bodies, construction geometry and origin items (items: ids or names, or a whole folder; visible: bool), so agents can hide helper sketches over MCP. What is hidden moved from the egui UI state into the engine session (view state: not saved, not an undo step); the desktop eye toggles and menus use it, headless renders and fit leave hidden items out, and document.inspect, sketch.inspect and ui.inspect report visibility. ui.set still accepts hiddenBodies, hiddenOrigin, hiddenSketches and shownSketches. Tests: helper sketches hide and show in the engine (hostile input changes nothing) and through MCP only
2026-10-10 14:33:56 -04:00
CypherNaugh_0x
9a22d9df92
Section Analysis takes a world coordinate: inspect.section {plane, at} places the cut at that coordinate on the named plane's axis (XY: Z, XZ: Y, YZ: X), so XZ's -Y normal no longer flips the sign; the params doc gives each named plane's normal; the result reports axis and at for named planes. at with offset, or with an {origin, normal} plane, is an error
2026-10-10 12:29:46 -04:00
CypherNaugh_0x
5d5ff44db2
Drawing connects to existing points: a new point landing exactly on an existing point (the origin too) gets a coincident constraint in the engine, for every drawing command and every caller (MCP, scripts, clicks), in the same undo step; connect: false opts out. Re-tying an existing coincident returns it ("existing": true) instead of failing; the UI's after-the-fact tie_snaps is gone
2026-10-10 12:08:19 -04:00
CypherNaugh_0x
49d6682fe7
Rectangles name their sides and corners: sketch.rectangle.two_point and .center return sides {bottom, right, top, left} (line ids) and corners {bottom_left, bottom_right, top_right, top_left} (point ids), so they can be dimensioned without a sketch.inspect round trip
2026-10-10 11:14:03 -04:00
bherbruck and Claude Opus 5.5
9d3cbb4acc
Browser fold arrows: each row is one widget with a stable id, and where the click lands decides what it does (fold arrow with padding, eye, radio, or the row), so an arrow click toggles without also selecting or picking the row or starting a drag; Collapse/Expand tips; ui.at {browser|chevron} and ui.browser for automation; scenario browser_chevrons clicks every folder's arrow (document settings, named views, origin, groups, sketches, construction, canvases, components, bodies, the design) and checks the children; the inch-width units test runs now that params reads unit-less lengths in design units
...
Co-Authored-By: Claude Opus 5.5 <[email protected] >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-10 07:19:58 +00:00