From 21b14abf23552dfaf57fbb1fd57ee704fe02c33b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:34:11 +0200 Subject: [PATCH 01/28] Move `Region` to `objects` module This is preparation for promoting it to an object. --- crates/fj-core/src/geometry/mod.rs | 1 - crates/fj-core/src/objects/kinds/face.rs | 3 +-- crates/fj-core/src/objects/kinds/mod.rs | 1 + crates/fj-core/src/{geometry => objects/kinds}/region.rs | 0 crates/fj-core/src/objects/kinds/sketch.rs | 3 +-- crates/fj-core/src/objects/mod.rs | 1 + crates/fj-core/src/operations/update/sketch.rs | 3 +-- 7 files changed, 5 insertions(+), 7 deletions(-) rename crates/fj-core/src/{geometry => objects/kinds}/region.rs (100%) diff --git a/crates/fj-core/src/geometry/mod.rs b/crates/fj-core/src/geometry/mod.rs index 6d34554b1..af0cf08f9 100644 --- a/crates/fj-core/src/geometry/mod.rs +++ b/crates/fj-core/src/geometry/mod.rs @@ -1,5 +1,4 @@ //! Types that are tied to objects, but aren't objects themselves pub mod curve; -pub mod region; pub mod surface; diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index 5b62e7f19..f5a998431 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -4,8 +4,7 @@ use fj_interop::mesh::Color; use fj_math::Winding; use crate::{ - geometry::region::Region, - objects::{Cycle, Surface}, + objects::{Cycle, Region, Surface}, storage::Handle, }; diff --git a/crates/fj-core/src/objects/kinds/mod.rs b/crates/fj-core/src/objects/kinds/mod.rs index 2261d4905..cf531b35e 100644 --- a/crates/fj-core/src/objects/kinds/mod.rs +++ b/crates/fj-core/src/objects/kinds/mod.rs @@ -1,6 +1,7 @@ pub mod cycle; pub mod edge; pub mod face; +pub mod region; pub mod shell; pub mod sketch; pub mod solid; diff --git a/crates/fj-core/src/geometry/region.rs b/crates/fj-core/src/objects/kinds/region.rs similarity index 100% rename from crates/fj-core/src/geometry/region.rs rename to crates/fj-core/src/objects/kinds/region.rs diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index 3baebb2a0..e768e18e8 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -1,8 +1,7 @@ use std::collections::BTreeSet; use crate::{ - geometry::region::Region, - objects::{FaceSet, Surface}, + objects::{FaceSet, Region, Surface}, services::Services, storage::Handle, }; diff --git a/crates/fj-core/src/objects/mod.rs b/crates/fj-core/src/objects/mod.rs index eb85cf1dc..0de859e33 100644 --- a/crates/fj-core/src/objects/mod.rs +++ b/crates/fj-core/src/objects/mod.rs @@ -49,6 +49,7 @@ pub use self::{ cycle::{Cycle, HalfEdgesOfCycle}, edge::{GlobalEdge, HalfEdge}, face::{Face, FaceSet, Handedness}, + region::Region, shell::Shell, sketch::Sketch, solid::Solid, diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index 42f518cb8..b04eb50fb 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -1,8 +1,7 @@ use fj_math::{Point, Scalar}; use crate::{ - geometry::region::Region, - objects::{Cycle, Sketch}, + objects::{Cycle, Region, Sketch}, operations::{BuildCycle, Insert}, services::Services, }; From 787881623a2c13e4268ef959758e3fbe92195135 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:37:59 +0200 Subject: [PATCH 02/28] Extract non-trivial expression to improve clarity --- crates/fj-core/src/algorithms/sweep/edge.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index 1868d1eb8..a10fa28b7 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -22,6 +22,9 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { let (edge, next_vertex, surface, color) = self; let path = path.into(); + let surface = + (edge.curve(), surface).sweep_with_cache(path, cache, services); + // Next, we need to define the boundaries of the face. Let's start with // the global vertices and edges. let (vertices, global_edges) = { @@ -105,7 +108,7 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { }); let face = Face::new( - (edge.curve(), surface).sweep_with_cache(path, cache, services), + surface, exterior.unwrap().insert(services), Vec::new(), color, From 52be3559c2d15a6ac62f6efb2c030d40aa3011ea Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:38:44 +0200 Subject: [PATCH 03/28] Simplify argument --- crates/fj-core/src/algorithms/sweep/edge.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index a10fa28b7..1e4b8c3a5 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -107,12 +107,8 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { half_edge }); - let face = Face::new( - surface, - exterior.unwrap().insert(services), - Vec::new(), - color, - ); + let face = + Face::new(surface, exterior.unwrap().insert(services), [], color); // And we're done creating the face! All that's left to do is build our // return values. From 4944355836ad93a2375057d65bbc20086d01dc8b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:42:27 +0200 Subject: [PATCH 04/28] Expect `Region` in `Face::new` This is more preparation for turning `Region` into an object. --- crates/fj-core/src/algorithms/reverse/face.rs | 9 ++++++--- crates/fj-core/src/algorithms/sweep/edge.rs | 6 +++--- crates/fj-core/src/algorithms/sweep/face.rs | 6 +++--- .../fj-core/src/algorithms/transform/face.rs | 5 +++-- crates/fj-core/src/objects/kinds/face.rs | 12 ++--------- crates/fj-core/src/objects/kinds/region.rs | 7 +------ crates/fj-core/src/operations/build/face.rs | 8 +++++--- crates/fj-core/src/operations/update/face.rs | 20 +++++++------------ crates/fj-core/src/validate/face.rs | 11 ++++------ 9 files changed, 34 insertions(+), 50 deletions(-) diff --git a/crates/fj-core/src/algorithms/reverse/face.rs b/crates/fj-core/src/algorithms/reverse/face.rs index a12043af5..4d15d90a5 100644 --- a/crates/fj-core/src/algorithms/reverse/face.rs +++ b/crates/fj-core/src/algorithms/reverse/face.rs @@ -1,5 +1,8 @@ use crate::{ - objects::Face, operations::Insert, services::Services, storage::Handle, + objects::{Face, Region}, + operations::Insert, + services::Services, + storage::Handle, }; use super::Reverse; @@ -12,7 +15,7 @@ impl Reverse for Handle { .map(|cycle| cycle.clone().reverse(services)) .collect::>(); - Face::new(self.surface().clone(), exterior, interiors, self.color()) - .insert(services) + let region = Region::new(exterior, interiors, self.color()); + Face::new(self.surface().clone(), region).insert(services) } } diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index 1e4b8c3a5..281566ae2 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -2,7 +2,7 @@ use fj_interop::{ext::ArrayExt, mesh::Color}; use fj_math::{Point, Scalar, Vector}; use crate::{ - objects::{Cycle, Face, HalfEdge, Surface, Vertex}, + objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex}, operations::{BuildHalfEdge, Insert, UpdateCycle, UpdateHalfEdge}, services::Services, storage::Handle, @@ -107,8 +107,8 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { half_edge }); - let face = - Face::new(surface, exterior.unwrap().insert(services), [], color); + let region = Region::new(exterior.unwrap().insert(services), [], color); + let face = Face::new(surface, region); // And we're done creating the face! All that's left to do is build our // return values. diff --git a/crates/fj-core/src/algorithms/sweep/face.rs b/crates/fj-core/src/algorithms/sweep/face.rs index 5b59cc6d5..7506f5a8c 100644 --- a/crates/fj-core/src/algorithms/sweep/face.rs +++ b/crates/fj-core/src/algorithms/sweep/face.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use crate::{ algorithms::{reverse::Reverse, transform::TransformObject}, geometry::curve::GlobalPath, - objects::{Cycle, Face, Shell}, + objects::{Cycle, Face, Region, Shell}, operations::{BuildCycle, Insert, JoinCycle}, services::Services, storage::Handle, @@ -92,8 +92,8 @@ impl Sweep for Handle { }; } - let top_face = - Face::new(top_surface, exterior.unwrap(), interiors, self.color()); + let region = Region::new(exterior.unwrap(), interiors, self.color()); + let top_face = Face::new(top_surface, region); let top_face = top_face.insert(services); faces.push(top_face); diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index cd3c5cd81..a1697b4e1 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -1,7 +1,7 @@ use fj_math::Transform; use crate::{ - objects::{Face, FaceSet}, + objects::{Face, FaceSet, Region}, services::Services, }; @@ -29,7 +29,8 @@ impl TransformObject for Face { interior.transform_with_cache(transform, services, cache) }); - Self::new(surface, exterior, interiors, color) + let region = Region::new(exterior, interiors, color); + Self::new(surface, region) } } diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index f5a998431..c00df24de 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -40,16 +40,8 @@ pub struct Face { impl Face { /// Construct an instance of `Face` - pub fn new( - surface: Handle, - exterior: Handle, - interiors: impl IntoIterator>, - color: Option, - ) -> Self { - Self { - surface, - region: Region::new(exterior, interiors, color), - } + pub fn new(surface: Handle, region: Region) -> Self { + Self { surface, region } } /// Access the surface of the face diff --git a/crates/fj-core/src/objects/kinds/region.rs b/crates/fj-core/src/objects/kinds/region.rs index e854408eb..7ad429226 100644 --- a/crates/fj-core/src/objects/kinds/region.rs +++ b/crates/fj-core/src/objects/kinds/region.rs @@ -66,12 +66,7 @@ impl Region { surface: Handle, services: &mut Services, ) -> Handle { - let face: Face = Face::new( - surface, - self.exterior().clone(), - self.interiors().cloned(), - self.color, - ); + let face: Face = Face::new(surface, self.clone()); face.insert(services) } } diff --git a/crates/fj-core/src/operations/build/face.rs b/crates/fj-core/src/operations/build/face.rs index 4146367a2..6403fd35d 100644 --- a/crates/fj-core/src/operations/build/face.rs +++ b/crates/fj-core/src/operations/build/face.rs @@ -2,7 +2,7 @@ use fj_interop::ext::ArrayExt; use fj_math::Point; use crate::{ - objects::{Cycle, Face, HalfEdge, Surface, Vertex}, + objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex}, operations::{ BuildCycle, BuildHalfEdge, BuildSurface, Insert, IsInserted, IsInsertedNo, @@ -16,7 +16,8 @@ pub trait BuildFace { /// Build a face with an empty exterior, no interiors, and no color fn unbound(surface: Handle, services: &mut Services) -> Face { let exterior = Cycle::empty().insert(services); - Face::new(surface, exterior, [], None) + let region = Region::new(exterior, [], None); + Face::new(surface, region) } /// Build a triangle @@ -44,7 +45,8 @@ pub trait BuildFace { (cycle, half_edges, vertices) }; - let face = Face::new(surface, exterior, [], None); + let region = Region::new(exterior, [], None); + let face = Face::new(surface, region); Polygon { face, diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 6e41a25ff..46ba02ef1 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -1,7 +1,7 @@ use std::array; use crate::{ - objects::{Cycle, Face}, + objects::{Cycle, Face, Region}, operations::Polygon, storage::Handle, }; @@ -28,12 +28,9 @@ impl UpdateFace for Face { ) -> Self { let exterior = f(self.exterior()); - Face::new( - self.surface().clone(), - exterior, - self.interiors().cloned(), - self.color(), - ) + let region = + Region::new(exterior, self.interiors().cloned(), self.color()); + Face::new(self.surface().clone(), region) } fn add_interiors( @@ -42,12 +39,9 @@ impl UpdateFace for Face { ) -> Self { let interiors = self.interiors().cloned().chain(interiors); - Face::new( - self.surface().clone(), - self.exterior().clone(), - interiors, - self.color(), - ) + let region = + Region::new(self.exterior().clone(), interiors, self.color()); + Face::new(self.surface().clone(), region) } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 33b31c0f9..36cb611d8 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -73,7 +73,7 @@ mod tests { use crate::{ algorithms::reverse::Reverse, assert_contains_err, - objects::{Cycle, Face}, + objects::{Cycle, Face, Region}, operations::{BuildCycle, BuildFace, Insert, UpdateFace}, services::Services, validate::{FaceValidationError, Validate, ValidationError}, @@ -104,12 +104,9 @@ mod tests { .map(|cycle| cycle.reverse(&mut services)) .collect::>(); - Face::new( - valid.surface().clone(), - valid.exterior().clone(), - interiors, - valid.color(), - ) + let region = + Region::new(valid.exterior().clone(), interiors, valid.color()); + Face::new(valid.surface().clone(), region) }; valid.validate_and_return_first_error()?; From 82e28e30077f4c0c096f7b565c19900d773703a9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:44:34 +0200 Subject: [PATCH 05/28] Add store for `Region` --- crates/fj-core/src/objects/stores.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/objects/stores.rs b/crates/fj-core/src/objects/stores.rs index b6270e48d..13783e398 100644 --- a/crates/fj-core/src/objects/stores.rs +++ b/crates/fj-core/src/objects/stores.rs @@ -6,7 +6,8 @@ use crate::{ }; use super::{ - Cycle, Face, GlobalEdge, HalfEdge, Shell, Sketch, Solid, Surface, Vertex, + Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, Surface, + Vertex, }; /// The available object stores @@ -24,6 +25,9 @@ pub struct Objects { /// Store for [`HalfEdge`]s pub half_edges: Store, + /// Store for [`Region`]s + pub regions: Store, + /// Store for [`Shell`]s pub shells: Store, From f703bd91163ded4cae2c5179f90e740c426719c9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:46:46 +0200 Subject: [PATCH 06/28] Fix typo in comment --- crates/fj-core/src/validate/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/validate/mod.rs b/crates/fj-core/src/validate/mod.rs index d8530b545..68d0d6144 100644 --- a/crates/fj-core/src/validate/mod.rs +++ b/crates/fj-core/src/validate/mod.rs @@ -19,7 +19,7 @@ use std::convert::Infallible; use fj_math::Scalar; -/// Assert that some object has a validation error which matches a specifc pattern. +/// Assert that some object has a validation error which matches a specific pattern. /// This is preferred to matching on [`Validate::validate_and_return_first_error`], since usually we don't care about the order. #[macro_export] macro_rules! assert_contains_err { From 97b167b0f7ac8e7cd9e4413d7126be1bcd4020e4 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:47:01 +0200 Subject: [PATCH 07/28] Fix formatting --- crates/fj-core/src/validate/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/validate/mod.rs b/crates/fj-core/src/validate/mod.rs index 68d0d6144..006527f66 100644 --- a/crates/fj-core/src/validate/mod.rs +++ b/crates/fj-core/src/validate/mod.rs @@ -19,8 +19,8 @@ use std::convert::Infallible; use fj_math::Scalar; -/// Assert that some object has a validation error which matches a specific pattern. -/// This is preferred to matching on [`Validate::validate_and_return_first_error`], since usually we don't care about the order. +/// Assert that some object has a validation error which matches a specific +/// pattern. This is preferred to matching on [`Validate::validate_and_return_first_error`], since usually we don't care about the order. #[macro_export] macro_rules! assert_contains_err { ($o:tt,$p:pat) => { From 527bebb9099d2fd04f28c8444661c0d00bdefa2b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:47:11 +0200 Subject: [PATCH 08/28] Implement `Validate` for `Region` --- crates/fj-core/src/validate/mod.rs | 1 + crates/fj-core/src/validate/region.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 crates/fj-core/src/validate/region.rs diff --git a/crates/fj-core/src/validate/mod.rs b/crates/fj-core/src/validate/mod.rs index 006527f66..9e93a26dc 100644 --- a/crates/fj-core/src/validate/mod.rs +++ b/crates/fj-core/src/validate/mod.rs @@ -3,6 +3,7 @@ mod cycle; mod edge; mod face; +mod region; mod shell; mod sketch; mod solid; diff --git a/crates/fj-core/src/validate/region.rs b/crates/fj-core/src/validate/region.rs new file mode 100644 index 000000000..3cd0ae87b --- /dev/null +++ b/crates/fj-core/src/validate/region.rs @@ -0,0 +1,12 @@ +use crate::objects::Region; + +use super::{Validate, ValidationConfig, ValidationError}; + +impl Validate for Region { + fn validate_with_config( + &self, + _: &ValidationConfig, + _: &mut Vec, + ) { + } +} From 495d2af5a6da6f57cf78ac3d48c9cc23862bf38f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:47:38 +0200 Subject: [PATCH 09/28] Add `Region` to `Object` --- crates/fj-core/src/objects/object.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/objects/object.rs b/crates/fj-core/src/objects/object.rs index a53840009..d8ca56152 100644 --- a/crates/fj-core/src/objects/object.rs +++ b/crates/fj-core/src/objects/object.rs @@ -1,7 +1,7 @@ use crate::{ objects::{ - Cycle, Face, GlobalEdge, HalfEdge, Objects, Shell, Sketch, Solid, - Surface, Vertex, + Cycle, Face, GlobalEdge, HalfEdge, Objects, Region, Shell, Sketch, + Solid, Surface, Vertex, }, storage::{Handle, HandleWrapper, ObjectId}, validate::{Validate, ValidationError}, @@ -95,6 +95,7 @@ object!( Face, "face", faces; GlobalEdge, "global edge", global_edges; HalfEdge, "half-edge", half_edges; + Region, "region", regions; Shell, "shell", shells; Sketch, "sketch", sketches; Solid, "solid", solids; From c0ad4862bafd6a40223077a4923458c6957152fd Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:48:06 +0200 Subject: [PATCH 10/28] Implement `Insert` for `Region` --- crates/fj-core/src/operations/insert.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/insert.rs b/crates/fj-core/src/operations/insert.rs index 66b6a1b42..4cba47b4f 100644 --- a/crates/fj-core/src/operations/insert.rs +++ b/crates/fj-core/src/operations/insert.rs @@ -1,7 +1,7 @@ use crate::{ objects::{ - Cycle, Face, GlobalEdge, HalfEdge, Shell, Sketch, Solid, Surface, - Vertex, + Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, + Surface, Vertex, }, services::Services, storage::Handle, @@ -46,6 +46,7 @@ impl_insert!( Face, faces; GlobalEdge, global_edges; HalfEdge, half_edges; + Region, regions; Shell, shells; Sketch, sketches; Solid, solids; From e4f0be687a7d54cc5317c395ba41e2ff70a31cfb Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:56:04 +0200 Subject: [PATCH 11/28] Make argument name more explicit --- crates/fj-core/src/objects/kinds/sketch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index e768e18e8..dc1e0e0a8 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -33,7 +33,7 @@ impl Sketch { ) -> FaceSet { self.regions .iter() - .map(|r| r.face(surface.clone(), services)) + .map(|region| region.face(surface.clone(), services)) .collect() } } From a37f9c7a1a9c967bfa781a26130803115e42008a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:59:16 +0200 Subject: [PATCH 12/28] Simplify docs to prepare for follow-on change --- crates/fj-core/src/objects/kinds/region.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/fj-core/src/objects/kinds/region.rs b/crates/fj-core/src/objects/kinds/region.rs index 7ad429226..d7608812e 100644 --- a/crates/fj-core/src/objects/kinds/region.rs +++ b/crates/fj-core/src/objects/kinds/region.rs @@ -8,8 +8,7 @@ use crate::{ storage::Handle, }; -/// A single, continuous 2d region, may contain holes. Once applied to a -/// [`Surface`] becomes a [`Face`] +/// A single, continuous 2d region, may contain holes /// /// Interior cycles must have the opposite winding of the exterior cycle, /// meaning on the front side of the region, they must appear clockwise. This From 01c0feba7da1f6017f2cd10178bb5cf68b23f765 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 11:57:40 +0200 Subject: [PATCH 13/28] Remove `Region::face` It has become redundant with `Face::new`. In addition, it will no longer be possible to support it, once `Region` becomes a full-blown object, as a `Handle` would be needed there. --- crates/fj-core/src/objects/kinds/region.rs | 17 +---------------- crates/fj-core/src/objects/kinds/sketch.rs | 7 +++++-- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/crates/fj-core/src/objects/kinds/region.rs b/crates/fj-core/src/objects/kinds/region.rs index d7608812e..1235c20b7 100644 --- a/crates/fj-core/src/objects/kinds/region.rs +++ b/crates/fj-core/src/objects/kinds/region.rs @@ -1,12 +1,7 @@ //! A single, continues 2d region use fj_interop::mesh::Color; -use crate::{ - objects::{Cycle, Face, Surface}, - operations::Insert, - services::Services, - storage::Handle, -}; +use crate::{objects::Cycle, storage::Handle}; /// A single, continuous 2d region, may contain holes /// @@ -58,14 +53,4 @@ impl Region { pub fn color(&self) -> Option { self.color } - - /// Convert the 2D region to a 3D face, by applying it to a surface. - pub fn face( - &self, - surface: Handle, - services: &mut Services, - ) -> Handle { - let face: Face = Face::new(surface, self.clone()); - face.insert(services) - } } diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index dc1e0e0a8..20ba58e25 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -1,7 +1,8 @@ use std::collections::BTreeSet; use crate::{ - objects::{FaceSet, Region, Surface}, + objects::{Face, FaceSet, Region, Surface}, + operations::Insert, services::Services, storage::Handle, }; @@ -33,7 +34,9 @@ impl Sketch { ) -> FaceSet { self.regions .iter() - .map(|region| region.face(surface.clone(), services)) + .map(|region| { + Face::new(surface.clone(), region.clone()).insert(services) + }) .collect() } } From 0943f415490456d2c60d2107827af99c74abe0c6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:02:11 +0200 Subject: [PATCH 14/28] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/update/sketch.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index b04eb50fb..d16d8fb9e 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -39,7 +39,8 @@ impl UpdateSketch for Sketch { services: &mut Services, ) -> Self { let exterior = Cycle::circle(center, radius, services).insert(services); - self.add_region(Region::new(exterior, [], None)) + let region = Region::new(exterior, [], None); + self.add_region(region) } fn add_polygon(&self, points: Ps, services: &mut Services) -> Self @@ -49,6 +50,7 @@ impl UpdateSketch for Sketch { Ps::IntoIter: Clone + ExactSizeIterator, { let exterior = Cycle::polygon(points, services).insert(services); - self.add_region(Region::new(exterior, [], None)) + let region = Region::new(exterior, [], None); + self.add_region(region) } } From b20d7c1d2b8c9900c4758e17fb5c6cfcdbf9bf7f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:03:10 +0200 Subject: [PATCH 15/28] Expect `Handle` in `UpdateSketch` method --- crates/fj-core/src/operations/update/sketch.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index d16d8fb9e..e285a1740 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -4,12 +4,13 @@ use crate::{ objects::{Cycle, Region, Sketch}, operations::{BuildCycle, Insert}, services::Services, + storage::Handle, }; /// Update a [`Sketch`] pub trait UpdateSketch { /// Add a region to the sketch - fn add_region(&self, region: Region) -> Self; + fn add_region(&self, region: Handle) -> Self; /// Add a circle to the sketch fn add_circle( @@ -28,8 +29,8 @@ pub trait UpdateSketch { } impl UpdateSketch for Sketch { - fn add_region(&self, region: Region) -> Self { - Sketch::new(self.regions().cloned().chain([region])) + fn add_region(&self, region: Handle) -> Self { + Sketch::new(self.regions().cloned().chain([region.clone_object()])) } fn add_circle( @@ -39,7 +40,7 @@ impl UpdateSketch for Sketch { services: &mut Services, ) -> Self { let exterior = Cycle::circle(center, radius, services).insert(services); - let region = Region::new(exterior, [], None); + let region = Region::new(exterior, [], None).insert(services); self.add_region(region) } @@ -50,7 +51,7 @@ impl UpdateSketch for Sketch { Ps::IntoIter: Clone + ExactSizeIterator, { let exterior = Cycle::polygon(points, services).insert(services); - let region = Region::new(exterior, [], None); + let region = Region::new(exterior, [], None).insert(services); self.add_region(region) } } From d2a7c8e1d017e41c02a31870d63dfbf4b16901ae Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:04:11 +0200 Subject: [PATCH 16/28] Store `Handle` in `Sketch` --- crates/fj-core/src/objects/kinds/sketch.rs | 9 +++++---- crates/fj-core/src/operations/update/sketch.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index 20ba58e25..5f6119151 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -10,19 +10,19 @@ use crate::{ /// A 2-dimensional shape #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Sketch { - regions: BTreeSet, + regions: BTreeSet>, } impl Sketch { /// Construct an empty instance of `Sketch` - pub fn new(regions: impl IntoIterator) -> Self { + pub fn new(regions: impl IntoIterator>) -> Self { Self { regions: regions.into_iter().collect(), } } /// Access the regions of the sketch - pub fn regions(&self) -> impl Iterator { + pub fn regions(&self) -> impl Iterator> { self.regions.iter() } @@ -35,7 +35,8 @@ impl Sketch { self.regions .iter() .map(|region| { - Face::new(surface.clone(), region.clone()).insert(services) + Face::new(surface.clone(), region.clone_object()) + .insert(services) }) .collect() } diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index e285a1740..8dd771cee 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -30,7 +30,7 @@ pub trait UpdateSketch { impl UpdateSketch for Sketch { fn add_region(&self, region: Handle) -> Self { - Sketch::new(self.regions().cloned().chain([region.clone_object()])) + Sketch::new(self.regions().cloned().chain([region])) } fn add_circle( From 1ba2e992b941c5ce45cc074657370be11b423a38 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:05:22 +0200 Subject: [PATCH 17/28] Improve formatting --- crates/fj-core/src/operations/update/face.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 46ba02ef1..dfab06b56 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -27,7 +27,6 @@ impl UpdateFace for Face { f: impl FnOnce(&Handle) -> Handle, ) -> Self { let exterior = f(self.exterior()); - let region = Region::new(exterior, self.interiors().cloned(), self.color()); Face::new(self.surface().clone(), region) @@ -38,7 +37,6 @@ impl UpdateFace for Face { interiors: impl IntoIterator>, ) -> Self { let interiors = self.interiors().cloned().chain(interiors); - let region = Region::new(self.exterior().clone(), interiors, self.color()); Face::new(self.surface().clone(), region) From a0da7203964475971cc1dcd99cf9db81f3781dd8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:14:43 +0200 Subject: [PATCH 18/28] Add `Face::region` --- crates/fj-core/src/objects/kinds/face.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index c00df24de..69921d75b 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -49,6 +49,11 @@ impl Face { &self.surface } + /// Access the region of the face + pub fn region(&self) -> &Region { + &self.region + } + /// Access the cycle that bounds the face on the outside pub fn exterior(&self) -> &Handle { self.region.exterior() From 3a5ce5777b6d25b0719904a05653ba76e2a0df6b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:16:51 +0200 Subject: [PATCH 19/28] Remove redundant method `Face::exterior` --- crates/fj-core/src/algorithms/approx/face.rs | 5 ++- .../src/algorithms/bounding_volume/face.rs | 2 +- .../src/algorithms/intersect/face_point.rs | 2 + .../src/algorithms/intersect/ray_face.rs | 2 + crates/fj-core/src/algorithms/reverse/face.rs | 2 +- .../fj-core/src/algorithms/transform/face.rs | 1 + crates/fj-core/src/objects/kinds/face.rs | 7 +--- crates/fj-core/src/objects/set.rs | 6 ++- crates/fj-core/src/operations/build/shell.rs | 42 ++++++++++++++++--- crates/fj-core/src/operations/update/face.rs | 15 ++++--- crates/fj-core/src/validate/face.rs | 11 +++-- 11 files changed, 68 insertions(+), 27 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/face.rs b/crates/fj-core/src/algorithms/approx/face.rs index 56f45c752..1daaa5931 100644 --- a/crates/fj-core/src/algorithms/approx/face.rs +++ b/crates/fj-core/src/algorithms/approx/face.rs @@ -85,8 +85,9 @@ impl Approx for &Face { // would need to provide its own approximation, as the edges that bound // it have nothing to do with its curvature. - let exterior = (self.exterior().deref(), self.surface().deref()) - .approx_with_cache(tolerance, cache); + let exterior = + (self.region().exterior().deref(), self.surface().deref()) + .approx_with_cache(tolerance, cache); let mut interiors = BTreeSet::new(); for cycle in self.interiors() { diff --git a/crates/fj-core/src/algorithms/bounding_volume/face.rs b/crates/fj-core/src/algorithms/bounding_volume/face.rs index 8926680ac..86cba6a08 100644 --- a/crates/fj-core/src/algorithms/bounding_volume/face.rs +++ b/crates/fj-core/src/algorithms/bounding_volume/face.rs @@ -4,7 +4,7 @@ use crate::{geometry::curve::GlobalPath, objects::Face}; impl super::BoundingVolume<3> for Face { fn aabb(&self) -> Option> { - self.exterior().aabb().map(|aabb2| { + self.region().exterior().aabb().map(|aabb2| { let surface = self.surface().geometry(); match surface.u { diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 474d0ec00..16f2e6ceb 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -302,6 +302,7 @@ mod tests { let intersection = (&face, &point).intersect(); let edge = face + .region() .exterior() .half_edges() .find(|edge| edge.start_position() == Point::from([0., 0.])) @@ -332,6 +333,7 @@ mod tests { let intersection = (&face, &point).intersect(); let vertex = face + .region() .exterior() .half_edges() .find(|half_edge| { diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index d4a8b141d..2ca4e2979 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -244,6 +244,7 @@ mod tests { let face = face.translate([1., 1., 0.], &mut services); let edge = face + .region() .exterior() .half_edges() .find(|edge| edge.start_position() == Point::from([-1., 1.])) @@ -274,6 +275,7 @@ mod tests { let face = face.translate([1., 1., 1.], &mut services); let vertex = face + .region() .exterior() .half_edges() .find(|half_edge| { diff --git a/crates/fj-core/src/algorithms/reverse/face.rs b/crates/fj-core/src/algorithms/reverse/face.rs index 4d15d90a5..ac476fba5 100644 --- a/crates/fj-core/src/algorithms/reverse/face.rs +++ b/crates/fj-core/src/algorithms/reverse/face.rs @@ -9,7 +9,7 @@ use super::Reverse; impl Reverse for Handle { fn reverse(self, services: &mut Services) -> Self { - let exterior = self.exterior().clone().reverse(services); + let exterior = self.region().exterior().clone().reverse(services); let interiors = self .interiors() .map(|cycle| cycle.clone().reverse(services)) diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index a1697b4e1..784232116 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -22,6 +22,7 @@ impl TransformObject for Face { .clone() .transform_with_cache(transform, services, cache); let exterior = self + .region() .exterior() .clone() .transform_with_cache(transform, services, cache); diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index 69921d75b..063aa58b3 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -54,11 +54,6 @@ impl Face { &self.region } - /// Access the cycle that bounds the face on the outside - pub fn exterior(&self) -> &Handle { - self.region.exterior() - } - /// Access the cycles that bound the face on the inside /// /// Each of these cycles defines a hole in the face. @@ -87,7 +82,7 @@ impl Face { /// back sides. The front side is the side, where the face's exterior cycle /// is wound counter-clockwise. pub fn coord_handedness(&self) -> Handedness { - match self.exterior().winding() { + match self.region.exterior().winding() { Winding::Ccw => Handedness::RightHanded, Winding::Cw => Handedness::LeftHanded, } diff --git a/crates/fj-core/src/objects/set.rs b/crates/fj-core/src/objects/set.rs index 23ae75202..003ad734a 100644 --- a/crates/fj-core/src/objects/set.rs +++ b/crates/fj-core/src/objects/set.rs @@ -71,8 +71,10 @@ impl InsertIntoSet for Face { objects.inner.insert(self.surface().clone().into()); self.surface().insert_into_set(objects); - objects.inner.insert(self.exterior().clone().into()); - self.exterior().insert_into_set(objects); + objects + .inner + .insert(self.region().exterior().clone().into()); + self.region().exterior().insert_into_set(objects); for interior in self.interiors() { objects.inner.insert(interior.clone().into()); diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 83aeed52e..32e96aa0c 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -39,22 +39,52 @@ pub trait BuildShell { let bad = Face::triangle([b, a, d], services).update_exterior(|cycle| { cycle - .join_to(abc.face.exterior(), 0..=0, 0..=0, services) + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + services, + ) .insert(services) }); let dac = Face::triangle([d, a, c], services).update_exterior(|cycle| { cycle - .join_to(abc.face.exterior(), 1..=1, 2..=2, services) - .join_to(bad.face.exterior(), 0..=0, 1..=1, services) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + services, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + services, + ) .insert(services) }); let cbd = Face::triangle([c, b, d], services).update_exterior(|cycle| { cycle - .join_to(abc.face.exterior(), 0..=0, 1..=1, services) - .join_to(bad.face.exterior(), 1..=1, 2..=2, services) - .join_to(dac.face.exterior(), 2..=2, 2..=2, services) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + services, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + services, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + services, + ) .insert(services) }); diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index dfab06b56..313364ac1 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -26,7 +26,7 @@ impl UpdateFace for Face { &self, f: impl FnOnce(&Handle) -> Handle, ) -> Self { - let exterior = f(self.exterior()); + let exterior = f(self.region().exterior()); let region = Region::new(exterior, self.interiors().cloned(), self.color()); Face::new(self.surface().clone(), region) @@ -37,8 +37,11 @@ impl UpdateFace for Face { interiors: impl IntoIterator>, ) -> Self { let interiors = self.interiors().cloned().chain(interiors); - let region = - Region::new(self.exterior().clone(), interiors, self.color()); + let region = Region::new( + self.region().exterior().clone(), + interiors, + self.color(), + ); Face::new(self.surface().clone(), region) } } @@ -50,7 +53,8 @@ impl UpdateFace for Polygon { ) -> Self { let face = self.face.update_exterior(f); let edges = array::from_fn(|i| { - face.exterior() + face.region() + .exterior() .nth_half_edge(i) .expect("Operation should not have changed length of cycle") .clone() @@ -59,7 +63,8 @@ impl UpdateFace for Polygon { // The duplicated code here is unfortunate, but unless we get a // stable `array::each_ref` and something like `array::unzip`, I'm // not sure how to avoid it. - face.exterior() + face.region() + .exterior() .nth_half_edge(i) .expect("Operation should not have changed length of cycle") .start_vertex() diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 36cb611d8..df58838b3 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -38,13 +38,13 @@ pub enum FaceValidationError { impl FaceValidationError { fn check_interior_winding(face: &Face, errors: &mut Vec) { - if face.exterior().half_edges().count() == 0 { + if face.region().exterior().half_edges().count() == 0 { // Can't determine winding, if the cycle has no half-edges. Sounds // like a job for a different validation check. return; } - let exterior_winding = face.exterior().winding(); + let exterior_winding = face.region().exterior().winding(); for interior in face.interiors() { if interior.half_edges().count() == 0 { @@ -104,8 +104,11 @@ mod tests { .map(|cycle| cycle.reverse(&mut services)) .collect::>(); - let region = - Region::new(valid.exterior().clone(), interiors, valid.color()); + let region = Region::new( + valid.region().exterior().clone(), + interiors, + valid.color(), + ); Face::new(valid.surface().clone(), region) }; From 0d26fc7777d3c6b2e13150a24abae5cf10c422ed Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:17:59 +0200 Subject: [PATCH 20/28] Remove redundant method `Face::interiors` --- crates/fj-core/src/algorithms/approx/face.rs | 2 +- crates/fj-core/src/algorithms/reverse/face.rs | 1 + crates/fj-core/src/algorithms/transform/face.rs | 2 +- crates/fj-core/src/objects/kinds/face.rs | 7 ------- crates/fj-core/src/objects/set.rs | 4 ++-- crates/fj-core/src/operations/update/face.rs | 9 ++++++--- crates/fj-core/src/validate/face.rs | 3 ++- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/face.rs b/crates/fj-core/src/algorithms/approx/face.rs index 1daaa5931..2a192a600 100644 --- a/crates/fj-core/src/algorithms/approx/face.rs +++ b/crates/fj-core/src/algorithms/approx/face.rs @@ -90,7 +90,7 @@ impl Approx for &Face { .approx_with_cache(tolerance, cache); let mut interiors = BTreeSet::new(); - for cycle in self.interiors() { + for cycle in self.region().interiors() { let cycle = (cycle.deref(), self.surface().deref()) .approx_with_cache(tolerance, cache); interiors.insert(cycle); diff --git a/crates/fj-core/src/algorithms/reverse/face.rs b/crates/fj-core/src/algorithms/reverse/face.rs index ac476fba5..7151d3306 100644 --- a/crates/fj-core/src/algorithms/reverse/face.rs +++ b/crates/fj-core/src/algorithms/reverse/face.rs @@ -11,6 +11,7 @@ impl Reverse for Handle { fn reverse(self, services: &mut Services) -> Self { let exterior = self.region().exterior().clone().reverse(services); let interiors = self + .region() .interiors() .map(|cycle| cycle.clone().reverse(services)) .collect::>(); diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index 784232116..d770ec640 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -26,7 +26,7 @@ impl TransformObject for Face { .exterior() .clone() .transform_with_cache(transform, services, cache); - let interiors = self.interiors().cloned().map(|interior| { + let interiors = self.region().interiors().cloned().map(|interior| { interior.transform_with_cache(transform, services, cache) }); diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index 063aa58b3..e9b8eea0a 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -54,13 +54,6 @@ impl Face { &self.region } - /// Access the cycles that bound the face on the inside - /// - /// Each of these cycles defines a hole in the face. - pub fn interiors(&self) -> impl Iterator> + '_ { - self.region.interiors() - } - /// Access all cycles of the face (both exterior and interior) pub fn all_cycles(&self) -> impl Iterator> + '_ { self.region.all_cycles() diff --git a/crates/fj-core/src/objects/set.rs b/crates/fj-core/src/objects/set.rs index 003ad734a..791ff1d0b 100644 --- a/crates/fj-core/src/objects/set.rs +++ b/crates/fj-core/src/objects/set.rs @@ -76,10 +76,10 @@ impl InsertIntoSet for Face { .insert(self.region().exterior().clone().into()); self.region().exterior().insert_into_set(objects); - for interior in self.interiors() { + for interior in self.region().interiors() { objects.inner.insert(interior.clone().into()); } - for interior in self.interiors() { + for interior in self.region().interiors() { interior.insert_into_set(objects); } } diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 313364ac1..5a1f0a5ab 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -27,8 +27,11 @@ impl UpdateFace for Face { f: impl FnOnce(&Handle) -> Handle, ) -> Self { let exterior = f(self.region().exterior()); - let region = - Region::new(exterior, self.interiors().cloned(), self.color()); + let region = Region::new( + exterior, + self.region().interiors().cloned(), + self.color(), + ); Face::new(self.surface().clone(), region) } @@ -36,7 +39,7 @@ impl UpdateFace for Face { &self, interiors: impl IntoIterator>, ) -> Self { - let interiors = self.interiors().cloned().chain(interiors); + let interiors = self.region().interiors().cloned().chain(interiors); let region = Region::new( self.region().exterior().clone(), interiors, diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index df58838b3..e173b7da6 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -46,7 +46,7 @@ impl FaceValidationError { let exterior_winding = face.region().exterior().winding(); - for interior in face.interiors() { + for interior in face.region().interiors() { if interior.half_edges().count() == 0 { // Can't determine winding, if the cycle has no half-edges. // Sounds like a job for a different validation check. @@ -99,6 +99,7 @@ mod tests { .insert(&mut services)]); let invalid = { let interiors = valid + .region() .interiors() .cloned() .map(|cycle| cycle.reverse(&mut services)) From 61d891869952950a4dc06245a69a052a61d6d5e1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:18:56 +0200 Subject: [PATCH 21/28] Remove redundant method `Face::all_cycles` --- crates/fj-core/src/algorithms/intersect/curve_face.rs | 5 ++++- crates/fj-core/src/algorithms/intersect/face_point.rs | 2 +- crates/fj-core/src/algorithms/sweep/face.rs | 3 ++- crates/fj-core/src/objects/kinds/face.rs | 7 +------ crates/fj-core/src/validate/shell.rs | 5 +++-- crates/fj-core/src/validate/solid.rs | 3 ++- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 7cb42d0dc..4ca6ec974 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -29,7 +29,10 @@ impl CurveFaceIntersection { /// Compute the intersection pub fn compute(curve: &Curve, face: &Face) -> Self { - let half_edges = face.all_cycles().flat_map(|cycle| cycle.half_edges()); + let half_edges = face + .region() + .all_cycles() + .flat_map(|cycle| cycle.half_edges()); let mut intersections = Vec::new(); diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 16f2e6ceb..2690bc46a 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -22,7 +22,7 @@ impl Intersect for (&Face, &Point<2>) { let mut num_hits = 0; - for cycle in face.all_cycles() { + for cycle in face.region().all_cycles() { // We need to properly detect the ray passing the boundary at the // "seam" of the polygon, i.e. the vertex between the last and the // first segment. The logic in the loop properly takes care of that, diff --git a/crates/fj-core/src/algorithms/sweep/face.rs b/crates/fj-core/src/algorithms/sweep/face.rs index 7506f5a8c..e2bb7f183 100644 --- a/crates/fj-core/src/algorithms/sweep/face.rs +++ b/crates/fj-core/src/algorithms/sweep/face.rs @@ -57,7 +57,8 @@ impl Sweep for Handle { let mut exterior = None; let mut interiors = Vec::new(); - for (i, cycle) in bottom_face.all_cycles().cloned().enumerate() { + for (i, cycle) in bottom_face.region().all_cycles().cloned().enumerate() + { let cycle = cycle.reverse(services); let mut top_edges = Vec::new(); diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index e9b8eea0a..11b0bdd27 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -4,7 +4,7 @@ use fj_interop::mesh::Color; use fj_math::Winding; use crate::{ - objects::{Cycle, Region, Surface}, + objects::{Region, Surface}, storage::Handle, }; @@ -54,11 +54,6 @@ impl Face { &self.region } - /// Access all cycles of the face (both exterior and interior) - pub fn all_cycles(&self) -> impl Iterator> + '_ { - self.region.all_cycles() - } - /// Access the color of the face pub fn color(&self) -> Option { self.region.color() diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index f1a81b4e8..c8054c41a 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -112,7 +112,8 @@ impl ShellValidationError { .faces() .into_iter() .flat_map(|face| { - face.all_cycles() + face.region() + .all_cycles() .flat_map(|cycle| cycle.half_edges().cloned()) .zip(repeat(face.surface().clone())) }) @@ -173,7 +174,7 @@ impl ShellValidationError { let faces = shell.faces(); let mut half_edge_to_faces: HashMap = HashMap::new(); for face in faces { - for cycle in face.all_cycles() { + for cycle in face.region().all_cycles() { for half_edge in cycle.half_edges() { let id = half_edge.global_form().id(); let entry = half_edge_to_faces.entry(id); diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index 9dff3630f..5c0cdbfe6 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -72,7 +72,8 @@ impl SolidValidationError { .shells() .flat_map(|s| s.faces()) .flat_map(|face| { - face.all_cycles() + face.region() + .all_cycles() .flat_map(|cycle| cycle.half_edges().cloned()) .zip(repeat(face.surface().geometry())) }) From 70622767309d12cfea27672df1d32f20f289115d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:20:22 +0200 Subject: [PATCH 22/28] Remove redundant method `Face::color` --- crates/fj-core/src/algorithms/approx/face.rs | 2 +- crates/fj-core/src/algorithms/reverse/face.rs | 2 +- crates/fj-core/src/algorithms/sweep/face.rs | 5 +++-- crates/fj-core/src/algorithms/transform/face.rs | 2 +- crates/fj-core/src/objects/kinds/face.rs | 6 ------ crates/fj-core/src/operations/update/face.rs | 4 ++-- crates/fj-core/src/validate/face.rs | 2 +- 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/face.rs b/crates/fj-core/src/algorithms/approx/face.rs index 2a192a600..261c0d7eb 100644 --- a/crates/fj-core/src/algorithms/approx/face.rs +++ b/crates/fj-core/src/algorithms/approx/face.rs @@ -99,7 +99,7 @@ impl Approx for &Face { FaceApprox { exterior, interiors, - color: self.color(), + color: self.region().color(), coord_handedness: self.coord_handedness(), } } diff --git a/crates/fj-core/src/algorithms/reverse/face.rs b/crates/fj-core/src/algorithms/reverse/face.rs index 7151d3306..6a1f92f15 100644 --- a/crates/fj-core/src/algorithms/reverse/face.rs +++ b/crates/fj-core/src/algorithms/reverse/face.rs @@ -16,7 +16,7 @@ impl Reverse for Handle { .map(|cycle| cycle.clone().reverse(services)) .collect::>(); - let region = Region::new(exterior, interiors, self.color()); + let region = Region::new(exterior, interiors, self.region().color()); Face::new(self.surface().clone(), region).insert(services) } } diff --git a/crates/fj-core/src/algorithms/sweep/face.rs b/crates/fj-core/src/algorithms/sweep/face.rs index e2bb7f183..3a98758ee 100644 --- a/crates/fj-core/src/algorithms/sweep/face.rs +++ b/crates/fj-core/src/algorithms/sweep/face.rs @@ -69,7 +69,7 @@ impl Sweep for Handle { half_edge.deref(), next.start_vertex(), self.surface().deref(), - self.color(), + self.region().color(), ) .sweep_with_cache(path, cache, services); @@ -93,7 +93,8 @@ impl Sweep for Handle { }; } - let region = Region::new(exterior.unwrap(), interiors, self.color()); + let region = + Region::new(exterior.unwrap(), interiors, self.region().color()); let top_face = Face::new(top_surface, region); let top_face = top_face.insert(services); diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index d770ec640..1e032ee04 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -15,7 +15,7 @@ impl TransformObject for Face { cache: &mut TransformCache, ) -> Self { // Color does not need to be transformed. - let color = self.color(); + let color = self.region().color(); let surface = self .surface() diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index 11b0bdd27..354e4063e 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -1,6 +1,5 @@ use std::collections::{btree_set, BTreeSet}; -use fj_interop::mesh::Color; use fj_math::Winding; use crate::{ @@ -54,11 +53,6 @@ impl Face { &self.region } - /// Access the color of the face - pub fn color(&self) -> Option { - self.region.color() - } - /// Determine handed-ness of the face's front-side coordinate system /// /// A face is defined on a surface, which has a coordinate system. Since diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 5a1f0a5ab..fd4d2a0be 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -30,7 +30,7 @@ impl UpdateFace for Face { let region = Region::new( exterior, self.region().interiors().cloned(), - self.color(), + self.region().color(), ); Face::new(self.surface().clone(), region) } @@ -43,7 +43,7 @@ impl UpdateFace for Face { let region = Region::new( self.region().exterior().clone(), interiors, - self.color(), + self.region().color(), ); Face::new(self.surface().clone(), region) } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index e173b7da6..525163d94 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -108,7 +108,7 @@ mod tests { let region = Region::new( valid.region().exterior().clone(), interiors, - valid.color(), + valid.region().color(), ); Face::new(valid.surface().clone(), region) }; From 1c3f87e283f74726ecc9aef4050442daee716fa1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:33:23 +0200 Subject: [PATCH 23/28] Add `UpdateFace::update_region` --- crates/fj-core/src/operations/update/face.rs | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index fd4d2a0be..dd36079e7 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -8,6 +8,9 @@ use crate::{ /// Update a [`Face`] pub trait UpdateFace { + /// Replace the region of the face + fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self; + /// Update the exterior of the face fn update_exterior( &self, @@ -22,6 +25,11 @@ pub trait UpdateFace { } impl UpdateFace for Face { + fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self { + let region = f(self.region()); + Face::new(self.surface().clone(), region.clone_object()) + } + fn update_exterior( &self, f: impl FnOnce(&Handle) -> Handle, @@ -50,6 +58,34 @@ impl UpdateFace for Face { } impl UpdateFace for Polygon { + fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self { + let face = self.face.update_region(f); + let edges = array::from_fn(|i| { + face.region() + .exterior() + .nth_half_edge(i) + .expect("Operation should not have changed length of cycle") + .clone() + }); + let vertices = array::from_fn(|i| { + // The duplicated code here is unfortunate, but unless we get a + // stable `array::each_ref` and something like `array::unzip`, I'm + // not sure how to avoid it. + face.region() + .exterior() + .nth_half_edge(i) + .expect("Operation should not have changed length of cycle") + .start_vertex() + .clone() + }); + + Polygon { + face, + edges, + vertices, + } + } + fn update_exterior( &self, f: impl FnOnce(&Handle) -> Handle, From da9d7ef2a274cd1a680194bd62f64ee338ff1346 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 12:39:56 +0200 Subject: [PATCH 24/28] Add `UpdateRegion` --- crates/fj-core/src/operations/mod.rs | 3 +- crates/fj-core/src/operations/update/face.rs | 16 ++------ crates/fj-core/src/operations/update/mod.rs | 1 + .../fj-core/src/operations/update/region.rs | 37 +++++++++++++++++++ 4 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 crates/fj-core/src/operations/update/region.rs diff --git a/crates/fj-core/src/operations/mod.rs b/crates/fj-core/src/operations/mod.rs index 5f7bbd90f..4f109a4f4 100644 --- a/crates/fj-core/src/operations/mod.rs +++ b/crates/fj-core/src/operations/mod.rs @@ -19,6 +19,7 @@ pub use self::{ join::cycle::JoinCycle, update::{ cycle::UpdateCycle, edge::UpdateHalfEdge, face::UpdateFace, - shell::UpdateShell, sketch::UpdateSketch, solid::UpdateSolid, + region::UpdateRegion, shell::UpdateShell, sketch::UpdateSketch, + solid::UpdateSolid, }, }; diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index dd36079e7..e24513af8 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -2,7 +2,7 @@ use std::array; use crate::{ objects::{Cycle, Face, Region}, - operations::Polygon, + operations::{Polygon, UpdateRegion}, storage::Handle, }; @@ -34,12 +34,7 @@ impl UpdateFace for Face { &self, f: impl FnOnce(&Handle) -> Handle, ) -> Self { - let exterior = f(self.region().exterior()); - let region = Region::new( - exterior, - self.region().interiors().cloned(), - self.region().color(), - ); + let region = self.region().update_exterior(f); Face::new(self.surface().clone(), region) } @@ -47,12 +42,7 @@ impl UpdateFace for Face { &self, interiors: impl IntoIterator>, ) -> Self { - let interiors = self.region().interiors().cloned().chain(interiors); - let region = Region::new( - self.region().exterior().clone(), - interiors, - self.region().color(), - ); + let region = self.region().add_interiors(interiors); Face::new(self.surface().clone(), region) } } diff --git a/crates/fj-core/src/operations/update/mod.rs b/crates/fj-core/src/operations/update/mod.rs index 8928937cb..26b29348a 100644 --- a/crates/fj-core/src/operations/update/mod.rs +++ b/crates/fj-core/src/operations/update/mod.rs @@ -1,6 +1,7 @@ pub mod cycle; pub mod edge; pub mod face; +pub mod region; pub mod shell; pub mod sketch; pub mod solid; diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs new file mode 100644 index 000000000..c98d53600 --- /dev/null +++ b/crates/fj-core/src/operations/update/region.rs @@ -0,0 +1,37 @@ +use crate::{ + objects::{Cycle, Region}, + storage::Handle, +}; + +/// Update a [`Region`] +pub trait UpdateRegion { + /// Update the exterior of the region + fn update_exterior( + &self, + f: impl FnOnce(&Handle) -> Handle, + ) -> Self; + + /// Add the provides interiors to the region + fn add_interiors( + &self, + interiors: impl IntoIterator>, + ) -> Self; +} + +impl UpdateRegion for Region { + fn update_exterior( + &self, + f: impl FnOnce(&Handle) -> Handle, + ) -> Self { + let exterior = f(self.exterior()); + Region::new(exterior, self.interiors().cloned(), self.color()) + } + + fn add_interiors( + &self, + interiors: impl IntoIterator>, + ) -> Self { + let interiors = self.interiors().cloned().chain(interiors); + Region::new(self.exterior().clone(), interiors, self.color()) + } +} From 0bec0c3a0dd98b81cac72893f546de1a1f69c873 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 13:08:08 +0200 Subject: [PATCH 25/28] Remove redundant `UpdateFace::update_exterior` --- .../src/algorithms/intersect/curve_face.rs | 10 +- .../src/algorithms/intersect/face_face.rs | 20 ++- .../src/algorithms/intersect/face_point.rs | 136 +++++++++++------- .../src/algorithms/intersect/ray_face.rs | 114 +++++++++------ .../fj-core/src/algorithms/triangulate/mod.rs | 31 ++-- crates/fj-core/src/operations/build/shell.rs | 115 ++++++++------- crates/fj-core/src/operations/update/face.rs | 45 ------ crates/fj-core/src/validate/face.rs | 18 ++- crates/fj-core/src/validate/shell.rs | 20 +-- 9 files changed, 287 insertions(+), 222 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 4ca6ec974..8d1cd3362 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -155,7 +155,7 @@ mod tests { use crate::{ geometry::curve::Curve, objects::{Cycle, Face}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, }; @@ -184,8 +184,12 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon(exterior_points, &mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon(exterior_points, &mut services) + .insert(&mut services) + }) .insert(&mut services) }) .add_interiors([Cycle::polygon( diff --git a/crates/fj-core/src/algorithms/intersect/face_face.rs b/crates/fj-core/src/algorithms/intersect/face_face.rs index dae7f0d6e..11694d9b9 100644 --- a/crates/fj-core/src/algorithms/intersect/face_face.rs +++ b/crates/fj-core/src/algorithms/intersect/face_face.rs @@ -64,7 +64,7 @@ mod tests { algorithms::intersect::CurveFaceIntersection, geometry::curve::Curve, objects::{Cycle, Face}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, }; @@ -86,8 +86,13 @@ mod tests { services.objects.surfaces.xz_plane(), ] .map(|surface| { - Face::unbound(surface, &mut services).update_exterior(|_| { - Cycle::polygon(points, &mut services).insert(&mut services) + Face::unbound(surface, &mut services).update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon(points, &mut services) + .insert(&mut services) + }) + .insert(&mut services) }) }); @@ -113,8 +118,13 @@ mod tests { services.objects.surfaces.xz_plane(), ]; let [a, b] = surfaces.clone().map(|surface| { - Face::unbound(surface, &mut services).update_exterior(|_| { - Cycle::polygon(points, &mut services).insert(&mut services) + Face::unbound(surface, &mut services).update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon(points, &mut services) + .insert(&mut services) + }) + .insert(&mut services) }) }); diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 2690bc46a..461b6cf65 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -139,7 +139,7 @@ mod tests { use crate::{ algorithms::intersect::{face_point::FacePointIntersection, Intersect}, objects::{Cycle, Face}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, }; @@ -149,12 +149,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 1.], [0., 2.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [1., 1.], [0., 2.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([2., 1.]); @@ -170,12 +174,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [0., 2.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [0., 2.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 1.]); @@ -194,12 +202,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[4., 2.], [0., 4.], [0., 0.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[4., 2.], [0., 4.], [0., 0.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 2.]); @@ -218,12 +230,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 1.]); @@ -242,12 +258,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 1.]); @@ -266,12 +286,22 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 1.], [4., 0.], [4., 5.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [0., 0.], + [2., 1.], + [3., 1.], + [4., 0.], + [4., 5.], + ], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 1.]); @@ -290,12 +320,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 0.], [0., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 0.], [0., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 0.]); @@ -321,12 +355,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 0.], [0., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [1., 0.], [0., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let point = Point::from([1., 0.]); diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index 2ca4e2979..be3a61283 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -153,7 +153,7 @@ mod tests { transform::TransformObject, }, objects::{Cycle, Face}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, }; @@ -165,12 +165,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.yz_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([-1., 0., 0.], &mut services); @@ -187,12 +191,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.yz_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([1., 0., 0.], &mut services); @@ -212,12 +220,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.yz_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([0., 0., 2.], &mut services); @@ -234,12 +246,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.yz_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([1., 1., 0.], &mut services); @@ -265,12 +281,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.yz_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([1., 1., 1.], &mut services); @@ -299,12 +319,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); assert_eq!( @@ -323,12 +347,16 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }); let face = face.translate([0., 0., 1.], &mut services); diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index b585ac229..548dfa224 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -80,7 +80,7 @@ mod tests { use crate::{ algorithms::approx::{Approx, Tolerance}, objects::{Cycle, Face}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, }; @@ -97,8 +97,12 @@ mod tests { let face = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon([a, b, c, d], &mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon([a, b, c, d], &mut services) + .insert(&mut services) + }) .insert(&mut services) }); services.only_validate(&face); @@ -135,8 +139,12 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); let face = Face::unbound(surface.clone(), &mut services) - .update_exterior(|_| { - Cycle::polygon([a, b, c, d], &mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon([a, b, c, d], &mut services) + .insert(&mut services) + }) .insert(&mut services) }) .add_interiors([Cycle::polygon([e, f, g, h], &mut services) @@ -196,11 +204,16 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); - let face = Face::unbound(surface.clone(), &mut services) - .update_exterior(|_| { - Cycle::polygon([a, b, c, d, e], &mut services) + let face = Face::unbound(surface.clone(), &mut services).update_region( + |region| { + region + .update_exterior(|_| { + Cycle::polygon([a, b, c, d, e], &mut services) + .insert(&mut services) + }) .insert(&mut services) - }); + }, + ); services.only_validate(&face); let triangles = triangulate(face)?; diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 32e96aa0c..a40344324 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -3,8 +3,8 @@ use fj_math::Point; use crate::{ objects::{Face, Shell}, operations::{ - BuildFace, Insert, IsInserted, IsInsertedNo, IsInsertedYes, JoinCycle, - Polygon, UpdateFace, + update::region::UpdateRegion, BuildFace, Insert, IsInserted, + IsInsertedNo, IsInsertedYes, JoinCycle, Polygon, UpdateFace, }, services::Services, }; @@ -36,57 +36,66 @@ pub trait BuildShell { let [a, b, c, d] = points.map(Into::into); let abc = Face::triangle([a, b, c], services); - let bad = - Face::triangle([b, a, d], services).update_exterior(|cycle| { - cycle - .join_to( - abc.face.region().exterior(), - 0..=0, - 0..=0, - services, - ) - .insert(services) - }); - let dac = - Face::triangle([d, a, c], services).update_exterior(|cycle| { - cycle - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - services, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - services, - ) - .insert(services) - }); - let cbd = - Face::triangle([c, b, d], services).update_exterior(|cycle| { - cycle - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - services, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - services, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - services, - ) - .insert(services) - }); + let bad = Face::triangle([b, a, d], services).update_region(|region| { + region + .update_exterior(|cycle| { + cycle + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + services, + ) + .insert(services) + }) + .insert(services) + }); + let dac = Face::triangle([d, a, c], services).update_region(|region| { + region + .update_exterior(|cycle| { + cycle + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + services, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + services, + ) + .insert(services) + }) + .insert(services) + }); + let cbd = Face::triangle([c, b, d], services).update_region(|region| { + region + .update_exterior(|cycle| { + cycle + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + services, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + services, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + services, + ) + .insert(services) + }) + .insert(services) + }); let triangles = [abc, bad, dac, cbd].map(|triangle| triangle.insert(services)); diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index e24513af8..70b5cd902 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -11,12 +11,6 @@ pub trait UpdateFace { /// Replace the region of the face fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self; - /// Update the exterior of the face - fn update_exterior( - &self, - f: impl FnOnce(&Handle) -> Handle, - ) -> Self; - /// Add the provides interiors to the face fn add_interiors( &self, @@ -30,14 +24,6 @@ impl UpdateFace for Face { Face::new(self.surface().clone(), region.clone_object()) } - fn update_exterior( - &self, - f: impl FnOnce(&Handle) -> Handle, - ) -> Self { - let region = self.region().update_exterior(f); - Face::new(self.surface().clone(), region) - } - fn add_interiors( &self, interiors: impl IntoIterator>, @@ -76,37 +62,6 @@ impl UpdateFace for Polygon { } } - fn update_exterior( - &self, - f: impl FnOnce(&Handle) -> Handle, - ) -> Self { - let face = self.face.update_exterior(f); - let edges = array::from_fn(|i| { - face.region() - .exterior() - .nth_half_edge(i) - .expect("Operation should not have changed length of cycle") - .clone() - }); - let vertices = array::from_fn(|i| { - // The duplicated code here is unfortunate, but unless we get a - // stable `array::each_ref` and something like `array::unzip`, I'm - // not sure how to avoid it. - face.region() - .exterior() - .nth_half_edge(i) - .expect("Operation should not have changed length of cycle") - .start_vertex() - .clone() - }); - - Polygon { - face, - edges, - vertices, - } - } - fn add_interiors( &self, _: impl IntoIterator>, diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 525163d94..3f5c84f5b 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -74,7 +74,7 @@ mod tests { algorithms::reverse::Reverse, assert_contains_err, objects::{Cycle, Face, Region}, - operations::{BuildCycle, BuildFace, Insert, UpdateFace}, + operations::{BuildCycle, BuildFace, Insert, UpdateFace, UpdateRegion}, services::Services, validate::{FaceValidationError, Validate, ValidationError}, }; @@ -85,12 +85,16 @@ mod tests { let valid = Face::unbound(services.objects.surfaces.xy_plane(), &mut services) - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [3., 0.], [0., 3.]], - &mut services, - ) - .insert(&mut services) + .update_region(|region| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [3., 0.], [0., 3.]], + &mut services, + ) + .insert(&mut services) + }) + .insert(&mut services) }) .add_interiors([Cycle::polygon( [[1., 1.], [1., 2.], [2., 1.]], diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index c8054c41a..d159272b4 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -197,7 +197,7 @@ mod tests { objects::{GlobalEdge, Shell}, operations::{ BuildShell, Insert, UpdateCycle, UpdateFace, UpdateHalfEdge, - UpdateShell, + UpdateRegion, UpdateShell, }, services::Services, validate::{shell::ShellValidationError, Validate, ValidationError}, @@ -216,13 +216,17 @@ mod tests { valid .abc .face - .update_exterior(|cycle| { - cycle - .update_nth_half_edge(0, |half_edge| { - let global_form = - GlobalEdge::new().insert(&mut services); - half_edge - .replace_global_form(global_form) + .update_region(|region| { + region + .update_exterior(|cycle| { + cycle + .update_nth_half_edge(0, |half_edge| { + let global_form = + GlobalEdge::new().insert(&mut services); + half_edge + .replace_global_form(global_form) + .insert(&mut services) + }) .insert(&mut services) }) .insert(&mut services) From 23358123e0a09465905277a8d1a63f03172397c8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 13:09:48 +0200 Subject: [PATCH 26/28] Remove redundant `UpdateFace::add_interiors` --- .../src/algorithms/intersect/curve_face.rs | 12 ++++----- .../fj-core/src/algorithms/triangulate/mod.rs | 14 +++++++---- crates/fj-core/src/operations/update/face.rs | 25 ++----------------- crates/fj-core/src/validate/face.rs | 12 ++++----- 4 files changed, 23 insertions(+), 40 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 8d1cd3362..339670b10 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -190,13 +190,13 @@ mod tests { Cycle::polygon(exterior_points, &mut services) .insert(&mut services) }) + .add_interiors([Cycle::polygon( + interior_points, + &mut services, + ) + .insert(&mut services)]) .insert(&mut services) - }) - .add_interiors([Cycle::polygon( - interior_points, - &mut services, - ) - .insert(&mut services)]); + }); let expected = CurveFaceIntersection::from_intervals([[[1.], [2.]], [[4.], [5.]]]); diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 548dfa224..6534b9b2e 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -138,17 +138,21 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); - let face = Face::unbound(surface.clone(), &mut services) - .update_region(|region| { + let face = Face::unbound(surface.clone(), &mut services).update_region( + |region| { region .update_exterior(|_| { Cycle::polygon([a, b, c, d], &mut services) .insert(&mut services) }) + .add_interiors([Cycle::polygon( + [e, f, g, h], + &mut services, + ) + .insert(&mut services)]) .insert(&mut services) - }) - .add_interiors([Cycle::polygon([e, f, g, h], &mut services) - .insert(&mut services)]); + }, + ); services.only_validate(&face); let triangles = triangulate(face)?; diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 70b5cd902..f69ecece9 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -1,8 +1,8 @@ use std::array; use crate::{ - objects::{Cycle, Face, Region}, - operations::{Polygon, UpdateRegion}, + objects::{Face, Region}, + operations::Polygon, storage::Handle, }; @@ -10,12 +10,6 @@ use crate::{ pub trait UpdateFace { /// Replace the region of the face fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self; - - /// Add the provides interiors to the face - fn add_interiors( - &self, - interiors: impl IntoIterator>, - ) -> Self; } impl UpdateFace for Face { @@ -23,14 +17,6 @@ impl UpdateFace for Face { let region = f(self.region()); Face::new(self.surface().clone(), region.clone_object()) } - - fn add_interiors( - &self, - interiors: impl IntoIterator>, - ) -> Self { - let region = self.region().add_interiors(interiors); - Face::new(self.surface().clone(), region) - } } impl UpdateFace for Polygon { @@ -61,11 +47,4 @@ impl UpdateFace for Polygon { vertices, } } - - fn add_interiors( - &self, - _: impl IntoIterator>, - ) -> Self { - panic!("Adding interiors to `Polygon` is not supported.") - } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 3f5c84f5b..c4d08ae5b 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -94,13 +94,13 @@ mod tests { ) .insert(&mut services) }) + .add_interiors([Cycle::polygon( + [[1., 1.], [1., 2.], [2., 1.]], + &mut services, + ) + .insert(&mut services)]) .insert(&mut services) - }) - .add_interiors([Cycle::polygon( - [[1., 1.], [1., 2.], [2., 1.]], - &mut services, - ) - .insert(&mut services)]); + }); let invalid = { let interiors = valid .region() From c24ebc671d3294012857be141665a35c15615d8b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 13:13:18 +0200 Subject: [PATCH 27/28] Store `Handle` in `Face` --- crates/fj-core/src/algorithms/reverse/face.rs | 4 +++- crates/fj-core/src/algorithms/sweep/edge.rs | 4 +++- crates/fj-core/src/algorithms/sweep/face.rs | 4 +++- crates/fj-core/src/algorithms/transform/face.rs | 4 +++- crates/fj-core/src/objects/kinds/face.rs | 6 +++--- crates/fj-core/src/objects/kinds/sketch.rs | 3 +-- crates/fj-core/src/operations/build/face.rs | 5 +++-- crates/fj-core/src/operations/update/face.rs | 2 +- crates/fj-core/src/validate/face.rs | 4 +++- 9 files changed, 23 insertions(+), 13 deletions(-) diff --git a/crates/fj-core/src/algorithms/reverse/face.rs b/crates/fj-core/src/algorithms/reverse/face.rs index 6a1f92f15..089964680 100644 --- a/crates/fj-core/src/algorithms/reverse/face.rs +++ b/crates/fj-core/src/algorithms/reverse/face.rs @@ -16,7 +16,9 @@ impl Reverse for Handle { .map(|cycle| cycle.clone().reverse(services)) .collect::>(); - let region = Region::new(exterior, interiors, self.region().color()); + let region = Region::new(exterior, interiors, self.region().color()) + .insert(services); + Face::new(self.surface().clone(), region).insert(services) } } diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index 281566ae2..5f32adb78 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -107,7 +107,9 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { half_edge }); - let region = Region::new(exterior.unwrap().insert(services), [], color); + let region = Region::new(exterior.unwrap().insert(services), [], color) + .insert(services); + let face = Face::new(surface, region); // And we're done creating the face! All that's left to do is build our diff --git a/crates/fj-core/src/algorithms/sweep/face.rs b/crates/fj-core/src/algorithms/sweep/face.rs index 3a98758ee..627dfc98e 100644 --- a/crates/fj-core/src/algorithms/sweep/face.rs +++ b/crates/fj-core/src/algorithms/sweep/face.rs @@ -94,7 +94,9 @@ impl Sweep for Handle { } let region = - Region::new(exterior.unwrap(), interiors, self.region().color()); + Region::new(exterior.unwrap(), interiors, self.region().color()) + .insert(services); + let top_face = Face::new(top_surface, region); let top_face = top_face.insert(services); diff --git a/crates/fj-core/src/algorithms/transform/face.rs b/crates/fj-core/src/algorithms/transform/face.rs index 1e032ee04..7c99c97dc 100644 --- a/crates/fj-core/src/algorithms/transform/face.rs +++ b/crates/fj-core/src/algorithms/transform/face.rs @@ -2,6 +2,7 @@ use fj_math::Transform; use crate::{ objects::{Face, FaceSet, Region}, + operations::Insert, services::Services, }; @@ -30,7 +31,8 @@ impl TransformObject for Face { interior.transform_with_cache(transform, services, cache) }); - let region = Region::new(exterior, interiors, color); + let region = Region::new(exterior, interiors, color).insert(services); + Self::new(surface, region) } } diff --git a/crates/fj-core/src/objects/kinds/face.rs b/crates/fj-core/src/objects/kinds/face.rs index 354e4063e..45006d283 100644 --- a/crates/fj-core/src/objects/kinds/face.rs +++ b/crates/fj-core/src/objects/kinds/face.rs @@ -34,12 +34,12 @@ use crate::{ #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Face { surface: Handle, - region: Region, + region: Handle, } impl Face { /// Construct an instance of `Face` - pub fn new(surface: Handle, region: Region) -> Self { + pub fn new(surface: Handle, region: Handle) -> Self { Self { surface, region } } @@ -49,7 +49,7 @@ impl Face { } /// Access the region of the face - pub fn region(&self) -> &Region { + pub fn region(&self) -> &Handle { &self.region } diff --git a/crates/fj-core/src/objects/kinds/sketch.rs b/crates/fj-core/src/objects/kinds/sketch.rs index 5f6119151..7cce6806e 100644 --- a/crates/fj-core/src/objects/kinds/sketch.rs +++ b/crates/fj-core/src/objects/kinds/sketch.rs @@ -35,8 +35,7 @@ impl Sketch { self.regions .iter() .map(|region| { - Face::new(surface.clone(), region.clone_object()) - .insert(services) + Face::new(surface.clone(), region.clone()).insert(services) }) .collect() } diff --git a/crates/fj-core/src/operations/build/face.rs b/crates/fj-core/src/operations/build/face.rs index 6403fd35d..91b02bfbc 100644 --- a/crates/fj-core/src/operations/build/face.rs +++ b/crates/fj-core/src/operations/build/face.rs @@ -16,7 +16,7 @@ pub trait BuildFace { /// Build a face with an empty exterior, no interiors, and no color fn unbound(surface: Handle, services: &mut Services) -> Face { let exterior = Cycle::empty().insert(services); - let region = Region::new(exterior, [], None); + let region = Region::new(exterior, [], None).insert(services); Face::new(surface, region) } @@ -45,7 +45,8 @@ pub trait BuildFace { (cycle, half_edges, vertices) }; - let region = Region::new(exterior, [], None); + let region = Region::new(exterior, [], None).insert(services); + let face = Face::new(surface, region); Polygon { diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index f69ecece9..294e2a8d8 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -15,7 +15,7 @@ pub trait UpdateFace { impl UpdateFace for Face { fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self { let region = f(self.region()); - Face::new(self.surface().clone(), region.clone_object()) + Face::new(self.surface().clone(), region) } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index c4d08ae5b..cf4f57303 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -113,7 +113,9 @@ mod tests { valid.region().exterior().clone(), interiors, valid.region().color(), - ); + ) + .insert(&mut services); + Face::new(valid.surface().clone(), region) }; From f8450c3901850528b112e0752c60a5997b01a6e9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 13 Jun 2023 13:15:14 +0200 Subject: [PATCH 28/28] Make `UpdateFace::update_region` more flexible --- crates/fj-core/src/operations/update/face.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 294e2a8d8..8bd5beaff 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -9,18 +9,27 @@ use crate::{ /// Update a [`Face`] pub trait UpdateFace { /// Replace the region of the face - fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self; + fn update_region( + &self, + f: impl FnOnce(&Handle) -> Handle, + ) -> Self; } impl UpdateFace for Face { - fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self { + fn update_region( + &self, + f: impl FnOnce(&Handle) -> Handle, + ) -> Self { let region = f(self.region()); Face::new(self.surface().clone(), region) } } impl UpdateFace for Polygon { - fn update_region(&self, f: impl FnOnce(&Region) -> Handle) -> Self { + fn update_region( + &self, + f: impl FnOnce(&Handle) -> Handle, + ) -> Self { let face = self.face.update_region(f); let edges = array::from_fn(|i| { face.region()