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.
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.
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.
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 <noreply@anthropic.com>
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
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
kernel::fillet_variable_points(body, edge, start, [(position, radius)...], smooth): the radius law is a B-spline of the edge parameter (straight pieces, or C1 cubic pieces with Catmull-Rom slopes), and since every section's arc is affine in its radius the blend is exactly a rational B-spline (degree 2 across, the law's degree along) with B-spline contact curves on the faces. The largest radius along the edge decides whether the blend fits. Fillet type variable takes mid: [[position, radius expr], ...] and smooth; middle radii are parameters of the feature (Mid radius) and follow user parameters. Tests: straight pieces against (1 - pi/4) L (a^2 + ab + b^2) / 3 per piece, smooth against the integrated law, either end as start, refusals; engine test with a parameter-driven middle radius.
Refs #9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
- solvecraft-cli fuzz / fuzz-one: seeded random modelling sessions (boxes, extruded profiles with arcs, revolves; joins and cuts of boxes, cylinders and spheres, fillets, chamfers, shells, holes, patterns) on a grid that makes coincident faces and tangencies common, every step checked (command ok, every body a sound solid via the new Body::validity, volume moving the right way), plus the boolean volume identity on random primitives; one process per seed with a time limit; failures minimised to scripts
- shell/offset: corners where a curved face meets another at an angle are refined onto the moved surfaces (Newton); edges that are neither lines nor arcs are rebuilt through their moved points; one shell per piece; faces that would cross say so (not supported yet) instead of leaving a cavity inside out; flat revolved faces count as planes; the unhealed body is tried when the healed one fails
- cylinders start their seams at an odd angle (grid-aligned seams broke booleans along them)
- partial revolves of profiles touching the axis build no zero-area face on the axis
- booleans on bodies in several pieces retry a piece at a time
- regression tests for each, and a fixed set of seeds in cargo test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
The old ids live only in crates/engine/src/legacy_ids.rs (the legacy migration table): find_command maps them, so old scripts, recipes and control calls keep working, and saved shortcuts, recent and pinned commands are migrated on load (designs store no command ids). Parity maps the observed catalog ids to ours through xtask/data/fusion-ids.tsv. The agent rule now reads: our own dotted id, never another product's. Cargo.toml's repository points at github.com/bherbruck/solvecraft.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New kernel file blend_variable.rs. The hooks into blend.rs are visibility
only: plane_normal, vtx, rebuild_face and unsupported are now pub(crate).
- fillet_variable(body, edge, start, r0, r1) works on the same edge
configuration as the constant fillet (straight edge, planar faces, end
faces square to it). The radius runs linearly from the end nearest
`start`, and every section square to the edge is a circular arc. The
blend is an exact degree (2, 1) rational B-spline: arc control points
move linearly.
- fillet_chord(body, edges, chord): the radius per edge comes from its
face angle (chord = 2 r cos(phi/2)).
Fillet feature: style constant | chord | variable {radius2, start};
FusionFilletEdgesCommand takes type, radius2 and start.
Tests:
- Variable 2 -> 5 on a box edge removes (1 - pi/4) L (r0^2 + r0 r1 + r1^2)/3.
Starting from the other end gives the same solid; equal radii give the
constant fillet; too large is refused.
- Chord 4 on a right angle equals radius 4/sqrt(2).
- Engine: both types by command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
- solvecraft_io::vfs: the engine's file access (disk natively; in the browser an in-memory set of
files the host loads and stores). File commands and write_atomic go through it.
- Web host (apps/solvecraft-web/src/files.rs): stored designs are read from OPFS at start
(storage.persist() asked for) and written back when a command writes one; Save/Save As keep
designs in the browser, exports (STEP, STL, 3MF, OBJ, ...) download as files.
- File > Open shows "Files in this browser": open, insert, rename, download, delete, plus open or
insert from the computer (showOpenFilePicker where there is one, an <input type=file>
otherwise). Files dropped on the page are inserted or opened.
- Unsaved work is autosaved to OPFS and offered again after a reload or crash.
- Start page recents come from the stored designs, with thumbnails. In the browser the samples
are built when opened (a picture blocks the page there, and a kernel panic can't be caught).
- Pages without OPFS (http on a network address, old browsers) keep designs in local storage.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL