From 8defcab4bfd564d8801fa96c8acf8c178f8bac47 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 21:07:17 +0200 Subject: [PATCH 01/16] Update argument names --- crates/fj-core/src/operations/build/shell.rs | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 02507f514..1afcc3662 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -182,8 +182,8 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { - [(edge, bad.face.surface()) + |half_edge, core| { + [(half_edge, bad.face.surface()) .reverse_curve_coordinate_systems( core, )] @@ -214,8 +214,8 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(1), - |edge, core| { - [(edge, dac.face.surface()) + |half_edge, core| { + [(half_edge, dac.face.surface()) .reverse_curve_coordinate_systems(core)] }, core, @@ -229,8 +229,8 @@ pub trait BuildShell { ) .update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { - [(edge, dac.face.surface()) + |half_edge, core| { + [(half_edge, dac.face.surface()) .reverse_curve_coordinate_systems(core)] }, core, @@ -259,24 +259,24 @@ pub trait BuildShell { cycle .update_half_edge( cycle.half_edges().nth_circular(0), - |edge, core| { - [(edge, cbd.face.surface()) + |half_edge, core| { + [(half_edge, cbd.face.surface()) .reverse_curve_coordinate_systems(core)] }, core, ) .update_half_edge( cycle.half_edges().nth_circular(1), - |edge, core| { - [(edge, cbd.face.surface()) + |half_edge, core| { + [(half_edge, cbd.face.surface()) .reverse_curve_coordinate_systems(core)] }, core, ) .update_half_edge( cycle.half_edges().nth_circular(2), - |edge, core| { - [(edge, cbd.face.surface()) + |half_edge, core| { + [(half_edge, cbd.face.surface()) .reverse_curve_coordinate_systems(core)] }, core, From 3897826b5c7fa0dc442cfc2ff4d6d18161a0c029 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 21:24:21 +0200 Subject: [PATCH 02/16] Require end vertex to reverse `HalfEdge` coords This is preparation for updating the vertex geometry in that code. --- crates/fj-core/src/operations/build/shell.rs | 262 +++++++++++------- .../src/operations/reverse/half_edge.rs | 8 +- 2 files changed, 161 insertions(+), 109 deletions(-) diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 1afcc3662..5b3200981 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -183,7 +183,14 @@ pub trait BuildShell { .update_half_edge( cycle.half_edges().nth_circular(0), |half_edge, core| { - [(half_edge, bad.face.surface()) + [( + half_edge, + cycle + .half_edges() + .nth_circular(1) + .start_vertex(), + bad.face.surface(), + ) .reverse_curve_coordinate_systems( core, )] @@ -204,111 +211,154 @@ pub trait BuildShell { core, ) }; - let dac = - { - let dac = Face::triangle([d, a, c], core); - dac.update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(1), - |half_edge, core| { - [(half_edge, dac.face.surface()) - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - dac.face.surface().clone(), - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(0), - |half_edge, core| { - [(half_edge, dac.face.surface()) - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - dac.face.surface().clone(), - core, - ) - }, - core, - ) - }, - core, - ) - }; - let cbd = - { - let cbd = Face::triangle([c, b, d], core); - cbd.update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |half_edge, core| { - [(half_edge, cbd.face.surface()) - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(1), - |half_edge, core| { - [(half_edge, cbd.face.surface()) - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(2), - |half_edge, core| { - [(half_edge, cbd.face.surface()) - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - cbd.face.surface().clone(), - core, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - cbd.face.surface().clone(), - core, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - cbd.face.surface().clone(), - core, - ) - }, - core, - ) - }, - core, - ) - }; + let dac = { + let dac = Face::triangle([d, a, c], core); + dac.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(1), + |half_edge, core| { + [( + half_edge, + cycle + .half_edges() + .nth_circular(2) + .start_vertex(), + dac.face.surface(), + ) + .reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + dac.face.surface().clone(), + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(0), + |half_edge, core| { + [( + half_edge, + cycle + .half_edges() + .nth_circular(1) + .start_vertex(), + dac.face.surface(), + ) + .reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + dac.face.surface().clone(), + core, + ) + }, + core, + ) + }, + core, + ) + }; + let cbd = { + let cbd = Face::triangle([c, b, d], core); + cbd.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |half_edge, core| { + [( + half_edge, + cycle + .half_edges() + .nth_circular(1) + .start_vertex(), + cbd.face.surface(), + ) + .reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(1), + |half_edge, core| { + [( + half_edge, + cycle + .half_edges() + .nth_circular(2) + .start_vertex(), + cbd.face.surface(), + ) + .reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(2), + |half_edge, core| { + [( + half_edge, + cycle + .half_edges() + .nth_circular(3) + .start_vertex(), + cbd.face.surface(), + ) + .reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + cbd.face.surface().clone(), + core, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + cbd.face.surface().clone(), + core, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + cbd.face.surface().clone(), + core, + ) + }, + core, + ) + }, + core, + ) + }; let triangles = [abc, bad, dac, cbd].map(|triangle| triangle.insert(core)); diff --git a/crates/fj-core/src/operations/reverse/half_edge.rs b/crates/fj-core/src/operations/reverse/half_edge.rs index eb7d3c4c5..e7c75101a 100644 --- a/crates/fj-core/src/operations/reverse/half_edge.rs +++ b/crates/fj-core/src/operations/reverse/half_edge.rs @@ -1,20 +1,22 @@ use crate::{ operations::{derive::DeriveFrom, insert::Insert}, storage::Handle, - topology::{HalfEdge, Surface}, + topology::{HalfEdge, Surface, Vertex}, Core, }; use super::ReverseCurveCoordinateSystems; -impl ReverseCurveCoordinateSystems for (&Handle, &Handle) { +impl ReverseCurveCoordinateSystems + for (&Handle, &Handle, &Handle) +{ type Reversed = Handle; fn reverse_curve_coordinate_systems( self, core: &mut Core, ) -> Self::Reversed { - let (half_edge, surface) = self; + let (half_edge, _end_vertex, surface) = self; let mut half_edge_geom = *core.layers.geometry.of_half_edge(half_edge); half_edge_geom.boundary = half_edge_geom.boundary.reverse(); From 021f8b7665f753213077816bf53f45c8b0ab8063 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 21:36:18 +0200 Subject: [PATCH 03/16] Update vertex geometry in half-edge reverse code --- .../src/operations/reverse/half_edge.rs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/reverse/half_edge.rs b/crates/fj-core/src/operations/reverse/half_edge.rs index e7c75101a..a93d5eb6c 100644 --- a/crates/fj-core/src/operations/reverse/half_edge.rs +++ b/crates/fj-core/src/operations/reverse/half_edge.rs @@ -16,7 +16,24 @@ impl ReverseCurveCoordinateSystems self, core: &mut Core, ) -> Self::Reversed { - let (half_edge, _end_vertex, surface) = self; + let (half_edge, end_vertex, surface) = self; + + let vertex_geom_start = core + .layers + .geometry + .of_vertex(half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .clone(); + let vertex_geom_end = core + .layers + .geometry + .of_vertex(end_vertex) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .clone(); let mut half_edge_geom = *core.layers.geometry.of_half_edge(half_edge); half_edge_geom.boundary = half_edge_geom.boundary.reverse(); @@ -28,6 +45,17 @@ impl ReverseCurveCoordinateSystems .insert(core) .derive_from(half_edge, core); + core.layers.geometry.define_vertex( + half_edge.start_vertex().clone(), + half_edge.curve().clone(), + vertex_geom_end, + ); + core.layers.geometry.define_vertex( + end_vertex.clone(), + half_edge.curve().clone(), + vertex_geom_start, + ); + core.layers .geometry .define_half_edge(half_edge.clone(), half_edge_geom); From 921b6c7c4646d5308f50a6aaf37852656bc3d379 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 20:46:00 +0200 Subject: [PATCH 04/16] Refactor to improve clarity --- .../fj-core/src/validation/checks/half_edge_connection.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/validation/checks/half_edge_connection.rs b/crates/fj-core/src/validation/checks/half_edge_connection.rs index bf445e9fa..29dd04a0c 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -178,12 +178,13 @@ mod tests { cycle.update_half_edge( cycle.half_edges().first(), |_, core| { - [HalfEdge::line_segment( + let (half_edge, _) = HalfEdge::line_segment( [[0., 0.], [2., 0.]], surface, core, - ) - .0] + ); + + [half_edge] }, core, ) From 07a48ef57a107030265a45eafe7c5218f38bc462 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 20:53:11 +0200 Subject: [PATCH 05/16] Set vertex geometry in test for validation check --- .../validation/checks/half_edge_connection.rs | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/validation/checks/half_edge_connection.rs b/crates/fj-core/src/validation/checks/half_edge_connection.rs index 29dd04a0c..dd762198e 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -142,6 +142,7 @@ fn check_cycle<'r>( mod tests { use crate::{ + geometry::LocalVertexGeom, operations::{ build::{BuildFace, BuildHalfEdge}, update::{UpdateCycle, UpdateFace, UpdateRegion}, @@ -178,10 +179,44 @@ mod tests { cycle.update_half_edge( cycle.half_edges().first(), |_, core| { - let (half_edge, _) = HalfEdge::line_segment( - [[0., 0.], [2., 0.]], - surface, - core, + let (half_edge, boundary) = + HalfEdge::line_segment( + [[0., 0.], [2., 0.]], + surface, + core, + ); + + let half_edge_prev = + cycle.half_edges().nth(2).unwrap(); + let half_edge_next = cycle + .half_edges() + .nth(1) + .unwrap() + .start_vertex() + .clone(); + + core.layers.geometry.define_vertex( + half_edge.start_vertex().clone(), + half_edge_prev.curve().clone(), + core.layers + .geometry + .of_vertex( + cycle + .half_edges() + .first() + .start_vertex(), + ) + .unwrap() + .local_on(half_edge_prev.curve()) + .unwrap() + .clone(), + ); + core.layers.geometry.define_vertex( + half_edge_next, + half_edge.curve().clone(), + LocalVertexGeom { + position: boundary.inner[1], + }, ); [half_edge] From e70a9f4836bd409970acbae6075aac7098e663ed Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 21:57:08 +0200 Subject: [PATCH 06/16] Update variable name --- crates/fj-core/src/operations/join/cycle.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 89adfeae6..a9f53c83c 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -154,7 +154,8 @@ impl JoinCycle for Cycle { range.zip(range_other).fold( self.clone(), |cycle, (index, index_other)| { - let edge_other = other.half_edges().nth_circular(index_other); + let half_edge_other = + other.half_edges().nth_circular(index_other); cycle .update_half_edge( @@ -178,7 +179,7 @@ impl JoinCycle for Cycle { }); if let Some(curve_geom) = curve_geom { core.layers.geometry.define_curve( - edge_other.curve().clone(), + half_edge_other.curve().clone(), surface_self.clone(), curve_geom.clone(), ); @@ -186,7 +187,7 @@ impl JoinCycle for Cycle { [half_edge .update_curve( - |_, _| edge_other.curve().clone(), + |_, _| half_edge_other.curve().clone(), core, ) .update_start_vertex( @@ -215,7 +216,9 @@ impl JoinCycle for Cycle { |half_edge, core| { [half_edge .update_start_vertex( - |_, _| edge_other.start_vertex().clone(), + |_, _| { + half_edge_other.start_vertex().clone() + }, core, ) .insert(core) From a65c5d83d6e3618cb21f9cf2b25ab361c15f7e70 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 21:58:01 +0200 Subject: [PATCH 07/16] Prepare for follow-on change --- crates/fj-core/src/operations/join/cycle.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index a9f53c83c..3d6231a27 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -154,12 +154,13 @@ impl JoinCycle for Cycle { range.zip(range_other).fold( self.clone(), |cycle, (index, index_other)| { + let half_edge = self.half_edges().nth_circular(index); let half_edge_other = other.half_edges().nth_circular(index_other); cycle .update_half_edge( - self.half_edges().nth_circular(index), + half_edge, |half_edge, core| { // The curve of the other half-edge we're joining // this one to already has a curve geometry, From dccfc27d43df7e3aed30c6a389c75be59efbaa74 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 22:06:35 +0200 Subject: [PATCH 08/16] Prepare for follow-on change --- crates/fj-core/src/operations/join/cycle.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 3d6231a27..000cc5f97 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -155,6 +155,7 @@ impl JoinCycle for Cycle { self.clone(), |cycle, (index, index_other)| { let half_edge = self.half_edges().nth_circular(index); + let half_edge_next = self.half_edges().nth_circular(index + 1); let half_edge_other = other.half_edges().nth_circular(index_other); @@ -213,7 +214,7 @@ impl JoinCycle for Cycle { core, ) .update_half_edge( - self.half_edges().nth_circular(index + 1), + half_edge_next, |half_edge, core| { [half_edge .update_start_vertex( From 692361532870407c48ebfc6d93a0ce42b12a1326 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 22:08:23 +0200 Subject: [PATCH 09/16] Prepare for follow-on change --- crates/fj-core/src/operations/join/cycle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 000cc5f97..364b57e1a 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -158,6 +158,8 @@ impl JoinCycle for Cycle { let half_edge_next = self.half_edges().nth_circular(index + 1); let half_edge_other = other.half_edges().nth_circular(index_other); + let half_edge_other_next = + other.half_edges().nth_circular(index_other + 1); cycle .update_half_edge( @@ -194,9 +196,7 @@ impl JoinCycle for Cycle { ) .update_start_vertex( |_, _| { - other - .half_edges() - .nth_circular(index_other + 1) + half_edge_other_next .start_vertex() .clone() }, From 011b93b8ac6b8f2595a46a3019663161ab4cc41f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 22:11:14 +0200 Subject: [PATCH 10/16] Update vertex geometry in `JoinCycle::join_to` --- crates/fj-core/src/operations/join/cycle.rs | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 364b57e1a..4e18a8412 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -189,6 +189,64 @@ impl JoinCycle for Cycle { ); } + // The same goes for vertices. We have to move over + // any local definitions we have to the other + // vertices. + let vertex_geom_prev_end = core + .layers + .geometry + .of_vertex(half_edge.start_vertex()) + .and_then(|vertex_geom| { + vertex_geom.local_on( + self.half_edges() + .before(half_edge) + .unwrap() + .curve(), + ) + }) + .cloned(); + let vertex_geom_start = core + .layers + .geometry + .of_vertex(half_edge.start_vertex()) + .and_then(|vertex_geom| { + vertex_geom.local_on(half_edge.curve()) + }) + .cloned(); + let vertex_geom_end = core + .layers + .geometry + .of_vertex(half_edge_next.start_vertex()) + .and_then(|vertex_geom| { + vertex_geom.local_on(half_edge.curve()) + }) + .cloned(); + if let Some(vertex_geom) = vertex_geom_prev_end { + core.layers.geometry.define_vertex( + half_edge_other_next.start_vertex().clone(), + self.half_edges() + .before(half_edge) + .unwrap() + .curve() + .clone(), + vertex_geom, + ); + } + if let Some(vertex_geom_start) = vertex_geom_start { + core.layers.geometry.define_vertex( + half_edge_other_next.start_vertex().clone(), + half_edge_other.curve().clone(), + vertex_geom_start, + ); + } + if let Some(vertex_geom_end) = vertex_geom_end { + core.layers.geometry.define_vertex( + half_edge_other.start_vertex().clone(), + half_edge_other.curve().clone(), + vertex_geom_end, + ); + } + [half_edge .update_curve( |_, _| half_edge_other.curve().clone(), @@ -216,6 +274,24 @@ impl JoinCycle for Cycle { .update_half_edge( half_edge_next, |half_edge, core| { + // And we need to move over the geometry for this + // vertex too. + let vertex_geom = core + .layers + .geometry + .of_vertex(half_edge_next.start_vertex()) + .and_then(|vertex_geom| { + vertex_geom.local_on(half_edge_next.curve()) + }) + .cloned(); + if let Some(vertex_geom) = vertex_geom { + core.layers.geometry.define_vertex( + half_edge_other.start_vertex().clone(), + half_edge.curve().clone(), + vertex_geom, + ); + } + [half_edge .update_start_vertex( |_, _| { From 39afc7eb0aa8d484e4f104c2f9099633303d621d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:08:02 +0200 Subject: [PATCH 11/16] Make variable name more specific --- crates/fj-core/src/operations/reverse/cycle.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/reverse/cycle.rs b/crates/fj-core/src/operations/reverse/cycle.rs index 5bc37498d..9bc657251 100644 --- a/crates/fj-core/src/operations/reverse/cycle.rs +++ b/crates/fj-core/src/operations/reverse/cycle.rs @@ -14,8 +14,9 @@ impl Reverse for Cycle { .half_edges() .pairs() .map(|(current, next)| { - let mut geometry = *core.layers.geometry.of_half_edge(current); - geometry.boundary = geometry.boundary.reverse(); + let mut half_edge_geom = + *core.layers.geometry.of_half_edge(current); + half_edge_geom.boundary = half_edge_geom.boundary.reverse(); HalfEdge::new( current.curve().clone(), @@ -23,7 +24,7 @@ impl Reverse for Cycle { ) .insert(core) .derive_from(current, core) - .set_geometry(geometry, &mut core.layers.geometry) + .set_geometry(half_edge_geom, &mut core.layers.geometry) }) .collect::>(); From 9cddbb3c5fd13312e7207d1583707d68444f21ad Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:15:26 +0200 Subject: [PATCH 12/16] Prepare for follow-on change --- crates/fj-core/src/operations/build/half_edge.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index 890d5b651..f33791f53 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -60,8 +60,10 @@ pub trait BuildHalfEdge { let path = SurfacePath::circle_from_center_and_radius(arc.center, arc.radius); - let boundary = - [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); + let boundary = CurveBoundary { + inner: [arc.start_angle, arc.end_angle] + .map(|coord| Point::from([coord])), + }; let half_edge = HalfEdge::unjoined(core).insert(core); @@ -70,12 +72,9 @@ pub trait BuildHalfEdge { surface, LocalCurveGeom { path }, ); - core.layers.geometry.define_half_edge( - half_edge.clone(), - HalfEdgeGeom { - boundary: boundary.into(), - }, - ); + core.layers + .geometry + .define_half_edge(half_edge.clone(), HalfEdgeGeom { boundary }); half_edge } From eab0f0da5cc1ff3d79f2bd2f9deda2591fc260f5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:16:05 +0200 Subject: [PATCH 13/16] Return boundary from `BuildHalfEdge::arc` --- crates/fj-core/src/operations/build/cycle.rs | 4 +++- crates/fj-core/src/operations/build/half_edge.rs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index 5195766d0..7a6cc46c6 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -59,7 +59,9 @@ pub trait BuildCycle { [[a, b], [b, c], [c, d], [d, a]] .into_iter() .map(|[start, end]| { - HalfEdge::arc(start, end, angle, surface.clone(), core) + let (half_edge, _) = + HalfEdge::arc(start, end, angle, surface.clone(), core); + half_edge }); Cycle::new(half_edges) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index f33791f53..45202e88b 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 { angle_rad: impl Into, surface: Handle, core: &mut Core, - ) -> Handle { + ) -> (Handle, CurveBoundary>) { 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"); @@ -76,7 +76,7 @@ pub trait BuildHalfEdge { .geometry .define_half_edge(half_edge.clone(), HalfEdgeGeom { boundary }); - half_edge + (half_edge, boundary) } /// Create a line segment From 0cd10cb5ab3bf56e3af1f2c496f334bc16dc51f9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:22:51 +0200 Subject: [PATCH 14/16] Add `BuildCycle::from_half_edges_and_boundaries` --- crates/fj-core/src/operations/build/cycle.rs | 55 ++++++++++++-------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index 7a6cc46c6..93382b478 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -2,7 +2,7 @@ use fj_math::{Point, Scalar, Vector}; use itertools::Itertools; use crate::{ - geometry::LocalVertexGeom, + geometry::{CurveBoundary, LocalVertexGeom}, operations::build::BuildHalfEdge, storage::Handle, topology::{Cycle, HalfEdge, Surface}, @@ -20,6 +20,38 @@ pub trait BuildCycle { Cycle::new([]) } + /// # Build a cycle from half-edges and associated curve boundaries + fn from_half_edges_and_boundaries( + half_edges_and_boundaries: I, + core: &mut Core, + ) -> Cycle + where + I: IntoIterator, CurveBoundary>)>, + I::IntoIter: Clone + ExactSizeIterator, + { + let half_edges = half_edges_and_boundaries + .into_iter() + .circular_tuple_windows() + .map(|((half_edge, boundary), (next_half_edge, _))| { + let [start, end] = boundary.inner; + + core.layers.geometry.define_vertex( + half_edge.start_vertex().clone(), + half_edge.curve().clone(), + LocalVertexGeom { position: start }, + ); + core.layers.geometry.define_vertex( + next_half_edge.start_vertex().clone(), + half_edge.curve().clone(), + LocalVertexGeom { position: end }, + ); + + half_edge + }); + + Cycle::new(half_edges) + } + /// # Build a circle /// /// This circle is built out of 4 distinct arcs. @@ -86,27 +118,8 @@ pub trait BuildCycle { HalfEdge::line_segment([start, end], surface.clone(), core) }) .collect::>(); - let half_edges = half_edges_and_boundaries - .into_iter() - .circular_tuple_windows() - .map(|((half_edge, boundary), (next_half_edge, _))| { - let [start, end] = boundary.inner; - core.layers.geometry.define_vertex( - half_edge.start_vertex().clone(), - half_edge.curve().clone(), - LocalVertexGeom { position: start }, - ); - core.layers.geometry.define_vertex( - next_half_edge.start_vertex().clone(), - half_edge.curve().clone(), - LocalVertexGeom { position: end }, - ); - - half_edge - }); - - Cycle::new(half_edges) + Self::from_half_edges_and_boundaries(half_edges_and_boundaries, core) } } From b542648be79e21aa9e6371b5d7263baa5a671357 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:24:18 +0200 Subject: [PATCH 15/16] Set vertex geometry in `BuildCycle::circle` --- crates/fj-core/src/operations/build/cycle.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index 93382b478..942f0364c 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -87,16 +87,14 @@ pub trait BuildCycle { let angle = Scalar::TAU / 4.; - let half_edges = - [[a, b], [b, c], [c, d], [d, a]] - .into_iter() - .map(|[start, end]| { - let (half_edge, _) = - HalfEdge::arc(start, end, angle, surface.clone(), core); - half_edge - }); + let half_edges_and_boundaries = [[a, b], [b, c], [c, d], [d, a]] + .into_iter() + .map(|[start, end]| { + HalfEdge::arc(start, end, angle, surface.clone(), core) + }) + .collect::>(); - Cycle::new(half_edges) + Self::from_half_edges_and_boundaries(half_edges_and_boundaries, core) } /// Build a polygon From 98f253236e49d30332da3b83a799c81104330ea1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:38:45 +0200 Subject: [PATCH 16/16] Set vertex geometry in test of validation check --- .../coincident_half_edges_are_not_siblings.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs index e2956053e..7e0299ac0 100644 --- a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs +++ b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs @@ -266,6 +266,37 @@ mod tests { &mut core.layers.geometry, ); + let start_vertex = + half_edge.start_vertex(); + let end_vertex = cycle + .half_edges() + .after(half_edge) + .unwrap() + .start_vertex(); + + core.layers.geometry.define_vertex( + start_vertex.clone(), + curve.clone(), + core.layers + .geometry + .of_vertex(start_vertex) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .clone(), + ); + core.layers.geometry.define_vertex( + end_vertex.clone(), + curve.clone(), + core.layers + .geometry + .of_vertex(end_vertex) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .clone(), + ); + [half_edge .update_curve(|_, _| curve, core) .insert(core)