diff --git a/crates/fj-core/src/algorithms/approx/cycle.rs b/crates/fj-core/src/algorithms/approx/cycle.rs index 998ac685c..94c3e9564 100644 --- a/crates/fj-core/src/algorithms/approx/cycle.rs +++ b/crates/fj-core/src/algorithms/approx/cycle.rs @@ -27,6 +27,7 @@ impl Approx for (&Cycle, &Surface) { let edges = cycle .edges() + .iter() .map(|edge| { (edge.deref(), surface).approx_with_cache(tolerance, cache) }) diff --git a/crates/fj-core/src/algorithms/approx/face.rs b/crates/fj-core/src/algorithms/approx/face.rs index 3babf79d3..9df592ee6 100644 --- a/crates/fj-core/src/algorithms/approx/face.rs +++ b/crates/fj-core/src/algorithms/approx/face.rs @@ -7,7 +7,7 @@ use std::{collections::BTreeSet, ops::Deref}; use fj_interop::mesh::Color; use crate::{ - objects::{Face, Handedness, HandleIter}, + objects::{Face, Handedness, Handles}, validate::ValidationConfig, }; @@ -15,7 +15,7 @@ use super::{ cycle::CycleApprox, edge::EdgeApproxCache, Approx, ApproxPoint, Tolerance, }; -impl Approx for HandleIter<'_, Face> { +impl Approx for &Handles { type Approximation = BTreeSet; type Cache = EdgeApproxCache; diff --git a/crates/fj-core/src/algorithms/approx/solid.rs b/crates/fj-core/src/algorithms/approx/solid.rs index 8fae93993..97ad09fc1 100644 --- a/crates/fj-core/src/algorithms/approx/solid.rs +++ b/crates/fj-core/src/algorithms/approx/solid.rs @@ -18,6 +18,7 @@ impl Approx for &Solid { let tolerance = tolerance.into(); self.shells() + .iter() .flat_map(|shell| shell.approx_with_cache(tolerance, cache)) .collect() } diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index a6f26b1d3..50fd269f0 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -29,9 +29,9 @@ impl Intersect for (&Face, &Point<2>) { // result of the last segment. let mut previous_hit = cycle .edges() + .iter() .last() - .cloned() - .and_then(|edge| (&ray, &edge).intersect()); + .and_then(|edge| (&ray, edge).intersect()); for (edge, next_edge) in cycle.edges().pairs() { let hit = (&ray, edge).intersect(); @@ -336,6 +336,7 @@ mod tests { .region() .exterior() .edges() + .iter() .find(|edge| edge.start_position() == Point::from([0., 0.])) .unwrap(); assert_eq!( @@ -371,6 +372,7 @@ mod tests { .region() .exterior() .edges() + .iter() .find(|edge| edge.start_position() == Point::from([1., 0.])) .map(|edge| edge.start_position()) .unwrap(); diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index e5930eed2..164c0cb8b 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -263,6 +263,7 @@ mod tests { .region() .exterior() .edges() + .iter() .find(|edge| edge.start_position() == Point::from([-1., 1.])) .unwrap(); assert_eq!( @@ -298,6 +299,7 @@ mod tests { .region() .exterior() .edges() + .iter() .find(|edge| edge.start_position() == Point::from([-1., -1.])) .map(|edge| edge.start_position()) .unwrap(); diff --git a/crates/fj-core/src/algorithms/transform/cycle.rs b/crates/fj-core/src/algorithms/transform/cycle.rs index 8a6d2ff51..98241f52b 100644 --- a/crates/fj-core/src/algorithms/transform/cycle.rs +++ b/crates/fj-core/src/algorithms/transform/cycle.rs @@ -11,7 +11,7 @@ impl TransformObject for Cycle { services: &mut Services, cache: &mut TransformCache, ) -> Self { - let edges = self.edges().map(|edge| { + let edges = self.edges().iter().map(|edge| { edge.clone() .transform_with_cache(transform, services, cache) }); diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index 1aa6e2278..a721e9a21 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -27,9 +27,10 @@ impl TransformObject for Face { .exterior() .clone() .transform_with_cache(transform, services, cache); - let interiors = self.region().interiors().cloned().map(|interior| { - interior.transform_with_cache(transform, services, cache) - }); + let interiors = + self.region().interiors().iter().cloned().map(|interior| { + interior.transform_with_cache(transform, services, cache) + }); let region = Region::new(exterior, interiors, color).insert(services); diff --git a/crates/fj-core/src/algorithms/transform/shell.rs b/crates/fj-core/src/algorithms/transform/shell.rs index 0d1d474e0..835299209 100644 --- a/crates/fj-core/src/algorithms/transform/shell.rs +++ b/crates/fj-core/src/algorithms/transform/shell.rs @@ -11,10 +11,10 @@ impl TransformObject for Shell { services: &mut Services, cache: &mut TransformCache, ) -> Self { - let faces = self - .faces() - .cloned() - .map(|face| face.transform_with_cache(transform, services, cache)); + let faces = + self.faces().iter().cloned().map(|face| { + face.transform_with_cache(transform, services, cache) + }); Self::new(faces) } diff --git a/crates/fj-core/src/algorithms/transform/solid.rs b/crates/fj-core/src/algorithms/transform/solid.rs index fa9c243a5..976b6bed2 100644 --- a/crates/fj-core/src/algorithms/transform/solid.rs +++ b/crates/fj-core/src/algorithms/transform/solid.rs @@ -11,7 +11,7 @@ impl TransformObject for Solid { services: &mut Services, cache: &mut TransformCache, ) -> Self { - let shells = self.shells().cloned().map(|shell| { + let shells = self.shells().iter().cloned().map(|shell| { shell.transform_with_cache(transform, services, cache) }); diff --git a/crates/fj-core/src/objects/handles.rs b/crates/fj-core/src/objects/handles.rs index d6afcdd10..a2ed0c6f1 100644 --- a/crates/fj-core/src/objects/handles.rs +++ b/crates/fj-core/src/objects/handles.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeSet, fmt::Debug}; +use std::{collections::BTreeSet, fmt::Debug, slice}; use itertools::Itertools; @@ -6,14 +6,11 @@ use crate::storage::Handle; /// An ordered set of object handles /// -/// This is an internal data structure that is used within objects that -/// reference multiple other objects of the same type. It does not contain any -/// duplicate elements, and it maintains the insertion order of those elements. -/// -/// `HandleSet` implement `FromIterator`, but it must never be constructed from -/// an iterator that contains duplicate handles. This will result in a panic. +/// This is the data structure used by all objects that reference multiple +/// objects of the same type. It is a set, not containing any duplicate +/// elements, and it maintains the insertion order of those elements. #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct HandleSet { +pub struct Handles { // This is supposed to be a set data structure, so what is that `Vec` doing // here? Well, it's here because we need it to preserve insertion order, but // that doesn't explain why it is here *alone*. @@ -26,28 +23,16 @@ pub struct HandleSet { inner: Vec>, } -impl HandleSet { - pub fn len(&self) -> usize { - self.inner.len() - } - - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - - pub fn iter(&self) -> HandleIter { - HandleIter { - handles: &self.inner, - next_index: 0, - } - } -} - -impl FromIterator> for HandleSet -where - O: Debug + Ord, -{ - fn from_iter>>(handles: T) -> Self { +impl Handles { + /// Create a new instances of `Handles` from an iterator over `Handle` + /// + /// # Panics + /// + /// Panics, if the iterator contains duplicate `Handle`s. + pub fn new(handles: impl IntoIterator>) -> Self + where + T: Debug + Ord, + { let mut added = BTreeSet::new(); let mut inner = Vec::new(); @@ -65,42 +50,35 @@ where Self { inner } } -} -/// An iterator over handles to objects -/// -/// This struct is returned by the respective methods of all objects that -/// reference multiple objects of the same type. -pub struct HandleIter<'r, T> { - handles: &'r Vec>, - next_index: usize, -} + /// Return the number of handles in this set + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Indicate whether the set is empty + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } -impl<'r, T> HandleIter<'r, T> { /// Return the n-th item - /// - /// This method is unaffected by any previous calls to `next`. pub fn nth(&self, index: usize) -> Option<&Handle> { - self.handles.get(index) + self.inner.get(index) } - /// Return the n-th item, treating the iterator as circular + /// Return the n-th item, treating the index space as circular /// - /// If the length of the iterator is `i`, then retrieving the i-th edge - /// using this method, is the same as retrieving the 0-th one. - /// - /// This method is unaffected by any previous calls to `next`. + /// If the length of `Handles` is `i`, then retrieving the i-th edge using + /// this method, is the same as retrieving the 0-th one. pub fn nth_circular(&self, index: usize) -> &Handle { let index = index % self.len(); self.nth(index) .expect("Index must be valid, due to modulo above") } - /// Return the index of the item, if it is in this iterator - /// - /// This method is unaffected by any previous calls to `next`. + /// Return the index of the item, if available pub fn index_of(&self, handle: &Handle) -> Option { - self.handles.iter().position(|h| h.id() == handle.id()) + self.inner.iter().position(|h| h.id() == handle.id()) } /// Access the item after the provided one @@ -111,13 +89,27 @@ impl<'r, T> HandleIter<'r, T> { .map(|index| self.nth_circular(index + 1)) } - /// Return iterator over the pairs of the remaining items in this iterator - pub fn pairs(self) -> impl Iterator, &'r Handle)> { - self.circular_tuple_windows() + /// Access an iterator over the handles + pub fn iter(&self) -> slice::Iter> { + self.inner.iter() + } + + /// Return iterator over the pairs of all handles + pub fn pairs(&self) -> impl Iterator, &Handle)> { + self.iter().circular_tuple_windows() + } +} + +impl FromIterator> for Handles +where + O: Debug + Ord, +{ + fn from_iter>>(handles: T) -> Self { + Self::new(handles) } } -impl<'r, T> Iterator for HandleIter<'r, T> { +impl<'r, T> IntoIterator for &'r Handles { // You might wonder why we're returning references to handles here, when // `Handle` already is kind of reference, and easily cloned. // @@ -127,28 +119,9 @@ impl<'r, T> Iterator for HandleIter<'r, T> { // an adapter's closure, if you own that argument. You can, if you just // reference the argument. type Item = &'r Handle; + type IntoIter = slice::Iter<'r, Handle>; - fn next(&mut self) -> Option { - let handle = self.handles.get(self.next_index); - self.next_index += 1; - handle - } - - fn size_hint(&self) -> (usize, Option) { - let size = self.handles.len(); - (size, Some(size)) - } -} - -impl ExactSizeIterator for HandleIter<'_, T> {} - -// Deriving won't work, as that only derives `Clone` where `T: Clone`. But -// `HandleIter` can be `Clone`d unconditionally. -impl Clone for HandleIter<'_, T> { - fn clone(&self) -> Self { - Self { - handles: self.handles, - next_index: self.next_index, - } + fn into_iter(self) -> Self::IntoIter { + self.iter() } } diff --git a/crates/fj-core/src/objects/kinds/cycle.rs b/crates/fj-core/src/objects/kinds/cycle.rs index ffa3f9a6b..e2e47bbff 100644 --- a/crates/fj-core/src/objects/kinds/cycle.rs +++ b/crates/fj-core/src/objects/kinds/cycle.rs @@ -2,14 +2,14 @@ use fj_math::{Scalar, Winding}; use crate::{ geometry::SurfacePath, - objects::{handles::HandleSet, Edge, HandleIter}, + objects::{handles::Handles, Edge}, storage::Handle, }; /// A cycle of connected edges #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Cycle { - edges: HandleSet, + edges: Handles, } impl Cycle { @@ -20,18 +20,8 @@ impl Cycle { } /// Access the edges that make up the cycle - pub fn edges(&self) -> HandleIter { - self.edges.iter() - } - - /// Return the number of edges in the cycle - pub fn len(&self) -> usize { - self.edges.len() - } - - /// Indicate whether the cycle is empty - pub fn is_empty(&self) -> bool { - self.edges.is_empty() + pub fn edges(&self) -> &Handles { + &self.edges } /// Indicate the cycle's winding, assuming a right-handed coordinate system @@ -46,6 +36,7 @@ impl Cycle { if self.edges.len() < 3 { let first = self .edges() + .iter() .next() .expect("Invalid cycle: expected at least one edge"); diff --git a/crates/fj-core/src/objects/kinds/region.rs b/crates/fj-core/src/objects/kinds/region.rs index e9028b5e2..a68d06594 100644 --- a/crates/fj-core/src/objects/kinds/region.rs +++ b/crates/fj-core/src/objects/kinds/region.rs @@ -2,7 +2,7 @@ use fj_interop::mesh::Color; use crate::{ - objects::{handles::HandleSet, Cycle, HandleIter}, + objects::{handles::Handles, Cycle}, storage::Handle, }; @@ -17,7 +17,7 @@ use crate::{ #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Region { exterior: Handle, - interiors: HandleSet, + interiors: Handles, color: Option, } @@ -43,17 +43,14 @@ impl Region { /// Access the cycles that bound the region on the inside /// /// Each of these cycles defines a hole in the region . - pub fn interiors(&self) -> HandleIter { - self.interiors.iter() + pub fn interiors(&self) -> &Handles { + &self.interiors } /// Access all cycles of the region (both exterior and interior) pub fn all_cycles(&self) -> impl Iterator> { - // It would be nice to return `HandleIter` here, but there's no - // straight-forward way to chain it to another iterator, given it's - // current implementation. - // - // Maybe this can be addressed, once the need arises. + // It would be nice to return `&Handles` here, but I don't see a way for + // doing that here *and* in `interiors`. [self.exterior()].into_iter().chain(self.interiors()) } diff --git a/crates/fj-core/src/objects/kinds/shell.rs b/crates/fj-core/src/objects/kinds/shell.rs index c8654945f..c905cf70b 100644 --- a/crates/fj-core/src/objects/kinds/shell.rs +++ b/crates/fj-core/src/objects/kinds/shell.rs @@ -1,12 +1,12 @@ use crate::{ - objects::{handles::HandleSet, Face, HandleIter}, + objects::{handles::Handles, Face}, storage::Handle, }; /// A 3-dimensional closed shell #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Shell { - faces: HandleSet, + faces: Handles, } impl Shell { @@ -18,7 +18,7 @@ impl Shell { } /// Access the faces of the shell - pub fn faces(&self) -> HandleIter { - self.faces.iter() + pub fn faces(&self) -> &Handles { + &self.faces } } diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index 3709783fd..f6d19d22b 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -1,12 +1,12 @@ use crate::{ - objects::{handles::HandleSet, HandleIter, Region}, + objects::{handles::Handles, Region}, storage::Handle, }; /// A 2-dimensional shape #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Sketch { - regions: HandleSet, + regions: Handles, } impl Sketch { @@ -18,7 +18,7 @@ impl Sketch { } /// Access the regions of the sketch - pub fn regions(&self) -> HandleIter { - self.regions.iter() + pub fn regions(&self) -> &Handles { + &self.regions } } diff --git a/crates/fj-core/src/objects/kinds/solid.rs b/crates/fj-core/src/objects/kinds/solid.rs index fe973df9d..203ca6189 100644 --- a/crates/fj-core/src/objects/kinds/solid.rs +++ b/crates/fj-core/src/objects/kinds/solid.rs @@ -1,5 +1,5 @@ use crate::{ - objects::{handles::HandleSet, HandleIter, Shell}, + objects::{handles::Handles, Shell}, storage::Handle, }; @@ -13,7 +13,7 @@ use crate::{ /// not currently validated. #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Solid { - shells: HandleSet, + shells: Handles, } impl Solid { @@ -25,7 +25,7 @@ impl Solid { } /// Access the solid's shells - pub fn shells(&self) -> HandleIter { - self.shells.iter() + pub fn shells(&self) -> &Handles { + &self.shells } } diff --git a/crates/fj-core/src/objects/mod.rs b/crates/fj-core/src/objects/mod.rs index 0f170f05d..033d91c0d 100644 --- a/crates/fj-core/src/objects/mod.rs +++ b/crates/fj-core/src/objects/mod.rs @@ -46,7 +46,7 @@ mod set; mod stores; pub use self::{ - handles::HandleIter, + handles::Handles, kinds::{ curve::Curve, cycle::Cycle, diff --git a/crates/fj-core/src/operations/build/face.rs b/crates/fj-core/src/operations/build/face.rs index 86157621f..361638565 100644 --- a/crates/fj-core/src/operations/build/face.rs +++ b/crates/fj-core/src/operations/build/face.rs @@ -32,7 +32,7 @@ pub trait BuildFace { let face = Face::polygon(surface, points_surface, services); let edges = { - let mut edges = face.region().exterior().edges().cloned(); + let mut edges = face.region().exterior().edges().iter().cloned(); let array = array::from_fn(|_| edges.next()).map(|edge| { edge.expect("Just asserted that there are three edges") diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 7dae78e0f..7fbdaad84 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -107,20 +107,19 @@ impl JoinCycle for Cycle { let mut cycle = self.clone(); for (index, index_other) in range.zip(range_other) { - let edges_self = self.edges(); - let edges_other = other.edges(); + let edge = self.edges().nth_circular(index); + let edge_other = other.edges().nth_circular(index_other); - let edge = edges_self.nth_circular(index); - let edge_other = edges_other.nth_circular(index_other); - - let vertex_a = edges_other + let vertex_a = other + .edges() .after(edge_other) .expect("Cycle must contain edge; just obtained edge from it") .start_vertex() .clone(); let vertex_b = edge_other.start_vertex().clone(); - let next_edge = edges_self + let next_edge = self + .edges() .after(edge) .expect("Cycle must contain edge; just obtained edge from it"); diff --git a/crates/fj-core/src/operations/merge.rs b/crates/fj-core/src/operations/merge.rs index 067a10c84..201b89154 100644 --- a/crates/fj-core/src/operations/merge.rs +++ b/crates/fj-core/src/operations/merge.rs @@ -11,6 +11,6 @@ pub trait Merge { impl Merge for Solid { fn merge(&self, other: &Self) -> Self { - self.add_shells(other.shells().cloned()) + self.add_shells(other.shells().iter().cloned()) } } diff --git a/crates/fj-core/src/operations/reverse/cycle.rs b/crates/fj-core/src/operations/reverse/cycle.rs index 30153a606..5e569163a 100644 --- a/crates/fj-core/src/operations/reverse/cycle.rs +++ b/crates/fj-core/src/operations/reverse/cycle.rs @@ -33,7 +33,7 @@ impl ReverseCurveCoordinateSystems for Cycle { &self, services: &mut Services, ) -> Self { - let edges = self.edges().map(|edge| { + let edges = self.edges().iter().map(|edge| { edge.reverse_curve_coordinate_systems(services) .insert(services) }); diff --git a/crates/fj-core/src/operations/reverse/region.rs b/crates/fj-core/src/operations/reverse/region.rs index 9c1c3026f..554f85b10 100644 --- a/crates/fj-core/src/operations/reverse/region.rs +++ b/crates/fj-core/src/operations/reverse/region.rs @@ -7,6 +7,7 @@ impl Reverse for Region { let exterior = self.exterior().reverse(services).insert(services); let interiors = self .interiors() + .iter() .map(|cycle| cycle.reverse(services).insert(services)); Region::new(exterior, interiors, self.color()) @@ -22,7 +23,7 @@ impl ReverseCurveCoordinateSystems for Region { .exterior() .reverse_curve_coordinate_systems(services) .insert(services); - let interiors = self.interiors().map(|cycle| { + let interiors = self.interiors().iter().map(|cycle| { cycle .reverse_curve_coordinate_systems(services) .insert(services) diff --git a/crates/fj-core/src/operations/update/cycle.rs b/crates/fj-core/src/operations/update/cycle.rs index 4d23ab6d7..beff12c6c 100644 --- a/crates/fj-core/src/operations/update/cycle.rs +++ b/crates/fj-core/src/operations/update/cycle.rs @@ -36,7 +36,7 @@ pub trait UpdateCycle { impl UpdateCycle for Cycle { fn add_edges(&self, edges: impl IntoIterator>) -> Self { - let edges = self.edges().cloned().chain(edges); + let edges = self.edges().iter().cloned().chain(edges); Cycle::new(edges) } @@ -47,7 +47,7 @@ impl UpdateCycle for Cycle { ) -> Self { let mut num_replacements = 0; - let edges = self.edges().map(|edge| { + let edges = self.edges().iter().map(|edge| { if edge.id() == original.id() { num_replacements += 1; replacement.clone() @@ -73,7 +73,7 @@ impl UpdateCycle for Cycle { ) -> Self { let mut num_replacements = 0; - let edges = self.edges().enumerate().map(|(i, edge)| { + let edges = self.edges().iter().enumerate().map(|(i, edge)| { if i == index { num_replacements += 1; f(edge) diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index 7fe62e6f2..f32fd4b23 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -26,14 +26,14 @@ impl UpdateRegion for Region { f: impl FnOnce(&Handle) -> Handle, ) -> Self { let exterior = f(self.exterior()); - Region::new(exterior, self.interiors().cloned(), self.color()) + Region::new(exterior, self.interiors().iter().cloned(), self.color()) } fn add_interiors( &self, interiors: impl IntoIterator>, ) -> Self { - let interiors = self.interiors().cloned().chain(interiors); + let interiors = self.interiors().iter().cloned().chain(interiors); Region::new(self.exterior().clone(), interiors, self.color()) } } diff --git a/crates/fj-core/src/operations/update/shell.rs b/crates/fj-core/src/operations/update/shell.rs index 52c9c6f36..eb7d78928 100644 --- a/crates/fj-core/src/operations/update/shell.rs +++ b/crates/fj-core/src/operations/update/shell.rs @@ -24,7 +24,7 @@ pub trait UpdateShell { impl UpdateShell for Shell { fn add_faces(&self, faces: impl IntoIterator>) -> Self { - let faces = self.faces().cloned().chain(faces); + let faces = self.faces().iter().cloned().chain(faces); Shell::new(faces) } @@ -33,7 +33,7 @@ impl UpdateShell for Shell { original: &Handle, replacement: Handle, ) -> Self { - let faces = self.faces().map(|face| { + let faces = self.faces().iter().map(|face| { if face.id() == original.id() { replacement.clone() } else { @@ -47,6 +47,7 @@ impl UpdateShell for Shell { fn remove_face(&self, handle: &Handle) -> Self { let faces = self .faces() + .iter() .filter(|face| face.id() == handle.id()) .cloned(); diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index 87739942a..d81c1f528 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -12,6 +12,6 @@ pub trait UpdateSketch { impl UpdateSketch for Sketch { fn add_region(&self, region: Handle) -> Self { - Sketch::new(self.regions().cloned().chain([region])) + Sketch::new(self.regions().iter().cloned().chain([region])) } } diff --git a/crates/fj-core/src/operations/update/solid.rs b/crates/fj-core/src/operations/update/solid.rs index a1460cb30..21f943fe8 100644 --- a/crates/fj-core/src/operations/update/solid.rs +++ b/crates/fj-core/src/operations/update/solid.rs @@ -18,7 +18,7 @@ impl UpdateSolid for Solid { &self, shells: impl IntoIterator>, ) -> Self { - let shells = self.shells().cloned().chain(shells); + let shells = self.shells().iter().cloned().chain(shells); Solid::new(shells) } } diff --git a/crates/fj-core/src/queries/all_edges_with_surface.rs b/crates/fj-core/src/queries/all_edges_with_surface.rs index 809112594..f77dd4424 100644 --- a/crates/fj-core/src/queries/all_edges_with_surface.rs +++ b/crates/fj-core/src/queries/all_edges_with_surface.rs @@ -21,6 +21,7 @@ impl AllEdgesWithSurface for Face { result.extend( cycle .edges() + .iter() .cloned() .map(|edge| (edge, self.surface().clone())), ); diff --git a/crates/fj-core/src/validate/cycle.rs b/crates/fj-core/src/validate/cycle.rs index e2a63bc6e..81a00b817 100644 --- a/crates/fj-core/src/validate/cycle.rs +++ b/crates/fj-core/src/validate/cycle.rs @@ -51,7 +51,7 @@ impl CycleValidationError { errors: &mut Vec, ) { // If there are no half edges - if cycle.edges().next().is_none() { + if cycle.edges().iter().next().is_none() { errors.push(Self::NotEnoughEdges.into()); } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 7c336d199..da834c3d8 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -38,7 +38,7 @@ pub enum FaceValidationError { impl FaceValidationError { fn check_interior_winding(face: &Face, errors: &mut Vec) { - if face.region().exterior().edges().count() == 0 { + if face.region().exterior().edges().is_empty() { // Can't determine winding, if the cycle has no edges. Sounds like a // job for a different validation check. return; @@ -47,7 +47,7 @@ impl FaceValidationError { let exterior_winding = face.region().exterior().winding(); for interior in face.region().interiors() { - if interior.edges().count() == 0 { + if interior.edges().is_empty() { // Can't determine winding, if the cycle has no edges. Sounds // like a job for a different validation check. continue; @@ -106,6 +106,7 @@ mod tests { let interiors = valid .region() .interiors() + .iter() .cloned() .map(|cycle| cycle.reverse(&mut services).insert(&mut services)) .collect::>(); diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index 550dce114..4c11a405b 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -70,11 +70,12 @@ impl SolidValidationError { ) { let vertices: Vec<(Point<3>, Handle)> = solid .shells() + .iter() .flat_map(|s| s.faces()) .flat_map(|face| { face.region() .all_cycles() - .flat_map(|cycle| cycle.edges().cloned()) + .flat_map(|cycle| cycle.edges().iter().cloned()) .zip(repeat(face.surface().geometry())) }) .map(|(h, s)| {