* Boolean nudge tried both ways: no sliver where a cut's end touches a round side (#897, #827)
Robustness seed 14 cuts a cylinder whose end lies exactly on the apex of the
plate's arc side. Since the display tessellation plans (#805) the generator sees
the arc's true extent, so the cut's base lands on -10 instead of -10.000000000000002
and the end is tangent to the arc. The direct boolean fails there and the
last-resort tool nudge pushed the end into the arc, leaving a planar sliver a
tenth of a millimetre wide; shell then picked that sliver and refused it. The
13 October merges were not the cause (the bisect lands on #805).
The nudge is now tried both ways and the simpler result (fewer faces) is kept,
so the opposite nudge parts the touching faces instead. The same change joins
the hinge barrel in #827, whose top lies tangent to the lid's underside where
the mounting leaf ends. Each result still passes the same checks as before.
Goldens: seeds 14, 26 and 85 now build to the end, 31 and 78 come out with
fewer faces. Seeds 6, 43 and 73 still stop at shell: their joins now succeed and
shell reaches corners it can't offset (a cusp where a box face touches an arc,
coplanar faces facing opposite ways), which is unchanged.
Fixes#897Fixes#827
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Nudge the other way only when the first nudge fails or leaves a sliver
Trying both nudges and keeping the one with fewer faces could prefer a result
that keeps two pieces joined by a hair over one that separates them (the
centred coplanar revolve cut). The opposite nudge now runs only when the first
one failed or left a face narrower than 1/200 of the part, and it is taken
when it works with fewer of those.
Goldens re-recorded on current main: seeds 14, 26 and 85 build to the end,
31 and 78 with fewer faces. The other changed seeds are main's own since its
last full record, identical with and without this change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Nudge the other way only for slivers the nudge made
On the sensor enclosure's lid the first nudge left thin faces the operands
already had (thin walls, small rounds), so the opposite nudge ran a second
boolean for nothing and the press/pull took 79 s against main's 55 s. The
opposite nudge now runs only when the first one failed or left more slivers
than the operands brought; the press/pull test takes 36 s against 42 s on main
(same machine, one after the other).
Goldens re-recorded on top of #940.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Goldens on current main: seeds 31, 43 and 78 with the two-way nudge
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep the hinge and tangent-cut tests beside the #871 fillet test
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Goldens: seeds 33 and 91 as main's fillet changes build them
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Goldens: keep main's #950 record
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
tests/robustness/goldens.json records what each of seeds 0-95 builds: its steps, how it ended (ok, or the kind and the start of the error it was refused with) and, for the design it left, the bodies' total volume and area (within a relative 1e-6) and their face, edge and shell counts. tests::robustness_goldens fails on any change; ROBUSTNESS_GOLDENS_BLESS="why" records one, with the reason and the seeds it moved. Pull requests that touch crates/kernel run every 8th seed; pushes to main and the nightly run every seed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A coincident face is pushed apart only when the space it moves through holds nothing that changes the result; otherwise the boolean falls through to the exact strategies.
Co-authored-by: NOWN-DEV <[email protected]>
Joining ribs flush with a lid's window left a zero-thickness slit far from the rib (the planar fallback glued back only one of the faces its pieces shared) and displaced the tool on the other joins. Gluing now joins every shared face pair, coincident-face separation checks there is material behind a pushed face for every join, and any join or cut that needed a retry must be closed, keep volume monotonic and leave the part unchanged outside the tool's box, or it is refused with an error. Feature command replies carry the feature's warning.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The oracle no longer uses Fusion measurements. tests/oracle/<case>/ now holds the 76 recipes
(our own format, with recorded measurements and tool-specific fields removed) and an
expected.json per case:
- 55 analytic cases: closed-form values from tools/oracle-analytic/ (stdlib Python, formulas
in each case's "method").
- 21 FreeCAD cases: the same recipe built with FreeCAD's public scripting API by
tools/freecad-oracle/ (an external program, not a dependency), with a reference.stl for 20.
solvecraft-cli oracle compares body count, volume, area, centre of mass, bbox, face counts
where the geometry fixes them, and, against reference.stl, the sampled Hausdorff distance and
the principal moments (spatial.rs from #301). cargo xtask oracle reads tests/oracle, writes
docs/oracle.md with the source of each value, and supports known_failure marks for tracked
bugs. CI runs it on every PR; a manual workflow regenerates the FreeCAD values. step-corpus,
seam normalisation and the through-all emulation, which only existed to compare with Fusion,
are removed.
75/76 pass; 75-sm-bracket-holes is a known failure (#296).
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>