CypherNaugh_0x
49ca7ef878
Merge origin/main into fix/flush-pad-over-hole (keeps both round_pads_crossing_a_shallow_fall from #119 and drain_pads_flush_under_a_floor_with_a_hole, which now also checks a boss ring standing on the 1° top around the hole)
2026-10-11 15:01:29 +02: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
79753040d5
Merge upstream and update curved-cut regression for fallback diagnostics
2026-10-11 13:25:06 +02:00
bherbruck
420ee723ee
Merge pull request #124 from CypherNaught-0x/fix/shell-four-face-corner
...
Shell works where four or more flat faces meet at a corner
2026-10-11 07:13:42 -04:00
CypherNaugh_0x
8970254672
A drain pad whose bore is the drain hole's wall (a ring joined flush under a floor, or overlapping it) now joins instead of failing with "coincident faces on curved bodies": the mesh intersection can't take two walls on one cylinder, and the coincident-face push only knew planes. Such unions now narrow one body's bore (its walls pushed toward the axis, clear of the other's), join, and cut the original bore's cylinder out again over that body's length, which is exact when the cylinder holds no material of either body (checked on samples). Inside that step a face is pushed into the other body only as deep as there is material behind it all over, so a narrowed rim over the other's bore can't fill it; then the other body's bore is narrowed instead. Test: drain_pads_flush_under_a_floor_with_a_hole (ring flush and 2 mm into a 1° floor, and a disc across the hole, against hand-calculated volumes)
2026-10-11 13:01:54 +02:00
CypherNaugh_0x
3573b96c7a
fix: shell bodies where four or more planar faces meet at a corner (a floor falling to a drain from the trough edges) by splitting such corners into several joined by short edges instead of refusing because the moved planes miss a common point
2026-10-11 12:23:23 +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
CypherNaugh_0x
5073f5dd72
A failed boolean no longer blames "coincident faces on curved bodies" whatever the cause: the exact polygon fallback runs after any failed B-rep boolean (faces that touch, or cross at a shallow angle) and takes planar faces only, but its refusal named coincident faces and curved bodies regardless. It now says which operand is in the way and why: "the tool has 2 curved faces (cylinder)" (kinds: cylinder, cone, sphere, torus, freeform), a face that could not be meshed, a planar face whose mesh is not flat, or a mesh too detailed. Test: planar_fallback_names_the_curved_faces
2026-10-11 10:25:10 +02:00
CypherNaugh_0x
8c1b1478ce
Joins and cuts of round pads, bosses and holes across a floor that falls a degree or two no longer fail: the B-rep results were right, but the plausibility check meshed them without refinement, and where the shallow cut trims a round side to a thin band the plain mesh spans it with triangles cutting through the cylinder, so the check saw missing material (0.8 to 1.6 % of samples misclassified), rejected the result, and the planar fallback then refused the round tool. The check now meshes the operands and the result with refinement on curved faces (as measure does). Test: round_pads_crossing_a_shallow_fall (a 1° fall and a 2° four-face fall toward a drain)
2026-10-11 05:33:50 +02:00
bherbruck
22672585c9
fix: join connected solids at exact edge contacts
2026-10-10 23:11:02 -04:00
bherbruck
fc8b71956c
fix: reject planar joins that displace original faces
2026-10-10 22:53:44 -04:00
bherbruck
c1b6478ab5
fix: join additive extrusions and merge coplanar faces
2026-10-10 21:31:19 -04:00
bherbruck
4b7e1d317d
fix: load designs off-thread and cache recent thumbnails as PNGs
2026-10-10 20:55:14 -04:00
CypherNaugh_0x
15bb64c2ab
Reject chamfer extensions beyond trimmed rim faces
2026-10-11 00:50:20 +02:00
CypherNaugh_0x
9c6f9410d2
Fix equal-distance chamfers on sloped end faces
2026-10-11 00:30:28 +02:00
CypherNaugh_0x and Claude Opus 5.5
9a2a3cef8b
A sweep along a path with sharp corners follows the corners: sweeping a rim profile along three lines (an open rectangle) gave a body of volume -0.0006 mm3 with its centre of mass at x = -3.5e9, and no error
...
kernel::sweep swept segment by segment: a line translates the profile along it, an arc turns it. At a sharp corner the next line runs within the plane the profile has reached, so the profile slid sideways in its own plane and the walls folded into an inside-out, zero-volume shell. Paths whose direction changes at a joint (more than 1e-3 rad) are now swept as a polyline by sweep_path, which mitres the corners; arcs become points within 0.01 mm. Smooth paths (lines and tangent arcs) are swept as before. Pipe uses the same path.
Tests: sweep_round_a_sharp_corner_is_mitred sweeps a 2 x 2 square along an L of two 10 mm lines and checks the volume, 80 mm3 (fails on main).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-10 17:57:34 -04:00
CypherNaugh_0x and Claude Opus 5.5
5249ae84ef
Moving a body that a boolean made no longer hangs: a boolean between a cylinder and a tilted plane (an elliptical edge) froze the app at 100 % CPU, because its retries move both bodies and the result back
...
Moving a body transforms its intersection-curve edges, and truck-geometry 0.5.0 scales each curve's tolerance by the operator norm of the matrix. matext4cgmath 0.1.0 computes it from eigenvalues through a quartic whose Newton refinement loops while the residual is above a tolerance and never gives up. For a translation matrix all four eigenvalues are 1, and near that quadruple root the iteration can cycle forever (about one translation in eight of the boolean retries' shifts, by a scan of sizes 0.1-2000 mm). matext4cgmath is vendored with both Newton loops stopped after 100 steps (vendor/README.md, ATTRIBUTION.md).
truck master no longer computes the norm in transform_by, so the vendored copy can go once a truck release after 0.5.0 is adopted.
Tests: moving_a_body_with_an_intersection_curve_edge_ends (kernel) cuts a cylinder with a tilted box and moves the result by one of the shifts that hung (hangs on main). examples/regressions/oblique_cut_of_cylinder_hang.json is the variant of the oblique cut that hung the app; it hangs on main, and since the previous commit it passes without reaching the shifted retries, so it is replayed by the engine test as a scenario only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-10 17:57:34 -04:00
bherbruck
d6cdec40da
Fix modelling regressions and reconcile WIP UI work
2026-10-10 15:37:00 -04:00
CypherNaugh_0x
aa268f0f0e
Faster tests: hostile_params_never_panic shares its commands across threads (154 s to 20 s), the design-file fuzz test tries its seeded cases on all cores (21 s to 7.5 s), the kernel's tangent-primitive boolean test runs its three seeds at once, and the headless scenario harness skips the software viewport render it threw away every frame (scenarios 63 s to 26 s). kill_mid_save waits for the saver to reach a varying round instead of sleeping a fixed time, so it holds on a busy machine
2026-10-10 13:24:08 -04:00
CypherNaugh_0x
9508ee749c
Shell refuses a wall thicker than a rim instead of returning a corrupt body: the topology-preserving face offset now checks every planar face's moved loops, and a loop that turns inside out or two loops that cross (a rim or ledge narrower than the move, e.g. a bowl opening sliding past the slab's outer edge) is an error naming the spot. Before, the self-crossing cavity went into the boolean and the shelled body came back with roughly twice its volume and its centre of mass outside the body, so every later cut failed its volume check
...
The check is geometric, not a tuned threshold: on the reported basin (18 mm rim, sloped bowl wall) the rim strip reaches zero width at 15.17 mm and the shell is refused from there on. Tolerances only absorb rounding (scaled to the body size), and at most 2000 straight edges per face are compared pairwise. Arc edges and curved faces are not checked.
This is a guard, not the full fix. Building such a shell needs the offset to change topology: drop the strip that collapses and let its neighbours meet, as offset_body already does for rounds thinner than the move, extended to planar faces. That is substantially more work in the most delicate part of the kernel (rims, ledges, steps, arc-bounded strips) and is left for a separate change; until then the workaround is to model the hollow directly (an offset loft and a box cut).
2026-10-10 12:32:03 -04:00
bherbruck and Claude Opus 5.5
67c79ec91c
Lips on rounded, shelled rims: the band along the rim's edge is raised from the body's own faces (kernel::raise_band: the rim face split along the band's exact offset edge, the band's walls swept up from the walls below, a top), since a join can't merge walls that continue each other; grooves cut with a band reaching into the free side so no wall coincides; tests against the band's area times its height
...
Fixes #29
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
2026-10-10 00:04:37 +00:00
bherbruck and Claude Opus 5.5
80f5a58806
Re-land the robustness batch on main ( #6 ): fillets running into an earlier round go to blend_corner (any radius) instead of the same-radius undo; the lip and drilled-hole regression tests move into tests/robustness.rs with the new command ids; measuring 5000 faces is checked for its counts, its time in an ignored perf test run alone
...
Part of #6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
2026-10-10 00:04:37 +00:00
bherbruck and Claude Opus 5.5
f967b8d3ff
Measuring bodies of thousands of faces: 13 s to 0.8 s for 5000 faces (the body's size was recomputed for every face); merged topology counts right on finely faceted bodies (vertices welded only when they coincide, planes merged only when parallel within 1e-9), with a test
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-10 00:04:37 +00:00
bherbruck and Claude Opus 5.5
ccde7a4837
Robustness runs and the kernel fixes they found
...
- 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
2026-10-10 00:04:37 +00:00
bherbruck and Claude Opus 5.5
38a6ae3d38
Topology counts: a horn torus pinched to a point is one face (smoothness ignores an edge's ends and points without a normal), with a degenerate loop at the pinch counted as Fusion does (two edges and a vertex); oracle 50 passes, 76/76
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 15:41:02 +00:00
bherbruck and Claude Opus 5.5
109b8acbb5
Topology counts weld coincident vertices and edges, and merge two pieces of one surface only across an edge that just those two share: tangent holes touching along a line keep the wall cut at the pinch, the same way at every pinch (oracle 42 passes; 75/76)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 15:41:02 +00:00
bherbruck and Claude Opus 5.5
8045904c54
Lofts through three or more sections are smooth: each side is one B-spline surface through every section (the middle sections leave no edges); two sections stay ruled
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 13:48:12 +00:00
bherbruck and Claude Opus 5.5
0ee343b9e6
Shell and offset faces on cones and spheres too (a dome moves to a smaller sphere about its centre, a cone's apex slides along its axis); surface fitting robust to poles and half cylinders; a shell retries on the unhealed body when the healed one won't cut
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 12:59:50 +00:00
bherbruck and Claude Opus 5.5
46f3ff713d
Fillets of edges meeting at corners in any selection order: blends go one at a time in an order that works (a run along a planar loop waits for a selected edge meeting its inner corner, then bridges the arc it left), so three edges at a box corner give a sphere octant
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 11:54:09 +00:00
bherbruck and Claude Opus 5.5
01b349842c
Fillets and chamfers on runs of neighbouring edges along a planar face's loop (two or three top edges of a box): the blends meet in mitres at the sharp corners between them and end square where unblended edges go on (those edges and the walls' seams stop at the blend)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 11:31:27 +00:00
bherbruck and Claude Opus 5.5
717b181082
Booleans: a tool wholly inside the target leaves a void (an inner shell); results are oriented outward from a mesh fine enough for every face (a sphere clipping a box's corner came out inside out); as a last resort the tool is nudged by a micron-scale screw motion (tangencies, seams on the other body); a boolean survey test over random boxes, cylinders and spheres
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 10:04:09 +00:00
bherbruck and Claude Opus 5.5
f7703ca720
Fillets and chamfers along open chains of curved edges that end at planar faces square to them (the round edge of a D-shaped block): the end faces take the blend's end arcs and their edges stop at the contacts; the curved blend is tried only for curved edges or edges between curved faces, and refuses a blend larger than its neighbouring faces
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 08:32:45 +00:00
bherbruck and Claude Opus 5.5
3e7826fe56
Fillets and chamfers along closed chains of curved edges between any two smooth sides (a branch pipe meeting a main pipe): a ball rolled along the edge gives the contact curves and the blend (rational B-spline through exact arcs, smooth across the chain's joints); side faces trimmed to the contacts and seams shortened; merged topology joins free-form faces that meet smoothly by their exact normals
...
Oracle: 72/76.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 06:37:13 +00:00
bherbruck and Claude Opus 5.5
5539de8fd4
Booleans: a face crossed by nested intersection loops (both walls of a tube) gives each hole to the innermost piece holding it (vendored shapeops; tubes and tori cut across now work); revolved full circles start at an odd angle so their seams don't lie in common cut planes
...
Oracle: 70/76.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 05:59:28 +00:00
bherbruck and Claude Opus 5.5
fc7cb5d60d
Booleans: prisms along one direction combined exactly in 2D (overlapping holes in plates; equal sections stacked end to end), bodies touching along one whole face stitched (a part joined with its mirror image), pushing coincident faces works with any plane-and-cylinder neighbours
...
Oracle: 60/76.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 04:53:49 +00:00
bherbruck and Claude Opus 5.5
7ca6e9278b
Loop blends: sharp corners between straight edges meet in mitres (ellipse arcs), arcs of exactly the blend's radius become sphere octants (pole-free), and loops plus the other edges blend in order (every edge of an extruded part: sphere and torus corners)
...
Oracle: 58/76.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 03:59:23 +00:00
bherbruck and Claude Opus 5.5
7e373ff1f7
Draft of walls between caps on non-convex bodies: planes tilt about their neutral-plane line, cylinders become cones (47: drafted round-ended pocket)
...
Oracle: 56/76.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 03:35:18 +00:00
bherbruck and Claude Opus 5.5
59685a9180
Shell and offset faces on bodies of planes and cylinders (filleted boxes, bosses: each face moves along its normal, cylinders change radius, corners and arcs follow); surface classification leaves out singular points (cone apexes); recipes: holes on cylinders drill toward the axis
...
Oracle: 55/76 (67-76 sheet metal not replayed yet).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 03:25:21 +00:00
bherbruck and Claude Opus 5.5
8c88fb8d2d
Measure: split triangles that cut through curved faces onto the surface (trimmed faces after booleans were measured up to 15% off; 61's keyway volume now matches); oracle step check shows the original volume
...
Oracle: 53/66.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 02:48:17 +00:00
bherbruck and Claude Opus 5.5
935e6465fa
Blends: whole smooth loops picked by one edge (tangent chain), full circles, walls at any angle, several loops per feature; flat non-plane faces healed into planes; fillets and chamfers repeat in feature patterns
...
Oracle: 49/66.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 00:30:38 +00:00
bherbruck and Claude Opus 5.5
57d01f8405
Kernel: revolved faces turned away from the angle wrap (booleans with revolved bodies work), cuts that leave pieces make separate bodies, trivial booleans (clear of / inside) by sampling, body mirrors with join; recipes: pattern source names, thread, holes at sketch points, mirror of bodies
...
Oracle: 43/66.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 00:00:51 +00:00
bherbruck and Claude Opus 5.5
37f4e4e49e
Kernel: shell of non-convex bodies with planar faces (faces offset with the body's topology)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 23:00:57 +00:00
bherbruck and Claude Opus 5.5
3229fd9740
Kernel: booleans with coincident planar faces push the faces apart exactly (perpendicular neighbours stretched or shrunk), union cuts the slab beyond the plane
...
Oracle: 29/29.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 22:41:29 +00:00
bherbruck and Claude Opus 5.5
51f5f8a0e5
Kernel tests: restore the mesh-body test after the merge
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 22:16:52 +00:00
bherbruck and Claude Opus 5.5
a4a17331dc
Kernel: concave edge fillets; whole smooth-loop blends of planar faces (cylinders and tori: pocket floors, plate outlines); rounding every edge of a convex planar body (sphere corners); healing after booleans (exact lines/arcs for intersection curves, coplanar faces merged, collinear edges joined); faces rebuilt on their stored surfaces
...
Oracle: 28/29.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 22:08:27 +00:00
bherbruck and Claude Opus 5.5
ea3dd0ed6e
3MF: export, and 3MF/STL import as mesh bodies
...
Export: ExportCommand/CLI --out/MCP export with .3mf write a 3MF Core package
([Content_Types].xml, _rels/.rels, 3D/3dmodel.model; millimetres), one
mesh object and build item per body, named after it, vertices shared and
welded watertight (T-junctions between faces split), base-material colours
when bodies carry one (STEP colours now ride on bodies). Tessellation as
for STL. File > Export 3MF.
Import: doc.open/drag-drop/CLI/MCP open accept .3mf and .stl; Insert Mesh
(ParaMeshInsertAlignCommand) adds them to a design as a MeshImport feature.
Kernel mesh bodies render, measure exactly, move and export; solid
features refuse them with a clear error. 3MF reading flattens components
and build transforms, converts units, reads colours; sizes, entries,
nesting and element counts are capped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 21:30:38 +00:00
bherbruck and Claude Opus 5.5
043a542e29
Kernel: pole-free six-patch spheres; vendored truck-shapeops with robust meshing and nearest-parameter loop projection (sphere and box booleans work); least-squares sphere classification
...
Oracle: 25/29 (14 and 15 now match Fusion).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 21:30:18 +00:00
bherbruck and Claude Opus 5.5
d585afd006
M2: exact planar boolean fallback for coincident faces (BSP polygons rebuilt into B-rep)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-07 19:22:27 +00:00
bherbruck and Claude Opus 5.5
c555f6f693
M2: loft (arc-length ruled sections) and sweep along sketch paths; three-level measurement voting
...
Oracle: 23/29 parts match Fusion.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-07 19:22:27 +00:00
bherbruck and Claude Opus 5.5
73a1ab40d0
M2: shell and draft (exact convex polyhedra from planes)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-07 19:22:27 +00:00