Commit Graph
22 Commits
Author SHA1 Message Date
Erikas d8a088f46a STEP export: a half-turn arc end as a cylinder, and cut faces' sheets bounded by their faces (#1198) (#1438)
STEP export writes a half-turn arc end as a cylinder, and cut faces' sheets bounded by their faces (#1198).
2026-10-15 13:31:46 -04:00
bherbruckandClaude Opus 5.5 4c7ea34a68 Web app: open and insert STEP files over frames, with progress and Cancel (#1376) (#1424)
* Web app: read a STEP file a piece per frame, with progress and Cancel (#1376)

The kernel's STEP reader walks the file first and converts its solids afterwards,
and StepReading exposes those stages: parse and walk, then convert a solid (or a
batch) per step, then finish into the shared import cache. The web app's file
load drives it from the frame loop for about 30 ms a frame, shows the same
progress card and Cancel as the desktop, and then runs the insert or open, which
finds the file already read. The desktop path is unchanged in behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Web app: make the imported bodies' meshes a few per frame too (#1376)

After the read, the insert or open runs, and then the bodies' display meshes are
made a frame's worth at a time ("Preparing the view"), as the desktop worker
warms them, instead of all in the first frame that draws the design.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:28:09 -04:00
NOWN-DEV 0ee5e97db5 STEP import takes up for Y-up files and names for the bodies' names (#1312)
file.insert_step and doc.open on a STEP file take `up` (turn a Y-up file so its up is +Z) and `names` (names for the imported bodies). The MCP tool and the app's control requests pass them through; an import without them works as before. Tests in the kernel's STEP reader, the engine, MCP and the file-load UI; docs/step-import.md and docs/mcp.md describe both.
2026-10-15 02:18:55 -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 <noreply@anthropic.com>
2026-10-14 14:23:33 -04:00
Erikas 2e6951135a STEP export: extruded arcs, straight rounds and countersinks as cylinders and cones (#612) (#1139)
Ruled B-spline sheets that are circular cylinders or cones are written as CYLINDRICAL_SURFACE and CONICAL_SURFACE, so other readers no longer bound the part by sheets that reach past its faces.
2026-10-14 13:40:10 -04:00
bherbruck 2f91338d3d Large STEP imports: no more multi-minute hang, shared STEP text, cancel and progress (#925) 2026-10-14 05:01:12 -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 <noreply@anthropic.com>
2026-10-13 10:55:56 -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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:17:01 -04:00
selune 65a99608d9 Prepare independent STEP bodies concurrently on desktop (#312) 2026-10-12 11:46:32 -04:00
lillith 4c6afc6ba4 test: avoid wall-clock assertions in import budget regressions 2026-10-11 19:23:13 +02: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 <noreply@anthropic.com>
(cherry picked from commit c32792b71c76d74348ad5002d8d2da870937e58e)
2026-10-11 08:22:07 -07: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
bherbruckandClaude Opus 5.5 0a1b6f0fff STEP export: pieces of a plane or extruded cylinder written as one face
Fusion round trip WARNs on face counts:
- 48: the pulley's annular end faces arrived as 240° and 120° sectors.
- 54: the side faces and holes of a body glued to its mirror image came
  in halves.

Changes:
- Planes merge: PLANE faces and flat B-spline sheets, as well as revolved
  planes. A plane keeps several loops (an annulus, a face with holes), no
  seam. Flat B-spline sheets are written as PLANE.
- Pieces of an extruded cylinder (B-spline sheets) merge when their edges
  are circles square to the axis. The merged face is written as a
  CYLINDRICAL_SURFACE, with its parameter seam on the face's seam edge.
- A full turn's loop is built explicitly: ring, seam, other ring (or the
  apex on the axis), seam back. Before, it depended on edge order, and
  after 81c85b5 the pulley's last pieces no longer merged.
- The read-back check moved to the whole file. If the merged file reads
  with warnings and the unmerged one does not, the unmerged one is
  written.

Results: 48 has 12 faces (Fusion 12), 54 has 12 (Fusion 12). Oracle
results are unchanged (73 PASS) and the STEP corpus passes 76/76. New
test: a plate with a hole glued to its mirror exports 8 faces, all
planes and cylinders, and round-trips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 13:16:39 +00:00
bherbruckandClaude Opus 5.5 81c85b553c Booleans are deterministic: result faces keep their shell's order
truck's connected components came out in hash order of face addresses, so a
boolean's faces, and everything built on them (fillet bands, STEP entity
order), changed from run to run. That made the oracle 35 export differ run to
run. Its old step_export flakes came from the orientation check's drifting
search, removed in 2db9e66. The result's shells and faces now keep the
order of the shell they come from (vendored truck-shapeops). Oracle results
are unchanged (73 PASS before and after). Test: the tee of oracle 35 with its
junction fillet exports byte-identical three times in one process (it failed
before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 09:53:16 +00:00
bherbruckandClaude Opus 5.5 b4c7177589 STEP test hostile_boundaries_mesh_in_bounded_time: 12x12 patch, as agreed with solvecraft-step (still a 180 s hang bound)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 06:15:33 +00:00
bherbruckandClaude Opus 5.5 d44a104dcc STEP test hostile_boundaries_mesh_in_bounded_time: smaller wild patch (16x16) and a 180 s bound, so it catches hangs without failing on a loaded machine (11 s now, was ~50 s against a 60 s bound)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 05:05:34 +00:00
bherbruckandClaude Opus 5.5 7382ebd6e8 STEP export: Fusion round-trip fixes (sense, analytic surfaces, horn torus)
- Surfaces of revolution follow ISO 10303-42 strictly in reader and writer: the
  normal is d/d(angle) x d/d(profile), the opposite of truck's revolution, as
  Fusion reads it (fixes Fusion inverting fillet sphere corners and the dimple).
  step_orientation_errors flags faces whose loop runs clockwise round their
  normal; engine, oracle and kernel round trips assert it.
- Revolved faces with analytic profiles are written as native PLANE,
  CYLINDRICAL/CONICAL/SPHERICAL/TOROIDAL surfaces, and the pieces truck splits
  a revolution into are merged back into one face per surface (with a seam
  edge for full turns), so face counts match other systems.
- A horn torus (tight sweep: tube touching its axis) is written as one rational
  B-spline face whose loop passes the pole twice, with truck's zero-length pole
  edges collapsed, instead of a degenerate surface of revolution; the reader
  starts such figure-eight loops off the pole (Fusion's own part 50 now imports
  with the right volume).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 04:23:46 +00:00
bherbruckandClaude Opus 5.5 1c10d1e56a STEP import: 65/66 Fusion files; bounded meshing
Meshing (vendored truck-meshalgo) works within a budget so hostile files
cannot hang: bounded edge and surface divisions (point caps, depth and
round limits, NaN-safe), and a grid budget per face shared out per shell.
Surface grids refine only the direction that bends; rulings left undivided
get cells comparable to the other direction, so trimmed cylinders (holes,
tee joints) no longer lose volume to long triangles. The helical sweep
imports in 12 s instead of 7 minutes.

Small sphere patches get poles away from them even when the file runs a
seam through the patch (a pyramid's corner blend). Faces the mesher cannot
mesh are reported as import warnings. Test: wild B-spline and far-off
boundaries import in bounded time.

STEP corpus 65/66 (50-sweep-tight-bend: a horn-torus bend whose inner side
collapses to a point; Fusion's own area for it is also off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 01:28:16 +00:00
bherbruckandClaude Opus 5.5 9330ee5698 STEP export: AP242 file of our own, names, colours, components as assemblies
Our writer assembles the file: AP242 header and contexts, a product per part
(or per component, with NEXT_ASSEMBLY_USAGE_OCCURRENCE and item-defined
placements per occurrence), named solids, surface colours as styled items,
ADVANCED_FACE for advanced breps. truck now writes only each body's B-rep,
which we copy in; identical geometric entities are written once and shared.
Designs with components export as assemblies (bodies in component frames).

step_validate also rejects unreferenced non-root entities. Tests: the sample
plate and a component assembly export, validate and read back with no
warnings and the same volume, area and face counts; the oracle replay checks
area and faces too (39 rebuildable cases pass). An independent Part 21
parser (step-p21, run outside the repo) accepts our exports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 00:16:52 +00:00
bherbruckandClaude Opus 5.5 08cf223ced STEP export: unique ids, plain curves, right revolution senses; seams on split faces
Vendored truck-stepio (writer only): an intersection curve's second surface
was written at the first one's id (duplicate ids for every boolean edge),
and revolved surfaces lost their orientation (the modeling-surface sense was
always true; inverted or mirrored revolutions came out inside out). Export
now writes intersection edges as C1 cubic B-splines through exact points,
so files carry plain 3D curves and no redundant surfaces.

Vendored truck-meshalgo: hinted parameter searches that run off a B-spline's
domain are rejected or clamped (meshing their grid never finished).

STEP import: straight revolution profiles are bounded in the meridian plane
and stop at the axis; loops on revolutions start away from the axis; face
extents include edge end points. Edges between pieces of one split surface
draw as seams.

kernel::step_validate checks a STEP file (duplicate ids, dangling
references, dense numbering); the oracle replay now exports every rebuilt
part, validates it and re-imports it with no warnings and the same volume
(all 32 rebuildable cases pass).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 23:40:07 +00:00
bherbruckandClaude Opus 5.5 b8d0fcc8e2 STEP: bound assembly traversal, name imports after a lone body
A visit budget stops shared sub-assemblies from growing exponentially (with
a test); the loose-solid pass gets its own budget. An Import feature is
named after the root product, else its only body, else the file. Restores
a test function closed off by the rebase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 21:01:04 +00:00
bherbruckandClaude Opus 5.5 ed611ed7ba STEP: reader
Own ISO 10303-21 parser and AP203/AP214/AP242 geometry reader in the kernel
(step_import): planes, cylinders, cones, spheres, tori, B-spline and rational
surfaces, surfaces of revolution/extrusion; lines, conics, B-spline curves;
breps with voids, faceted breps, shell models; units (SI prefixes, conversion
based), product names, colours, assemblies (NAUO + item-defined
transformations, mapped items). Hostile input is capped and guarded; faces
that cannot be read are left out and reported. Faces that wrap around a
closed non-periodic direction (pipe tori, revolved B-spline bands) are split
for truck's mesher. Bodies are meshed per shell so open imports never panic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 21:01:04 +00:00