From 73e0cd8eacd6d2d224da4db3865eaec6220381c5 Mon Sep 17 00:00:00 2001 From: A-Walrus Date: Sat, 29 Jul 2023 13:18:27 +0300 Subject: [PATCH] Check orientation by comparing half-edge dirs This solution almost works, but fails on edges that start and end at the same vertex. --- crates/fj-core/src/validate/shell.rs | 32 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index cf8ac3e19..1ac0e7dc5 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -268,13 +268,31 @@ impl ShellValidationError { shell: &Shell, errors: &mut Vec, ) { - let mut orientations = shell - .faces() - .into_iter() - .map(|f| f.region().exterior().winding()); - let first = orientations.next().unwrap(); - if !orientations.all(|elem| elem == first) { - errors.push(Self::MixedOrientations.into()) + let mut global_to_half: HashMap> = HashMap::new(); + + for face in shell.faces() { + for cycle in face.region().all_cycles() { + for half_edge in cycle.half_edges() { + let id = half_edge.global_form().id(); + global_to_half + .entry(id) + .or_insert(Vec::new()) + .push(half_edge.clone()); + } + } + } + + // In order for the faces to all have the same outside winding global + // edge should have two half edges in opposite directions. + for (_, halfs) in global_to_half { + if let (Some(a), Some(b)) = (halfs.get(0), halfs.get(1)) { + // Check if a is reverse of b + if a.start_vertex().id() == b.start_vertex().id() { + errors.push(Self::MixedOrientations.into()); + dbg!(a, b); + return; + } + } } } }