diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index a1df9dc6f..9c24fbe67 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -10,6 +10,8 @@ use fj_kernel::{ }; use fj_math::Aabb; +use crate::planes::Planes; + use super::Shape; impl Shape for fj::Difference2d { @@ -19,6 +21,7 @@ impl Shape for fj::Difference2d { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { // This method assumes that `b` is fully contained within `a`: @@ -33,8 +36,9 @@ impl Shape for fj::Difference2d { // - https://doc.rust-lang.org/std/primitive.array.html#method.each_ref // - https://doc.rust-lang.org/std/primitive.array.html#method.try_map let [a, b] = self.shapes(); - let [a, b] = - [a, b].map(|shape| shape.compute_brep(config, stores, debug_info)); + let [a, b] = [a, b].map(|shape| { + shape.compute_brep(config, stores, planes, debug_info) + }); let [a, b] = [a?, b?]; if let Some(face) = a.face_iter().next() { diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index 7c4e5672d..bf4670fd6 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -8,6 +8,8 @@ use fj_kernel::{ }; use fj_math::Aabb; +use crate::planes::Planes; + use super::Shape; impl Shape for fj::Group { @@ -17,12 +19,13 @@ impl Shape for fj::Group { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { let mut faces = Faces::new(); - let a = self.a.compute_brep(config, stores, debug_info)?; - let b = self.b.compute_brep(config, stores, debug_info)?; + let a = self.a.compute_brep(config, stores, planes, debug_info)?; + let b = self.b.compute_brep(config, stores, planes, debug_info)?; faces.extend(a.into_inner()); faces.extend(b.into_inner()); diff --git a/crates/fj-operations/src/lib.rs b/crates/fj-operations/src/lib.rs index 8b79b1e67..c87387787 100644 --- a/crates/fj-operations/src/lib.rs +++ b/crates/fj-operations/src/lib.rs @@ -20,10 +20,13 @@ pub mod shape_processor; mod difference_2d; mod group; +mod planes; mod sketch; mod sweep; mod transform; +pub use self::planes::Planes; + use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::validate::{ @@ -44,6 +47,7 @@ pub trait Shape { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError>; @@ -61,19 +65,20 @@ impl Shape for fj::Shape { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { match self { Self::Shape2d(shape) => shape - .compute_brep(config, stores, debug_info)? + .compute_brep(config, stores, planes, debug_info)? .into_inner() .into_faces() .validate_with_config(config), Self::Group(shape) => { - shape.compute_brep(config, stores, debug_info) + shape.compute_brep(config, stores, planes, debug_info) } Self::Sweep(shape) => shape - .compute_brep(config, stores, debug_info)? + .compute_brep(config, stores, planes, debug_info)? .into_inner() .into_shells() .map(|shell| shell.into_faces()) @@ -84,7 +89,7 @@ impl Shape for fj::Shape { .unwrap_or_default() .validate_with_config(config), Self::Transform(shape) => { - shape.compute_brep(config, stores, debug_info) + shape.compute_brep(config, stores, planes, debug_info) } } } @@ -106,14 +111,15 @@ impl Shape for fj::Shape2d { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { match self { Self::Difference(shape) => { - shape.compute_brep(config, stores, debug_info) + shape.compute_brep(config, stores, planes, debug_info) } Self::Sketch(shape) => { - shape.compute_brep(config, stores, debug_info) + shape.compute_brep(config, stores, planes, debug_info) } } } diff --git a/crates/fj-operations/src/planes.rs b/crates/fj-operations/src/planes.rs new file mode 100644 index 000000000..584e2b1ec --- /dev/null +++ b/crates/fj-operations/src/planes.rs @@ -0,0 +1,50 @@ +use fj_kernel::{ + objects::Surface, + stores::{Handle, Stores}, +}; + +/// The static planes +/// +/// Keeps [`Handle`]s to the xy-, xz- and yz-planes. The purpose of this struct +/// is to provide these handles to implementations of [`Shape`], so they don't +/// have to create a duplicate `Surface` whenever they need one of those. +/// +/// [`Shape`]: crate::Shape +pub struct Planes { + xy: Handle, + xz: Handle, + yz: Handle, +} + +impl Planes { + /// Create a new instance of `Planes` + /// + /// Please note that the whole point of this struct is to not duplicate the + /// standard planes, and creating multiple instances of it defeats that + /// point. + /// + /// Create one instance of this struct, then share it everywhere it's + /// needed. + pub fn new(stores: &Stores) -> Self { + let xy = stores.surfaces.insert(Surface::xy_plane()); + let xz = stores.surfaces.insert(Surface::xz_plane()); + let yz = stores.surfaces.insert(Surface::yz_plane()); + + Self { xy, xz, yz } + } + + /// Access the xy-plane + pub fn xy(&self) -> Handle { + self.xy.clone() + } + + /// Access the xz-plane + pub fn xz(&self) -> Handle { + self.xz.clone() + } + + /// Access the yz-plane + pub fn yz(&self) -> Handle { + self.yz.clone() + } +} diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index e66f89bd3..0800fcbfd 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -11,7 +11,7 @@ use fj_kernel::{ }; use fj_math::Scalar; -use crate::Shape as _; +use crate::{planes::Planes, Shape as _}; /// Processes an [`fj::Shape`] into a [`ProcessedShape`] pub struct ShapeProcessor { @@ -44,8 +44,10 @@ impl ShapeProcessor { let config = ValidationConfig::default(); let stores = Stores::new(); + let planes = Planes::new(&stores); let mut debug_info = DebugInfo::new(); - let shape = shape.compute_brep(&config, &stores, &mut debug_info)?; + let shape = + shape.compute_brep(&config, &stores, &planes, &mut debug_info)?; let mesh = (&shape.into_inner(), tolerance).triangulate(); Ok(ProcessedShape { diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 7ab36767d..62ee23263 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -3,12 +3,14 @@ use fj_kernel::{ algorithms::validate::{ Validate, Validated, ValidationConfig, ValidationError, }, - objects::{Cycle, Face, HalfEdge, Sketch, Surface}, + objects::{Cycle, Face, HalfEdge, Sketch}, partial::HasPartial, stores::Stores, }; use fj_math::{Aabb, Point}; +use crate::planes::Planes; + use super::Shape; impl Shape for fj::Sketch { @@ -18,9 +20,10 @@ impl Shape for fj::Sketch { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, _: &mut DebugInfo, ) -> Result, ValidationError> { - let surface = stores.surfaces.insert(Surface::xy_plane()); + let surface = planes.xy(); let face = match self.chain() { fj::Chain::Circle(circle) => { diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 67a7f00a7..15438e4a3 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -9,6 +9,8 @@ use fj_kernel::{ }; use fj_math::{Aabb, Vector}; +use crate::planes::Planes; + use super::Shape; impl Shape for fj::Sweep { @@ -18,9 +20,12 @@ impl Shape for fj::Sweep { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { - let sketch = self.shape().compute_brep(config, stores, debug_info)?; + let sketch = self + .shape() + .compute_brep(config, stores, planes, debug_info)?; let path = Vector::from(self.path()); let solid = sketch.into_inner().sweep(path, stores); diff --git a/crates/fj-operations/src/transform.rs b/crates/fj-operations/src/transform.rs index 5b79c1b53..959993883 100644 --- a/crates/fj-operations/src/transform.rs +++ b/crates/fj-operations/src/transform.rs @@ -9,6 +9,8 @@ use fj_kernel::{ }; use fj_math::{Aabb, Transform, Vector}; +use crate::planes::Planes; + use super::Shape; impl Shape for fj::Transform { @@ -18,11 +20,12 @@ impl Shape for fj::Transform { &self, config: &ValidationConfig, stores: &Stores, + planes: &Planes, debug_info: &mut DebugInfo, ) -> Result, ValidationError> { let faces = self .shape - .compute_brep(config, stores, debug_info)? + .compute_brep(config, stores, planes, debug_info)? .into_inner() .transform(&make_transform(self), stores);