From 1adab8ee832693e93212c1215a5ea03e449b6167 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 13:36:40 +0100 Subject: [PATCH 01/10] Remove unnecessary `clone` --- crates/fj-core/src/geometry/geometry.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/geometry/geometry.rs b/crates/fj-core/src/geometry/geometry.rs index 3b8f4ee00..00cd56e77 100644 --- a/crates/fj-core/src/geometry/geometry.rs +++ b/crates/fj-core/src/geometry/geometry.rs @@ -59,7 +59,7 @@ impl Geometry { surface: Handle, geometry: SurfaceGeometry, ) { - self.surface.insert(surface.clone().into(), geometry); + self.surface.insert(surface.into(), geometry); } /// # Access the geometry of the provided surface From b907947d2127b5fcfd237907af7cfac6ac7a7a43 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:07:55 +0100 Subject: [PATCH 02/10] Update variable name --- crates/fj-core/src/operations/join/cycle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index e05a8effa..b90fcdb92 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -87,8 +87,8 @@ impl JoinCycle for Cycle { let half_edges = edges .into_iter() .circular_tuple_windows() - .map(|((prev_half_edge, _, _), (half_edge, curve, boundary))| { - HalfEdge::unjoined(curve, boundary, core) + .map(|((prev_half_edge, _, _), (half_edge, path, boundary))| { + HalfEdge::unjoined(path, boundary, core) .update_curve(|_, _| half_edge.curve().clone(), core) .update_start_vertex( |_, _| prev_half_edge.start_vertex().clone(), From fc1f174631279acdcc3c0dfcd5242e2f4be527b7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 13:47:47 +0100 Subject: [PATCH 03/10] Return `Handle` from geometry builders All `HalfEdge` builder methods that involve geometry will have to deal with a stored object, once half-edge geometry is moved to the geometry layer. --- crates/fj-core/src/operations/build/cycle.rs | 4 ++-- .../fj-core/src/operations/build/half_edge.rs | 12 +++++------ crates/fj-core/src/operations/holes.rs | 7 ++----- crates/fj-core/src/validate/sketch.rs | 9 +++----- crates/fj-core/src/validate/solid.rs | 21 +++++++------------ 5 files changed, 20 insertions(+), 33 deletions(-) diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index 118c09102..e0500a8d9 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use crate::{ objects::{Cycle, HalfEdge}, - operations::{build::BuildHalfEdge, insert::Insert, update::UpdateCycle}, + operations::{build::BuildHalfEdge, update::UpdateCycle}, Core, }; @@ -40,7 +40,7 @@ pub trait BuildCycle { .map(Into::into) .circular_tuple_windows() .map(|(start, end)| { - HalfEdge::line_segment([start, end], None, core).insert(core) + HalfEdge::line_segment([start, end], None, core) }); Cycle::new(edges) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index b786e7a8e..a9d1d371d 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -50,7 +50,7 @@ pub trait BuildHalfEdge { end: impl Into>, angle_rad: impl Into, core: &mut Core, - ) -> HalfEdge { + ) -> Handle { let angle_rad = angle_rad.into(); if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU { panic!("arc angle must be in the range (-2pi, 2pi) radians"); @@ -63,7 +63,7 @@ pub trait BuildHalfEdge { let boundary = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); - HalfEdge::unjoined(path, boundary, core) + HalfEdge::unjoined(path, boundary, core).insert(core) } /// Create a circle @@ -71,12 +71,12 @@ pub trait BuildHalfEdge { center: impl Into>, radius: impl Into, core: &mut Core, - ) -> HalfEdge { + ) -> Handle { let path = SurfacePath::circle_from_center_and_radius(center, radius); let boundary = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); - HalfEdge::unjoined(path, boundary, core) + HalfEdge::unjoined(path, boundary, core).insert(core) } /// Create a line segment @@ -84,14 +84,14 @@ pub trait BuildHalfEdge { points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, core: &mut Core, - ) -> HalfEdge { + ) -> Handle { let boundary = boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from)); let path = SurfacePath::line_from_points_with_coords( boundary.zip_ext(points_surface), ); - HalfEdge::unjoined(path, boundary, core) + HalfEdge::unjoined(path, boundary, core).insert(core) } } diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index d8d296cf8..6d878f2c7 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -10,7 +10,6 @@ use crate::{ use super::{ build::{BuildCycle, BuildHalfEdge, BuildRegion}, - insert::Insert, join::JoinCycle, sweep::{SweepCache, SweepRegion}, update::{UpdateCycle, UpdateFace, UpdateRegion, UpdateShell}, @@ -44,8 +43,7 @@ impl AddHole for Shell { path: impl Into>, core: &mut Core, ) -> Self { - let entry = - HalfEdge::circle(location.position, radius, core).insert(core); + let entry = HalfEdge::circle(location.position, radius, core); let hole = Region::empty(core) .update_exterior( |_, core| Cycle::empty().add_half_edges([entry.clone()], core), @@ -94,8 +92,7 @@ impl AddHole for Shell { ) -> Self { let radius = radius.into(); - let entry = HalfEdge::circle(entry_location.position, radius, core) - .insert(core); + let entry = HalfEdge::circle(entry_location.position, radius, core); let path = { let point = |location: &HoleLocation| { diff --git a/crates/fj-core/src/validate/sketch.rs b/crates/fj-core/src/validate/sketch.rs index 2674a177d..5a38631a6 100644 --- a/crates/fj-core/src/validate/sketch.rs +++ b/crates/fj-core/src/validate/sketch.rs @@ -186,8 +186,7 @@ mod tests { fn should_find_clockwise_exterior_cycle() -> anyhow::Result<()> { let mut core = Core::new(); - let valid_outer_circle = - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core); + let valid_outer_circle = HalfEdge::circle([0., 0.], 1., &mut core); let valid_exterior = Cycle::new(vec![valid_outer_circle.clone()]).insert(&mut core); let valid_sketch = @@ -222,10 +221,8 @@ mod tests { fn should_find_counterclockwise_interior_cycle() -> anyhow::Result<()> { let mut core = Core::new(); - let outer_circle = - HalfEdge::circle([0., 0.], 2., &mut core).insert(&mut core); - let inner_circle = - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core); + let outer_circle = HalfEdge::circle([0., 0.], 2., &mut core); + let inner_circle = HalfEdge::circle([0., 0.], 1., &mut core); let cw_inner_circle = HalfEdge::from_sibling( &inner_circle, Vertex::new().insert(&mut core), diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index 60df5825b..394fe750e 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -202,10 +202,8 @@ mod tests { &mut core, ), Region::new( - Cycle::new(vec![ - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core) - ]) - .insert(&mut core), + Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) + .insert(&mut core), vec![], ) .insert(&mut core), @@ -249,10 +247,8 @@ mod tests { let mut core = Core::new(); let shared_region = Region::new( - Cycle::new(vec![ - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core) - ]) - .insert(&mut core), + Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) + .insert(&mut core), vec![], ) .insert(&mut core); @@ -302,10 +298,8 @@ mod tests { let mut core = Core::new(); let shared_cycle = - Cycle::new(vec![ - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core) - ]) - .insert(&mut core); + Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) + .insert(&mut core); let invalid_solid = Solid::new(vec![Shell::new(vec![ Face::new( @@ -351,8 +345,7 @@ mod tests { fn should_find_half_edge_multiple_references() -> anyhow::Result<()> { let mut core = Core::new(); - let shared_edge = - HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core); + let shared_edge = HalfEdge::circle([0., 0.], 1., &mut core); let invalid_solid = Solid::new(vec![Shell::new(vec![Face::new( Surface::surface_from_uv( From be84712713fffa5b152b6ab0dba017739bc37258 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:00:01 +0100 Subject: [PATCH 04/10] Require `Handle` when creating sibling --- crates/fj-core/src/operations/build/half_edge.rs | 2 +- crates/fj-core/src/operations/split/face.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index a9d1d371d..fb94b7334 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -29,7 +29,7 @@ pub trait BuildHalfEdge { /// Create a half-edge from its sibling fn from_sibling( - sibling: &HalfEdge, + sibling: &Handle, start_vertex: Handle, ) -> HalfEdge { HalfEdge::new( diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index e455b7de4..3833c95ea 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -106,7 +106,8 @@ impl SplitFace for Shell { None, core, ) - .update_start_vertex(|_, _| b.start_vertex().clone(), core); + .update_start_vertex(|_, _| b.start_vertex().clone(), core) + .insert(core); let dividing_half_edge_c_to_b = HalfEdge::from_sibling( &dividing_half_edge_a_to_d, d.start_vertex().clone(), From c93f8a844a4987fad65ffa7759d315b6c3c29558 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:04:17 +0100 Subject: [PATCH 05/10] Create sibling as `Handle` --- crates/fj-core/src/operations/build/half_edge.rs | 4 +++- crates/fj-core/src/operations/split/face.rs | 1 + crates/fj-core/src/validate/sketch.rs | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index fb94b7334..0835c9d5d 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -31,13 +31,15 @@ pub trait BuildHalfEdge { fn from_sibling( sibling: &Handle, start_vertex: Handle, - ) -> HalfEdge { + core: &mut Core, + ) -> Handle { HalfEdge::new( sibling.path(), sibling.boundary().reverse(), sibling.curve().clone(), start_vertex, ) + .insert(core) } /// Create an arc diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 3833c95ea..11a7bf513 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -111,6 +111,7 @@ impl SplitFace for Shell { let dividing_half_edge_c_to_b = HalfEdge::from_sibling( &dividing_half_edge_a_to_d, d.start_vertex().clone(), + core, ); let mut half_edges_of_face_starting_at_b = diff --git a/crates/fj-core/src/validate/sketch.rs b/crates/fj-core/src/validate/sketch.rs index 5a38631a6..100ed5fa8 100644 --- a/crates/fj-core/src/validate/sketch.rs +++ b/crates/fj-core/src/validate/sketch.rs @@ -198,8 +198,8 @@ mod tests { let invalid_outer_circle = HalfEdge::from_sibling( &valid_outer_circle, Vertex::new().insert(&mut core), - ) - .insert(&mut core); + &mut core, + ); let invalid_exterior = Cycle::new(vec![invalid_outer_circle.clone()]).insert(&mut core); let invalid_sketch = @@ -226,8 +226,8 @@ mod tests { let cw_inner_circle = HalfEdge::from_sibling( &inner_circle, Vertex::new().insert(&mut core), - ) - .insert(&mut core); + &mut core, + ); let exterior = Cycle::new(vec![outer_circle.clone()]).insert(&mut core); let valid_interior = From c584612e168dc2c6b66f2c04c9dcd53e423ec954 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:15:40 +0100 Subject: [PATCH 06/10] Implement reverse trait for `Handle` --- crates/fj-core/src/operations/reverse/cycle.rs | 9 ++++----- crates/fj-core/src/operations/reverse/edge.rs | 13 ++++++++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/operations/reverse/cycle.rs b/crates/fj-core/src/operations/reverse/cycle.rs index a8985ba68..f3d12acff 100644 --- a/crates/fj-core/src/operations/reverse/cycle.rs +++ b/crates/fj-core/src/operations/reverse/cycle.rs @@ -31,11 +31,10 @@ 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) - .derive_from(edge, core) - }); + let edges = self + .half_edges() + .iter() + .map(|edge| edge.reverse_curve_coordinate_systems(core)); Cycle::new(edges) } diff --git a/crates/fj-core/src/operations/reverse/edge.rs b/crates/fj-core/src/operations/reverse/edge.rs index e58f7c7b3..91e6affa2 100644 --- a/crates/fj-core/src/operations/reverse/edge.rs +++ b/crates/fj-core/src/operations/reverse/edge.rs @@ -1,9 +1,14 @@ -use crate::{objects::HalfEdge, Core}; +use crate::{ + objects::HalfEdge, + operations::{derive::DeriveFrom, insert::Insert}, + storage::Handle, + Core, +}; use super::ReverseCurveCoordinateSystems; -impl ReverseCurveCoordinateSystems for HalfEdge { - fn reverse_curve_coordinate_systems(&self, _: &mut Core) -> Self { +impl ReverseCurveCoordinateSystems for Handle { + fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self { let path = self.path().reverse(); let boundary = self.boundary().reverse(); @@ -13,5 +18,7 @@ impl ReverseCurveCoordinateSystems for HalfEdge { self.curve().clone(), self.start_vertex().clone(), ) + .insert(core) + .derive_from(self, core) } } From ced66d9a8cb05ae70d4ba10073af325c12ec0e08 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:21:03 +0100 Subject: [PATCH 07/10] Return `Handle` from `SplitEdge` --- crates/fj-core/src/operations/split/edge.rs | 10 ++++++---- crates/fj-core/src/operations/split/half_edge.rs | 11 +++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/operations/split/edge.rs b/crates/fj-core/src/operations/split/edge.rs index 2a74412d1..fd476bcb5 100644 --- a/crates/fj-core/src/operations/split/edge.rs +++ b/crates/fj-core/src/operations/split/edge.rs @@ -48,10 +48,12 @@ 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(), - core, - ); + let sibling_b = sibling_b + .update_start_vertex( + |_, _| half_edge_b.start_vertex().clone(), + core, + ) + .insert(core); [sibling_a, sibling_b].map(|half_edge| { half_edge.insert(core).derive_from(&sibling, core) }) diff --git a/crates/fj-core/src/operations/split/half_edge.rs b/crates/fj-core/src/operations/split/half_edge.rs index cb2d0d8e5..d842fae1e 100644 --- a/crates/fj-core/src/operations/split/half_edge.rs +++ b/crates/fj-core/src/operations/split/half_edge.rs @@ -3,6 +3,7 @@ use fj_math::Point; use crate::{ objects::{HalfEdge, Vertex}, operations::insert::Insert, + storage::Handle, Core, }; @@ -28,7 +29,7 @@ pub trait SplitHalfEdge { &self, point: impl Into>, core: &mut Core, - ) -> [HalfEdge; 2]; + ) -> [Handle; 2]; } impl SplitHalfEdge for HalfEdge { @@ -36,7 +37,7 @@ impl SplitHalfEdge for HalfEdge { &self, point: impl Into>, core: &mut Core, - ) -> [HalfEdge; 2] { + ) -> [Handle; 2] { let point = point.into(); let [start, end] = self.boundary().inner; @@ -46,13 +47,15 @@ impl SplitHalfEdge for HalfEdge { [start, point], self.curve().clone(), self.start_vertex().clone(), - ); + ) + .insert(core); let b = HalfEdge::new( self.path(), [point, end], self.curve().clone(), Vertex::new().insert(core), - ); + ) + .insert(core); [a, b] } From 34ce68d89fd11089e5ee35647dc485f53d40746d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:24:59 +0100 Subject: [PATCH 08/10] Implement `TransformObject` for `Handle` --- crates/fj-core/src/operations/transform/edge.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/transform/edge.rs b/crates/fj-core/src/operations/transform/edge.rs index 5aa5424f1..9c11a244d 100644 --- a/crates/fj-core/src/operations/transform/edge.rs +++ b/crates/fj-core/src/operations/transform/edge.rs @@ -1,10 +1,12 @@ use fj_math::Transform; -use crate::{objects::HalfEdge, Core}; +use crate::{ + objects::HalfEdge, operations::insert::Insert, storage::Handle, Core, +}; use super::{TransformCache, TransformObject}; -impl TransformObject for HalfEdge { +impl TransformObject for Handle { fn transform_with_cache( &self, transform: &Transform, @@ -24,6 +26,6 @@ impl TransformObject for HalfEdge { .clone() .transform_with_cache(transform, core, cache); - Self::new(path, boundary, curve, start_vertex) + HalfEdge::new(path, boundary, curve, start_vertex).insert(core) } } From f8038849d95353329106a54d277fd615a1a2036f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:29:13 +0100 Subject: [PATCH 09/10] Return `Handle` from `UpdateHalfEdge::update_path` --- crates/fj-core/src/operations/update/half_edge.rs | 9 ++++++--- crates/fj-core/src/validate/shell.rs | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index ef7dbf9e9..6c2ff19be 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -9,13 +9,14 @@ use crate::{ }; /// Update a [`HalfEdge`] -pub trait UpdateHalfEdge { +pub trait UpdateHalfEdge: Sized { /// Update the path of the edge #[must_use] fn update_path( &self, update: impl FnOnce(SurfacePath) -> SurfacePath, - ) -> Self; + core: &mut Core, + ) -> Handle; /// Update the boundary of the edge #[must_use] @@ -49,13 +50,15 @@ impl UpdateHalfEdge for HalfEdge { fn update_path( &self, update: impl FnOnce(SurfacePath) -> SurfacePath, - ) -> Self { + core: &mut Core, + ) -> Handle { HalfEdge::new( update(self.path()), self.boundary(), self.curve().clone(), self.start_vertex().clone(), ) + .insert(core) } fn update_boundary( diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 2628a30f7..ff062f243 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -429,9 +429,12 @@ mod tests { |cycle, core| { cycle.update_half_edge( cycle.half_edges().nth_circular(0), - |edge, _| { + |edge, core| { [edge - .update_path(|path| path.reverse()) + .update_path( + |path| path.reverse(), + core, + ) .update_boundary(|boundary| { boundary.reverse() })] From ee9dc0de0f70f027226c14a0129ef600de1451a7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 14 Mar 2024 14:38:15 +0100 Subject: [PATCH 10/10] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/update/half_edge.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/update/half_edge.rs b/crates/fj-core/src/operations/update/half_edge.rs index 6c2ff19be..c8992c629 100644 --- a/crates/fj-core/src/operations/update/half_edge.rs +++ b/crates/fj-core/src/operations/update/half_edge.rs @@ -52,8 +52,10 @@ impl UpdateHalfEdge for HalfEdge { update: impl FnOnce(SurfacePath) -> SurfacePath, core: &mut Core, ) -> Handle { + let path = update(self.path()); + HalfEdge::new( - update(self.path()), + path, self.boundary(), self.curve().clone(), self.start_vertex().clone(),