diff --git a/crates/fj-core/src/operations/derive.rs b/crates/fj-core/src/operations/derive.rs new file mode 100644 index 000000000..5063b214c --- /dev/null +++ b/crates/fj-core/src/operations/derive.rs @@ -0,0 +1,19 @@ +//! Mark a stored object as derived from another +//! +//! See [`DeriveFrom`]. + +use crate::{storage::Handle, Core}; + +/// Mark a store object as derived from another +pub trait DeriveFrom { + /// Mark this object as derived from the other object provided + fn derive_from(self, other: &Self, core: &mut Core) -> Self; +} + +impl DeriveFrom for Handle { + fn derive_from(self, _other: &Self, _core: &mut Core) -> Self { + // This is currently a no-op. Eventually, it will trigger a command to + // the layers that this information is relevant for. + self + } +} diff --git a/crates/fj-core/src/operations/mod.rs b/crates/fj-core/src/operations/mod.rs index fa138c719..9645aa6ed 100644 --- a/crates/fj-core/src/operations/mod.rs +++ b/crates/fj-core/src/operations/mod.rs @@ -39,6 +39,7 @@ //! send a pull request! pub mod build; +pub mod derive; pub mod holes; pub mod insert; pub mod join; diff --git a/crates/fj-core/src/operations/replace/curve.rs b/crates/fj-core/src/operations/replace/curve.rs index 9ee37380a..fe6454ec6 100644 --- a/crates/fj-core/src/operations/replace/curve.rs +++ b/crates/fj-core/src/operations/replace/curve.rs @@ -4,7 +4,7 @@ use crate::{ objects::{ Curve, Cycle, Face, HalfEdge, IsObject, Region, Shell, Sketch, Solid, }, - operations::{insert::Insert, update::UpdateHalfEdge}, + operations::{derive::DeriveFrom, insert::Insert, update::UpdateHalfEdge}, storage::Handle, Core, }; @@ -52,13 +52,20 @@ impl ReplaceCurve for Cycle { let mut replacement_happened = false; let mut half_edges = Vec::new(); - for half_edge in self.half_edges() { - let half_edge = - half_edge.replace_curve(original, replacement.clone(), core); + for original_half_edge in self.half_edges() { + let half_edge = original_half_edge.replace_curve( + original, + replacement.clone(), + core, + ); replacement_happened |= half_edge.was_updated(); half_edges.push( half_edge - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated + .insert(core) + .derive_from(original_half_edge, core) + }) .into_inner(), ); } @@ -86,13 +93,18 @@ impl ReplaceCurve for Region { replacement_happened |= exterior.was_updated(); let mut interiors = Vec::new(); - for cycle in self.interiors() { - let cycle = - cycle.replace_curve(original, replacement.clone(), core); + for original_cycle in self.interiors() { + let cycle = original_cycle.replace_curve( + original, + replacement.clone(), + core, + ); replacement_happened |= cycle.was_updated(); interiors.push( cycle - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_cycle, core) + }) .into_inner(), ); } @@ -100,7 +112,9 @@ impl ReplaceCurve for Region { if replacement_happened { ReplaceOutput::Updated(Region::new( exterior - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.exterior(), core) + }) .into_inner(), interiors, self.color(), @@ -121,13 +135,18 @@ impl ReplaceCurve for Sketch { let mut replacement_happened = false; let mut regions = Vec::new(); - for region in self.regions() { - let region = - region.replace_curve(original, replacement.clone(), core); + for original_region in self.regions() { + let region = original_region.replace_curve( + original, + replacement.clone(), + core, + ); replacement_happened |= region.was_updated(); regions.push( region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_region, core) + }) .into_inner(), ); } @@ -153,7 +172,9 @@ impl ReplaceCurve for Face { ReplaceOutput::Updated(Face::new( self.surface().clone(), region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.region(), core) + }) .into_inner(), )) } else { @@ -172,12 +193,18 @@ impl ReplaceCurve for Shell { let mut replacement_happened = false; let mut faces = Vec::new(); - for face in self.faces() { - let face = face.replace_curve(original, replacement.clone(), core); + for original_face in self.faces() { + let face = original_face.replace_curve( + original, + replacement.clone(), + core, + ); replacement_happened |= face.was_updated(); faces.push( - face.map_updated(|updated| updated.insert(core)) - .into_inner(), + face.map_updated(|updated| { + updated.insert(core).derive_from(original_face, core) + }) + .into_inner(), ); } @@ -199,13 +226,18 @@ impl ReplaceCurve for Solid { let mut replacement_happened = false; let mut shells = Vec::new(); - for shell in self.shells() { - let shell = - shell.replace_curve(original, replacement.clone(), core); + for original_shell in self.shells() { + let shell = original_shell.replace_curve( + original, + replacement.clone(), + core, + ); replacement_happened |= shell.was_updated(); shells.push( shell - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_shell, core) + }) .into_inner(), ); } diff --git a/crates/fj-core/src/operations/replace/half_edge.rs b/crates/fj-core/src/operations/replace/half_edge.rs index 6ab6ae316..4142287e5 100644 --- a/crates/fj-core/src/operations/replace/half_edge.rs +++ b/crates/fj-core/src/operations/replace/half_edge.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use crate::{ objects::{Cycle, Face, HalfEdge, IsObject, Region, Shell, Sketch, Solid}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -59,13 +59,18 @@ impl ReplaceHalfEdge for Region { replacement_happened |= exterior.was_updated(); let mut interiors = Vec::new(); - for cycle in self.interiors() { - let cycle = - cycle.replace_half_edge(original, replacements.clone(), core); + for original_cycle in self.interiors() { + let cycle = original_cycle.replace_half_edge( + original, + replacements.clone(), + core, + ); replacement_happened |= cycle.was_updated(); interiors.push( cycle - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_cycle, core) + }) .into_inner(), ); } @@ -73,7 +78,9 @@ impl ReplaceHalfEdge for Region { if replacement_happened { ReplaceOutput::Updated(Region::new( exterior - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.exterior(), core) + }) .into_inner(), interiors, self.color(), @@ -94,13 +101,18 @@ impl ReplaceHalfEdge for Sketch { let mut replacement_happened = false; let mut regions = Vec::new(); - for region in self.regions() { - let region = - region.replace_half_edge(original, replacements.clone(), core); + for original_region in self.regions() { + let region = original_region.replace_half_edge( + original, + replacements.clone(), + core, + ); replacement_happened |= region.was_updated(); regions.push( region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_region, core) + }) .into_inner(), ); } @@ -128,7 +140,9 @@ impl ReplaceHalfEdge for Face { ReplaceOutput::Updated(Face::new( self.surface().clone(), region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.region(), core) + }) .into_inner(), )) } else { @@ -147,13 +161,18 @@ impl ReplaceHalfEdge for Shell { let mut replacement_happened = false; let mut faces = Vec::new(); - for face in self.faces() { - let face = - face.replace_half_edge(original, replacements.clone(), core); + for original_face in self.faces() { + let face = original_face.replace_half_edge( + original, + replacements.clone(), + core, + ); replacement_happened |= face.was_updated(); faces.push( - face.map_updated(|updated| updated.insert(core)) - .into_inner(), + face.map_updated(|updated| { + updated.insert(core).derive_from(original_face, core) + }) + .into_inner(), ); } @@ -175,13 +194,18 @@ impl ReplaceHalfEdge for Solid { let mut replacement_happened = false; let mut shells = Vec::new(); - for shell in self.shells() { - let shell = - shell.replace_half_edge(original, replacements.clone(), core); + for original_shell in self.shells() { + let shell = original_shell.replace_half_edge( + original, + replacements.clone(), + core, + ); replacement_happened |= shell.was_updated(); shells.push( shell - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_shell, core) + }) .into_inner(), ); } diff --git a/crates/fj-core/src/operations/replace/vertex.rs b/crates/fj-core/src/operations/replace/vertex.rs index 968a74372..48dd82952 100644 --- a/crates/fj-core/src/operations/replace/vertex.rs +++ b/crates/fj-core/src/operations/replace/vertex.rs @@ -4,7 +4,7 @@ use crate::{ objects::{ Cycle, Face, HalfEdge, IsObject, Region, Shell, Sketch, Solid, Vertex, }, - operations::{insert::Insert, update::UpdateHalfEdge}, + operations::{derive::DeriveFrom, insert::Insert, update::UpdateHalfEdge}, storage::Handle, Core, }; @@ -54,13 +54,20 @@ impl ReplaceVertex for Cycle { let mut replacement_happened = false; let mut half_edges = Vec::new(); - for half_edge in self.half_edges() { - let half_edge = - half_edge.replace_vertex(original, replacement.clone(), core); + for original_half_edge in self.half_edges() { + let half_edge = original_half_edge.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= half_edge.was_updated(); half_edges.push( half_edge - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated + .insert(core) + .derive_from(original_half_edge, core) + }) .into_inner(), ); } @@ -88,13 +95,18 @@ impl ReplaceVertex for Region { replacement_happened |= exterior.was_updated(); let mut interiors = Vec::new(); - for cycle in self.interiors() { - let cycle = - cycle.replace_vertex(original, replacement.clone(), core); + for original_cycle in self.interiors() { + let cycle = original_cycle.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= cycle.was_updated(); interiors.push( cycle - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_cycle, core) + }) .into_inner(), ); } @@ -102,7 +114,9 @@ impl ReplaceVertex for Region { if replacement_happened { ReplaceOutput::Updated(Region::new( exterior - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.exterior(), core) + }) .into_inner(), interiors, self.color(), @@ -123,13 +137,18 @@ impl ReplaceVertex for Sketch { let mut replacement_happened = false; let mut regions = Vec::new(); - for region in self.regions() { - let region = - region.replace_vertex(original, replacement.clone(), core); + for original_region in self.regions() { + let region = original_region.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= region.was_updated(); regions.push( region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_region, core) + }) .into_inner(), ); } @@ -155,7 +174,9 @@ impl ReplaceVertex for Face { ReplaceOutput::Updated(Face::new( self.surface().clone(), region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(self.region(), core) + }) .into_inner(), )) } else { @@ -174,12 +195,18 @@ impl ReplaceVertex for Shell { let mut replacement_happened = false; let mut faces = Vec::new(); - for face in self.faces() { - let face = face.replace_vertex(original, replacement.clone(), core); + for original_face in self.faces() { + let face = original_face.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= face.was_updated(); faces.push( - face.map_updated(|updated| updated.insert(core)) - .into_inner(), + face.map_updated(|updated| { + updated.insert(core).derive_from(original_face, core) + }) + .into_inner(), ); } @@ -201,13 +228,18 @@ impl ReplaceVertex for Solid { let mut replacement_happened = false; let mut shells = Vec::new(); - for shell in self.shells() { - let shell = - shell.replace_vertex(original, replacement.clone(), core); + for original_shell in self.shells() { + let shell = original_shell.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= shell.was_updated(); shells.push( shell - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_shell, core) + }) .into_inner(), ); } @@ -269,13 +301,18 @@ impl ReplaceVertex for Handle { let mut replacement_happened = false; let mut regions = Vec::new(); - for region in self.regions() { - let region = - region.replace_vertex(original, replacement.clone(), core); + for original_region in self.regions() { + let region = original_region.replace_vertex( + original, + replacement.clone(), + core, + ); replacement_happened |= region.was_updated(); regions.push( region - .map_updated(|updated| updated.insert(core)) + .map_updated(|updated| { + updated.insert(core).derive_from(original_region, core) + }) .into_inner(), ); } diff --git a/crates/fj-core/src/operations/reverse/cycle.rs b/crates/fj-core/src/operations/reverse/cycle.rs index 7332edc0f..a8985ba68 100644 --- a/crates/fj-core/src/operations/reverse/cycle.rs +++ b/crates/fj-core/src/operations/reverse/cycle.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Cycle, HalfEdge}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, Core, }; @@ -19,6 +19,7 @@ impl Reverse for Cycle { next.start_vertex().clone(), ) .insert(core) + .derive_from(current, core) }) .collect::>(); @@ -31,7 +32,9 @@ impl Reverse for Cycle { impl ReverseCurveCoordinateSystems for Cycle { fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self { let edges = self.half_edges().iter().map(|edge| { - edge.reverse_curve_coordinate_systems(core).insert(core) + edge.reverse_curve_coordinate_systems(core) + .insert(core) + .derive_from(edge, core) }); Cycle::new(edges) diff --git a/crates/fj-core/src/operations/reverse/face.rs b/crates/fj-core/src/operations/reverse/face.rs index 7ec620ebc..00508d086 100644 --- a/crates/fj-core/src/operations/reverse/face.rs +++ b/crates/fj-core/src/operations/reverse/face.rs @@ -4,6 +4,7 @@ use crate::{ objects::Face, operations::{ build::Polygon, + derive::DeriveFrom, insert::{Insert, IsInsertedNo, IsInsertedYes}, }, Core, @@ -13,7 +14,11 @@ use super::{Reverse, ReverseCurveCoordinateSystems}; impl Reverse for Face { fn reverse(&self, core: &mut Core) -> Self { - let region = self.region().reverse(core).insert(core); + let region = self + .region() + .reverse(core) + .insert(core) + .derive_from(self.region(), core); Face::new(self.surface().clone(), region) } } @@ -28,7 +33,10 @@ impl Reverse for Polygon { impl Reverse for Polygon { fn reverse(&self, core: &mut Core) -> Self { let face: &Face = self.face.borrow(); - let face = face.reverse(core).insert(core); + let face = face + .reverse(core) + .insert(core) + .derive_from(&self.face, core); self.replace_face(face) } @@ -39,7 +47,8 @@ impl ReverseCurveCoordinateSystems for Face { let region = self .region() .reverse_curve_coordinate_systems(core) - .insert(core); + .insert(core) + .derive_from(self.region(), core); Face::new(self.surface().clone(), region) } } @@ -58,7 +67,10 @@ impl ReverseCurveCoordinateSystems { fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self { let face: &Face = self.face.borrow(); - let face = face.reverse_curve_coordinate_systems(core).insert(core); + let face = face + .reverse_curve_coordinate_systems(core) + .insert(core) + .derive_from(&self.face, core); self.replace_face(face) } diff --git a/crates/fj-core/src/operations/reverse/region.rs b/crates/fj-core/src/operations/reverse/region.rs index 8af95d882..e90b8b799 100644 --- a/crates/fj-core/src/operations/reverse/region.rs +++ b/crates/fj-core/src/operations/reverse/region.rs @@ -1,14 +1,21 @@ -use crate::{objects::Region, operations::insert::Insert, Core}; +use crate::{ + objects::Region, + operations::{derive::DeriveFrom, insert::Insert}, + Core, +}; use super::{Reverse, ReverseCurveCoordinateSystems}; impl Reverse for Region { fn reverse(&self, core: &mut Core) -> Self { - let exterior = self.exterior().reverse(core).insert(core); - let interiors = self - .interiors() - .iter() - .map(|cycle| cycle.reverse(core).insert(core)); + let exterior = self + .exterior() + .reverse(core) + .insert(core) + .derive_from(self.exterior(), core); + let interiors = self.interiors().iter().map(|cycle| { + cycle.reverse(core).insert(core).derive_from(cycle, core) + }); Region::new(exterior, interiors, self.color()) } @@ -19,9 +26,13 @@ impl ReverseCurveCoordinateSystems for Region { let exterior = self .exterior() .reverse_curve_coordinate_systems(core) - .insert(core); + .insert(core) + .derive_from(self.exterior(), core); let interiors = self.interiors().iter().map(|cycle| { - cycle.reverse_curve_coordinate_systems(core).insert(core) + cycle + .reverse_curve_coordinate_systems(core) + .insert(core) + .derive_from(cycle, core) }); Region::new(exterior, interiors, self.color()) diff --git a/crates/fj-core/src/operations/split/edge.rs b/crates/fj-core/src/operations/split/edge.rs index f2b378839..2a74412d1 100644 --- a/crates/fj-core/src/operations/split/edge.rs +++ b/crates/fj-core/src/operations/split/edge.rs @@ -3,8 +3,8 @@ use fj_math::Point; use crate::{ objects::{HalfEdge, Shell}, operations::{ - insert::Insert, replace::ReplaceHalfEdge, split::SplitHalfEdge, - update::UpdateHalfEdge, + derive::DeriveFrom, insert::Insert, replace::ReplaceHalfEdge, + split::SplitHalfEdge, update::UpdateHalfEdge, }, queries::SiblingOfHalfEdge, storage::Handle, @@ -42,7 +42,9 @@ impl SplitEdge for Shell { let [half_edge_a, half_edge_b] = half_edge .split_half_edge(point, core) - .map(|half_edge| half_edge.insert(core)); + .map(|half_edge_part| { + half_edge_part.insert(core).derive_from(half_edge, core) + }); let siblings = { let [sibling_a, sibling_b] = sibling.split_half_edge(point, core); @@ -50,7 +52,9 @@ impl SplitEdge for Shell { |_, _| half_edge_b.start_vertex().clone(), core, ); - [sibling_a, sibling_b].map(|half_edge| half_edge.insert(core)) + [sibling_a, sibling_b].map(|half_edge| { + half_edge.insert(core).derive_from(&sibling, core) + }) }; let shell = self diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index f512e24a6..ee1b93aa9 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -6,6 +6,7 @@ use crate::{ objects::{Face, HalfEdge, Shell}, operations::{ build::{BuildFace, BuildHalfEdge}, + derive::DeriveFrom, insert::Insert, presentation::SetColor, split::SplitEdge, @@ -145,17 +146,22 @@ impl SplitFace for Shell { }, core, ) - .insert(core); + .insert(core) + .derive_from(region, core); if let Some(color) = face.region().color() { - region = region.set_color(color).insert(core); + region = region + .set_color(color) + .insert(core) + .derive_from(®ion, core); } region }, core, ) - .insert(core); + .insert(core) + .derive_from(face, core); // The previous operation has moved the iterator along. let half_edges_of_face_starting_at_d = half_edges_of_face_starting_at_b; @@ -183,17 +189,22 @@ impl SplitFace for Shell { }, core, ) - .insert(core); + .insert(core) + .derive_from(region, core); if let Some(color) = face.region().color() { - region = region.set_color(color).insert(core); + region = region + .set_color(color) + .insert(core) + .derive_from(®ion, core); } region }, core, ) - .insert(core); + .insert(core) + .derive_from(face, core); let faces = [split_face_a, split_face_b]; let self_ = self_.update_face( diff --git a/crates/fj-core/src/operations/sweep/shell_face.rs b/crates/fj-core/src/operations/sweep/shell_face.rs index 3deb888cd..6cace2c42 100644 --- a/crates/fj-core/src/operations/sweep/shell_face.rs +++ b/crates/fj-core/src/operations/sweep/shell_face.rs @@ -3,6 +3,7 @@ use fj_math::Vector; use crate::{ objects::{Face, Region, Shell}, operations::{ + derive::DeriveFrom, insert::Insert, reverse::Reverse, sweep::{SweepCache, SweepRegion}, @@ -56,7 +57,12 @@ impl SweepFaceOfShell for Shell { let mut cache = SweepCache::default(); - let exterior = face.region().exterior().reverse(core).insert(core); + let exterior = face + .region() + .exterior() + .reverse(core) + .insert(core) + .derive_from(face.region().exterior(), core); let region = Region::new(exterior, [], face.region().color()); let faces = region .sweep_region(face.surface(), path, &mut cache, core) diff --git a/crates/fj-core/src/operations/sweep/sketch.rs b/crates/fj-core/src/operations/sweep/sketch.rs index 5e1a0e141..320ccedd8 100644 --- a/crates/fj-core/src/operations/sweep/sketch.rs +++ b/crates/fj-core/src/operations/sweep/sketch.rs @@ -3,7 +3,7 @@ use fj_math::{Scalar, Vector}; use crate::{ geometry::GlobalPath, objects::{Face, Sketch, Solid, Surface}, - operations::{insert::Insert, reverse::Reverse}, + operations::{derive::DeriveFrom, insert::Insert, reverse::Reverse}, storage::Handle, Core, }; @@ -60,7 +60,7 @@ impl SweepSketch for Sketch { if is_negative_sweep { region.clone() } else { - region.reverse(core).insert(core) + region.reverse(core).insert(core).derive_from(region, core) } }; diff --git a/crates/fj-core/src/operations/transform/mod.rs b/crates/fj-core/src/operations/transform/mod.rs index b47b473f7..538e00b68 100644 --- a/crates/fj-core/src/operations/transform/mod.rs +++ b/crates/fj-core/src/operations/transform/mod.rs @@ -21,6 +21,8 @@ use crate::{ Core, }; +use super::derive::DeriveFrom; + /// Transform an object /// /// # Implementation Note @@ -81,7 +83,8 @@ where let transformed = self .clone_object() .transform_with_cache(transform, core, cache) - .insert(core); + .insert(core) + .derive_from(self, core); cache.insert(self.clone(), transformed.clone()); diff --git a/crates/fj-core/src/operations/update/cycle.rs b/crates/fj-core/src/operations/update/cycle.rs index 3a56af1e0..1f672a424 100644 --- a/crates/fj-core/src/operations/update/cycle.rs +++ b/crates/fj-core/src/operations/update/cycle.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Cycle, HalfEdge}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -64,7 +64,9 @@ impl UpdateCycle for Cycle { .half_edges() .replace( handle, - update(handle, core).map(|object| object.insert(core)), + update(handle, core).map(|object| { + object.insert(core).derive_from(handle, core) + }), ) .expect("Half-edge not found"); Cycle::new(edges) diff --git a/crates/fj-core/src/operations/update/face.rs b/crates/fj-core/src/operations/update/face.rs index 8df9dc624..6c8303ff1 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, insert::Insert}, + operations::{build::Polygon, derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -28,7 +28,10 @@ impl UpdateFace for Face { T: Insert>, { let region = update(self.region(), core); - Face::new(self.surface().clone(), region.insert(core)) + Face::new( + self.surface().clone(), + region.insert(core).derive_from(self.region(), core), + ) } } diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index e04acbb6c..ef7dbf9e9 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -3,7 +3,7 @@ use fj_math::Point; use crate::{ geometry::{CurveBoundary, SurfacePath}, objects::{Curve, HalfEdge, Vertex}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -81,7 +81,9 @@ impl UpdateHalfEdge for HalfEdge { HalfEdge::new( self.path(), self.boundary(), - update(self.curve(), core).insert(core), + update(self.curve(), core) + .insert(core) + .derive_from(self.curve(), core), self.start_vertex().clone(), ) } @@ -98,7 +100,9 @@ impl UpdateHalfEdge for HalfEdge { self.path(), self.boundary(), self.curve().clone(), - update(self.start_vertex(), core).insert(core), + update(self.start_vertex(), core) + .insert(core) + .derive_from(self.start_vertex(), core), ) } } diff --git a/crates/fj-core/src/operations/update/region.rs b/crates/fj-core/src/operations/update/region.rs index adff50ef1..cca4cd08b 100644 --- a/crates/fj-core/src/operations/update/region.rs +++ b/crates/fj-core/src/operations/update/region.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Cycle, Region}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -54,7 +54,9 @@ impl UpdateRegion for Region { where T: Insert>, { - let exterior = update(self.exterior(), core).insert(core); + let exterior = update(self.exterior(), core) + .insert(core) + .derive_from(self.exterior(), core); Region::new(exterior, self.interiors().iter().cloned(), self.color()) } @@ -84,7 +86,9 @@ impl UpdateRegion for Region { .interiors() .replace( handle, - update(handle, core).map(|object| object.insert(core)), + update(handle, core).map(|object| { + object.insert(core).derive_from(handle, core) + }), ) .expect("Cycle not found"); Region::new(self.exterior().clone(), interiors, self.color()) diff --git a/crates/fj-core/src/operations/update/shell.rs b/crates/fj-core/src/operations/update/shell.rs index 5116b89dd..6b46c76cd 100644 --- a/crates/fj-core/src/operations/update/shell.rs +++ b/crates/fj-core/src/operations/update/shell.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Face, Shell}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -66,7 +66,9 @@ impl UpdateShell for Shell { .faces() .replace( handle, - update(handle, core).map(|object| object.insert(core)), + update(handle, core).map(|object| { + object.insert(core).derive_from(handle, core) + }), ) .expect("Face not found"); Shell::new(faces) diff --git a/crates/fj-core/src/operations/update/sketch.rs b/crates/fj-core/src/operations/update/sketch.rs index e13087e44..192e7da19 100644 --- a/crates/fj-core/src/operations/update/sketch.rs +++ b/crates/fj-core/src/operations/update/sketch.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Region, Sketch}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -62,7 +62,9 @@ impl UpdateSketch for Sketch { .regions() .replace( handle, - update(handle, core).map(|object| object.insert(core)), + update(handle, core).map(|object| { + object.insert(core).derive_from(handle, core) + }), ) .expect("Region not found"); Sketch::new(regions) diff --git a/crates/fj-core/src/operations/update/solid.rs b/crates/fj-core/src/operations/update/solid.rs index c6ce788bc..f7882a637 100644 --- a/crates/fj-core/src/operations/update/solid.rs +++ b/crates/fj-core/src/operations/update/solid.rs @@ -1,6 +1,6 @@ use crate::{ objects::{Shell, Solid}, - operations::insert::Insert, + operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, Core, }; @@ -62,7 +62,9 @@ impl UpdateSolid for Solid { .shells() .replace( handle, - update(handle, core).map(|object| object.insert(core)), + update(handle, core).map(|object| { + object.insert(core).derive_from(handle, core) + }), ) .expect("Shell not found"); Solid::new(shells) diff --git a/crates/fj-core/src/validate/face.rs b/crates/fj-core/src/validate/face.rs index fcf16ee14..8ba4a8b31 100644 --- a/crates/fj-core/src/validate/face.rs +++ b/crates/fj-core/src/validate/face.rs @@ -89,6 +89,7 @@ mod tests { objects::{Cycle, Face, HalfEdge, Region}, operations::{ build::{BuildCycle, BuildFace, BuildHalfEdge}, + derive::DeriveFrom, insert::Insert, reverse::Reverse, update::{UpdateCycle, UpdateFace, UpdateRegion}, @@ -161,7 +162,12 @@ mod tests { .interiors() .iter() .cloned() - .map(|cycle| cycle.reverse(&mut core).insert(&mut core)) + .map(|cycle| { + cycle + .reverse(&mut core) + .insert(&mut core) + .derive_from(&cycle, &mut core) + }) .collect::>(); let region = Region::new(