From 10b87867571fdff13f90fce4a2e66df85197a9ed Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 09:28:34 +0100 Subject: [PATCH 1/6] Make `ReplaceOutput` more flexible Make it possible to specify the types for the original and updated objects separately. This will make it possible to implement the replace traits for the bare object types too. --- crates/fj-core/src/operations/replace/curve.rs | 16 ++++++++-------- .../fj-core/src/operations/replace/half_edge.rs | 14 +++++++------- crates/fj-core/src/operations/replace/mod.rs | 10 ++++++---- crates/fj-core/src/operations/replace/vertex.rs | 16 ++++++++-------- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/crates/fj-core/src/operations/replace/curve.rs b/crates/fj-core/src/operations/replace/curve.rs index 6e130c91df..62eec2d3b4 100644 --- a/crates/fj-core/src/operations/replace/curve.rs +++ b/crates/fj-core/src/operations/replace/curve.rs @@ -23,7 +23,7 @@ pub trait ReplaceCurve: Sized { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput; + ) -> ReplaceOutput; } impl ReplaceCurve for Handle { @@ -34,7 +34,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, _: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { if original.id() == self.curve().id() { ReplaceOutput::Updated(self.update_curve(|_| replacement)) } else { @@ -51,7 +51,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut half_edges = Vec::new(); @@ -81,7 +81,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let exterior = self.exterior().replace_curve( @@ -119,7 +119,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut regions = Vec::new(); @@ -146,7 +146,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let region = self.region().replace_curve(original, replacement, services); @@ -169,7 +169,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut faces = Vec::new(); @@ -196,7 +196,7 @@ impl ReplaceCurve for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut shells = Vec::new(); diff --git a/crates/fj-core/src/operations/replace/half_edge.rs b/crates/fj-core/src/operations/replace/half_edge.rs index 3da5bf547a..289ebbd4ce 100644 --- a/crates/fj-core/src/operations/replace/half_edge.rs +++ b/crates/fj-core/src/operations/replace/half_edge.rs @@ -22,7 +22,7 @@ pub trait ReplaceHalfEdge: Sized { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput; + ) -> ReplaceOutput; } impl ReplaceHalfEdge for Handle { @@ -33,7 +33,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], _: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { if let Some(half_edges) = self.half_edges().replace(original, replacements) { @@ -52,7 +52,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let exterior = self.exterior().replace_half_edge( @@ -93,7 +93,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut regions = Vec::new(); @@ -123,7 +123,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let region = self.region() .replace_half_edge(original, replacements, services); @@ -147,7 +147,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut faces = Vec::new(); @@ -177,7 +177,7 @@ impl ReplaceHalfEdge for Handle { original: &Handle, replacements: [Handle; N], services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut shells = Vec::new(); diff --git a/crates/fj-core/src/operations/replace/mod.rs b/crates/fj-core/src/operations/replace/mod.rs index 8b8e721161..88db6b98ca 100644 --- a/crates/fj-core/src/operations/replace/mod.rs +++ b/crates/fj-core/src/operations/replace/mod.rs @@ -107,12 +107,12 @@ use super::insert::Insert; /// See [module documentation] for more information. /// /// [module documentation]: self -pub enum ReplaceOutput { +pub enum ReplaceOutput { /// The original object that the replace operation was called on /// /// If this variant is returned, the object to be replaced was not /// referenced, and no replacement happened. - Original(Handle), + Original(Original), /// The updated version of the object that the operation was called on /// @@ -125,15 +125,17 @@ pub enum ReplaceOutput { /// modeling process. The validation infrastructure currently provides no /// good ways to deal with invalid intermediate results, even if the end /// result ends up valid. - Updated(T), + Updated(Updated), } -impl ReplaceOutput { +impl ReplaceOutput { /// Indicate whether the original object was updated pub fn was_updated(&self) -> bool { matches!(self, ReplaceOutput::Updated(_)) } +} +impl ReplaceOutput, T> { /// Return the original object, or insert the updated on and return handle pub fn into_inner(self, services: &mut Services) -> Handle where diff --git a/crates/fj-core/src/operations/replace/vertex.rs b/crates/fj-core/src/operations/replace/vertex.rs index 617d945e2f..04108f9413 100644 --- a/crates/fj-core/src/operations/replace/vertex.rs +++ b/crates/fj-core/src/operations/replace/vertex.rs @@ -23,7 +23,7 @@ pub trait ReplaceVertex: Sized { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput; + ) -> ReplaceOutput; } impl ReplaceVertex for Handle { @@ -34,7 +34,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, _: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { if original.id() == self.start_vertex().id() { ReplaceOutput::Updated(self.update_start_vertex(|_| replacement)) } else { @@ -51,7 +51,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut half_edges = Vec::new(); @@ -81,7 +81,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let exterior = self.exterior().replace_vertex( @@ -119,7 +119,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut regions = Vec::new(); @@ -146,7 +146,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let region = self.region() .replace_vertex(original, replacement, services); @@ -170,7 +170,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut faces = Vec::new(); @@ -197,7 +197,7 @@ impl ReplaceVertex for Handle { original: &Handle, replacement: Handle, services: &mut Services, - ) -> ReplaceOutput { + ) -> ReplaceOutput { let mut replacement_happened = false; let mut shells = Vec::new(); From 21eb70b0724eadfb148fc891678d3e6b3db38aa2 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 09:31:56 +0100 Subject: [PATCH 2/6] Add `ReplaceOutput::map_updated` --- crates/fj-core/src/operations/replace/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/fj-core/src/operations/replace/mod.rs b/crates/fj-core/src/operations/replace/mod.rs index 88db6b98ca..5c5520bffa 100644 --- a/crates/fj-core/src/operations/replace/mod.rs +++ b/crates/fj-core/src/operations/replace/mod.rs @@ -133,6 +133,17 @@ impl ReplaceOutput { pub fn was_updated(&self) -> bool { matches!(self, ReplaceOutput::Updated(_)) } + + /// Map the `Updated` variant using the provided function + pub fn map_updated( + self, + f: impl FnOnce(Updated) -> T, + ) -> ReplaceOutput { + match self { + Self::Original(original) => ReplaceOutput::Original(original), + Self::Updated(updated) => ReplaceOutput::Updated(f(updated)), + } + } } impl ReplaceOutput, T> { From a705e6d826a1eabd90c74b0f975a5df162d3187e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 09:32:21 +0100 Subject: [PATCH 3/6] Refactor to increase consistency --- crates/fj-core/src/operations/replace/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/replace/mod.rs b/crates/fj-core/src/operations/replace/mod.rs index 5c5520bffa..b360aaa394 100644 --- a/crates/fj-core/src/operations/replace/mod.rs +++ b/crates/fj-core/src/operations/replace/mod.rs @@ -153,8 +153,8 @@ impl ReplaceOutput, T> { T: Insert>, { match self { - ReplaceOutput::Original(inner) => inner, - ReplaceOutput::Updated(inner) => inner.insert(services), + Self::Original(inner) => inner, + Self::Updated(inner) => inner.insert(services), } } } From 0e3b930f2f2c7791f45a745a5d175bf2b614c04b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 09:38:14 +0100 Subject: [PATCH 4/6] Make `ReplaceOutput` API more orthogonal --- .../fj-core/src/operations/replace/curve.rs | 39 +++++++++++++++---- .../src/operations/replace/half_edge.rs | 32 ++++++++++++--- crates/fj-core/src/operations/replace/mod.rs | 13 ++----- .../fj-core/src/operations/replace/vertex.rs | 39 +++++++++++++++---- 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/crates/fj-core/src/operations/replace/curve.rs b/crates/fj-core/src/operations/replace/curve.rs index 62eec2d3b4..90d8e0df50 100644 --- a/crates/fj-core/src/operations/replace/curve.rs +++ b/crates/fj-core/src/operations/replace/curve.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Curve, Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid}, - operations::update::UpdateHalfEdge, + operations::{insert::Insert, update::UpdateHalfEdge}, services::Services, storage::Handle, }; @@ -62,7 +62,11 @@ impl ReplaceCurve for Handle { services, ); replacement_happened |= half_edge.was_updated(); - half_edges.push(half_edge.into_inner(services)); + half_edges.push( + half_edge + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -96,12 +100,18 @@ impl ReplaceCurve for Handle { let cycle = cycle.replace_curve(original, replacement.clone(), services); replacement_happened |= cycle.was_updated(); - interiors.push(cycle.into_inner(services)); + interiors.push( + cycle + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { ReplaceOutput::Updated(Region::new( - exterior.into_inner(services), + exterior + .map_updated(|updated| updated.insert(services)) + .into_inner(), interiors, self.color(), )) @@ -127,7 +137,11 @@ impl ReplaceCurve for Handle { let region = region.replace_curve(original, replacement.clone(), services); replacement_happened |= region.was_updated(); - regions.push(region.into_inner(services)); + regions.push( + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -153,7 +167,9 @@ impl ReplaceCurve for Handle { if region.was_updated() { ReplaceOutput::Updated(Face::new( self.surface().clone(), - region.into_inner(services), + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), )) } else { ReplaceOutput::Original(self.clone()) @@ -177,7 +193,10 @@ impl ReplaceCurve for Handle { let face = face.replace_curve(original, replacement.clone(), services); replacement_happened |= face.was_updated(); - faces.push(face.into_inner(services)); + faces.push( + face.map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -204,7 +223,11 @@ impl ReplaceCurve for Handle { let shell = shell.replace_curve(original, replacement.clone(), services); replacement_happened |= shell.was_updated(); - shells.push(shell.into_inner(services)); + shells.push( + shell + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { diff --git a/crates/fj-core/src/operations/replace/half_edge.rs b/crates/fj-core/src/operations/replace/half_edge.rs index 289ebbd4ce..df6284c4d2 100644 --- a/crates/fj-core/src/operations/replace/half_edge.rs +++ b/crates/fj-core/src/operations/replace/half_edge.rs @@ -1,5 +1,6 @@ use crate::{ objects::{Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid}, + operations::insert::Insert, services::Services, storage::Handle, }; @@ -70,12 +71,18 @@ impl ReplaceHalfEdge for Handle { services, ); replacement_happened |= cycle.was_updated(); - interiors.push(cycle.into_inner(services)); + interiors.push( + cycle + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { ReplaceOutput::Updated(Region::new( - exterior.into_inner(services), + exterior + .map_updated(|updated| updated.insert(services)) + .into_inner(), interiors, self.color(), )) @@ -104,7 +111,11 @@ impl ReplaceHalfEdge for Handle { services, ); replacement_happened |= region.was_updated(); - regions.push(region.into_inner(services)); + regions.push( + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -131,7 +142,9 @@ impl ReplaceHalfEdge for Handle { if region.was_updated() { ReplaceOutput::Updated(Face::new( self.surface().clone(), - region.into_inner(services), + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), )) } else { ReplaceOutput::Original(self.clone()) @@ -158,7 +171,10 @@ impl ReplaceHalfEdge for Handle { services, ); replacement_happened |= face.was_updated(); - faces.push(face.into_inner(services)); + faces.push( + face.map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -188,7 +204,11 @@ impl ReplaceHalfEdge for Handle { services, ); replacement_happened |= shell.was_updated(); - shells.push(shell.into_inner(services)); + shells.push( + shell + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { diff --git a/crates/fj-core/src/operations/replace/mod.rs b/crates/fj-core/src/operations/replace/mod.rs index b360aaa394..83218040af 100644 --- a/crates/fj-core/src/operations/replace/mod.rs +++ b/crates/fj-core/src/operations/replace/mod.rs @@ -98,10 +98,6 @@ pub use self::{ curve::ReplaceCurve, half_edge::ReplaceHalfEdge, vertex::ReplaceVertex, }; -use crate::{services::Services, storage::Handle}; - -use super::insert::Insert; - /// The output of a replace operation /// /// See [module documentation] for more information. @@ -146,15 +142,12 @@ impl ReplaceOutput { } } -impl ReplaceOutput, T> { +impl ReplaceOutput { /// Return the original object, or insert the updated on and return handle - pub fn into_inner(self, services: &mut Services) -> Handle - where - T: Insert>, - { + pub fn into_inner(self) -> T { match self { Self::Original(inner) => inner, - Self::Updated(inner) => inner.insert(services), + Self::Updated(inner) => inner, } } } diff --git a/crates/fj-core/src/operations/replace/vertex.rs b/crates/fj-core/src/operations/replace/vertex.rs index 04108f9413..fd1fb8430d 100644 --- a/crates/fj-core/src/operations/replace/vertex.rs +++ b/crates/fj-core/src/operations/replace/vertex.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid, Vertex}, - operations::update::UpdateHalfEdge, + operations::{insert::Insert, update::UpdateHalfEdge}, services::Services, storage::Handle, }; @@ -62,7 +62,11 @@ impl ReplaceVertex for Handle { services, ); replacement_happened |= half_edge.was_updated(); - half_edges.push(half_edge.into_inner(services)); + half_edges.push( + half_edge + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -96,12 +100,18 @@ impl ReplaceVertex for Handle { let cycle = cycle.replace_vertex(original, replacement.clone(), services); replacement_happened |= cycle.was_updated(); - interiors.push(cycle.into_inner(services)); + interiors.push( + cycle + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { ReplaceOutput::Updated(Region::new( - exterior.into_inner(services), + exterior + .map_updated(|updated| updated.insert(services)) + .into_inner(), interiors, self.color(), )) @@ -127,7 +137,11 @@ impl ReplaceVertex for Handle { let region = region.replace_vertex(original, replacement.clone(), services); replacement_happened |= region.was_updated(); - regions.push(region.into_inner(services)); + regions.push( + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -154,7 +168,9 @@ impl ReplaceVertex for Handle { if region.was_updated() { ReplaceOutput::Updated(Face::new( self.surface().clone(), - region.into_inner(services), + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), )) } else { ReplaceOutput::Original(self.clone()) @@ -178,7 +194,10 @@ impl ReplaceVertex for Handle { let face = face.replace_vertex(original, replacement.clone(), services); replacement_happened |= face.was_updated(); - faces.push(face.into_inner(services)); + faces.push( + face.map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { @@ -205,7 +224,11 @@ impl ReplaceVertex for Handle { let shell = shell.replace_vertex(original, replacement.clone(), services); replacement_happened |= shell.was_updated(); - shells.push(shell.into_inner(services)); + shells.push( + shell + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); } if replacement_happened { From 4205f1ea3424bcd5655dff5a38c657b9c609c48c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 09:41:54 +0100 Subject: [PATCH 5/6] Add `ReplaceOutput::map_original` --- crates/fj-core/src/operations/replace/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/fj-core/src/operations/replace/mod.rs b/crates/fj-core/src/operations/replace/mod.rs index 83218040af..0de9891821 100644 --- a/crates/fj-core/src/operations/replace/mod.rs +++ b/crates/fj-core/src/operations/replace/mod.rs @@ -130,6 +130,17 @@ impl ReplaceOutput { matches!(self, ReplaceOutput::Updated(_)) } + /// Map the `Original` variant using the provided function + pub fn map_original( + self, + f: impl FnOnce(Original) -> T, + ) -> ReplaceOutput { + match self { + Self::Original(original) => ReplaceOutput::Original(f(original)), + Self::Updated(updated) => ReplaceOutput::Updated(updated), + } + } + /// Map the `Updated` variant using the provided function pub fn map_updated( self, From af0350469575d0c4c253bd54106bcbaf24113f9f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 14 Nov 2023 10:04:34 +0100 Subject: [PATCH 6/6] Implement replace traits for bare objects --- .../fj-core/src/operations/replace/curve.rs | 135 ++++++++++++++-- .../src/operations/replace/half_edge.rs | 116 ++++++++++++-- .../fj-core/src/operations/replace/vertex.rs | 151 ++++++++++++++++-- 3 files changed, 362 insertions(+), 40 deletions(-) diff --git a/crates/fj-core/src/operations/replace/curve.rs b/crates/fj-core/src/operations/replace/curve.rs index 90d8e0df50..784253f9a5 100644 --- a/crates/fj-core/src/operations/replace/curve.rs +++ b/crates/fj-core/src/operations/replace/curve.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use crate::{ objects::{Curve, Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid}, operations::{insert::Insert, update::UpdateHalfEdge}, @@ -26,8 +28,8 @@ pub trait ReplaceCurve: Sized { ) -> ReplaceOutput; } -impl ReplaceCurve for Handle { - type BareObject = HalfEdge; +impl ReplaceCurve for HalfEdge { + type BareObject = Self; fn replace_curve( &self, @@ -43,8 +45,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Cycle; +impl ReplaceCurve for Cycle { + type BareObject = Self; fn replace_curve( &self, @@ -77,8 +79,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Region; +impl ReplaceCurve for Region { + type BareObject = Self; fn replace_curve( &self, @@ -121,8 +123,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Sketch; +impl ReplaceCurve for Sketch { + type BareObject = Self; fn replace_curve( &self, @@ -152,8 +154,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Face; +impl ReplaceCurve for Face { + type BareObject = Self; fn replace_curve( &self, @@ -177,8 +179,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Shell; +impl ReplaceCurve for Shell { + type BareObject = Self; fn replace_curve( &self, @@ -207,8 +209,8 @@ impl ReplaceCurve for Handle { } } -impl ReplaceCurve for Handle { - type BareObject = Solid; +impl ReplaceCurve for Solid { + type BareObject = Self; fn replace_curve( &self, @@ -237,3 +239,108 @@ impl ReplaceCurve for Handle { } } } + +impl ReplaceCurve for Handle { + type BareObject = HalfEdge; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Cycle; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Region; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Sketch; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Face; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Shell; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceCurve for Handle { + type BareObject = Solid; + + fn replace_curve( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_curve(original, replacement, services) + .map_original(|_| self.clone()) + } +} diff --git a/crates/fj-core/src/operations/replace/half_edge.rs b/crates/fj-core/src/operations/replace/half_edge.rs index df6284c4d2..848c3c261f 100644 --- a/crates/fj-core/src/operations/replace/half_edge.rs +++ b/crates/fj-core/src/operations/replace/half_edge.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use crate::{ objects::{Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid}, operations::insert::Insert, @@ -26,8 +28,8 @@ pub trait ReplaceHalfEdge: Sized { ) -> ReplaceOutput; } -impl ReplaceHalfEdge for Handle { - type BareObject = Cycle; +impl ReplaceHalfEdge for Cycle { + type BareObject = Self; fn replace_half_edge( &self, @@ -45,8 +47,8 @@ impl ReplaceHalfEdge for Handle { } } -impl ReplaceHalfEdge for Handle { - type BareObject = Region; +impl ReplaceHalfEdge for Region { + type BareObject = Self; fn replace_half_edge( &self, @@ -92,8 +94,8 @@ impl ReplaceHalfEdge for Handle { } } -impl ReplaceHalfEdge for Handle { - type BareObject = Sketch; +impl ReplaceHalfEdge for Sketch { + type BareObject = Self; fn replace_half_edge( &self, @@ -126,8 +128,8 @@ impl ReplaceHalfEdge for Handle { } } -impl ReplaceHalfEdge for Handle { - type BareObject = Face; +impl ReplaceHalfEdge for Face { + type BareObject = Self; fn replace_half_edge( &self, @@ -152,8 +154,8 @@ impl ReplaceHalfEdge for Handle { } } -impl ReplaceHalfEdge for Handle { - type BareObject = Shell; +impl ReplaceHalfEdge for Shell { + type BareObject = Self; fn replace_half_edge( &self, @@ -185,8 +187,8 @@ impl ReplaceHalfEdge for Handle { } } -impl ReplaceHalfEdge for Handle { - type BareObject = Solid; +impl ReplaceHalfEdge for Solid { + type BareObject = Self; fn replace_half_edge( &self, @@ -218,3 +220,93 @@ impl ReplaceHalfEdge for Handle { } } } + +impl ReplaceHalfEdge for Handle { + type BareObject = Cycle; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceHalfEdge for Handle { + type BareObject = Region; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceHalfEdge for Handle { + type BareObject = Sketch; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceHalfEdge for Handle { + type BareObject = Face; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceHalfEdge for Handle { + type BareObject = Shell; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceHalfEdge for Handle { + type BareObject = Solid; + + fn replace_half_edge( + &self, + original: &Handle, + replacements: [Handle; N], + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_half_edge(original, replacements, services) + .map_original(|_| self.clone()) + } +} diff --git a/crates/fj-core/src/operations/replace/vertex.rs b/crates/fj-core/src/operations/replace/vertex.rs index fd1fb8430d..be5120aae1 100644 --- a/crates/fj-core/src/operations/replace/vertex.rs +++ b/crates/fj-core/src/operations/replace/vertex.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use crate::{ objects::{Cycle, Face, HalfEdge, Region, Shell, Sketch, Solid, Vertex}, operations::{insert::Insert, update::UpdateHalfEdge}, @@ -26,8 +28,8 @@ pub trait ReplaceVertex: Sized { ) -> ReplaceOutput; } -impl ReplaceVertex for Handle { - type BareObject = HalfEdge; +impl ReplaceVertex for HalfEdge { + type BareObject = Self; fn replace_vertex( &self, @@ -43,8 +45,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Cycle; +impl ReplaceVertex for Cycle { + type BareObject = Self; fn replace_vertex( &self, @@ -77,8 +79,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Region; +impl ReplaceVertex for Region { + type BareObject = Self; fn replace_vertex( &self, @@ -121,8 +123,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Sketch; +impl ReplaceVertex for Sketch { + type BareObject = Self; fn replace_vertex( &self, @@ -152,8 +154,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Face; +impl ReplaceVertex for Face { + type BareObject = Self; fn replace_vertex( &self, @@ -178,8 +180,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Shell; +impl ReplaceVertex for Shell { + type BareObject = Self; fn replace_vertex( &self, @@ -208,8 +210,8 @@ impl ReplaceVertex for Handle { } } -impl ReplaceVertex for Handle { - type BareObject = Solid; +impl ReplaceVertex for Solid { + type BareObject = Self; fn replace_vertex( &self, @@ -238,3 +240,124 @@ impl ReplaceVertex for Handle { } } } + +impl ReplaceVertex for Handle { + type BareObject = HalfEdge; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceVertex for Handle { + type BareObject = Cycle; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceVertex for Handle { + type BareObject = Region; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceVertex for Handle { + type BareObject = Sketch; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + let mut replacement_happened = false; + + let mut regions = Vec::new(); + for region in self.regions() { + let region = + region.replace_vertex(original, replacement.clone(), services); + replacement_happened |= region.was_updated(); + regions.push( + region + .map_updated(|updated| updated.insert(services)) + .into_inner(), + ); + } + + if replacement_happened { + ReplaceOutput::Updated(Sketch::new(regions)) + } else { + ReplaceOutput::Original(self.clone()) + } + } +} + +impl ReplaceVertex for Handle { + type BareObject = Face; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceVertex for Handle { + type BareObject = Shell; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +} + +impl ReplaceVertex for Handle { + type BareObject = Solid; + + fn replace_vertex( + &self, + original: &Handle, + replacement: Handle, + services: &mut Services, + ) -> ReplaceOutput { + self.deref() + .replace_vertex(original, replacement, services) + .map_original(|_| self.clone()) + } +}