mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-04 02:55:54 +00:00
Kernel: an extrusion's cap is in its own plane however thin the extrusion
The roles of a swept body's faces take a face as a cap when all its points lie within a flatness tolerance of the start or end plane, sized to the body (1e-5 of it). A box 0.1 µm thick in a 14 mm body is thinner than that, so each cap lay in both planes and box_solid refused "box role correspondence" (engine component_clone boundary_material_proof_requires_resolvable_stock_and_void). Between parallel start and end planes the tolerance stays under a quarter of their gap; a cap's points lie on its plane to the evaluation's precision. Regression case: a 10 x 10 x 1e-4 box in box_certificates_are_six_construction_roles... Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,9 @@ fn box_certificates_are_six_construction_roles_with_dimension_stable_axes() {
|
||||
// A side far shorter than the body (a 0.3 mm label of a metre): its walls' edges lie
|
||||
// closer together than the sweep's body-sized nearness, and each keeps its own role.
|
||||
(Vec3::new(500., -0.3, 1400.), Vec3::new(1500., 0., 1800.)),
|
||||
// Far thinner than the body's flatness tolerance (0.1 µm in 14 mm): each cap is in its
|
||||
// own plane only.
|
||||
(Vec3::ZERO, Vec3::new(10., 10., 1e-4)),
|
||||
] {
|
||||
let body = crate::box_solid(a, b).unwrap().with_box_certificate(42).unwrap();
|
||||
let mut roles = std::collections::HashSet::new();
|
||||
|
||||
@@ -272,7 +272,12 @@ mod imp {
|
||||
let m = body.mesh(&crate::MeshTolerance::chord(mesh_tol))?;
|
||||
let faces = face_tris(&m);
|
||||
let n = body.face_count();
|
||||
let flat_tol = size * 1e-5 + 1e-9;
|
||||
// A cap's points lie on its plane to the evaluation's precision. Sized to the body, the
|
||||
// flatness tolerance can exceed the gap between parallel start and end planes (a box
|
||||
// 0.1 µm thick in a 14 mm body), which would put each cap in both: it stays under a
|
||||
// quarter of that gap.
|
||||
let gap = end.filter(|e| e.normal().cross(start.normal()).len() < 1e-9).map_or(f64::INFINITY, |e| start.height(e.origin).abs());
|
||||
let flat_tol = (size * 1e-5 + 1e-9).min(0.25 * gap);
|
||||
let near = 3.0 * mesh_tol + flat_tol;
|
||||
let flat = |f: usize, pl: &Plane| {
|
||||
faces.get(f).is_some_and(|ft| !ft.tris.is_empty() && ft.tris.iter().all(|(t, _)| t.iter().all(|q| pl.height(*q).abs() <= flat_tol)))
|
||||
|
||||
Reference in New Issue
Block a user