Kernel tests: the collapsed taper's mesh is held to its B-rep, the taper to validity

collapsed_taper_mesh_stays_accurate_as_tolerance_decreases compared each
display mesh's volume with the taper law's integral,
6000 - (1 - pi/4) 40 integral r^2, at 1e-4: the built fillet removes about
10 mm3 more than that (5212.9 against 5223.1) at every tolerance, so it
measured the fillet, not the mesher. It now holds each mesh to the B-rep it
meshes: a mesh within its chord tolerance of the faces has its volume
within area x tolerance of the exact one (SMLib's, integrated on the
surfaces to 1e-8), the bound fillet_mixed_arc_and_line_removed_volume
_converges uses. It passes today.

taper_follows_the_room_along_the_edge keeps its law and closed-form
volumes (the 10 mm3 against the law is the failure it still shows) and
drops the two internal checks at its end (no unmeshed face, a face with
three vertices) for the outcome: the wedge's tapered fillet is valid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-30 06:38:22 -04:00
committed by Irakli Kourtis
parent a0c24b87c0
commit c69dbc5d39
2 changed files with 11 additions and 13 deletions
+1 -2
View File
@@ -730,8 +730,7 @@ mod tests {
let f = fillet_variable_spline(&wedge, at, t.start, &t.spline).unwrap();
let v = fine_volume(&f);
assert!(rel(v, 6000.0 - removed(&law, 40.0)) < 1e-4, "{v} vs {}", 6000.0 - removed(&law, 40.0));
assert_eq!(f.unmeshed_faces(), 0);
assert!(faces_and_vertices(&f).0.contains(&3));
assert!(f.validity().is_empty(), "{:?}", f.validity());
}
/// A radius spline given directly: a cubic with its control radii pulling the radius up in
+10 -11
View File
@@ -1,6 +1,6 @@
use super::*;
fn wedge() -> (Body, RadiusSpline) {
fn wedge() -> Body {
use solidcraft_geom::{Loop2, Plane, Region2, Vec2};
let outer = Loop2::polygon(&[Vec2::new(0., 0.), Vec2::new(40., 0.), Vec2::new(0., 20.)]);
let body = crate::extrude(&Plane::XY, &[Region2 { outer, holes: vec![] }], 0., 15.).unwrap().pop().unwrap();
@@ -9,23 +9,22 @@ fn wedge() -> (Body, RadiusSpline) {
// is built over the wedge's cliffs (the blend-overflow decision), so a tapered fillet no
// longer tapers it.
let t = taper(&body, at, 16.).unwrap();
(fillet_variable_spline(&body, at, t.start, &t.spline).unwrap(), t.spline)
}
fn expected(law: &RadiusSpline) -> f64 {
let n = 20_000;
let integral = (0..n).map(|i| law.eval((i as f64 + 0.5) / n as f64).powi(2)).sum::<f64>() / n as f64;
6000. - (1. - std::f64::consts::FRAC_PI_4) * 40. * integral
fillet_variable_spline(&body, at, t.start, &t.spline).unwrap()
}
/// The display mesh of a fillet tapering to zero at a wedge's tip converges to the B-rep: each
/// mesh lies within its chord tolerance of the faces, so its volume is within the body's area
/// times that tolerance of the exact one (SMLib's, integrated on the surfaces, to 1e-8). Only
/// the mesher is under test here; the taper's own law is `taper_follows_the_room_along_the_edge`'s.
#[test]
fn collapsed_taper_mesh_stays_accurate_as_tolerance_decreases() {
let (body, law) = wedge();
let wanted = expected(&law);
let body = wedge();
let exact = crate::measure(&body).unwrap();
for tol in [0.002, 0.001, 0.0005, 0.0002] {
let mesh = body.mesh(&crate::MeshTolerance::chord(tol)).unwrap();
assert!(mesh.positions.iter().all(|p| p.x.is_finite() && p.y.is_finite() && p.z.is_finite()));
let got = mesh.measure().volume;
assert!((got - wanted).abs() / wanted < 1e-4, "tol={tol}: {got} vs {wanted}");
let bound = exact.area * tol;
assert!((got - exact.volume).abs() <= bound, "tol={tol}: mesh {got} vs exact {} (within {bound})", exact.volume);
}
}