From 2db9e66048beedcd4d89ceac8e751da60fc470bc Mon Sep 17 00:00:00 2001 From: bherbruck Date: Thu, 8 Oct 2026 06:17:16 +0000 Subject: [PATCH] STEP orientation check: judge only revolution faces, no drifting parameter hint Free-form strips (a curved-edge fillet's B-spline bands round a saddle) vary their normal too much along the loop for the loop-direction test, and the hinted nearest-parameter search drifted on them: false 'runs clockwise' reports on faces that round-trip exactly. The check now covers cylinders, cones, spheres and tori (closed surfaces, where a loop read the wrong way silently gives the rest of the surface); volume checks cover the rest. It still flags all 8 sphere corners of a fillet box with their sense flipped. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL --- crates/kernel/src/step_in/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/kernel/src/step_in/mod.rs b/crates/kernel/src/step_in/mod.rs index ceaf0d55..24a98018 100644 --- a/crates/kernel/src/step_in/mod.rs +++ b/crates/kernel/src/step_in/mod.rs @@ -606,6 +606,13 @@ pub fn step_orientation_errors(text: &str) -> std::result::Result, S // Patches only: a face with several loops (a band between two rings, a face with // holes) has no single loop direction to compare. let [w] = bounds.as_slice() else { continue }; + // Only revolutions (cylinders, cones, spheres, tori: closed surfaces, where a loop + // read the wrong way round silently gives the rest of the surface). On free-form + // strips the loop's normals vary too much for this test; the round trips' volume + // checks cover those. + if !matches!(f.surface(), mt::Surface::RevolutedCurve(_)) { + continue; + } // A loop through a vertex twice (a figure eight round a pole) has no single direction. let fronts: std::collections::HashSet<_> = w.edge_iter().map(|e| e.front().id()).collect(); if fronts.len() != w.len() { @@ -642,10 +649,8 @@ pub fn step_orientation_errors(text: &str) -> std::result::Result, S let s = f.oriented_surface(); let mut normal = mt::Vector3::new(0.0, 0.0, 0.0); let mut count = 0usize; - let mut prev = None; for p in &pts { - if let Some(uv) = s.search_nearest_parameter(*p, prev, 100) { - prev = Some(uv); + if let Some(uv) = s.search_nearest_parameter(*p, None, 100) { let n = s.normal(uv.0, uv.1); if n.x.is_finite() && n.y.is_finite() && n.z.is_finite() { normal += n;