From a36b7b42454eeeaeedba8575467a857fa186590f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:07:17 +0100 Subject: [PATCH 01/19] Implement `Insert` for `Handle` --- .../fj-core/src/operations/insert/insert_trait.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/crates/fj-core/src/operations/insert/insert_trait.rs b/crates/fj-core/src/operations/insert/insert_trait.rs index c83edccf60..d4a50474eb 100644 --- a/crates/fj-core/src/operations/insert/insert_trait.rs +++ b/crates/fj-core/src/operations/insert/insert_trait.rs @@ -61,6 +61,20 @@ impl_insert!( Vertex, vertices; ); +// Implement `Insert` for `Handle` as a no-op. This is useful for code that +// needs a `Handle` in the end, but doesn't care if it gets that directly or +// inserts a bare object itself. +impl Insert for Handle +where + T: Insert, +{ + type Inserted = Self; + + fn insert(self, _: &mut Services) -> Self::Inserted { + self + } +} + impl Insert for Polygon { type Inserted = Polygon; From dc91fb57cb9ba8deb9a243dd7b413cbee5030718 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 12:55:57 +0100 Subject: [PATCH 02/19] Require `&mut Instance` in `update_half_edge` --- crates/fj-core/src/operations/build/shell.rs | 18 ++++++++++++------ crates/fj-core/src/operations/join/cycle.rs | 6 ++++-- crates/fj-core/src/operations/update/cycle.rs | 15 ++++++++++++--- crates/fj-core/src/validate/shell.rs | 6 ++++-- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index bc8d39f6ca..1c59fe32bf 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -151,11 +151,12 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .join_to( abc.face.region().exterior(), @@ -173,11 +174,12 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(1), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .join_to( abc.face.region().exterior(), @@ -187,11 +189,12 @@ pub trait BuildShell { ) .update_half_edge( cycle.half_edges().nth_circular(0), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .join_to( bad.face.region().exterior(), @@ -209,27 +212,30 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .update_half_edge( cycle.half_edges().nth_circular(1), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .update_half_edge( cycle.half_edges().nth_circular(2), - |edge| { + |edge, core| { [edge .reverse_curve_coordinate_systems(core) .insert(&mut core.services)] }, + core, ) .join_to( abc.face.region().exterior(), diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 4a7aac1651..aa1a0e5eac 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -118,7 +118,7 @@ impl JoinCycle for Cycle { cycle .update_half_edge( self.half_edges().nth_circular(index), - |edge| { + |edge, core| { [edge .update_curve(|_| edge_other.curve().clone()) .update_start_vertex(|_| { @@ -130,16 +130,18 @@ impl JoinCycle for Cycle { }) .insert(&mut core.services)] }, + core, ) .update_half_edge( self.half_edges().nth_circular(index + 1), - |edge| { + |edge, core| { [edge .update_start_vertex(|_| { edge_other.start_vertex().clone() }) .insert(&mut core.services)] }, + core, ) }, ) diff --git a/crates/fj-core/src/operations/update/cycle.rs b/crates/fj-core/src/operations/update/cycle.rs index 0172f8d603..7868d86991 100644 --- a/crates/fj-core/src/operations/update/cycle.rs +++ b/crates/fj-core/src/operations/update/cycle.rs @@ -1,6 +1,7 @@ use crate::{ objects::{Cycle, HalfEdge}, storage::Handle, + Instance, }; /// Update a [`Cycle`] @@ -23,7 +24,11 @@ pub trait UpdateCycle { fn update_half_edge( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce( + &Handle, + &mut Instance, + ) -> [Handle; N], + core: &mut Instance, ) -> Self; } @@ -39,11 +44,15 @@ impl UpdateCycle for Cycle { fn update_half_edge( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce( + &Handle, + &mut Instance, + ) -> [Handle; N], + core: &mut Instance, ) -> Self { let edges = self .half_edges() - .replace(handle, update(handle)) + .replace(handle, update(handle, core)) .expect("Half-edge not found"); Cycle::new(edges) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 387c730f5c..07fc5037f4 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -424,7 +424,7 @@ mod tests { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge| { + |edge, core| { [edge .update_path(|path| path.reverse()) .update_boundary(|boundary| { @@ -432,6 +432,7 @@ mod tests { }) .insert(&mut core.services)] }, + &mut core, ) .insert(&mut core.services) }) @@ -488,7 +489,7 @@ mod tests { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge| { + |edge, core| { [edge .update_curve(|_| { Curve::new() @@ -496,6 +497,7 @@ mod tests { }) .insert(&mut core.services)] }, + &mut core, ) .insert(&mut core.services) }) From 1483d8b164ba69238e1d390ece29943b146b31ec Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 13:00:33 +0100 Subject: [PATCH 03/19] Make `update_half_edge` more convenient to use --- crates/fj-core/src/operations/build/shell.rs | 24 ++++----------- crates/fj-core/src/operations/join/cycle.rs | 15 ++++------ crates/fj-core/src/operations/update/cycle.rs | 30 +++++++++++-------- crates/fj-core/src/validate/shell.rs | 15 ++++------ 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 1c59fe32bf..05342c6ca3 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -152,9 +152,7 @@ pub trait BuildShell { .update_half_edge( cycle.half_edges().nth_circular(0), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) @@ -175,9 +173,7 @@ pub trait BuildShell { .update_half_edge( cycle.half_edges().nth_circular(1), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) @@ -190,9 +186,7 @@ pub trait BuildShell { .update_half_edge( cycle.half_edges().nth_circular(0), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) @@ -213,27 +207,21 @@ pub trait BuildShell { .update_half_edge( cycle.half_edges().nth_circular(0), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) .update_half_edge( cycle.half_edges().nth_circular(1), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) .update_half_edge( cycle.half_edges().nth_circular(2), |edge, core| { - [edge - .reverse_curve_coordinate_systems(core) - .insert(&mut core.services)] + [edge.reverse_curve_coordinate_systems(core)] }, core, ) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index aa1a0e5eac..ce1d5b8a0a 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -118,7 +118,7 @@ impl JoinCycle for Cycle { cycle .update_half_edge( self.half_edges().nth_circular(index), - |edge, core| { + |edge, _| { [edge .update_curve(|_| edge_other.curve().clone()) .update_start_vertex(|_| { @@ -127,19 +127,16 @@ impl JoinCycle for Cycle { .nth_circular(index_other + 1) .start_vertex() .clone() - }) - .insert(&mut core.services)] + })] }, core, ) .update_half_edge( self.half_edges().nth_circular(index + 1), - |edge, core| { - [edge - .update_start_vertex(|_| { - edge_other.start_vertex().clone() - }) - .insert(&mut core.services)] + |edge, _| { + [edge.update_start_vertex(|_| { + edge_other.start_vertex().clone() + })] }, core, ) diff --git a/crates/fj-core/src/operations/update/cycle.rs b/crates/fj-core/src/operations/update/cycle.rs index 7868d86991..e6a2640337 100644 --- a/crates/fj-core/src/operations/update/cycle.rs +++ b/crates/fj-core/src/operations/update/cycle.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Cycle, HalfEdge}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -21,15 +22,14 @@ pub trait UpdateCycle { /// /// Panics, if the update results in a duplicate object. #[must_use] - fn update_half_edge( + fn update_half_edge( &self, handle: &Handle, - update: impl FnOnce( - &Handle, - &mut Instance, - ) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateCycle for Cycle { @@ -41,18 +41,22 @@ impl UpdateCycle for Cycle { Cycle::new(half_edges) } - fn update_half_edge( + fn update_half_edge( &self, handle: &Handle, - update: impl FnOnce( - &Handle, - &mut Instance, - ) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let edges = self .half_edges() - .replace(handle, update(handle, core)) + .replace( + handle, + update(handle, core) + .map(|object| object.insert(&mut core.services)), + ) .expect("Half-edge not found"); Cycle::new(edges) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 07fc5037f4..518fb98317 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -424,13 +424,12 @@ mod tests { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { + |edge, _| { [edge .update_path(|path| path.reverse()) .update_boundary(|boundary| { boundary.reverse() - }) - .insert(&mut core.services)] + })] }, &mut core, ) @@ -490,12 +489,10 @@ mod tests { .update_half_edge( cycle.half_edges().nth_circular(0), |edge, core| { - [edge - .update_curve(|_| { - Curve::new() - .insert(&mut core.services) - }) - .insert(&mut core.services)] + [edge.update_curve(|_| { + Curve::new() + .insert(&mut core.services) + })] }, &mut core, ) From 70309896a69351f8f19cb1ed2817407f4efa1b8e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:04:17 +0100 Subject: [PATCH 04/19] Require `&mut Instance` in `update_curve` --- crates/fj-core/src/operations/build/shell.rs | 2 +- crates/fj-core/src/operations/join/cycle.rs | 9 ++++++--- crates/fj-core/src/operations/replace/curve.rs | 4 ++-- crates/fj-core/src/operations/sweep/half_edge.rs | 2 +- crates/fj-core/src/operations/update/half_edge.rs | 9 ++++++--- crates/fj-core/src/validate/shell.rs | 11 +++++++---- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 05342c6ca3..caae195097 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -98,7 +98,7 @@ pub trait BuildShell { core, ) .update_start_vertex(|_| vertex) - .update_curve(|_| curve) + .update_curve(|_, _| curve, core) .insert(&mut core.services) }) }; diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index ce1d5b8a0a..f7571d5ac0 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -88,7 +88,7 @@ impl JoinCycle for Cycle { self.add_half_edges(edges.into_iter().circular_tuple_windows().map( |((prev_half_edge, _, _), (half_edge, curve, boundary))| { HalfEdge::unjoined(curve, boundary, core) - .update_curve(|_| half_edge.curve().clone()) + .update_curve(|_, _| half_edge.curve().clone(), core) .update_start_vertex(|_| { prev_half_edge.start_vertex().clone() }) @@ -118,9 +118,12 @@ impl JoinCycle for Cycle { cycle .update_half_edge( self.half_edges().nth_circular(index), - |edge, _| { + |edge, core| { [edge - .update_curve(|_| edge_other.curve().clone()) + .update_curve( + |_, _| edge_other.curve().clone(), + core, + ) .update_start_vertex(|_| { other .half_edges() diff --git a/crates/fj-core/src/operations/replace/curve.rs b/crates/fj-core/src/operations/replace/curve.rs index 4ec5b10003..2b34ae46ca 100644 --- a/crates/fj-core/src/operations/replace/curve.rs +++ b/crates/fj-core/src/operations/replace/curve.rs @@ -32,10 +32,10 @@ impl ReplaceCurve for HalfEdge { &self, original: &Handle, replacement: Handle, - _: &mut Instance, + core: &mut Instance, ) -> ReplaceOutput { if original.id() == self.curve().id() { - ReplaceOutput::Updated(self.update_curve(|_| replacement)) + ReplaceOutput::Updated(self.update_curve(|_, _| replacement, core)) } else { ReplaceOutput::Original(self.clone()) } diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index f1911c6ac1..e5b0467017 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -123,7 +123,7 @@ impl SweepHalfEdge for HalfEdge { .update_start_vertex(|_| start_vertex); let edge = if let Some(curve) = curve { - edge.update_curve(|_| curve) + edge.update_curve(|_, _| curve, core) } else { edge }; diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index c555c9cf80..fcfffc27a7 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -4,6 +4,7 @@ use crate::{ geometry::{CurveBoundary, SurfacePath}, objects::{Curve, HalfEdge, Vertex}, storage::Handle, + Instance, }; /// Update a [`HalfEdge`] @@ -26,7 +27,8 @@ pub trait UpdateHalfEdge { #[must_use] fn update_curve( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self; /// Update the start vertex of the edge @@ -64,12 +66,13 @@ impl UpdateHalfEdge for HalfEdge { fn update_curve( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self { HalfEdge::new( self.path(), self.boundary(), - update(self.curve()), + update(self.curve(), core), self.start_vertex().clone(), ) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 518fb98317..0bd73f2bc7 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -489,10 +489,13 @@ mod tests { .update_half_edge( cycle.half_edges().nth_circular(0), |edge, core| { - [edge.update_curve(|_| { - Curve::new() - .insert(&mut core.services) - })] + [edge.update_curve( + |_, core| { + Curve::new() + .insert(&mut core.services) + }, + core, + )] }, &mut core, ) From 1349202dba7894cb889b44a7cf765bacf6f0e06f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:07:37 +0100 Subject: [PATCH 05/19] Make `update_curve` more convenient to use --- .../src/operations/update/half_edge.rs | 20 ++++++++++++------- crates/fj-core/src/validate/shell.rs | 5 +---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index fcfffc27a7..10031be650 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -3,6 +3,7 @@ use fj_math::Point; use crate::{ geometry::{CurveBoundary, SurfacePath}, objects::{Curve, HalfEdge, Vertex}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -25,11 +26,13 @@ pub trait UpdateHalfEdge { /// Update the curve of the edge #[must_use] - fn update_curve( + fn update_curve( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; /// Update the start vertex of the edge #[must_use] @@ -64,15 +67,18 @@ impl UpdateHalfEdge for HalfEdge { ) } - fn update_curve( + fn update_curve( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { HalfEdge::new( self.path(), self.boundary(), - update(self.curve(), core), + update(self.curve(), core).insert(&mut core.services), self.start_vertex().clone(), ) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 0bd73f2bc7..e2576b4e61 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -490,10 +490,7 @@ mod tests { cycle.half_edges().nth_circular(0), |edge, core| { [edge.update_curve( - |_, core| { - Curve::new() - .insert(&mut core.services) - }, + |_, _| Curve::new(), core, )] }, From fb90247221c328c354ae5d6dbd2cf5b530bc73ac Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:16:30 +0100 Subject: [PATCH 06/19] Expect `&mut Instance` in `update_start_vertex` --- crates/fj-core/src/operations/build/shell.rs | 2 +- crates/fj-core/src/operations/join/cycle.rs | 33 +++++++++++-------- .../fj-core/src/operations/replace/vertex.rs | 6 ++-- crates/fj-core/src/operations/split/edge.rs | 6 ++-- crates/fj-core/src/operations/split/face.rs | 2 +- .../fj-core/src/operations/sweep/half_edge.rs | 2 +- .../src/operations/update/half_edge.rs | 8 +++-- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index caae195097..c3abf51f26 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -97,7 +97,7 @@ pub trait BuildShell { Some(boundary.reverse().inner), core, ) - .update_start_vertex(|_| vertex) + .update_start_vertex(|_, _| vertex, core) .update_curve(|_, _| curve, core) .insert(&mut core.services) }) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index f7571d5ac0..e62b00dabe 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -89,9 +89,10 @@ impl JoinCycle for Cycle { |((prev_half_edge, _, _), (half_edge, curve, boundary))| { HalfEdge::unjoined(curve, boundary, core) .update_curve(|_, _| half_edge.curve().clone(), core) - .update_start_vertex(|_| { - prev_half_edge.start_vertex().clone() - }) + .update_start_vertex( + |_, _| prev_half_edge.start_vertex().clone(), + core, + ) .insert(&mut core.services) }, )) @@ -124,22 +125,26 @@ impl JoinCycle for Cycle { |_, _| edge_other.curve().clone(), core, ) - .update_start_vertex(|_| { - other - .half_edges() - .nth_circular(index_other + 1) - .start_vertex() - .clone() - })] + .update_start_vertex( + |_, _| { + other + .half_edges() + .nth_circular(index_other + 1) + .start_vertex() + .clone() + }, + core, + )] }, core, ) .update_half_edge( self.half_edges().nth_circular(index + 1), - |edge, _| { - [edge.update_start_vertex(|_| { - edge_other.start_vertex().clone() - })] + |edge, core| { + [edge.update_start_vertex( + |_, _| edge_other.start_vertex().clone(), + core, + )] }, core, ) diff --git a/crates/fj-core/src/operations/replace/vertex.rs b/crates/fj-core/src/operations/replace/vertex.rs index c42554a2b5..bd884e001e 100644 --- a/crates/fj-core/src/operations/replace/vertex.rs +++ b/crates/fj-core/src/operations/replace/vertex.rs @@ -32,10 +32,12 @@ impl ReplaceVertex for HalfEdge { &self, original: &Handle, replacement: Handle, - _: &mut Instance, + core: &mut Instance, ) -> ReplaceOutput { if original.id() == self.start_vertex().id() { - ReplaceOutput::Updated(self.update_start_vertex(|_| replacement)) + ReplaceOutput::Updated( + self.update_start_vertex(|_, _| replacement, core), + ) } else { ReplaceOutput::Original(self.clone()) } diff --git a/crates/fj-core/src/operations/split/edge.rs b/crates/fj-core/src/operations/split/edge.rs index 4a3d17d36b..98b22f98da 100644 --- a/crates/fj-core/src/operations/split/edge.rs +++ b/crates/fj-core/src/operations/split/edge.rs @@ -46,8 +46,10 @@ impl SplitEdge for Shell { let siblings = { let [sibling_a, sibling_b] = sibling.split_half_edge(point, core); - let sibling_b = sibling_b - .update_start_vertex(|_| half_edge_b.start_vertex().clone()); + let sibling_b = sibling_b.update_start_vertex( + |_, _| half_edge_b.start_vertex().clone(), + core, + ); [sibling_a, sibling_b] .map(|half_edge| half_edge.insert(&mut core.services)) }; diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 713e42caa0..4a516b27b2 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -106,7 +106,7 @@ impl SplitFace for Shell { None, core, ) - .update_start_vertex(|_| b.start_vertex().clone()) + .update_start_vertex(|_, _| b.start_vertex().clone(), core) .insert(&mut core.services); let dividing_half_edge_c_to_b = HalfEdge::from_sibling( &dividing_half_edge_a_to_d, diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index e5b0467017..89a6291984 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -120,7 +120,7 @@ impl SweepHalfEdge for HalfEdge { Some(boundary), core, ) - .update_start_vertex(|_| start_vertex); + .update_start_vertex(|_, _| start_vertex, core); let edge = if let Some(curve) = curve { edge.update_curve(|_, _| curve, core) diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index 10031be650..881b599a02 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -38,7 +38,8 @@ pub trait UpdateHalfEdge { #[must_use] fn update_start_vertex( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self; } @@ -85,13 +86,14 @@ impl UpdateHalfEdge for HalfEdge { fn update_start_vertex( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self { HalfEdge::new( self.path(), self.boundary(), self.curve().clone(), - update(self.start_vertex()), + update(self.start_vertex(), core), ) } } From 80052b6a0aff1b82f4bc9016586c78c93ba0fa38 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:18:41 +0100 Subject: [PATCH 07/19] Make `update_start_vertex` more convenient to call --- .../src/operations/update/half_edge.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index 881b599a02..a8e05f9e7e 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -36,11 +36,13 @@ pub trait UpdateHalfEdge { /// Update the start vertex of the edge #[must_use] - fn update_start_vertex( + fn update_start_vertex( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateHalfEdge for HalfEdge { @@ -84,16 +86,19 @@ impl UpdateHalfEdge for HalfEdge { ) } - fn update_start_vertex( + fn update_start_vertex( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { HalfEdge::new( self.path(), self.boundary(), self.curve().clone(), - update(self.start_vertex(), core), + update(self.start_vertex(), core).insert(&mut core.services), ) } } From ca85864808b1b7dd065252a77ea17e156a4c83fe Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:27:55 +0100 Subject: [PATCH 08/19] Expect `&mut Instance` in `update_region` --- .../src/algorithms/intersect/curve_face.rs | 29 ++- .../src/algorithms/intersect/face_face.rs | 38 +-- .../src/algorithms/intersect/face_point.rs | 196 +++++++------- .../src/algorithms/intersect/ray_face.rs | 196 +++++++++----- .../fj-core/src/algorithms/triangulate/mod.rs | 41 +-- crates/fj-core/src/operations/build/shell.rs | 240 ++++++++++-------- crates/fj-core/src/operations/holes.rs | 89 ++++--- crates/fj-core/src/operations/split/face.rs | 70 ++--- crates/fj-core/src/operations/update/face.rs | 14 +- crates/fj-core/src/validate/face.rs | 62 +++-- crates/fj-core/src/validate/shell.rs | 82 +++--- models/color/src/lib.rs | 11 +- 12 files changed, 612 insertions(+), 456 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 21f95920ed..6f1d0b3576 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -188,19 +188,22 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon(exterior_points, &mut core) - .insert(&mut core.services) - }) - .add_interiors([Cycle::polygon( - interior_points, - &mut core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }); + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon(exterior_points, core) + .insert(&mut core.services) + }) + .add_interiors([Cycle::polygon( + interior_points, + core, + ) + .insert(&mut core.services)]) + .insert(&mut core.services) + }, + &mut core, + ); let expected = CurveFaceIntersection::from_intervals([[[1.], [2.]], [[4.], [5.]]]); diff --git a/crates/fj-core/src/algorithms/intersect/face_face.rs b/crates/fj-core/src/algorithms/intersect/face_face.rs index e4748dc7e7..8c0212f3a8 100644 --- a/crates/fj-core/src/algorithms/intersect/face_face.rs +++ b/crates/fj-core/src/algorithms/intersect/face_face.rs @@ -90,14 +90,17 @@ mod tests { core.services.objects.surfaces.xz_plane(), ] .map(|surface| { - Face::unbound(surface, &mut core).update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon(points, &mut core) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }) + Face::unbound(surface, &mut core).update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon(points, core) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ) }); let intersection = FaceFaceIntersection::compute([&a, &b]); @@ -120,14 +123,17 @@ mod tests { core.services.objects.surfaces.xz_plane(), ]; let [a, b] = surfaces.clone().map(|surface| { - Face::unbound(surface, &mut core).update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon(points, &mut core) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }) + Face::unbound(surface, &mut core).update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon(points, core) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ) }); let intersection = FaceFaceIntersection::compute([&a, &b]); diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 7e1ccff861..143e6dd66e 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -150,17 +150,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 1.], [0., 2.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [1., 1.], [0., 2.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([2., 1.]); let intersection = (&face, &point).intersect(); @@ -173,17 +176,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [0., 2.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [0., 2.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -199,17 +205,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[4., 2.], [0., 4.], [0., 0.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[4., 2.], [0., 4.], [0., 0.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 2.]); let intersection = (&face, &point).intersect(); @@ -225,17 +234,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -251,17 +263,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -277,23 +292,26 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [0., 0.], - [2., 1.], - [3., 1.], - [4., 0.], - [4., 5.], - ], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [0., 0.], + [2., 1.], + [3., 1.], + [4., 0.], + [4., 5.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -309,17 +327,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 0.], [0., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 0.], [0., 1.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 0.]); let intersection = (&face, &point).intersect(); @@ -343,17 +364,20 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 0.], [0., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [1., 0.], [0., 1.]], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let point = Point::from([1., 0.]); let intersection = (&face, &point).intersect(); diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index e5cf63e17a..bc8d3ba5c7 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -166,17 +166,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([-1., 0., 0.], &mut core); assert_eq!((&ray, &face).intersect(), None); @@ -190,17 +198,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([1., 0., 0.], &mut core); assert_eq!( @@ -217,17 +233,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([0., 0., 2.], &mut core); assert_eq!((&ray, &face).intersect(), None); @@ -241,17 +265,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([1., 1., 0.], &mut core); let edge = face @@ -275,17 +307,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([1., 1., 1.], &mut core); let vertex = face @@ -310,17 +350,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); assert_eq!( (&ray, &face).intersect(), @@ -336,17 +384,25 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - &mut core, - ) + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }) .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + }, + &mut core, + ); let face = face.translate([0., 0., 1.], &mut core); assert_eq!((&ray, &face).intersect(), None); diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index ea686893a6..0f73e86891 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -101,14 +101,17 @@ mod tests { let face = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon([a, b, c, d], &mut core) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon([a, b, c, d], core) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ); let a = Point::from(a).to_xyz(); let b = Point::from(b).to_xyz(); @@ -141,17 +144,19 @@ mod tests { let surface = core.services.objects.surfaces.xy_plane(); - let face = - Face::unbound(surface.clone(), &mut core).update_region(|region| { + let face = Face::unbound(surface.clone(), &mut core).update_region( + |region, core| { region .update_exterior(|_| { - Cycle::polygon([a, b, c, d], &mut core) + Cycle::polygon([a, b, c, d], core) .insert(&mut core.services) }) - .add_interiors([Cycle::polygon([e, f, g, h], &mut core) + .add_interiors([Cycle::polygon([e, f, g, h], core) .insert(&mut core.services)]) .insert(&mut core.services) - }); + }, + &mut core, + ); let triangles = triangulate(face)?; @@ -206,15 +211,17 @@ mod tests { let surface = core.services.objects.surfaces.xy_plane(); - let face = - Face::unbound(surface.clone(), &mut core).update_region(|region| { + let face = Face::unbound(surface.clone(), &mut core).update_region( + |region, core| { region .update_exterior(|_| { - Cycle::polygon([a, b, c, d, e], &mut core) + Cycle::polygon([a, b, c, d, e], core) .insert(&mut core.services) }) .insert(&mut core.services) - }); + }, + &mut core, + ); 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 c3abf51f26..4c682d938e 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -104,15 +104,18 @@ pub trait BuildShell { }; Face::unbound(surface, core) - .update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .add_half_edges(half_edges) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services) }) .collect::>(); @@ -145,108 +148,123 @@ pub trait BuildShell { let [a, b, c, d] = points.map(Into::into); let abc = Face::triangle([a, b, c], core); - let bad = Face::triangle([b, a, d], core).update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 0..=0, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }); - let dac = Face::triangle([d, a, c], core).update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }); - let cbd = Face::triangle([c, b, d], core).update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(2), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + let bad = Face::triangle([b, a, d], core).update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + core, + ) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + core, + ); + let dac = Face::triangle([d, a, c], core).update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + core, + ); + let cbd = Face::triangle([c, b, d], core).update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(2), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + core, + ) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + core, + ); let triangles = [abc, bad, dac, cbd] .map(|triangle| triangle.insert(&mut core.services)); diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 06c2d4f1a6..5d129a834d 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -64,20 +64,23 @@ impl AddHole for Shell { self.update_face(location.face, |face| { [face - .update_region(|region| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services)] }) .add_faces(hole) @@ -137,34 +140,44 @@ impl AddHole for Shell { self.update_face(entry_location.face, |face| { [face - .update_region(|region| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services)] }) .update_face(exit_location.face, |face| { [face - .update_region(|region| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [(exit.clone(), exit.path(), exit.boundary())], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .add_interiors([Cycle::empty() + .add_joined_edges( + [( + exit.clone(), + exit.path(), + exit.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services)] }) .add_faces(hole) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 4a516b27b2..35bc75a98c 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -130,22 +130,25 @@ impl SplitFace for Shell { updated_face_after_split_edges.surface().clone(), core, ) - .update_region(|region| { - let mut region = region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges_b_to_c_inclusive) - .add_half_edges([dividing_half_edge_c_to_b]) - .insert(&mut core.services) - }) - .insert(&mut core.services); - - if let Some(color) = face.region().color() { - region = region.set_color(color).insert(&mut core.services); - } - - region - }) + .update_region( + |region, core| { + let mut region = region + .update_exterior(|cycle| { + cycle + .add_half_edges(half_edges_b_to_c_inclusive) + .add_half_edges([dividing_half_edge_c_to_b]) + .insert(&mut core.services) + }) + .insert(&mut core.services); + + if let Some(color) = face.region().color() { + region = region.set_color(color).insert(&mut core.services); + } + + region + }, + core, + ) .insert(&mut core.services); // The previous operation has moved the iterator along. @@ -157,22 +160,25 @@ impl SplitFace for Shell { updated_face_after_split_edges.surface().clone(), core, ) - .update_region(|region| { - let mut region = region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges_d_to_a_inclusive) - .add_half_edges([dividing_half_edge_a_to_d]) - .insert(&mut core.services) - }) - .insert(&mut core.services); - - if let Some(color) = face.region().color() { - region = region.set_color(color).insert(&mut core.services); - } - - region - }) + .update_region( + |region, core| { + let mut region = region + .update_exterior(|cycle| { + cycle + .add_half_edges(half_edges_d_to_a_inclusive) + .add_half_edges([dividing_half_edge_a_to_d]) + .insert(&mut core.services) + }) + .insert(&mut core.services); + + if let Some(color) = face.region().color() { + region = region.set_color(color).insert(&mut core.services); + } + + region + }, + core, + ) .insert(&mut core.services); let faces = [split_face_a, split_face_b]; diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 2a6ae53bb3..a6b46dde02 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -2,6 +2,7 @@ use crate::{ objects::{Face, Region}, operations::build::Polygon, storage::Handle, + Instance, }; /// Update a [`Face`] @@ -10,16 +11,18 @@ pub trait UpdateFace { #[must_use] fn update_region( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self; } impl UpdateFace for Face { fn update_region( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self { - let region = update(self.region()); + let region = update(self.region(), core); Face::new(self.surface().clone(), region) } } @@ -27,8 +30,9 @@ impl UpdateFace for Face { impl UpdateFace for Polygon { fn update_region( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self { - self.replace_face(self.face.update_region(update)) + self.replace_face(self.face.update_region(update, core)) } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 9fbcd8c038..d38d9bf5d8 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -103,20 +103,23 @@ mod tests { let invalid = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core); - let valid = invalid.update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .add_half_edges([HalfEdge::circle( - [0., 0.], - 1., - &mut core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }); + let valid = invalid.update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .add_half_edges([HalfEdge::circle( + [0., 0.], + 1., + core, + ) + .insert(&mut core.services)]) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ); valid.validate_and_return_first_error()?; assert_contains_err!( @@ -133,22 +136,25 @@ mod tests { let valid = Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) - .update_region(|region| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [3., 0.], [0., 3.]], - &mut core, + .update_region( + |region, core| { + region + .update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [3., 0.], [0., 3.]], + core, + ) + .insert(&mut core.services) + }) + .add_interiors([Cycle::polygon( + [[1., 1.], [1., 2.], [2., 1.]], + core, ) + .insert(&mut core.services)]) .insert(&mut core.services) - }) - .add_interiors([Cycle::polygon( - [[1., 1.], [1., 2.], [2., 1.]], - &mut core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) - }); + }, + &mut core, + ); let invalid = { let interiors = valid .region() diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index e2576b4e61..569ede802e 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -418,25 +418,30 @@ mod tests { ); let invalid = valid.shell.update_face(&valid.abc.face, |face| { [face - .update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| path.reverse()) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - &mut core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| { + path.reverse() + }) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ) .insert(&mut core.services)] }); @@ -482,24 +487,27 @@ mod tests { ); let invalid = valid.shell.update_face(&valid.abc.face, |face| { [face - .update_region(|region| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - &mut core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) + .insert(&mut core.services) + }) + .insert(&mut core.services) + }, + &mut core, + ) .insert(&mut core.services)] }); diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index a0689f1ccb..4d400f5b59 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -15,9 +15,14 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { cuboid.update_shell(cuboid.shells().only(), |shell| { let shell = shell.update_face(shell.faces().first(), |face| { [face - .update_region(|region| { - region.set_color([0., 1., 0.]).insert(&mut core.services) - }) + .update_region( + |region, core| { + region + .set_color([0., 1., 0.]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services)] }); From 9bcb67046f2b828951aa1ad2ebb473b33e1e9a05 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:32:12 +0100 Subject: [PATCH 09/19] Make `update_region` more convenient to call --- .../src/algorithms/intersect/curve_face.rs | 1 - .../src/algorithms/intersect/face_face.rs | 18 +- .../src/algorithms/intersect/face_point.rs | 109 ++++------ .../src/algorithms/intersect/ray_face.rs | 133 ++++-------- .../fj-core/src/algorithms/triangulate/mod.rs | 21 +- crates/fj-core/src/operations/build/shell.rs | 204 ++++++++---------- crates/fj-core/src/operations/holes.rs | 62 +++--- crates/fj-core/src/operations/update/face.rs | 30 ++- crates/fj-core/src/validate/face.rs | 17 +- crates/fj-core/src/validate/shell.rs | 64 +++--- models/color/src/lib.rs | 9 +- 11 files changed, 270 insertions(+), 398 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 6f1d0b3576..589475503d 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -200,7 +200,6 @@ mod tests { core, ) .insert(&mut core.services)]) - .insert(&mut core.services) }, &mut core, ); diff --git a/crates/fj-core/src/algorithms/intersect/face_face.rs b/crates/fj-core/src/algorithms/intersect/face_face.rs index 8c0212f3a8..9e76d66531 100644 --- a/crates/fj-core/src/algorithms/intersect/face_face.rs +++ b/crates/fj-core/src/algorithms/intersect/face_face.rs @@ -92,12 +92,9 @@ mod tests { .map(|surface| { Face::unbound(surface, &mut core).update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon(points, core) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|_| { + Cycle::polygon(points, core).insert(&mut core.services) + }) }, &mut core, ) @@ -125,12 +122,9 @@ mod tests { let [a, b] = surfaces.clone().map(|surface| { Face::unbound(surface, &mut core).update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon(points, core) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|_| { + Cycle::polygon(points, core).insert(&mut core.services) + }) }, &mut core, ) diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 143e6dd66e..0375847fc4 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -152,15 +152,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 1.], [0., 2.]], - core, - ) + region.update_exterior(|_| { + Cycle::polygon([[0., 0.], [1., 1.], [0., 2.]], core) .insert(&mut core.services) - }) - .insert(&mut core.services) + }) }, &mut core, ); @@ -178,15 +173,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [0., 2.]], - core, - ) + region.update_exterior(|_| { + Cycle::polygon([[0., 0.], [2., 1.], [0., 2.]], core) .insert(&mut core.services) - }) - .insert(&mut core.services) + }) }, &mut core, ); @@ -207,15 +197,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[4., 2.], [0., 4.], [0., 0.]], - core, - ) + region.update_exterior(|_| { + Cycle::polygon([[4., 2.], [0., 4.], [0., 0.]], core) .insert(&mut core.services) - }) - .insert(&mut core.services) + }) }, &mut core, ); @@ -236,15 +221,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -265,15 +248,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -294,21 +275,19 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [0., 0.], - [2., 1.], - [3., 1.], - [4., 0.], - [4., 5.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [ + [0., 0.], + [2., 1.], + [3., 1.], + [4., 0.], + [4., 5.], + ], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -329,15 +308,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 0.], [0., 1.]], - core, - ) + region.update_exterior(|_| { + Cycle::polygon([[0., 0.], [2., 0.], [0., 1.]], core) .insert(&mut core.services) - }) - .insert(&mut core.services) + }) }, &mut core, ); @@ -366,15 +340,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [1., 0.], [0., 1.]], - core, - ) + region.update_exterior(|_| { + Cycle::polygon([[0., 0.], [1., 0.], [0., 1.]], core) .insert(&mut core.services) - }) - .insert(&mut core.services) + }) }, &mut core, ); diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index bc8d3ba5c7..eaa4148f55 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -168,20 +168,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -200,20 +193,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -235,20 +221,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -267,20 +246,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -309,20 +281,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -352,20 +317,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); @@ -386,20 +344,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon( - [ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior(|_| { + Cycle::polygon( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + core, + ) .insert(&mut core.services) + }) }, &mut core, ); diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 0f73e86891..d9566b2d5c 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -103,12 +103,10 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon([a, b, c, d], core) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|_| { + Cycle::polygon([a, b, c, d], core) + .insert(&mut core.services) + }) }, &mut core, ); @@ -153,7 +151,6 @@ mod tests { }) .add_interiors([Cycle::polygon([e, f, g, h], core) .insert(&mut core.services)]) - .insert(&mut core.services) }, &mut core, ); @@ -213,12 +210,10 @@ mod tests { let face = Face::unbound(surface.clone(), &mut core).update_region( |region, core| { - region - .update_exterior(|_| { - Cycle::polygon([a, b, c, d, e], core) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|_| { + Cycle::polygon([a, b, c, d, e], core) + .insert(&mut core.services) + }) }, &mut core, ); diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 4c682d938e..bfb01389ed 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -106,13 +106,11 @@ pub trait BuildShell { Face::unbound(surface, core) .update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .add_half_edges(half_edges) + .insert(&mut core.services) + }) }, core, ) @@ -150,118 +148,106 @@ pub trait BuildShell { let abc = Face::triangle([a, b, c], core); let bad = Face::triangle([b, a, d], core).update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 0..=0, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + core, + ) + .insert(&mut core.services) + }) }, core, ); let dac = Face::triangle([d, a, c], core).update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .insert(&mut core.services) + }) }, core, ); let cbd = Face::triangle([c, b, d], core).update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(2), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(2), + |edge, core| { + [edge.reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + core, + ) + .insert(&mut core.services) + }) }, core, ); diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 5d129a834d..aea71a853b 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -66,18 +66,16 @@ impl AddHole for Shell { [face .update_region( |region, core| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) }, core, ) @@ -142,18 +140,16 @@ impl AddHole for Shell { [face .update_region( |region, core| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) }, core, ) @@ -163,18 +159,12 @@ impl AddHole for Shell { [face .update_region( |region, core| { - region - .add_interiors([Cycle::empty() - .add_joined_edges( - [( - exit.clone(), - exit.path(), - exit.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) + region.add_interiors([Cycle::empty() + .add_joined_edges( + [(exit.clone(), exit.path(), exit.boundary())], + core, + ) + .insert(&mut core.services)]) }, core, ) diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index a6b46dde02..f9e6b64fea 100644 --- a/crates/fj-core/src/operations/update/face.rs +++ b/crates/fj-core/src/operations/update/face.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Face, Region}, - operations::build::Polygon, + operations::{build::Polygon, insert::Insert}, storage::Handle, Instance, }; @@ -9,30 +9,38 @@ use crate::{ pub trait UpdateFace { /// Update the region of the face #[must_use] - fn update_region( + fn update_region( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateFace for Face { - fn update_region( + fn update_region( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let region = update(self.region(), core); - Face::new(self.surface().clone(), region) + Face::new(self.surface().clone(), region.insert(&mut core.services)) } } impl UpdateFace for Polygon { - fn update_region( + fn update_region( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { self.replace_face(self.face.update_region(update, core)) } } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index d38d9bf5d8..63e133df70 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -105,18 +105,12 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core); let valid = invalid.update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .add_half_edges([HalfEdge::circle( - [0., 0.], - 1., - core, - ) + region.update_exterior(|cycle| { + cycle + .add_half_edges([HalfEdge::circle([0., 0.], 1., core) .insert(&mut core.services)]) - .insert(&mut core.services) - }) - .insert(&mut core.services) + .insert(&mut core.services) + }) }, &mut core, ); @@ -151,7 +145,6 @@ mod tests { core, ) .insert(&mut core.services)]) - .insert(&mut core.services) }, &mut core, ); diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 569ede802e..029166a182 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -420,25 +420,21 @@ mod tests { [face .update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| { - path.reverse() - }) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| path.reverse()) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) + .insert(&mut core.services) + }) }, &mut core, ) @@ -489,22 +485,20 @@ mod tests { [face .update_region( |region, core| { - region - .update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - core, - ) - .insert(&mut core.services) - }) - .insert(&mut core.services) + region.update_exterior(|cycle| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) + .insert(&mut core.services) + }) }, &mut core, ) diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index 4d400f5b59..069037c0aa 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -15,14 +15,7 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { cuboid.update_shell(cuboid.shells().only(), |shell| { let shell = shell.update_face(shell.faces().first(), |face| { [face - .update_region( - |region, core| { - region - .set_color([0., 1., 0.]) - .insert(&mut core.services) - }, - core, - ) + .update_region(|region, _| region.set_color([0., 1., 0.]), core) .insert(&mut core.services)] }); From d8eedc42b907a75df55726174470c00b429cd60e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:38:17 +0100 Subject: [PATCH 10/19] Expect `&mut Instance` in `update_exterior` --- .../src/algorithms/intersect/curve_face.rs | 11 +- .../src/algorithms/intersect/face_face.rs | 20 +- .../src/algorithms/intersect/face_point.rs | 123 +++++++---- .../src/algorithms/intersect/ray_face.rs | 154 ++++++++----- .../fj-core/src/algorithms/triangulate/mod.rs | 33 ++- crates/fj-core/src/operations/build/shell.rs | 208 ++++++++++-------- crates/fj-core/src/operations/holes.rs | 26 ++- crates/fj-core/src/operations/split/face.rs | 30 ++- .../fj-core/src/operations/update/region.rs | 9 +- crates/fj-core/src/validate/face.rs | 34 ++- crates/fj-core/src/validate/shell.rs | 66 +++--- 11 files changed, 440 insertions(+), 274 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 589475503d..610bcf5b30 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -191,10 +191,13 @@ mod tests { .update_region( |region, core| { region - .update_exterior(|_| { - Cycle::polygon(exterior_points, core) - .insert(&mut core.services) - }) + .update_exterior( + |_, core| { + Cycle::polygon(exterior_points, core) + .insert(&mut core.services) + }, + core, + ) .add_interiors([Cycle::polygon( interior_points, core, diff --git a/crates/fj-core/src/algorithms/intersect/face_face.rs b/crates/fj-core/src/algorithms/intersect/face_face.rs index 9e76d66531..63a96ee143 100644 --- a/crates/fj-core/src/algorithms/intersect/face_face.rs +++ b/crates/fj-core/src/algorithms/intersect/face_face.rs @@ -92,9 +92,13 @@ mod tests { .map(|surface| { Face::unbound(surface, &mut core).update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon(points, core).insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon(points, core) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ) @@ -122,9 +126,13 @@ mod tests { let [a, b] = surfaces.clone().map(|surface| { Face::unbound(surface, &mut core).update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon(points, core).insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon(points, core) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ) diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 0375847fc4..3ad5d3305d 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -152,10 +152,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([[0., 0.], [1., 1.], [0., 2.]], core) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [1., 1.], [0., 2.]], + core, + ) .insert(&mut core.services) - }) + }, + core, + ) }, &mut core, ); @@ -173,10 +179,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([[0., 0.], [2., 1.], [0., 2.]], core) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [2., 1.], [0., 2.]], + core, + ) .insert(&mut core.services) - }) + }, + core, + ) }, &mut core, ); @@ -197,10 +209,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([[4., 2.], [0., 4.], [0., 0.]], core) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[4., 2.], [0., 4.], [0., 0.]], + core, + ) .insert(&mut core.services) - }) + }, + core, + ) }, &mut core, ); @@ -221,13 +239,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -248,13 +269,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -275,19 +299,22 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [ - [0., 0.], - [2., 1.], - [3., 1.], - [4., 0.], - [4., 5.], - ], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [0., 0.], + [2., 1.], + [3., 1.], + [4., 0.], + [4., 5.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -308,10 +335,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([[0., 0.], [2., 0.], [0., 1.]], core) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [2., 0.], [0., 1.]], + core, + ) .insert(&mut core.services) - }) + }, + core, + ) }, &mut core, ); @@ -340,10 +373,16 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([[0., 0.], [1., 0.], [0., 1.]], core) + region.update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [1., 0.], [0., 1.]], + core, + ) .insert(&mut core.services) - }) + }, + core, + ) }, &mut core, ); diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index eaa4148f55..f9c8a35d5d 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -168,13 +168,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -193,13 +201,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -221,13 +237,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -246,13 +270,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -281,13 +313,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.yz_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -317,13 +357,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -344,13 +392,21 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon( - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon( + [ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.], + ], + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index d9566b2d5c..007eca9ad8 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -103,10 +103,13 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core) .update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([a, b, c, d], core) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon([a, b, c, d], core) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -145,10 +148,13 @@ mod tests { let face = Face::unbound(surface.clone(), &mut core).update_region( |region, core| { region - .update_exterior(|_| { - Cycle::polygon([a, b, c, d], core) - .insert(&mut core.services) - }) + .update_exterior( + |_, core| { + Cycle::polygon([a, b, c, d], core) + .insert(&mut core.services) + }, + core, + ) .add_interiors([Cycle::polygon([e, f, g, h], core) .insert(&mut core.services)]) }, @@ -210,10 +216,13 @@ mod tests { let face = Face::unbound(surface.clone(), &mut core).update_region( |region, core| { - region.update_exterior(|_| { - Cycle::polygon([a, b, c, d, e], core) - .insert(&mut core.services) - }) + region.update_exterior( + |_, core| { + Cycle::polygon([a, b, c, d, e], core) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index bfb01389ed..288ad82daf 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -106,11 +106,14 @@ pub trait BuildShell { Face::unbound(surface, core) .update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .add_half_edges(half_edges) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .add_half_edges(half_edges) + .insert(&mut core.services) + }, + core, + ) }, core, ) @@ -148,106 +151,121 @@ pub trait BuildShell { let abc = Face::triangle([a, b, c], core); let bad = Face::triangle([b, a, d], core).update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 0..=0, - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + core, + ) + .insert(&mut core.services) + }, + core, + ) }, core, ); let dac = Face::triangle([d, a, c], core).update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .insert(&mut core.services) + }, + core, + ) }, core, ); let cbd = Face::triangle([c, b, d], core).update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(2), - |edge, core| { - [edge.reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(2), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + core, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + core, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + core, + ) + .insert(&mut core.services) + }, + core, + ) }, core, ); diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index aea71a853b..436216a0c3 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -47,11 +47,14 @@ impl AddHole for Shell { let entry = HalfEdge::circle(location.position, radius, core) .insert(&mut core.services); let hole = Region::empty(core) - .update_exterior(|_| { - Cycle::empty() - .add_half_edges([entry.clone()]) - .insert(&mut core.services) - }) + .update_exterior( + |_, core| { + Cycle::empty() + .add_half_edges([entry.clone()]) + .insert(&mut core.services) + }, + core, + ) .sweep_region( location.face.surface(), path, @@ -111,11 +114,14 @@ impl AddHole for Shell { }; let swept_region = Region::empty(core) - .update_exterior(|_| { - Cycle::empty() - .add_half_edges([entry.clone()]) - .insert(&mut core.services) - }) + .update_exterior( + |_, core| { + Cycle::empty() + .add_half_edges([entry.clone()]) + .insert(&mut core.services) + }, + core, + ) .sweep_region( entry_location.face.surface(), path, diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 35bc75a98c..f2b70455a4 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -133,12 +133,15 @@ impl SplitFace for Shell { .update_region( |region, core| { let mut region = region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges_b_to_c_inclusive) - .add_half_edges([dividing_half_edge_c_to_b]) - .insert(&mut core.services) - }) + .update_exterior( + |cycle, core| { + cycle + .add_half_edges(half_edges_b_to_c_inclusive) + .add_half_edges([dividing_half_edge_c_to_b]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services); if let Some(color) = face.region().color() { @@ -163,12 +166,15 @@ impl SplitFace for Shell { .update_region( |region, core| { let mut region = region - .update_exterior(|cycle| { - cycle - .add_half_edges(half_edges_d_to_a_inclusive) - .add_half_edges([dividing_half_edge_a_to_d]) - .insert(&mut core.services) - }) + .update_exterior( + |cycle, core| { + cycle + .add_half_edges(half_edges_d_to_a_inclusive) + .add_half_edges([dividing_half_edge_a_to_d]) + .insert(&mut core.services) + }, + core, + ) .insert(&mut core.services); if let Some(color) = face.region().color() { diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index eb26853e87..e7823fe855 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -1,6 +1,7 @@ use crate::{ objects::{Cycle, Region}, storage::Handle, + Instance, }; /// Update a [`Region`] @@ -9,7 +10,8 @@ pub trait UpdateRegion { #[must_use] fn update_exterior( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self; /// Add the provided interiors to the region @@ -37,9 +39,10 @@ pub trait UpdateRegion { impl UpdateRegion for Region { fn update_exterior( &self, - update: impl FnOnce(&Handle) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> Handle, + core: &mut Instance, ) -> Self { - let exterior = update(self.exterior()); + let exterior = update(self.exterior(), core); Region::new(exterior, self.interiors().iter().cloned(), self.color()) } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 63e133df70..13ef927e17 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -105,12 +105,19 @@ mod tests { Face::unbound(core.services.objects.surfaces.xy_plane(), &mut core); let valid = invalid.update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .add_half_edges([HalfEdge::circle([0., 0.], 1., core) + region.update_exterior( + |cycle, core| { + cycle + .add_half_edges([HalfEdge::circle( + [0., 0.], + 1., + core, + ) .insert(&mut core.services)]) - .insert(&mut core.services) - }) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ); @@ -133,13 +140,16 @@ mod tests { .update_region( |region, core| { region - .update_exterior(|_| { - Cycle::polygon( - [[0., 0.], [3., 0.], [0., 3.]], - core, - ) - .insert(&mut core.services) - }) + .update_exterior( + |_, core| { + Cycle::polygon( + [[0., 0.], [3., 0.], [0., 3.]], + core, + ) + .insert(&mut core.services) + }, + core, + ) .add_interiors([Cycle::polygon( [[1., 1.], [1., 2.], [2., 1.]], core, diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 029166a182..6ba1b40596 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -420,21 +420,26 @@ mod tests { [face .update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| path.reverse()) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| { + path.reverse() + }) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ) @@ -485,20 +490,23 @@ mod tests { [face .update_region( |region, core| { - region.update_exterior(|cycle| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - core, - ) - .insert(&mut core.services) - }) + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) + .insert(&mut core.services) + }, + core, + ) }, &mut core, ) From bd347696bdf82520cd7e2cae8f415f835fc58f4d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:42:12 +0100 Subject: [PATCH 11/19] Make `update_exterior` more convenient to call --- .../src/algorithms/intersect/curve_face.rs | 5 +- .../src/algorithms/intersect/face_face.rs | 11 +---- .../src/algorithms/intersect/face_point.rs | 9 ---- .../src/algorithms/intersect/ray_face.rs | 8 ---- .../fj-core/src/algorithms/triangulate/mod.rs | 15 ++---- crates/fj-core/src/operations/build/shell.rs | 9 +--- crates/fj-core/src/operations/holes.rs | 12 +---- crates/fj-core/src/operations/split/face.rs | 6 +-- .../fj-core/src/operations/update/region.rs | 20 +++++--- crates/fj-core/src/validate/face.rs | 15 +++--- crates/fj-core/src/validate/shell.rs | 48 ++++++++----------- 11 files changed, 51 insertions(+), 107 deletions(-) diff --git a/crates/fj-core/src/algorithms/intersect/curve_face.rs b/crates/fj-core/src/algorithms/intersect/curve_face.rs index 610bcf5b30..d7afca844c 100644 --- a/crates/fj-core/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-core/src/algorithms/intersect/curve_face.rs @@ -192,10 +192,7 @@ mod tests { |region, core| { region .update_exterior( - |_, core| { - Cycle::polygon(exterior_points, core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon(exterior_points, core), core, ) .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 63a96ee143..b818ee6ac4 100644 --- a/crates/fj-core/src/algorithms/intersect/face_face.rs +++ b/crates/fj-core/src/algorithms/intersect/face_face.rs @@ -66,7 +66,6 @@ mod tests { objects::{Cycle, Face}, operations::{ build::{BuildCycle, BuildFace}, - insert::Insert, update::{UpdateFace, UpdateRegion}, }, Instance, @@ -93,10 +92,7 @@ mod tests { Face::unbound(surface, &mut core).update_region( |region, core| { region.update_exterior( - |_, core| { - Cycle::polygon(points, core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon(points, core), core, ) }, @@ -127,10 +123,7 @@ mod tests { Face::unbound(surface, &mut core).update_region( |region, core| { region.update_exterior( - |_, core| { - Cycle::polygon(points, core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon(points, core), core, ) }, diff --git a/crates/fj-core/src/algorithms/intersect/face_point.rs b/crates/fj-core/src/algorithms/intersect/face_point.rs index 3ad5d3305d..06d9ae95d3 100644 --- a/crates/fj-core/src/algorithms/intersect/face_point.rs +++ b/crates/fj-core/src/algorithms/intersect/face_point.rs @@ -138,7 +138,6 @@ mod tests { objects::{Cycle, Face}, operations::{ build::{BuildCycle, BuildFace}, - insert::Insert, update::{UpdateFace, UpdateRegion}, }, Instance, @@ -158,7 +157,6 @@ mod tests { [[0., 0.], [1., 1.], [0., 2.]], core, ) - .insert(&mut core.services) }, core, ) @@ -185,7 +183,6 @@ mod tests { [[0., 0.], [2., 1.], [0., 2.]], core, ) - .insert(&mut core.services) }, core, ) @@ -215,7 +212,6 @@ mod tests { [[4., 2.], [0., 4.], [0., 0.]], core, ) - .insert(&mut core.services) }, core, ) @@ -245,7 +241,6 @@ mod tests { [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], core, ) - .insert(&mut core.services) }, core, ) @@ -275,7 +270,6 @@ mod tests { [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], core, ) - .insert(&mut core.services) }, core, ) @@ -311,7 +305,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -341,7 +334,6 @@ mod tests { [[0., 0.], [2., 0.], [0., 1.]], core, ) - .insert(&mut core.services) }, core, ) @@ -379,7 +371,6 @@ mod tests { [[0., 0.], [1., 0.], [0., 1.]], core, ) - .insert(&mut core.services) }, core, ) diff --git a/crates/fj-core/src/algorithms/intersect/ray_face.rs b/crates/fj-core/src/algorithms/intersect/ray_face.rs index f9c8a35d5d..741213b68c 100644 --- a/crates/fj-core/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-core/src/algorithms/intersect/ray_face.rs @@ -151,7 +151,6 @@ mod tests { objects::{Cycle, Face}, operations::{ build::{BuildCycle, BuildFace}, - insert::Insert, transform::TransformObject, update::{UpdateFace, UpdateRegion}, }, @@ -179,7 +178,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -212,7 +210,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -248,7 +245,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -281,7 +277,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -324,7 +319,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -368,7 +362,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) @@ -403,7 +396,6 @@ mod tests { ], core, ) - .insert(&mut core.services) }, core, ) diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 007eca9ad8..cdc60e6d72 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -104,10 +104,7 @@ mod tests { .update_region( |region, core| { region.update_exterior( - |_, core| { - Cycle::polygon([a, b, c, d], core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon([a, b, c, d], core), core, ) }, @@ -149,10 +146,7 @@ mod tests { |region, core| { region .update_exterior( - |_, core| { - Cycle::polygon([a, b, c, d], core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon([a, b, c, d], core), core, ) .add_interiors([Cycle::polygon([e, f, g, h], core) @@ -217,10 +211,7 @@ mod tests { let face = Face::unbound(surface.clone(), &mut core).update_region( |region, core| { region.update_exterior( - |_, core| { - Cycle::polygon([a, b, c, d, e], core) - .insert(&mut core.services) - }, + |_, core| Cycle::polygon([a, b, c, d, e], core), core, ) }, diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 288ad82daf..1bca88c72d 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -107,11 +107,7 @@ pub trait BuildShell { .update_region( |region, core| { region.update_exterior( - |cycle, core| { - cycle - .add_half_edges(half_edges) - .insert(&mut core.services) - }, + |cycle, _| cycle.add_half_edges(half_edges), core, ) }, @@ -168,7 +164,6 @@ pub trait BuildShell { 0..=0, core, ) - .insert(&mut core.services) }, core, ) @@ -208,7 +203,6 @@ pub trait BuildShell { 1..=1, core, ) - .insert(&mut core.services) }, core, ) @@ -262,7 +256,6 @@ pub trait BuildShell { 2..=2, core, ) - .insert(&mut core.services) }, core, ) diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 436216a0c3..8046617cd2 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -48,11 +48,7 @@ impl AddHole for Shell { .insert(&mut core.services); let hole = Region::empty(core) .update_exterior( - |_, core| { - Cycle::empty() - .add_half_edges([entry.clone()]) - .insert(&mut core.services) - }, + |_, _| Cycle::empty().add_half_edges([entry.clone()]), core, ) .sweep_region( @@ -115,11 +111,7 @@ impl AddHole for Shell { let swept_region = Region::empty(core) .update_exterior( - |_, core| { - Cycle::empty() - .add_half_edges([entry.clone()]) - .insert(&mut core.services) - }, + |_, _| Cycle::empty().add_half_edges([entry.clone()]), core, ) .sweep_region( diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index f2b70455a4..4c277c5663 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -134,11 +134,10 @@ impl SplitFace for Shell { |region, core| { let mut region = region .update_exterior( - |cycle, core| { + |cycle, _| { cycle .add_half_edges(half_edges_b_to_c_inclusive) .add_half_edges([dividing_half_edge_c_to_b]) - .insert(&mut core.services) }, core, ) @@ -167,11 +166,10 @@ impl SplitFace for Shell { |region, core| { let mut region = region .update_exterior( - |cycle, core| { + |cycle, _| { cycle .add_half_edges(half_edges_d_to_a_inclusive) .add_half_edges([dividing_half_edge_a_to_d]) - .insert(&mut core.services) }, core, ) diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index e7823fe855..3f17395bb8 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Cycle, Region}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -8,11 +9,13 @@ use crate::{ pub trait UpdateRegion { /// Update the exterior of the region #[must_use] - fn update_exterior( + fn update_exterior( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; /// Add the provided interiors to the region #[must_use] @@ -37,12 +40,15 @@ pub trait UpdateRegion { } impl UpdateRegion for Region { - fn update_exterior( + fn update_exterior( &self, - update: impl FnOnce(&Handle, &mut Instance) -> Handle, + update: impl FnOnce(&Handle, &mut Instance) -> T, core: &mut Instance, - ) -> Self { - let exterior = update(self.exterior(), core); + ) -> Self + where + T: Insert>, + { + let exterior = update(self.exterior(), core).insert(&mut core.services); Region::new(exterior, self.interiors().iter().cloned(), self.color()) } diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index 13ef927e17..ead4f0c8a2 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -107,14 +107,12 @@ mod tests { |region, core| { region.update_exterior( |cycle, core| { - cycle - .add_half_edges([HalfEdge::circle( - [0., 0.], - 1., - core, - ) - .insert(&mut core.services)]) - .insert(&mut core.services) + cycle.add_half_edges([HalfEdge::circle( + [0., 0.], + 1., + core, + ) + .insert(&mut core.services)]) }, core, ) @@ -146,7 +144,6 @@ mod tests { [[0., 0.], [3., 0.], [0., 3.]], core, ) - .insert(&mut core.services) }, core, ) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 6ba1b40596..9f44e7d38b 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -422,21 +422,17 @@ mod tests { |region, core| { region.update_exterior( |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| { - path.reverse() - }) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - core, - ) - .insert(&mut core.services) + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| path.reverse()) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) }, core, ) @@ -492,18 +488,16 @@ mod tests { |region, core| { region.update_exterior( |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - core, - ) - .insert(&mut core.services) + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) }, core, ) From 58db7fff7a5835e4937a80cc1cb999b87f6d1f25 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:44:23 +0100 Subject: [PATCH 12/19] Expect `&mut Instance` in `update_interior` --- crates/fj-core/src/operations/update/region.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index 3f17395bb8..8d3c396847 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -35,7 +35,8 @@ pub trait UpdateRegion { fn update_interior( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self; } @@ -63,11 +64,12 @@ impl UpdateRegion for Region { fn update_interior( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self { let interiors = self .interiors() - .replace(handle, update(handle)) + .replace(handle, update(handle, core)) .expect("Cycle not found"); Region::new(self.exterior().clone(), interiors, self.color()) } From 1a868bdbab145529db9f8499dfb04136a2801162 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:45:45 +0100 Subject: [PATCH 13/19] Make `update_interior` more convenient to call --- .../fj-core/src/operations/update/region.rs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index 8d3c396847..bde6501574 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -32,12 +32,14 @@ pub trait UpdateRegion { /// /// Panics, if the update results in a duplicate object. #[must_use] - fn update_interior( + fn update_interior( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateRegion for Region { @@ -61,15 +63,22 @@ impl UpdateRegion for Region { Region::new(self.exterior().clone(), interiors, self.color()) } - fn update_interior( + fn update_interior( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let interiors = self .interiors() - .replace(handle, update(handle, core)) + .replace( + handle, + update(handle, core) + .map(|object| object.insert(&mut core.services)), + ) .expect("Cycle not found"); Region::new(self.exterior().clone(), interiors, self.color()) } From 506ce8f6ade899746103de83a28eabc339264990 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:48:52 +0100 Subject: [PATCH 14/19] Expect `Instance` in `UpdateShell::update_face` --- crates/fj-core/src/operations/holes.rs | 122 ++++++++++-------- crates/fj-core/src/operations/split/face.rs | 7 +- crates/fj-core/src/operations/update/shell.rs | 9 +- crates/fj-core/src/validate/shell.rs | 108 +++++++++------- models/color/src/lib.rs | 17 ++- 5 files changed, 151 insertions(+), 112 deletions(-) diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 8046617cd2..4594532d64 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -61,25 +61,29 @@ impl AddHole for Shell { .map(|face| face.insert(&mut core.services)) .collect::>(); - self.update_face(location.face, |face| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] - }) + self.update_face( + location.face, + |face, core| { + [face + .update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + }, + core, + ) + .insert(&mut core.services)] + }, + core, + ) .add_faces(hole) } @@ -134,40 +138,52 @@ impl AddHole for Shell { .half_edges() .only(); - self.update_face(entry_location.face, |face| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] - }) - .update_face(exit_location.face, |face| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [(exit.clone(), exit.path(), exit.boundary())], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] - }) + self.update_face( + entry_location.face, + |face, core| { + [face + .update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + }, + core, + ) + .insert(&mut core.services)] + }, + core, + ) + .update_face( + exit_location.face, + |face, core| { + [face + .update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + exit.clone(), + exit.path(), + exit.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + }, + core, + ) + .insert(&mut core.services)] + }, + core, + ) .add_faces(hole) } } diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 4c277c5663..70beb28b30 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -186,8 +186,11 @@ impl SplitFace for Shell { .insert(&mut core.services); let faces = [split_face_a, split_face_b]; - let self_ = self_ - .update_face(updated_face_after_split_edges, |_| faces.clone()); + let self_ = self_.update_face( + updated_face_after_split_edges, + |_, _| faces.clone(), + core, + ); (self_, faces) } diff --git a/crates/fj-core/src/operations/update/shell.rs b/crates/fj-core/src/operations/update/shell.rs index 79f7a7c140..834d337272 100644 --- a/crates/fj-core/src/operations/update/shell.rs +++ b/crates/fj-core/src/operations/update/shell.rs @@ -1,6 +1,7 @@ use crate::{ objects::{Face, Shell}, storage::Handle, + Instance, }; /// Update a [`Shell`] @@ -20,7 +21,8 @@ pub trait UpdateShell { fn update_face( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self; /// Remove a face from the shell @@ -37,11 +39,12 @@ impl UpdateShell for Shell { fn update_face( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self { let faces = self .faces() - .replace(handle, update(handle)) + .replace(handle, update(handle, core)) .expect("Face not found"); Shell::new(faces) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 9f44e7d38b..b5fe49317e 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -416,31 +416,37 @@ mod tests { [[0., 0., 0.], [0., 1., 0.], [1., 0., 0.], [0., 0., 1.]], &mut core, ); - let invalid = valid.shell.update_face(&valid.abc.face, |face| { - [face - .update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle.update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| path.reverse()) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - core, - ) - }, - core, - ) - }, - &mut core, - ) - .insert(&mut core.services)] - }); + let invalid = valid.shell.update_face( + &valid.abc.face, + |face, core| { + [face + .update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| { + path.reverse() + }) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) + }, + core, + ) + }, + core, + ) + .insert(&mut core.services)] + }, + &mut core, + ); valid.shell.validate_and_return_first_error()?; assert_contains_err!( @@ -482,30 +488,34 @@ mod tests { [[0., 0., 0.], [0., 1., 0.], [1., 0., 0.], [0., 0., 1.]], &mut core, ); - let invalid = valid.shell.update_face(&valid.abc.face, |face| { - [face - .update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle.update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - core, - ) - }, - core, - ) - }, - &mut core, - ) - .insert(&mut core.services)] - }); + let invalid = valid.shell.update_face( + &valid.abc.face, + |face, core| { + [face + .update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) + }, + core, + ) + }, + core, + ) + .insert(&mut core.services)] + }, + &mut core, + ); valid.shell.validate_and_return_first_error()?; assert_contains_err!( diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index 069037c0aa..24b12aa6a7 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -13,11 +13,18 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { let cuboid = cuboid::model([size, size, size], core); cuboid.update_shell(cuboid.shells().only(), |shell| { - let shell = shell.update_face(shell.faces().first(), |face| { - [face - .update_region(|region, _| region.set_color([0., 1., 0.]), core) - .insert(&mut core.services)] - }); + let shell = shell.update_face( + shell.faces().first(), + |face, core| { + [face + .update_region( + |region, _| region.set_color([0., 1., 0.]), + core, + ) + .insert(&mut core.services)] + }, + core, + ); // Split colored face, to make sure the same color is applied to the // two derived faces. From e34455bd238fde51cc8c3b52e759c870c65e6b67 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:52:15 +0100 Subject: [PATCH 15/19] Make `update_face` more convenient to call --- crates/fj-core/src/operations/holes.rs | 92 +++++++++---------- crates/fj-core/src/operations/update/shell.rs | 24 +++-- crates/fj-core/src/validate/shell.rs | 89 +++++++++--------- models/color/src/lib.rs | 10 +- 4 files changed, 103 insertions(+), 112 deletions(-) diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 4594532d64..9d4e05a5c2 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -64,23 +64,21 @@ impl AddHole for Shell { self.update_face( location.face, |face, core| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + }, + core, + )] }, core, ) @@ -141,46 +139,38 @@ impl AddHole for Shell { self.update_face( entry_location.face, |face, core| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [( - entry.clone(), - entry.path(), - entry.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [( + entry.clone(), + entry.path(), + entry.boundary(), + )], + core, + ) + .insert(&mut core.services)]) + }, + core, + )] }, core, ) .update_face( exit_location.face, |face, core| { - [face - .update_region( - |region, core| { - region.add_interiors([Cycle::empty() - .add_joined_edges( - [( - exit.clone(), - exit.path(), - exit.boundary(), - )], - core, - ) - .insert(&mut core.services)]) - }, - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, core| { + region.add_interiors([Cycle::empty() + .add_joined_edges( + [(exit.clone(), exit.path(), exit.boundary())], + core, + ) + .insert(&mut core.services)]) + }, + core, + )] }, core, ) diff --git a/crates/fj-core/src/operations/update/shell.rs b/crates/fj-core/src/operations/update/shell.rs index 834d337272..e4126042be 100644 --- a/crates/fj-core/src/operations/update/shell.rs +++ b/crates/fj-core/src/operations/update/shell.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Face, Shell}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -18,12 +19,14 @@ pub trait UpdateShell { /// /// Panics, if the update results in a duplicate object. #[must_use] - fn update_face( + fn update_face( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; /// Remove a face from the shell #[must_use] @@ -36,15 +39,22 @@ impl UpdateShell for Shell { Shell::new(faces) } - fn update_face( + fn update_face( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let faces = self .faces() - .replace(handle, update(handle, core)) + .replace( + handle, + update(handle, core) + .map(|object| object.insert(&mut core.services)), + ) .expect("Face not found"); Shell::new(faces) } diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index b5fe49317e..c75e8546ea 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -398,7 +398,6 @@ mod tests { objects::{Curve, Shell}, operations::{ build::BuildShell, - insert::Insert, update::{ UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateRegion, UpdateShell, @@ -419,31 +418,27 @@ mod tests { let invalid = valid.shell.update_face( &valid.abc.face, |face, core| { - [face - .update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle.update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, _| { - [edge - .update_path(|path| { - path.reverse() - }) - .update_boundary(|boundary| { - boundary.reverse() - })] - }, - core, - ) - }, - core, - ) - }, - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, _| { + [edge + .update_path(|path| path.reverse()) + .update_boundary(|boundary| { + boundary.reverse() + })] + }, + core, + ) + }, + core, + ) + }, + core, + )] }, &mut core, ); @@ -491,28 +486,26 @@ mod tests { let invalid = valid.shell.update_face( &valid.abc.face, |face, core| { - [face - .update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle.update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( - |_, _| Curve::new(), - core, - )] - }, - core, - ) - }, - core, - ) - }, - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle.update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.update_curve( + |_, _| Curve::new(), + core, + )] + }, + core, + ) + }, + core, + ) + }, + core, + )] }, &mut core, ); diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index 24b12aa6a7..777ebfaa17 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -16,12 +16,10 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { let shell = shell.update_face( shell.faces().first(), |face, core| { - [face - .update_region( - |region, _| region.set_color([0., 1., 0.]), - core, - ) - .insert(&mut core.services)] + [face.update_region( + |region, _| region.set_color([0., 1., 0.]), + core, + )] }, core, ); From 38f35ca188ee14dab074e4c377068877a316917a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:53:21 +0100 Subject: [PATCH 16/19] Expect `&mut Instance` in `update_region` --- crates/fj-core/src/operations/update/sketch.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index e85108ba5a..715e9bc67c 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -1,6 +1,7 @@ use crate::{ objects::{Region, Sketch}, storage::Handle, + Instance, }; /// Update a [`Sketch`] @@ -23,7 +24,8 @@ pub trait UpdateSketch { fn update_region( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self; } @@ -38,11 +40,12 @@ impl UpdateSketch for Sketch { fn update_region( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self { let regions = self .regions() - .replace(handle, update(handle)) + .replace(handle, update(handle, core)) .expect("Region not found"); Sketch::new(regions) } From d40f5e43d2f337489b9b236af8e87d0eb4ff4c03 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:55:21 +0100 Subject: [PATCH 17/19] Make `update_region` more convenient to call --- .../fj-core/src/operations/update/sketch.rs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index 715e9bc67c..5e698c7666 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Region, Sketch}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -21,12 +22,14 @@ pub trait UpdateSketch { /// /// Panics, if the update results in a duplicate object. #[must_use] - fn update_region( + fn update_region( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateSketch for Sketch { @@ -37,15 +40,22 @@ impl UpdateSketch for Sketch { Sketch::new(self.regions().iter().cloned().chain(regions)) } - fn update_region( + fn update_region( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let regions = self .regions() - .replace(handle, update(handle, core)) + .replace( + handle, + update(handle, core) + .map(|object| object.insert(&mut core.services)), + ) .expect("Region not found"); Sketch::new(regions) } From 8df1c307edffba191dd11f3b417d71d3feb602a0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:56:45 +0100 Subject: [PATCH 18/19] Expect `Instance` in `UpdateSolid::update_shell` --- crates/fj-core/src/operations/update/solid.rs | 9 ++- models/color/src/lib.rs | 58 ++++++++------- models/holes/src/lib.rs | 74 ++++++++++--------- models/split/src/lib.rs | 28 ++++--- 4 files changed, 92 insertions(+), 77 deletions(-) diff --git a/crates/fj-core/src/operations/update/solid.rs b/crates/fj-core/src/operations/update/solid.rs index eb54f2287b..dd86ecc189 100644 --- a/crates/fj-core/src/operations/update/solid.rs +++ b/crates/fj-core/src/operations/update/solid.rs @@ -1,6 +1,7 @@ use crate::{ objects::{Shell, Solid}, storage::Handle, + Instance, }; /// Update a [`Solid`] @@ -23,7 +24,8 @@ pub trait UpdateSolid { fn update_shell( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self; } @@ -39,11 +41,12 @@ impl UpdateSolid for Solid { fn update_shell( &self, handle: &Handle, - update: impl FnOnce(&Handle) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + core: &mut Instance, ) -> Self { let shells = self .shells() - .replace(handle, update(handle)) + .replace(handle, update(handle, core)) .expect("Shell not found"); Solid::new(shells) } diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index 777ebfaa17..bdc89e021b 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -12,35 +12,39 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { let size = 1.; let cuboid = cuboid::model([size, size, size], core); - cuboid.update_shell(cuboid.shells().only(), |shell| { - let shell = shell.update_face( - shell.faces().first(), - |face, core| { - [face.update_region( - |region, _| region.set_color([0., 1., 0.]), - core, - )] - }, - core, - ); + cuboid.update_shell( + cuboid.shells().only(), + |shell, core| { + let shell = shell.update_face( + shell.faces().first(), + |face, core| { + [face.update_region( + |region, _| region.set_color([0., 1., 0.]), + core, + )] + }, + core, + ); - // Split colored face, to make sure the same color is applied to the - // two derived faces. - let shell = { - let face = shell.faces().first(); - let line = { - let cycle = face.region().exterior(); + // Split colored face, to make sure the same color is applied to the + // two derived faces. + let shell = { + let face = shell.faces().first(); + let line = { + let cycle = face.region().exterior(); - [ - (cycle.half_edges().nth(0).unwrap(), [0.2]), - (cycle.half_edges().nth(2).unwrap(), [0.2]), - ] - }; + [ + (cycle.half_edges().nth(0).unwrap(), [0.2]), + (cycle.half_edges().nth(2).unwrap(), [0.2]), + ] + }; - let (shell, _) = shell.split_face(face, line, core); - shell - }; + let (shell, _) = shell.split_face(face, line, core); + shell + }; - [shell.insert(&mut core.services)] - }) + [shell.insert(&mut core.services)] + }, + core, + ) } diff --git a/models/holes/src/lib.rs b/models/holes/src/lib.rs index a9d0461ff7..51cf7672c7 100644 --- a/models/holes/src/lib.rs +++ b/models/holes/src/lib.rs @@ -19,42 +19,46 @@ pub fn model( let size = radius * 4.; let cuboid = cuboid::model([size * 2., size, size], core); - cuboid.update_shell(cuboid.shells().only(), |shell| { - let bottom_face = shell.faces().first(); - let offset = size / 2.; - let depth = size / 2.; + cuboid.update_shell( + cuboid.shells().only(), + |shell, core| { + let bottom_face = shell.faces().first(); + let offset = size / 2.; + let depth = size / 2.; - let shell = shell.add_blind_hole( - HoleLocation { - face: bottom_face, - position: [-offset, Scalar::ZERO].into(), - }, - radius, - [Scalar::ZERO, Scalar::ZERO, depth], - core, - ); - - let bottom_face = shell.faces().first(); - let top_face = shell - .faces() - .nth(5) - .expect("Expected shell to have top face"); - - [shell - .add_through_hole( - [ - HoleLocation { - face: bottom_face, - position: [offset, Scalar::ZERO].into(), - }, - HoleLocation { - face: top_face, - position: [offset, Scalar::ZERO].into(), - }, - ], + let shell = shell.add_blind_hole( + HoleLocation { + face: bottom_face, + position: [-offset, Scalar::ZERO].into(), + }, radius, + [Scalar::ZERO, Scalar::ZERO, depth], core, - ) - .insert(&mut core.services)] - }) + ); + + let bottom_face = shell.faces().first(); + let top_face = shell + .faces() + .nth(5) + .expect("Expected shell to have top face"); + + [shell + .add_through_hole( + [ + HoleLocation { + face: bottom_face, + position: [offset, Scalar::ZERO].into(), + }, + HoleLocation { + face: top_face, + position: [offset, Scalar::ZERO].into(), + }, + ], + radius, + core, + ) + .insert(&mut core.services)] + }, + core, + ) } diff --git a/models/split/src/lib.rs b/models/split/src/lib.rs index 6b209cb0bd..a1eab6e48a 100644 --- a/models/split/src/lib.rs +++ b/models/split/src/lib.rs @@ -13,19 +13,23 @@ pub fn model( ) -> Solid { let cuboid = cuboid::model([size, size, size], core); - cuboid.update_shell(cuboid.shells().only(), |shell| { - let face = shell.faces().first(); - let cycle = face.region().exterior(); + cuboid.update_shell( + cuboid.shells().only(), + |shell, core| { + let face = shell.faces().first(); + let cycle = face.region().exterior(); - let line = [ - (cycle.half_edges().nth(0).unwrap(), [split_pos]), - (cycle.half_edges().nth(2).unwrap(), [split_pos]), - ]; + let line = [ + (cycle.half_edges().nth(0).unwrap(), [split_pos]), + (cycle.half_edges().nth(2).unwrap(), [split_pos]), + ]; - let (shell, [face, _]) = shell.split_face(face, line, core); + let (shell, [face, _]) = shell.split_face(face, line, core); - [shell - .sweep_face_of_shell(face, [0., 0., -size / 2.], core) - .insert(&mut core.services)] - }) + [shell + .sweep_face_of_shell(face, [0., 0., -size / 2.], core) + .insert(&mut core.services)] + }, + core, + ) } From e7a61434a2e1e12431aa5c96fd26497960afc827 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 9 Feb 2024 14:58:01 +0100 Subject: [PATCH 19/19] Make `update_shell` more convenient to call --- crates/fj-core/src/operations/update/solid.rs | 24 +++++++++----- models/color/src/lib.rs | 3 +- models/holes/src/lib.rs | 31 +++++++++---------- models/split/src/lib.rs | 7 ++--- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/crates/fj-core/src/operations/update/solid.rs b/crates/fj-core/src/operations/update/solid.rs index dd86ecc189..c2715cd0cc 100644 --- a/crates/fj-core/src/operations/update/solid.rs +++ b/crates/fj-core/src/operations/update/solid.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Shell, Solid}, + operations::insert::Insert, storage::Handle, Instance, }; @@ -21,12 +22,14 @@ pub trait UpdateSolid { /// /// Panics, if the update results in a duplicate object. #[must_use] - fn update_shell( + fn update_shell( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self; + ) -> Self + where + T: Insert>; } impl UpdateSolid for Solid { @@ -38,15 +41,22 @@ impl UpdateSolid for Solid { Solid::new(shells) } - fn update_shell( + fn update_shell( &self, handle: &Handle, - update: impl FnOnce(&Handle, &mut Instance) -> [Handle; N], + update: impl FnOnce(&Handle, &mut Instance) -> [T; N], core: &mut Instance, - ) -> Self { + ) -> Self + where + T: Insert>, + { let shells = self .shells() - .replace(handle, update(handle, core)) + .replace( + handle, + update(handle, core) + .map(|object| object.insert(&mut core.services)), + ) .expect("Shell not found"); Solid::new(shells) } diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index bdc89e021b..fab80c971a 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -1,7 +1,6 @@ use fj::core::{ objects::Solid, operations::{ - insert::Insert, presentation::SetColor, split::SplitFace, update::{UpdateFace, UpdateShell, UpdateSolid}, @@ -43,7 +42,7 @@ pub fn model(core: &mut fj::core::Instance) -> Solid { shell }; - [shell.insert(&mut core.services)] + [shell] }, core, ) diff --git a/models/holes/src/lib.rs b/models/holes/src/lib.rs index 51cf7672c7..42da648812 100644 --- a/models/holes/src/lib.rs +++ b/models/holes/src/lib.rs @@ -3,7 +3,6 @@ use fj::{ objects::Solid, operations::{ holes::{AddHole, HoleLocation}, - insert::Insert, update::UpdateSolid, }, }, @@ -42,22 +41,20 @@ pub fn model( .nth(5) .expect("Expected shell to have top face"); - [shell - .add_through_hole( - [ - HoleLocation { - face: bottom_face, - position: [offset, Scalar::ZERO].into(), - }, - HoleLocation { - face: top_face, - position: [offset, Scalar::ZERO].into(), - }, - ], - radius, - core, - ) - .insert(&mut core.services)] + [shell.add_through_hole( + [ + HoleLocation { + face: bottom_face, + position: [offset, Scalar::ZERO].into(), + }, + HoleLocation { + face: top_face, + position: [offset, Scalar::ZERO].into(), + }, + ], + radius, + core, + )] }, core, ) diff --git a/models/split/src/lib.rs b/models/split/src/lib.rs index a1eab6e48a..55d90f97e4 100644 --- a/models/split/src/lib.rs +++ b/models/split/src/lib.rs @@ -1,8 +1,7 @@ use fj::core::{ objects::Solid, operations::{ - insert::Insert, split::SplitFace, sweep::SweepFaceOfShell, - update::UpdateSolid, + split::SplitFace, sweep::SweepFaceOfShell, update::UpdateSolid, }, }; @@ -26,9 +25,7 @@ pub fn model( let (shell, [face, _]) = shell.split_face(face, line, core); - [shell - .sweep_face_of_shell(face, [0., 0., -size / 2.], core) - .insert(&mut core.services)] + [shell.sweep_face_of_shell(face, [0., 0., -size / 2.], core)] }, core, )