Commit Graph
495 Commits
Author SHA1 Message Date
lucas-aguilar89andClaude Opus 5.5 8eda982489 Pattern and Mirror dialogs copy picked bodies, fillets included (#193)
With Object Type = Bodies, the Mirror, Rectangular Pattern and Circular
Pattern dialogs sent the feature that created each picked body
({"features": ["Extrude1"]}), so the copies replayed only that feature and
lost everything done to the body afterwards (a fillet, a chamfer, a cut).
They now send the bodies themselves ({"bodies": [...]}), which the commands
already support and the Path Pattern dialog already did. Picking Features
is unchanged.

Editing a body Mirror or Pattern from the timeline now reopens the dialog
with its bodies selected.

Copies made this way take the body-copy names ("Body1 (2)"), as the
commands already give; pattern_direction_edge now looks up "Body1 (3)".

Tests: UI scenarios mirror_body_keeps_fillets and pattern_body_keeps_fillets
(filleted cube, copy and edit through the dialogs); both fail without the
fix with the copies' sharp 8000 mm3 volume.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 10:06:18 -04:00
lucas-aguilar89andClaude Opus 5.5 cab698bf12 Offset Plane from a planar body face (#167)
construct.plane.offset now takes a planar face as its base
({"face": [x,y,z], body?, index?, path?}), captured with the same exact
face attachment a sketch on that face uses. The Offset Plane dialog accepts
planar faces as well as origin and construction planes.

A construction plane on a face is resolved through its face anchor when the
timeline is evaluated, so it follows the face when upstream features change
(and after reopening), instead of keeping the plane as it was when picked.

Tests: engine (top and side faces, follows a box resize, survives reopen,
hostile picks are refused without adding a feature) and a UI scenario that
picks a face in the dialog and builds a pad on the new plane.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 10:06:10 -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
lillith 8c13914d6c Ignore repeated initial sketch points while drawing 2026-10-12 09:30:18 -04:00
lillith 732447d2dc Fix dialog header chevrons to collapse and restore forms 2026-10-12 09:08:31 -04:00
lillith db0a2a007a Apply remaining sketch constraints to complete preselection 2026-10-12 08:48:05 -04:00
lillith ed102b5393 fix: reject degenerate boolean intersection polylines 2026-10-12 08:36:40 -04:00
ich777 53b092d287 feat: add German (de) UI localization
Adds German (Deutsch) as a third UI language, following the procedure outlined in docs/localization.md
2026-10-12 08:10:14 +02:00
bherbruck c53aff7592 Fix artificial Shell wall splits on stepped bodies 2026-10-11 22:32:53 -04:00
bherbruck 13aac4296d Keep prepared assembly geometry through selection changes 2026-10-11 21:59:33 -04:00
bherbruck ff9653a353 Merge current main into wheel zoom smoothing option 2026-10-11 20:36:16 -04:00
bherbruck 400f200efa Speed up cold document geometry rebuilds 2026-10-11 20:22:19 -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 78aa2aacfb Resolve #159 against current sketch preselection 2026-10-11 17:23:12 -04:00
bherbruck 8cce89d78a Merge pull request #189: add Windows SpaceMouse navigation 2026-10-11 17:04:47 -04:00
bherbruck 6ce472c29e Integrate current main before app icon merge 2026-10-11 16:48:45 -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 3f1b07d35c Merge pull request #181 from Koschtetnix/feat/tool-select-highlight
feat: highlight active tool or dialog in toolbar
2026-10-11 16:45:52 -04:00
bherbruck f6e7d754e5 Merge pull request #192: update app and package icons 2026-10-11 16:44:56 -04:00
bherbruck 6c06168fa7 Merge pull request #184 from tbreckle/fix/175-glyphs-clear-of-dimensions
fix(sketch): constraint glyphs move off dimension values
2026-10-11 16:44:49 -04:00
bherbruck af536a7907 Rename displayed product to SolidCraft and add header bug reporting 2026-10-11 16:16:48 -04:00
kenos ee1b56cac4 feat: add Windows SpaceNavigator navigation 2026-10-12 05:07:44 +09:00
NAX LAB 35555c0b9f Merge branch 'bherbruck:main' into main 2026-10-11 15:41:26 -04:00
bherbruck 1d3048062d Merge pull request #178 from 0xlillith/fix/sketch-dimension-placement-preview
fix: preview sketch dimensions before the placement click
2026-10-11 15:33:15 -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
NAX LAB 33f0b9e3cc Updated Logo 2026-10-11 15:28:45 -04:00
bherbruck ef8f6ca6f9 fix: restore shell and cut wall topology in 0.2.1 2026-10-11 15:17:05 -04:00
tbreckleandClaude Opus 5.5 cb5144b6e2 fix(sketch): constraint glyphs move off dimension values
A horizontal or vertical glyph sat beside its line on a fixed side, so a
dimension placed on that side drew its value box on top of the glyph.
A glyph that would overlap a dimension's value now goes to the other side
of its line, or steps along it when both sides are taken.

The scenario `glyphs` check also fails when a glyph overlaps a dimension
value; constraint_glyphs_clear_of_dimensions covers it.

Fixes #175

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 21:14:02 +02:00
lillith cc2ee6a0f9 fix: apply point constraints to sketch preselection 2026-10-11 20:52:48 +02:00
Koschtetnix 9bfd1158d0 feat: highlight active tool or dialog in toolbar 2026-10-11 20:50:43 +02:00
lillith 58c0ed8a90 fix: preview sketch dimensions before placement 2026-10-11 20:45:04 +02: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
lillith 4c6afc6ba4 test: avoid wall-clock assertions in import budget regressions 2026-10-11 19:23:13 +02:00
lillith 09bf9cafdf fix: apply horizontal and vertical constraints to preselection 2026-10-11 18:51:34 +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
bherbruck 2eee967d40 Merge pull request #154 from EmDecay/fix/146-step-iges-expansions
fix: bound four unbounded expansions in STEP and IGES import
2026-10-11 12:38:30 -04:00
bherbruck 6140f89a42 Merge pull request #153 from EmDecay/fix/145-sketch-size-caps
fix: hold the sketch caps at design load and bound the solver per component
2026-10-11 12:38:00 -04:00
bherbruck 66f351e93b Merge pull request #152 from EmDecay/fix/144-import-work-budgets
fix: budget the work 3MF and DXF import does, not only its output
2026-10-11 12:37:23 -04:00
bherbruck 5b54275626 Merge pull request #151 from EmDecay/fix/143-construction-plane-recursion
fix: continue the plane depth count through model geometry
2026-10-11 12:36:25 -04:00
bherbruck 2f78d3ef81 Merge pull request #149 from jyviko/fix/join-merges-met-bodies
Join merges every body the tool meets
2026-10-11 11:36:27 -04:00
Matt 78f80143d5 fix: hold the sketch caps at design load and bound the solver per component
Nothing on the load path checked a sketch's size, and every sketch in the
timeline is solved when a design opens. The solver sizes its dense matrices by
the connected component, so a 30 MB file with 200,000 chained points asked the
allocator for terabytes and the process aborted, which no panic guard can
intercept.

Reject an oversized sketch while the design is still raw JSON, so the typed
arrays are never built, and refuse a connected component with more variables
than fits in a bounded matrix: that component now reports a failed solve and
leaves its geometry alone. 10,000 chained points went from 9.6 GB and 25
seconds to a failed solve in well under a second.

Fixes #145

Co-Authored-By: Claude Opus 5 <[email protected]>
(cherry picked from commit 04abbf95c26f68c7d0a126ed9e2827049f593361)
2026-10-11 08:22:11 -07: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
Matt b5fb86f245 fix: bound four unbounded expansions in STEP and IGES import
Each of these asks the allocator for tens of gigabytes, or runs for hours, from
a file of a few kilobytes to a few megabytes. An allocation failure is an abort,
so no panic guard can report it and the user's unsaved work is gone.

- IGES composite curves (102) name their children by pointer, and a tree whose
  every node names the same child twice fans out to 2^30 leaf visits under the
  depth cap. Count the entities visited and the segments produced against one
  budget, since a node that yields no segment trips no bound on the output, and
  refuse a composite curve that contains itself.
- IGES directory entries could all name the same parameter range, each
  materialising it as its own string and token list. Keep the total text
  proportional to the parameter section the file carries.
- STEP knot multiplicities were expanded into one value each before the knot
  count was compared with the control points: 20 million knots of multiplicity
  64 built a 10 GB vector only to be rejected. Check the sum first.
- One STEP face could list any number of boundary loops, each cloning its edge
  handles into a new wire that the face extent then samples. Cap the loops and
  the edges they hold; 100,000 bounds went from 2.1 GB to an immediate error.

Also guard the IGES translation, which was the one importer stage outside every
panic guard, keep the vertex-sewing bucket key clear of the overflow its
neighbour lookup caused for coordinates near f64's range, and count how often a
loop passes each vertex once instead of once per edge.

Fixes #146

Co-Authored-By: Claude Opus 5 <[email protected]>
(cherry picked from commit c32792b71c76d74348ad5002d8d2da870937e58e)
2026-10-11 08:22:07 -07:00
Matt a03e4b9413 fix: budget the work 3MF and DXF import does, not only its output
3MF: flatten budgeted triangles but copied the whole vertex array for every
placement, so an object with 100,000 vertices and one triangle placed by 500
build items reached 6.8 GB resident, and 10,000 items (still a ~200 KB file)
asked for about 140 GB and aborted on the allocation. Copy only the vertices
the triangles reach, keeping their relative order so an ordinary mesh is
numbered as it was in the file.

DXF: every bound in convert was on the geometry that comes out, and a block
that emits none tripped none of them. Six self-inserts in one empty block fan
out to 6^16 visits, and a 176-byte file never returned. Count entities visited
and array cells placed against a work budget, skip the array loop for a block
with no geometry, and bound the array size on its own.

Fixes #144

Co-Authored-By: Claude Opus 5 <[email protected]>
(cherry picked from commit 3bf3b68a1340d9bdef8dcefd6c4fb5a7cae6eec4)
2026-10-11 08:22:07 -07:00
Matt 0b5e15e2b9 fix: continue the plane depth count through model geometry
A construction plane built from model geometry resolves each of its sides
through the document again. That hop restarted the recursion depth at 0, so a
plane that is its own side never exceeded depth 1 and the 32-level cap never
fired: a ~600-byte design file recursed until the stack overflowed and the
process aborted, which no panic guard can intercept.

Carry the depth on the construction context so the geometry arms continue the
caller's count instead of restarting it.

Fixes #143

Co-Authored-By: Claude Opus 5 <[email protected]>
(cherry picked from commit 4bca1d49f27dfe9ef0140132746e1c7415daba8e)
2026-10-11 08:22:07 -07:00