diff --git a/crates/fj-core/src/objects/kinds/shell.rs b/crates/fj-core/src/objects/kinds/shell.rs index 261783517..c905cf70b 100644 --- a/crates/fj-core/src/objects/kinds/shell.rs +++ b/crates/fj-core/src/objects/kinds/shell.rs @@ -1,6 +1,5 @@ use crate::{ - objects::{handles::Handles, Face, HalfEdge}, - queries::BoundingVerticesOfHalfEdge, + objects::{handles::Handles, Face}, storage::Handle, }; @@ -22,28 +21,4 @@ impl Shell { pub fn faces(&self) -> &Handles { &self.faces } - - /// Indicate whether the provided half-edges are siblings - pub fn are_siblings( - &self, - a: &Handle, - b: &Handle, - ) -> bool { - let same_curve = a.curve().id() == b.curve().id(); - let same_boundary = a.boundary() == b.boundary().reverse(); - let same_vertices = { - let Some(a_vertices) = self.bounding_vertices_of_half_edge(a) - else { - return false; - }; - let Some(b_vertices) = self.bounding_vertices_of_half_edge(b) - else { - return false; - }; - - a_vertices == b_vertices.reverse() - }; - - same_curve && same_boundary && same_vertices - } } diff --git a/crates/fj-core/src/queries/mod.rs b/crates/fj-core/src/queries/mod.rs index 03ac82d26..6f6488caf 100644 --- a/crates/fj-core/src/queries/mod.rs +++ b/crates/fj-core/src/queries/mod.rs @@ -11,8 +11,10 @@ mod all_half_edges_with_surface; mod bounding_vertices_of_half_edge; +mod sibling_of_half_edge; pub use self::{ all_half_edges_with_surface::AllHalfEdgesWithSurface, bounding_vertices_of_half_edge::BoundingVerticesOfHalfEdge, + sibling_of_half_edge::SiblingOfHalfEdge, }; diff --git a/crates/fj-core/src/queries/sibling_of_half_edge.rs b/crates/fj-core/src/queries/sibling_of_half_edge.rs new file mode 100644 index 000000000..5c5dd2314 --- /dev/null +++ b/crates/fj-core/src/queries/sibling_of_half_edge.rs @@ -0,0 +1,60 @@ +use crate::{ + objects::{HalfEdge, Shell}, + storage::Handle, +}; + +use super::BoundingVerticesOfHalfEdge; + +/// Queries related to the sibling of a [`HalfEdge`] +pub trait SiblingOfHalfEdge { + /// Indicate whether the provided half-edges are siblings + fn are_siblings(&self, a: &Handle, b: &Handle) -> bool; + + /// Retrieve the sibling of this half-edge + /// + /// Returns `None`, if the provided half-edge is not part of the object this + /// method is called on, or if the provided half-edge has no sibling within + /// the object. + fn get_sibling_of( + &self, + half_edge: &Handle, + ) -> Option>; +} + +impl SiblingOfHalfEdge for Shell { + fn are_siblings(&self, a: &Handle, b: &Handle) -> bool { + let same_curve = a.curve().id() == b.curve().id(); + let same_boundary = a.boundary() == b.boundary().reverse(); + let same_vertices = { + let Some(a_vertices) = self.bounding_vertices_of_half_edge(a) + else { + return false; + }; + let Some(b_vertices) = self.bounding_vertices_of_half_edge(b) + else { + return false; + }; + + a_vertices == b_vertices.reverse() + }; + + same_curve && same_boundary && same_vertices + } + + fn get_sibling_of( + &self, + half_edge: &Handle, + ) -> Option> { + for face in self.faces() { + for cycle in face.region().all_cycles() { + for h in cycle.half_edges() { + if self.are_siblings(half_edge, h) { + return Some(h.clone()); + } + } + } + } + + None + } +} diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 571aaf40b..a6dde5b6b 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -5,7 +5,9 @@ use fj_math::{Point, Scalar}; use crate::{ geometry::SurfaceGeometry, objects::{HalfEdge, Shell, Surface}, - queries::{AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge}, + queries::{ + AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, SiblingOfHalfEdge, + }, storage::{Handle, HandleWrapper}, };