From fae1a956ef3206ff366c911e250aac415c2ffb72 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:17:00 +0100 Subject: [PATCH 01/17] Update documentation of `UpdateHalfEdgeGeometry` --- crates/fj-core/src/operations/geometry/half_edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/geometry/half_edge.rs b/crates/fj-core/src/operations/geometry/half_edge.rs index 8f05de05a..d0fe025f6 100644 --- a/crates/fj-core/src/operations/geometry/half_edge.rs +++ b/crates/fj-core/src/operations/geometry/half_edge.rs @@ -10,7 +10,7 @@ use crate::{ /// Update the geometry of a [`HalfEdge`] pub trait UpdateHalfEdgeGeometry { - /// Update the path of the edge + /// Update the path of the half-edge #[must_use] fn update_path( &self, @@ -18,7 +18,7 @@ pub trait UpdateHalfEdgeGeometry { core: &mut Core, ) -> Self; - /// Update the boundary of the edge + /// Update the boundary of the half-edge #[must_use] fn update_boundary( &self, From 33ab6dd331608db04ecf043837e84ec4f6eec277 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:18:59 +0100 Subject: [PATCH 02/17] Add `UpdateHalfEdgeGeometry::set_path` --- .../src/operations/geometry/half_edge.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/geometry/half_edge.rs b/crates/fj-core/src/operations/geometry/half_edge.rs index d0fe025f6..1ac2dd40b 100644 --- a/crates/fj-core/src/operations/geometry/half_edge.rs +++ b/crates/fj-core/src/operations/geometry/half_edge.rs @@ -1,7 +1,8 @@ use fj_math::Point; use crate::{ - geometry::{CurveBoundary, HalfEdgeGeometry, SurfacePath}, + geometry::{CurveBoundary, Geometry, HalfEdgeGeometry, SurfacePath}, + layers::Layer, objects::HalfEdge, operations::insert::Insert, storage::Handle, @@ -10,6 +11,13 @@ use crate::{ /// Update the geometry of a [`HalfEdge`] pub trait UpdateHalfEdgeGeometry { + /// Set the path of the half-edge + fn set_path( + self, + path: SurfacePath, + geometry: &mut Layer, + ) -> Self; + /// Update the path of the half-edge #[must_use] fn update_path( @@ -28,6 +36,15 @@ pub trait UpdateHalfEdgeGeometry { } impl UpdateHalfEdgeGeometry for Handle { + fn set_path( + self, + path: SurfacePath, + geometry: &mut Layer, + ) -> Self { + geometry.define_half_edge(self.clone(), HalfEdgeGeometry { path }); + self + } + fn update_path( &self, update: impl FnOnce(SurfacePath) -> SurfacePath, From 696a878ae32cd3b64492c76691f64030bac027d8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:45:39 +0100 Subject: [PATCH 03/17] Update variable name --- crates/fj-core/src/operations/sweep/half_edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index 3d0ba3380..4f000630e 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -114,7 +114,7 @@ impl SweepHalfEdge for HalfEdge { .zip_ext(curves) .map(|((((boundary, start), end), start_vertex), curve)| { let edge = { - let edge = HalfEdge::line_segment( + let half_edge = HalfEdge::line_segment( [start, end], Some(boundary), core, @@ -122,9 +122,9 @@ impl SweepHalfEdge for HalfEdge { .update_start_vertex(|_, _| start_vertex, core); let edge = if let Some(curve) = curve { - edge.update_curve(|_, _| curve, core) + half_edge.update_curve(|_, _| curve, core) } else { - edge + half_edge }; edge.insert(core) From bd042b7b46e6076c305416942fadc02e60028332 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:45:53 +0100 Subject: [PATCH 04/17] Update variable name --- crates/fj-core/src/operations/sweep/half_edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index 4f000630e..bb7c9f343 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -121,13 +121,13 @@ impl SweepHalfEdge for HalfEdge { ) .update_start_vertex(|_, _| start_vertex, core); - let edge = if let Some(curve) = curve { + let half_edge = if let Some(curve) = curve { half_edge.update_curve(|_, _| curve, core) } else { half_edge }; - edge.insert(core) + half_edge.insert(core) }; exterior = exterior.add_half_edges([edge.clone()], core); From 34109ecc6960f037e55895a28ac814eb8acf809b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:46:26 +0100 Subject: [PATCH 05/17] Update variable name --- crates/fj-core/src/operations/sweep/half_edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index bb7c9f343..32a6872ad 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -113,7 +113,7 @@ impl SweepHalfEdge for HalfEdge { .zip_ext(vertices) .zip_ext(curves) .map(|((((boundary, start), end), start_vertex), curve)| { - let edge = { + let half_edge = { let half_edge = HalfEdge::line_segment( [start, end], Some(boundary), @@ -130,9 +130,9 @@ impl SweepHalfEdge for HalfEdge { half_edge.insert(core) }; - exterior = exterior.add_half_edges([edge.clone()], core); + exterior = exterior.add_half_edges([half_edge.clone()], core); - edge + half_edge }); let exterior = exterior.insert(core); From b798afa9d0d4a81348bf21dbca6025bebbf7470c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:47:32 +0100 Subject: [PATCH 06/17] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/sweep/half_edge.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index 32a6872ad..0a4ada45a 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -114,12 +114,13 @@ impl SweepHalfEdge for HalfEdge { .zip_ext(curves) .map(|((((boundary, start), end), start_vertex), curve)| { let half_edge = { - let half_edge = HalfEdge::line_segment( + let line_segment = HalfEdge::line_segment( [start, end], Some(boundary), core, - ) - .update_start_vertex(|_, _| start_vertex, core); + ); + let half_edge = line_segment + .update_start_vertex(|_, _| start_vertex, core); let half_edge = if let Some(curve) = curve { half_edge.update_curve(|_, _| curve, core) From 348e4bf8896780b21557eb781f3083ae7b2c4642 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:49:18 +0100 Subject: [PATCH 07/17] Set half-edge geometry in `SweepHalfEdge` --- crates/fj-core/src/operations/sweep/half_edge.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index 0a4ada45a..883e42525 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -6,6 +6,7 @@ use crate::{ objects::{Cycle, Face, HalfEdge, Region, Vertex}, operations::{ build::{BuildCycle, BuildHalfEdge}, + geometry::UpdateHalfEdgeGeometry, insert::Insert, presentation::SetColor, update::{UpdateCycle, UpdateHalfEdge}, @@ -128,7 +129,10 @@ impl SweepHalfEdge for HalfEdge { half_edge }; - half_edge.insert(core) + half_edge.insert(core).set_path( + core.layers.geometry.of_half_edge(&line_segment).path, + &mut core.layers.geometry, + ) }; exterior = exterior.add_half_edges([half_edge.clone()], core); From 028dd22d59543dd3c9eb4c2f65bf29d11022f683 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:21:49 +0100 Subject: [PATCH 08/17] Update argument names --- crates/fj-core/src/operations/join/cycle.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 91af735fa..66b82508a 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -129,8 +129,8 @@ impl JoinCycle for Cycle { cycle .update_half_edge( self.half_edges().nth_circular(index), - |edge, core| { - [edge + |half_edge, core| { + [half_edge .update_curve( |_, _| edge_other.curve().clone(), core, @@ -150,8 +150,8 @@ impl JoinCycle for Cycle { ) .update_half_edge( self.half_edges().nth_circular(index + 1), - |edge, core| { - [edge.update_start_vertex( + |half_edge, core| { + [half_edge.update_start_vertex( |_, _| edge_other.start_vertex().clone(), core, )] From 8bd530daf8aba7b76502d34a20d189f7b4e7c7f9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:24:25 +0100 Subject: [PATCH 09/17] Set half-edge geometry when joining cycles --- crates/fj-core/src/operations/join/cycle.rs | 26 +++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 66b82508a..563858971 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -8,6 +8,7 @@ use crate::{ objects::{Cycle, HalfEdge}, operations::{ build::BuildHalfEdge, + geometry::UpdateHalfEdgeGeometry, insert::Insert, update::{UpdateCycle, UpdateHalfEdge}, }, @@ -144,6 +145,14 @@ impl JoinCycle for Cycle { .clone() }, core, + ) + .insert(core) + .set_path( + core.layers + .geometry + .of_half_edge(half_edge) + .path, + &mut core.layers.geometry, )] }, core, @@ -151,10 +160,19 @@ impl JoinCycle for Cycle { .update_half_edge( self.half_edges().nth_circular(index + 1), |half_edge, core| { - [half_edge.update_start_vertex( - |_, _| edge_other.start_vertex().clone(), - core, - )] + [half_edge + .update_start_vertex( + |_, _| edge_other.start_vertex().clone(), + core, + ) + .insert(core) + .set_path( + core.layers + .geometry + .of_half_edge(half_edge) + .path, + &mut core.layers.geometry, + )] }, core, ) From f7f52fa687448692abf5dca28e7ca8f319e4a9bf Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:27:50 +0100 Subject: [PATCH 10/17] Update argument names --- crates/fj-core/src/validate/shell.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 48bf7a8cb..133b572a2 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -430,8 +430,8 @@ mod tests { |cycle, core| { cycle.update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { - [edge + |half_edge, core| { + [half_edge .update_path( |path| path.reverse(), core, @@ -508,8 +508,8 @@ mod tests { |cycle, core| { cycle.update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { - [edge.update_curve( + |half_edge, core| { + [half_edge.update_curve( |_, _| Curve::new(), core, )] From 3f5c2854cdbb8078f9dcd1e5f9fbe72a0aaa0232 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:29:20 +0100 Subject: [PATCH 11/17] Set half-edge geometry in test --- crates/fj-core/src/validate/shell.rs | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 133b572a2..6946ab589 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -431,6 +431,34 @@ mod tests { cycle.update_half_edge( cycle.half_edges().nth_circular(0), |half_edge, core| { + // This is going to be weird: + // + // - That first call to `update_path` is + // going to reverse a path and insert + // a new object with the reversed + // path. + // - The next call to `update_boundary` + // relies on that, because it inserts + // an object too, and that would cause + // a validation failure without the + // first call. + // - But the new object created from + // those two operations doesn't + // actually have its geometry set in + // the geometry layer, because that + // happens in `update_path`, for an + // earlier version of the object. + // - So we need a last `set_path`, which + // sets the path again. + // + // This is very weird, but good new is, + // it's just an artifact of the + // transition from a unified object + // graph to separate topology and + // geometry layers. This should clear up + // again, once the separation is + // finished, and all APIs can adapt to + // the new reality. [half_edge .update_path( |path| path.reverse(), @@ -439,6 +467,14 @@ mod tests { .update_boundary( |boundary| boundary.reverse(), core, + ) + .set_path( + core.layers + .geometry + .of_half_edge(half_edge) + .path + .reverse(), + &mut core.layers.geometry, )] }, core, From 5b8ae052c6d523a503328f42eae7033fd9d77bd1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 12:41:50 +0100 Subject: [PATCH 12/17] Set half-edge geometry in test --- crates/fj-core/src/validate/shell.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 6946ab589..51e8d6dba 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -404,6 +404,7 @@ mod tests { operations::{ build::BuildShell, geometry::UpdateHalfEdgeGeometry, + insert::Insert, update::{ UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateRegion, UpdateShell, @@ -545,10 +546,19 @@ mod tests { cycle.update_half_edge( cycle.half_edges().nth_circular(0), |half_edge, core| { - [half_edge.update_curve( - |_, _| Curve::new(), - core, - )] + [half_edge + .update_curve( + |_, _| Curve::new(), + core, + ) + .insert(core) + .set_path( + core.layers + .geometry + .of_half_edge(half_edge) + .path, + &mut core.layers.geometry, + )] }, core, ) From 2bacac3a73ea1dd813d84f109dffca7b4c6cb247 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:09:43 +0100 Subject: [PATCH 13/17] Set half-edge geometry in `SplitEdge` --- crates/fj-core/src/operations/split/edge.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/split/edge.rs b/crates/fj-core/src/operations/split/edge.rs index fd476bcb5..fb0237a46 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::{ - derive::DeriveFrom, insert::Insert, replace::ReplaceHalfEdge, - split::SplitHalfEdge, update::UpdateHalfEdge, + derive::DeriveFrom, geometry::UpdateHalfEdgeGeometry, insert::Insert, + replace::ReplaceHalfEdge, split::SplitHalfEdge, update::UpdateHalfEdge, }, queries::SiblingOfHalfEdge, storage::Handle, @@ -55,10 +55,21 @@ impl SplitEdge for Shell { ) .insert(core); [sibling_a, sibling_b].map(|half_edge| { - half_edge.insert(core).derive_from(&sibling, core) + half_edge.insert(core).derive_from(&sibling, core).set_path( + core.layers.geometry.of_half_edge(&sibling).path, + &mut core.layers.geometry, + ) }) }; + let [half_edge_a, half_edge_b] = + [half_edge_a, half_edge_b].map(|half_edge_part| { + half_edge_part.set_path( + core.layers.geometry.of_half_edge(half_edge).path, + &mut core.layers.geometry, + ) + }); + let shell = self .replace_half_edge( half_edge, From 82686e1a88f313e7a084316faf3fa7945f0a34d0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:11:42 +0100 Subject: [PATCH 14/17] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/split/face.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 11a7bf513..7bc70aac0 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -101,13 +101,16 @@ impl SplitFace for Shell { .expect("Updated shell must contain updated face"); // Build the edge that's going to divide the new faces. - let dividing_half_edge_a_to_d = HalfEdge::line_segment( - [b.start_position(), d.start_position()], - None, - core, - ) - .update_start_vertex(|_, _| b.start_vertex().clone(), core) - .insert(core); + let dividing_half_edge_a_to_d = { + let half_edge = HalfEdge::line_segment( + [b.start_position(), d.start_position()], + None, + core, + ); + half_edge + .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 35b731d8504bf19721e1182d20ed7af9b0a37a21 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:12:47 +0100 Subject: [PATCH 15/17] Set half-edge geometry in `SplitFace` --- crates/fj-core/src/operations/split/face.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 7bc70aac0..0acf856c5 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -7,6 +7,7 @@ use crate::{ operations::{ build::{BuildCycle, BuildHalfEdge}, derive::DeriveFrom, + geometry::UpdateHalfEdgeGeometry, insert::Insert, split::SplitEdge, update::{ @@ -110,6 +111,10 @@ impl SplitFace for Shell { half_edge .update_start_vertex(|_, _| b.start_vertex().clone(), core) .insert(core) + .set_path( + core.layers.geometry.of_half_edge(&half_edge).path, + &mut core.layers.geometry, + ) }; let dividing_half_edge_c_to_b = HalfEdge::from_sibling( &dividing_half_edge_a_to_d, From 4d8d57728bafc65b1e1e449d8448d36cbec77952 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 13:59:36 +0100 Subject: [PATCH 16/17] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/build/shell.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 2a6b9b2ab..44cd8ae6b 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -91,13 +91,14 @@ pub trait BuildShell { .zip_ext([[a, b], [b, c], [c, a]]) .zip_ext(curves_and_boundaries) .map(|((vertex, positions), (curve, boundary))| { - HalfEdge::line_segment( + let half_edge = HalfEdge::line_segment( positions, Some(boundary.reverse().inner), core, - ) - .update_start_vertex(|_, _| vertex, core) - .update_curve(|_, _| curve, core) + ); + half_edge + .update_start_vertex(|_, _| vertex, core) + .update_curve(|_, _| curve, core) }) }; From 23dae5e20c0c5058c37f0daf37bf31c726386812 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 20 Mar 2024 14:00:51 +0100 Subject: [PATCH 17/17] Set half-edge geometry in `BuildShell` method --- crates/fj-core/src/operations/build/shell.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 44cd8ae6b..57a5666f6 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -8,6 +8,7 @@ use crate::{ objects::{Curve, Face, HalfEdge, Shell, Surface, Vertex}, operations::{ build::{BuildFace, BuildHalfEdge, BuildSurface, Polygon}, + geometry::UpdateHalfEdgeGeometry, insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes}, join::JoinCycle, reverse::ReverseCurveCoordinateSystems, @@ -99,6 +100,14 @@ pub trait BuildShell { half_edge .update_start_vertex(|_, _| vertex, core) .update_curve(|_, _| curve, core) + .insert(core) + .set_path( + core.layers + .geometry + .of_half_edge(&half_edge) + .path, + &mut core.layers.geometry, + ) }) };