diff --git a/crates/fj-operations/src/circle.rs b/crates/fj-operations/src/circle.rs index f80703a16..cebc6d7da 100644 --- a/crates/fj-operations/src/circle.rs +++ b/crates/fj-operations/src/circle.rs @@ -15,31 +15,31 @@ impl ToShape for fj::Circle { config: &ValidationConfig, _: Tolerance, _: &mut DebugInfo, - ) -> Result, ValidationError> { - let mut shape = Shape::new(); + ) -> Result>, ValidationError> { + let mut tmp = Shape::new(); // Circles have just a single round edge with no vertices. So none need // to be added here. - let edge = Edge::builder(&mut shape) + let edge = Edge::builder(&mut tmp) .build_circle(Scalar::from_f64(self.radius())); let cycle_local = Cycle { edges: vec![edge.clone()], }; - let cycle_canonical = shape.insert(Cycle::new(vec![edge.canonical()])); - - let surface = shape.insert(Surface::xy_plane()); - shape.insert(Face::new( - surface, - vec![LocalForm::new(cycle_local, cycle_canonical)], - Vec::new(), - self.color(), - )); - - let shape = validate(shape, config)?; - - Ok(shape) + let cycle_canonical = tmp.insert(Cycle::new(vec![edge.canonical()])); + + let surface = tmp.insert(Surface::xy_plane()); + let face = tmp + .insert(Face::new( + surface, + vec![LocalForm::new(cycle_local, cycle_canonical)], + Vec::new(), + self.color(), + )) + .get(); + + validate(vec![face], config) } fn bounding_volume(&self) -> Aabb<3> { diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index 1ed752f9f..2b4dc09f4 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -1,6 +1,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, + iter::ObjectIters, objects::{Cycle, Edge, Face}, shape::{LocalForm, Shape}, validation::{validate, Validated, ValidationConfig, ValidationError}, @@ -15,11 +16,11 @@ impl ToShape for fj::Difference2d { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError> { + ) -> Result>, ValidationError> { // This method assumes that `b` is fully contained within `a`: // https://github.com/hannobraun/Fornjot/issues/92 - let mut difference = Shape::new(); + let mut difference = Vec::new(); let mut exteriors = Vec::new(); let mut interiors = Vec::new(); @@ -32,13 +33,12 @@ impl ToShape for fj::Difference2d { [a, b].map(|shape| shape.to_shape(config, tolerance, debug_info)); let [a, b] = [a?, b?]; - if let Some(face) = a.faces().next() { + if let Some(face) = a.face_iter().next() { // If there's at least one face to subtract from, we can proceed. - let surface = face.get().brep().surface.clone(); + let surface = face.brep().surface.clone(); - for face in a.faces() { - let face = face.get(); + for face in a.face_iter() { let face = face.brep(); assert_eq!( @@ -48,17 +48,16 @@ impl ToShape for fj::Difference2d { ); for cycle in face.exteriors.as_local_form().cloned() { - let cycle = add_cycle(cycle, &mut difference, false); + let cycle = add_cycle(cycle, false); exteriors.push(cycle); } for cycle in face.interiors.as_local_form().cloned() { - let cycle = add_cycle(cycle, &mut difference, true); + let cycle = add_cycle(cycle, true); interiors.push(cycle); } } - for face in b.faces() { - let face = face.get(); + for face in b.face_iter() { let face = face.brep(); assert_eq!( @@ -68,12 +67,12 @@ impl ToShape for fj::Difference2d { ); for cycle in face.exteriors.as_local_form().cloned() { - let cycle = add_cycle(cycle, &mut difference, true); + let cycle = add_cycle(cycle, true); interiors.push(cycle); } } - difference.merge(Face::new( + difference.push(Face::new( surface, exteriors, interiors, @@ -81,9 +80,7 @@ impl ToShape for fj::Difference2d { )); } - let difference = validate(difference, config)?; - - Ok(difference) + validate(difference, config) } fn bounding_volume(&self) -> Aabb<3> { @@ -96,9 +93,10 @@ impl ToShape for fj::Difference2d { fn add_cycle( cycle: LocalForm, Cycle<3>>, - shape: &mut Shape, reverse: bool, ) -> LocalForm, Cycle<3>> { + let mut tmp = Shape::new(); + let mut edges = Vec::new(); for edge in cycle.local().edges.clone() { let curve_local = *edge.local().curve.local(); @@ -114,7 +112,7 @@ fn add_cycle( } else { curve_canonical }; - let curve_canonical = shape.insert(curve_canonical); + let curve_canonical = tmp.insert(curve_canonical); let vertices = if reverse { edge.local().vertices.clone().reverse() @@ -126,7 +124,7 @@ fn add_cycle( curve: LocalForm::new(curve_local, curve_canonical.clone()), vertices: vertices.clone(), }; - let edge_canonical = shape.merge(Edge { + let edge_canonical = tmp.merge(Edge { curve: LocalForm::canonical_only(curve_canonical), vertices, }); @@ -141,8 +139,8 @@ fn add_cycle( let cycle_local = Cycle { edges: edges.clone(), }; - let cycle_canonical = shape - .insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical()))); + let cycle_canonical = + tmp.insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical()))); LocalForm::new(cycle_local, cycle_canonical) } diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index 560584cd7..e873b1d1f 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -1,7 +1,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, - shape::Shape, + objects::Face, validation::{validate, Validated, ValidationConfig, ValidationError}, }; use fj_math::Aabb; @@ -14,18 +14,16 @@ impl ToShape for fj::Group { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError> { - let mut shape = Shape::new(); + ) -> Result>, ValidationError> { + let mut shape = Vec::new(); let a = self.a.to_shape(config, tolerance, debug_info)?; let b = self.b.to_shape(config, tolerance, debug_info)?; - shape.merge_shape(&a); - shape.merge_shape(&b); + shape.extend(a.into_inner()); + shape.extend(b.into_inner()); - let shape = validate(shape, config)?; - - Ok(shape) + validate(shape, config) } fn bounding_volume(&self) -> Aabb<3> { diff --git a/crates/fj-operations/src/lib.rs b/crates/fj-operations/src/lib.rs index f8836bf30..bcd294fd8 100644 --- a/crates/fj-operations/src/lib.rs +++ b/crates/fj-operations/src/lib.rs @@ -28,7 +28,7 @@ mod transform; use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, - shape::Shape, + objects::Face, validation::{Validated, ValidationConfig, ValidationError}, }; use fj_math::Aabb; @@ -41,7 +41,7 @@ pub trait ToShape { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError>; + ) -> Result>, ValidationError>; /// Access the axis-aligned bounding box of a shape /// @@ -94,6 +94,6 @@ dispatch! { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError>; + ) -> Result>, ValidationError>; bounding_volume() -> Aabb<3>; } diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index b7eb835ac..de2d67c82 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -40,12 +40,8 @@ impl ShapeProcessor { let config = ValidationConfig::default(); let mut debug_info = DebugInfo::new(); - let shape = shape - .to_shape(&config, tolerance, &mut debug_info)? - .faces() - .map(|handle| handle.get()) - .collect(); - let mesh = triangulate(shape, tolerance, &mut debug_info); + let shape = shape.to_shape(&config, tolerance, &mut debug_info)?; + let mesh = triangulate(shape.into_inner(), tolerance, &mut debug_info); Ok(ProcessedShape { aabb, diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 772873fa8..40678a332 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -15,20 +15,19 @@ impl ToShape for fj::Sketch { config: &ValidationConfig, _: Tolerance, _: &mut DebugInfo, - ) -> Result, ValidationError> { - let mut shape = Shape::new(); + ) -> Result>, ValidationError> { + let mut tmp = Shape::new(); let surface = Surface::xy_plane(); let points = self.to_points().into_iter().map(Point::from); - Face::builder(surface, &mut shape) + let sketch = Face::builder(surface, &mut tmp) .with_exterior_polygon(points) .with_color(self.color()) - .build(); + .build() + .get(); - let shape = validate(shape, config)?; - - Ok(shape) + validate(vec![sketch], config) } fn bounding_volume(&self) -> Aabb<3> { diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 90c3bd915..0f4ef5c86 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -1,8 +1,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{sweep, Tolerance}, - iter::ObjectIters, - shape::Shape, + objects::Face, validation::{validate, Validated, ValidationConfig, ValidationError}, }; use fj_math::{Aabb, Vector}; @@ -15,22 +14,14 @@ impl ToShape for fj::Sweep { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError> { - let shape = self.shape().to_shape(config, tolerance, debug_info)?; + ) -> Result>, ValidationError> { + let sketch = self.shape().to_shape(config, tolerance, debug_info)?; let path = Vector::from(self.path()); let color = self.shape().color(); - let shape = shape.face_iter().collect::>(); - let swept = sweep(shape, path, tolerance, color); + let solid = sweep(sketch.into_inner(), path, tolerance, color); - let mut shape = Shape::new(); - for face in swept { - shape.merge(face); - } - - let swept = validate(shape, config)?; - - Ok(swept) + validate(solid, config) } fn bounding_volume(&self) -> Aabb<3> { diff --git a/crates/fj-operations/src/transform.rs b/crates/fj-operations/src/transform.rs index 39eb98380..07f4868e7 100644 --- a/crates/fj-operations/src/transform.rs +++ b/crates/fj-operations/src/transform.rs @@ -1,8 +1,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{transform, Tolerance}, - iter::ObjectIters, - shape::Shape, + objects::Face, validation::{validate, Validated, ValidationConfig, ValidationError}, }; use fj_math::{Aabb, Transform, Vector}; @@ -15,21 +14,10 @@ impl ToShape for fj::Transform { config: &ValidationConfig, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result, ValidationError> { + ) -> Result>, ValidationError> { let shape = self.shape.to_shape(config, tolerance, debug_info)?; - let shape = shape.into_inner(); - - let shape = shape.face_iter().collect::>(); - let faces = transform(&shape, &make_transform(self)); - - let mut target = Shape::new(); - for face in faces { - target.merge(face); - } - - let shape = validate(target, config)?; - - Ok(shape) + let faces = transform(&shape.into_inner(), &make_transform(self)); + validate(faces, config) } fn bounding_volume(&self) -> Aabb<3> {