Kernel: a body's size counts its edges, so a sphere, cylinder or torus is its own size

Body size (the box diagonal every size-relative tolerance comes from: mesh chords, reach,
fit tolerances) came from the record's vertices alone. SMLib closes a sphere, a cylinder or a
torus along seam edges, so those vertices can be two poles, two seam ends or a single point: a
torus was 1 mm across (its preview at a hundredth of that took 214 720 triangles and broke the
budget), a 5 x 8 cylinder 8 instead of 16.2. The size now also takes three points along each
edge: points on the edges, not their control hulls, which for a rational edge can lie far off
it (a sheared L-prism's outline box was 49 km across).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-29 00:11:19 -04:00
committed by Irakli Kourtis
parent 55f48e4e58
commit 8eb77affb0
+18 -2
View File
@@ -344,9 +344,25 @@ fn coarse_tolerance(span: f64) -> f64 {
(span * 0.01).clamp(1e-3, 1.0)
}
/// Box diagonal of a record's vertices (0 when it has none or no finite extent).
/// Box diagonal of a record's vertices and points along its edges (0 when it has none or no
/// finite extent). The edges count: SMLib closes a sphere, a cylinder or a torus along seams, so
/// its vertices alone can be two poles or a single point (a torus came out 1 mm across, and its
/// display mesh at a hundredth of that took 214 720 triangles). Points on the edges, not their
/// control hulls: a rational edge's control points can lie far off it.
fn span_of(record: &Brep) -> f64 {
let bounds: Aabb3 = record.vertices.iter().map(|v| v3(v.point)).collect();
let mut bounds: Aabb3 = record.vertices.iter().map(|v| v3(v.point)).collect();
for e in &record.edges {
if let Ok(c) = brep::eval::CurveEval::new(e.parameters()) {
let [t0, t1] = e.interval;
for i in 1..4 {
if let Some(p) = c.point(t0 + (t1 - t0) * f64::from(i) / 4.0)
&& p.is_finite()
{
bounds.add(p);
}
}
}
}
let d = if bounds.is_empty() { 0.0 } else { bounds.diagonal() };
if d.is_finite() && d > 0.0 { d } else { 0.0 }
}