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 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-10 00:04:37 +00:00
1 parent 5d69452db3
commit ccde7a4837
16 files changed
+1260 -16

No files matched your search

+20 -3
View File
@@ -365,14 +365,31 @@ fn shell_planar(b: &Body, open: &[Vec3], thickness: f64) -> Result<Body> {
match crate::ops::boolean(&healed, &cavity, crate::BoolOp::Cut) {
Ok(Some(r)) => Ok(r),
Ok(None) => Err(KernelError::Failed("the shell removed everything".into())),
// Healing can leave faces the boolean dislikes (revolved patches): the body as it was.
Err(e) if healed.face_count() == b.face_count() => {
// Healing can leave faces the boolean dislikes (revolved patches): the body as it was,
// its faces to open found again.
Err(e) => {
let raw = b.tessellate((size * 1e-3).max(1e-3)).map_err(|_| e.clone())?;
let mut opened_raw: Vec<usize> = Vec::new();
for p in open {
let near = raw
.triangles
.iter()
.zip(&raw.tri_face)
.filter_map(|(t, f)| raw.tri(t).map(|[x, y, z]| (point_tri(*p, x, y, z), *f as usize)))
.min_by(|a, c| a.0.total_cmp(&c.0));
if let Some((d, f)) = near
&& d < size * 1e-3 + 1e-6
&& !opened_raw.contains(&f)
{
opened_raw.push(f);
}
}
let opened = opened_raw;
let cavity = offset_planar(b, |fi, _| if opened.contains(&fi) { margin } else { -thickness }).map_err(|_| e.clone())?;
crate::ops::boolean(b, &cavity, crate::BoolOp::Cut)
.map_err(|_| e)?
.ok_or_else(|| KernelError::Failed("the shell removed everything".into()))
}
Err(e) => Err(e),
}
}