Repro (256 segments, all operands z 11.1..17.1): fuse 12 filleted posts (post ∪ fillet_block(+1) ∪ fillet_block(−1), rotated 0..330°) into ONE multi-shell solid, then union with ring().
|
volume |
open edges |
| closed form |
≈ 7447 |
– |
ring ∪ posts (analytic) |
7360.8 (−1.16%) |
1358 |
posts ∪ ring (analytic) |
7433.6 |
2448 |
| one filleted post at any of the 12 angles |
4950.4 vs 4949.9 ✓ |
6–38 hairline |
Rasterising the result's caps against the CSG reference shows the top AND bottom caps missing over every post∩ring region (r ≈ 24..25). With k = 2 or 3 posts the union already falls back (VolumeDisagreement).
Consequence: api::boolean_op_reported's union referee (added in #890) overrules the analytic result, so the stator solves to the right volume (7831 vs 7848 mm³) but as ~103k-triangle soup instead of ~15k analytic triangles. tests/coplanar_cap_union.rs::twelve_filleted_posts_into_the_ring only passes because of the referee.
Done when: that test passes with VCAD_NO_UNION_REFEREE=1 and both operand orders report reason == None.
Lead: split_planar_face takes crossings[0]/crossings[1] of the OUTER loop for every recorded segment of a line. On a face the line crosses in several spans (a notched plate, an annulus cut by many chords) it cuts the first span repeatedly and never the others — confirmed as the cause of the sheet-metal bend-relief discrepancy (fix: pass the trimmed segment down and pick the span it overlaps). The annular cap here is cut by ~60 full-chord lines.
Found while getting the rana-60-cnc stator to solve (#890). Helpers ring(), post(), fillet_block(side) live in crates/vcad-kernel-booleans/tests/coplanar_cap_union.rs; assert volume against a closed form in any new test — every failure in this family was a plausible mesh of the wrong solid.
🤖 Filed by Claude Code
Repro (256 segments, all operands z 11.1..17.1): fuse 12 filleted posts (
post ∪ fillet_block(+1) ∪ fillet_block(−1), rotated 0..330°) into ONE multi-shell solid, then union withring().ring ∪ posts(analytic)posts ∪ ring(analytic)Rasterising the result's caps against the CSG reference shows the top AND bottom caps missing over every post∩ring region (r ≈ 24..25). With k = 2 or 3 posts the union already falls back (
VolumeDisagreement).Consequence:
api::boolean_op_reported's union referee (added in #890) overrules the analytic result, so the stator solves to the right volume (7831 vs 7848 mm³) but as ~103k-triangle soup instead of ~15k analytic triangles.tests/coplanar_cap_union.rs::twelve_filleted_posts_into_the_ringonly passes because of the referee.Done when: that test passes with
VCAD_NO_UNION_REFEREE=1and both operand orders reportreason == None.Lead:
split_planar_facetakescrossings[0]/crossings[1]of the OUTER loop for every recorded segment of a line. On a face the line crosses in several spans (a notched plate, an annulus cut by many chords) it cuts the first span repeatedly and never the others — confirmed as the cause of the sheet-metal bend-relief discrepancy (fix: pass the trimmed segment down and pick the span it overlaps). The annular cap here is cut by ~60 full-chord lines.Found while getting the rana-60-cnc stator to solve (#890). Helpers
ring(),post(),fillet_block(side)live incrates/vcad-kernel-booleans/tests/coplanar_cap_union.rs; assert volume against a closed form in any new test — every failure in this family was a plausible mesh of the wrong solid.🤖 Filed by Claude Code