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 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 07:37:31 +00:00
1 parent 66fa6fe584
commit 2db9e66048
1 file changed
+8 -3
+8 -3
View File
@@ -606,6 +606,13 @@ pub fn step_orientation_errors(text: &str) -> std::result::Result<Vec<String>, 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<Vec<String>, 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;