Commit Graph
20 Commits
Author SHA1 Message Date
Que 1cc65cbc91 fix: a lip swept flush around a rounded rim joins the body it sits on (#1164)
fix: a lip swept flush around a rounded rim joins the body it sits on.
2026-10-14 18:49:45 -04:00
bherbruckandClaude Opus 5.5 9b0f028f13 STEP assemblies: mesh a repeated part once and place it for its instances (#1152)
The reader converts each item once, but every instance made its own display mesh
(tessellation, seam and tangent flags), the most expensive step of opening a large
assembly. A later instance of an item now shows its first instance's mesh, placed by
the difference of the two placements. Only rigid placements share; split lines and
any operation drop the link. Measurements and export read each instance's own
geometry, so eval output is unchanged.

Generated assemblies: mesh phase 2,215 -> 139 ms (901 bodies) and 1,028 -> 85 ms
(5,401 bodies), with the same triangle counts.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-14 14:23:33 -04:00
froglemonade2 c3e0ea498a fix: joins, cuts and sketch profiles where outlines touch at a point (#841)
Fixes #588.
2026-10-13 16:33:24 -04:00
SahenandClaude Opus 5.5 2bb24d1d2a perf: prism pairs before the mesh, bodies measured once, and a STEP import that copies less (#714)
A cut or an intersection between prisms (a plate and the tools through it) is now decided in 2D before either operand is meshed. A body's size and volume are measured once, a placement reads its orientation from its matrix, the evaluation cache is bounded to 64 MiB, and STEP import copies fewer shells. Hole plates evaluate 20-30% faster with less memory, and models are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 10:55:56 -04:00
bherbruckandClaude Opus 5.5 add4a18961 fix: fuse bodies that touch back to back over part of a face (#679, #674) (#704)
Two L's extruded up and down from one 2 x 2 grid now join into one solid (the planar rebuild gives each fan of faces around a pinched vertex its own vertex copy), and a pad whose end lies half past the edge of the face it stands on fuses exactly: contact faces are imprinted with each other's outline and the common faces glued away, still held to the retry guard. Face splitting handles a line crossing an edge twice; glue matches differently parametrised curves and keeps several pieces apart. Robustness seed 16 now fuses with the exact volume.

Fixes #679, fixes #674.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 10:02:44 -04:00
bherbruckandClaude Opus 5.5 296683229d Rename SolveCraft to SolidCraft everywhere, with compatibility shims (#389)
* WIP deep rename (not for push)

* WIP2

* WIP3

* WIP4 wxs fix

* rustfmt

* Rename the remaining identifiers in merged crash-report code

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 17:17:01 -04:00
Iraklis KourtisandClaude Opus 5.5 08d7037176 feat(kernel): modifiers report exact face and edge history
Fillets (local, loop, rolling ball, corner, variable, chord), chamfers
(cutters, local corners, loops, two sides), shell, draft, offset faces,
split face/body, delete face, patch/copy/stitch/trim/extend and
transforms record their history over [body] while they build: faces
rebuilt from the body's, blends in place of edges (corner patches in
place of the edges at the corner), shell walls as offsets, edges as
pieces of the body's or where two faces meet. Multi-step operations
compose each step. The push-face offset fallback now has history, and
the bore union composes its narrowed tool.

A reflection reorders a body's edges, so transforms now match edges by
identity (mirrored copies reported the wrong edges).

Refs #136

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 c87efa1f35 feat(kernel): exact face and edge history model
Bodies can now carry the exact history of the operation that made them:
for each result face its origins among the operation's operands (kept,
modified, split, merged, or generated from a profile segment, cap, edge or
offset) and for each edge the faces it separates and the operand edge or
face pair it came from. History is recorded by the operation, never
sampled, and checked against the body when attached.

- history.rs: the vocabulary (moved from provenance.rs), History::check,
  identity, substitute (composes an operation with the one that made an
  operand, including bodies made from a sketch) and face-source propagation.
- One edge order for a body (body::edge_order), shared by tessellation and
  history, so history edge indices are the mesh's edge indices.
- Transforms report an identity history; placed_topology documents the
  face/edge order guarantee it relies on.
- provenance.rs keeps the geometric trace for operations that do not yet
  report history.

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
bherbruck c53aff7592 Fix artificial Shell wall splits on stepped bodies 2026-10-11 22:32:53 -04: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 4b7e1d317d fix: load designs off-thread and cache recent thumbnails as PNGs 2026-10-10 20:55:14 -04:00
bherbruck d6cdec40da Fix modelling regressions and reconcile WIP UI work 2026-10-10 15:37:00 -04:00
bherbruckandClaude Opus 5.5 1bf377c14b No panics in the boolean's final assembly (the web build aborts on any panic: the Plastic Enclosure sample panicked 8 times and crashed the browser's start page); face pushes check their result and fall back to the general offset (a boss standing on a plate joins again with off-axis cylinder seams); offset errors name the face they can't move; docs/robustness.md with the before and after rates; caught panics counted per design in the robustness runs
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-10 00:04:37 +00:00
bherbruckandClaude Opus 5.5 4c8f080691 Faces split on purpose stay split: the body remembers its Split Face lines, export and healing keep the pieces apart
Split Face records the new edges as polylines on the body (Body::split_lines); the document carries them through later features. STEP export no longer joins pieces of one surface across such a line, and healing (fillets, chamfers, booleans, shell, draft) no longer merges coplanar pieces there, while incidental pieces (boolean leftovers, seam halves) still merge as before. Tests: plane and cylinder splits keep their face count through a STEP round trip (and join without the record), a second split keeps both lines, and an engine test exports a split box after a fillet with 8 faces.

Fixes #11

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
2026-10-09 21:31:16 +00:00
bherbruckandClaude Opus 5.5 740360d7c3 Fillet corners: a radius per edge (kernel::fillet_radii), rounds next to earlier rounds of another radius, and smooth corner patches where three rounds meet
blend_corner.rs rebuilds the planar faces at the ends of the filleted edges (three planar faces and three straight edges at each such vertex) and keeps the rest. One round at a vertex ends in the third face's exact section of its cylinder; two rounds with the third edge sharp trim each other (rolling ball: the crease from where their contact lines cross to the third edge for equal radii, else to the smaller round's contact line on the face that ends the larger one, which gets the exact section between); three rounds meet a sphere for equal radii, else a rational degree-4 patch through plane sections of the cylinders, the sections turned so that the cylinders' curvatures agree where two meet on a face and the patch fitted tangent to all three (within 0.01 degrees) and to the face at its closed corner.

kernel::fillet falls back to it when the local blends refuse: an edge that ends on an earlier round (any radius) takes the round off (delete_faces) and blends both edges together, so r3 next to r2 and a third edge into a mitred pair work. delete_faces: a gap stretch along several deleted faces keeps the corners between them (two rounds meeting in a mitre come off back to the sharp corner). splitface::fit is shared for the crease.

Tests: volumes against the strips-minus-overlap reference (exact strips, overlap integrated; checked against an independent 1D integral), the sphere-octant formula for three equal rounds, tangency along the patch, closed meshes, refusals without panics.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 22:37:29 +00:00
bherbruckandClaude Opus 5.5 7027382667 split_faces: exact sketch segments, a face map, and misses named
For solvecraft-params' Split Face feature:
- Sketch tools are chains of Seg2. A single line splits by its plane and a
  single arc by its cylinder, exactly (a circular edge on a planar face);
  longer chains and splines follow the curve.
- split_faces_with_map gives the source face of each face of the result.
- A listed face the tool misses is an error naming it (split_any keeps
  the lenient form for Trim).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 19:49:50 +00:00
bherbruckandClaude Opus 5.5 dd6c8e1a6b Surface bodies: Patch, Stitch, Trim and Thicken
Kernel (surfaces):
- Bodies with an open shell are surface bodies (Body::is_surface).
- patch_region: a planar patch of a sketch region. patch_edges: a planar
  patch filling a closed loop of a body's edges.
- copy_faces: faces copied out as a surface.
- stitch: sew surfaces along coinciding edges, turning faces to agree; the
  result is a solid when it closes.
- trim: cut a surface by a plane or face and keep one side.
- thicken: offset planar and circular-cylindrical faces along their
  normals (one side or symmetric) into a solid. Plane copies slide;
  cylinder copies scale about the axis, exact for NURBS circles. Free
  edges get ruled walls. Faces meeting at a sharp edge are refused.

Doc features Patch, Stitch, Thicken (with operations) and SurfaceTrim;
engine commands FusionSurfacePatchCommand, FusionSurfaceStitchCommand,
FusionSurfaceThickenCommand and FusionSurfaceTrimCommand.

Tests (volumes):
- A 10x10 patch thickened by 2 gives 200, also symmetric.
- Half a cylinder side thickened outward gives half a ring; both halves
  inward give the full ring.
- Six faces of a box stitched back give 6000; an open box with its top
  patched from the edges, stitched, gives 6000.
- Trim keeps 30 or 70 of 100.
- Engine: patch, trim, thicken gives 140.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 17:31:57 +00:00
bherbruckandClaude Opus 5.5 34be218639 Kernel: split a body by a plane or another face's surface
split_body(body, tool) divides every face where the tool meets it and
closes each side with the piece of the tool surface inside the body.
- Patches have outer loops and holes.
- Bands go round a cylinder or another surface of revolution.
- Each side falls apart into its connected parts.
- A body the tool misses comes back whole.

Faces that are B-spline sheets but really planes or circular cylinders
(extruded faces) split as the whole plane or cylinder: the tool is
extended, and the field is exact and cheap.

Tests (volumes): a box split by a plane (2400/3600); a holed plate split
through its hole into two equal halves; a box split by a cylinder's side
into the core (pi*16*30) and the rest; a plane that misses.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 17:31:57 +00:00
bherbruckandClaude Opus 5.5 69d7bcfe7d split_faces: faces chosen by position stay chosen when a neighbour's split cuts their edges
A face whose edges were cut by an earlier split got a new identity and was
skipped. Chosen faces are now tracked by position through each split.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 17:31:57 +00:00
bherbruckandClaude Opus 5.5 f8a4ffbc67 Kernel: split faces by a plane, another face's surface or sketch curves
split_faces(body, faces, tool) divides the chosen faces where the tool
meets them and leaves the solid unchanged. It handles:
- lines across a face;
- closed lines inside a face (a disc inside a ring);
- lines that run into a hole (the face is divided around it).
Edges the line ends on are cut in every face that uses them. The tool's
zero set is traced on a finely divided triangulation of the face, each
point is placed exactly on the surface by bisection in its parameters,
the ends are placed exactly on the boundary edges, and a cubic is fitted
through the points (a line when they are straight).

Tests: a box top split by a plane (areas 80/120, later booleans still
work); a cylinder side split by a sketch line; a cylinder top split in
ring and disc by a smaller cylinder's face; a plate top split through
its hole into two equal halves; a tool that misses is an error. Volume
and area are unchanged in every case.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 17:31:57 +00:00