From b2830a4afe4b7cc71a3b6e87e12ac860b34bfc20 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 10:57:17 +0100 Subject: [PATCH 01/43] Make trait method more convenient to call --- crates/fj-kernel/src/builder/edge.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index a214a232ee..bbaeb2c725 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -19,8 +19,8 @@ pub trait HalfEdgeBuilder { /// Panics if the given angle is not within the range (-2pi, 2pi) radians. fn update_as_arc( &mut self, - start: Point<2>, - end: Point<2>, + start: impl Into>, + end: impl Into>, angle_rad: impl Into, ); @@ -54,8 +54,8 @@ impl HalfEdgeBuilder for PartialHalfEdge { fn update_as_arc( &mut self, - start: Point<2>, - end: Point<2>, + start: impl Into>, + end: impl Into>, angle_rad: impl Into, ) { let angle_rad = angle_rad.into(); From 37e16896e7302cfcada7c58a4f09e51dd19b66d0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:05:01 +0100 Subject: [PATCH 02/43] Update variable names --- crates/fj-kernel/src/builder/edge.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index bbaeb2c725..35002ce0a8 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -37,8 +37,8 @@ impl HalfEdgeBuilder for PartialHalfEdge { &mut self, radius: impl Into, ) -> Curve { - let path = Curve::circle_from_radius(radius); - self.curve = Some(path); + let curve = Curve::circle_from_radius(radius); + self.curve = Some(curve); let [a_curve, b_curve] = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); @@ -49,7 +49,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { *point_boundary = Some(point_curve); } - path + curve } fn update_as_arc( @@ -65,8 +65,9 @@ impl HalfEdgeBuilder for PartialHalfEdge { let arc = fj_math::Arc::from_endpoints_and_angle(start, end, angle_rad); - let path = Curve::circle_from_center_and_radius(arc.center, arc.radius); - self.curve = Some(path); + let curve = + Curve::circle_from_center_and_radius(arc.center, arc.radius); + self.curve = Some(curve); let [a_curve, b_curve] = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); From b936c4f538c0f5497d8f3f9624d89867ecc16ddf Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:06:14 +0100 Subject: [PATCH 03/43] Return curve from `HalfEdgeBuilder::update_as_arc` --- crates/fj-kernel/src/builder/edge.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 35002ce0a8..bbdcdb028e 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -22,7 +22,7 @@ pub trait HalfEdgeBuilder { start: impl Into>, end: impl Into>, angle_rad: impl Into, - ); + ) -> Curve; /// Update partial half-edge to be a line segment fn update_as_line_segment( @@ -57,7 +57,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { start: impl Into>, end: impl Into>, angle_rad: impl Into, - ) { + ) -> Curve { 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"); @@ -77,6 +77,8 @@ impl HalfEdgeBuilder for PartialHalfEdge { { *point_boundary = Some(point_curve); } + + curve } fn update_as_line_segment( From 857adb23bc7dde347bcc63ab80da2f61279380bc Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:11:43 +0100 Subject: [PATCH 04/43] Merge variables --- crates/fj-kernel/src/builder/edge.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index bbdcdb028e..7bf886630b 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -40,11 +40,11 @@ impl HalfEdgeBuilder for PartialHalfEdge { let curve = Curve::circle_from_radius(radius); self.curve = Some(curve); - let [a_curve, b_curve] = + let points_curve = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); for (point_boundary, point_curve) in - self.boundary.each_mut_ext().zip_ext([a_curve, b_curve]) + self.boundary.each_mut_ext().zip_ext(points_curve) { *point_boundary = Some(point_curve); } @@ -69,11 +69,11 @@ impl HalfEdgeBuilder for PartialHalfEdge { Curve::circle_from_center_and_radius(arc.center, arc.radius); self.curve = Some(curve); - let [a_curve, b_curve] = + let points_curve = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); for (point_boundary, point_curve) in - self.boundary.each_mut_ext().zip_ext([a_curve, b_curve]) + self.boundary.each_mut_ext().zip_ext(points_curve) { *point_boundary = Some(point_curve); } From 73b313cddf9c19d0c30d9dff3a1be9c527d62a08 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:21:34 +0100 Subject: [PATCH 05/43] Remove needless allocation --- crates/fj-operations/src/sketch.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 7db8bb1efe..980413f497 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -57,19 +57,18 @@ impl Shape for fj::Sketch { let exterior = { let mut cycle = PartialCycle::new(objects); - let half_edges = poly_chain + let segments = poly_chain .to_segments() .into_iter() .map(|fj::SketchSegment { endpoint, route }| { let endpoint = Point::from(endpoint); - let half_edge = cycle.add_half_edge(objects); - (half_edge, endpoint, route) + (endpoint, route) }) - .collect::>(); + .circular_tuple_windows(); + + for ((start, route), (end, _)) in segments { + let mut half_edge = cycle.add_half_edge(objects); - for ((mut half_edge, start, route), (_, end, _)) in - half_edges.into_iter().circular_tuple_windows() - { match route { fj::SketchSegmentRoute::Direct => { half_edge From 72b6086d61cefe9f49f5e8c28c2e1c19d51fe4f0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:38:26 +0100 Subject: [PATCH 06/43] Consolidate redundant code --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 42da26e0f4..c7ac8e5bd2 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -1,3 +1,5 @@ +use std::array; + use fj_interop::{ext::ArrayExt, mesh::Color}; use fj_math::{Point, Scalar, Vector}; use itertools::Itertools; @@ -37,10 +39,8 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { ); // Now we're ready to create the edges. - let mut edge_bottom = face.exterior.write().add_half_edge(objects); - let mut edge_up = face.exterior.write().add_half_edge(objects); - let mut edge_top = face.exterior.write().add_half_edge(objects); - let mut edge_down = face.exterior.write().add_half_edge(objects); + let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = + array::from_fn(|_| face.exterior.write().add_half_edge(objects)); // Those edges aren't fully defined yet. We'll do that shortly, but // first we have to figure a few things out. From 889f4a5099471854182acf2986335290035d3422 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:43:54 +0100 Subject: [PATCH 07/43] Simplify `CycleBuilder::add_half_edge` --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 8 ++++++-- crates/fj-kernel/src/builder/cycle.rs | 16 +++++++++++----- crates/fj-operations/src/sketch.rs | 3 ++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index c7ac8e5bd2..778ee0d99e 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -8,7 +8,7 @@ use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, objects::{Face, HalfEdge, Objects, Surface, Vertex}, - partial::{PartialFace, PartialObject}, + partial::{Partial, PartialFace, PartialObject}, services::Service, storage::Handle, }; @@ -40,7 +40,11 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { // Now we're ready to create the edges. let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = - array::from_fn(|_| face.exterior.write().add_half_edge(objects)); + array::from_fn(|_| { + let edge = Partial::new(objects); + face.exterior.write().add_half_edge(edge.clone()); + edge + }); // Those edges aren't fully defined yet. We'll do that shortly, but // first we have to figure a few things out. diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 62aadad7f7..7ada341903 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -22,7 +22,7 @@ pub trait CycleBuilder { /// meaning its front and back vertices are the same. fn add_half_edge( &mut self, - objects: &mut Service, + half_edge: Partial, ) -> Partial; /// Update cycle as a polygon from the provided points @@ -53,9 +53,8 @@ pub trait CycleBuilder { impl CycleBuilder for PartialCycle { fn add_half_edge( &mut self, - objects: &mut Service, + half_edge: Partial, ) -> Partial { - let half_edge = Partial::new(objects); self.half_edges.push(half_edge.clone()); half_edge } @@ -72,7 +71,11 @@ impl CycleBuilder for PartialCycle { let mut start_positions = Vec::new(); let half_edges = points.map(|point| { start_positions.push(point.into()); - self.add_half_edge(objects) + + let half_edge = Partial::new(objects); + self.add_half_edge(half_edge.clone()); + + half_edge }); for ((start, end), half_edge) in start_positions @@ -95,8 +98,11 @@ impl CycleBuilder for PartialCycle { O: ObjectArgument>, { edges.map_with_prev(|_, prev| { - let mut edge = self.add_half_edge(objects); + let mut edge: Partial = Partial::new(objects); edge.write().start_vertex = prev.read().start_vertex.clone(); + + self.add_half_edge(edge.clone()); + edge }) } diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 980413f497..b2cdb8ee12 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -67,7 +67,8 @@ impl Shape for fj::Sketch { .circular_tuple_windows(); for ((start, route), (end, _)) in segments { - let mut half_edge = cycle.add_half_edge(objects); + let mut half_edge = Partial::new(objects); + cycle.add_half_edge(half_edge.clone()); match route { fj::SketchSegmentRoute::Direct => { From 2c0a7d4b9486fb1811a77e7680491e10f09b715b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 11:45:06 +0100 Subject: [PATCH 08/43] Remove redundant return value --- crates/fj-kernel/src/builder/cycle.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 7ada341903..b5c72470a3 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -20,10 +20,7 @@ pub trait CycleBuilder { /// /// If this is the first half-edge being added, it is connected to itself, /// meaning its front and back vertices are the same. - fn add_half_edge( - &mut self, - half_edge: Partial, - ) -> Partial; + fn add_half_edge(&mut self, half_edge: Partial); /// Update cycle as a polygon from the provided points fn update_as_polygon_from_points( @@ -51,12 +48,8 @@ pub trait CycleBuilder { } impl CycleBuilder for PartialCycle { - fn add_half_edge( - &mut self, - half_edge: Partial, - ) -> Partial { - self.half_edges.push(half_edge.clone()); - half_edge + fn add_half_edge(&mut self, half_edge: Partial) { + self.half_edges.push(half_edge); } fn update_as_polygon_from_points( From 3b84e7364d98a3e3dac361b1963139fe6141b515 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:10:16 +0100 Subject: [PATCH 09/43] Add `HalfEdgeBuilder::make_circle` Replace `HalfEdgeBuilder::update_as_circle_from_radius`. --- .../fj-kernel/src/algorithms/approx/edge.rs | 9 ++--- crates/fj-kernel/src/builder/edge.rs | 35 ++++++++++--------- crates/fj-operations/src/sketch.rs | 8 ++--- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/approx/edge.rs b/crates/fj-kernel/src/algorithms/approx/edge.rs index 1e5ba66c09..9e5cbaf244 100644 --- a/crates/fj-kernel/src/algorithms/approx/edge.rs +++ b/crates/fj-kernel/src/algorithms/approx/edge.rs @@ -378,13 +378,10 @@ mod tests { let surface = services.objects.surfaces.xz_plane(); let half_edge = { - let mut half_edge = PartialHalfEdge::new(&mut services.objects); + let half_edge = + PartialHalfEdge::make_circle(1., &mut services.objects); - half_edge.update_as_circle_from_radius(1.); - - half_edge - .build(&mut services.objects) - .insert(&mut services.objects) + half_edge.build(&mut services.objects) }; let tolerance = 1.; diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 7bf886630b..5da66c1223 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -1,15 +1,21 @@ use fj_interop::ext::ArrayExt; use fj_math::{Point, Scalar}; -use crate::{geometry::curve::Curve, partial::PartialHalfEdge}; +use crate::{ + geometry::curve::Curve, + insert::Insert, + objects::{GlobalEdge, HalfEdge, Objects, Vertex}, + partial::{Partial, PartialHalfEdge}, + services::Service, +}; /// Builder API for [`PartialHalfEdge`] pub trait HalfEdgeBuilder { /// Update partial half-edge to be a circle, from the given radius - fn update_as_circle_from_radius( - &mut self, + fn make_circle( radius: impl Into, - ) -> Curve; + objects: &mut Service, + ) -> Partial; /// Update partial half-edge to be an arc, spanning the given angle in /// radians @@ -33,23 +39,20 @@ pub trait HalfEdgeBuilder { } impl HalfEdgeBuilder for PartialHalfEdge { - fn update_as_circle_from_radius( - &mut self, + fn make_circle( radius: impl Into, - ) -> Curve { + objects: &mut Service, + ) -> Partial { let curve = Curve::circle_from_radius(radius); - self.curve = Some(curve); - let points_curve = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); - for (point_boundary, point_curve) in - self.boundary.each_mut_ext().zip_ext(points_curve) - { - *point_boundary = Some(point_curve); - } - - curve + Partial::from_partial(PartialHalfEdge { + curve: Some(curve), + boundary: points_curve.map(Some), + start_vertex: Vertex::new().insert(objects), + global_form: GlobalEdge::new().insert(objects), + }) } fn update_as_arc( diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index b2cdb8ee12..55ac44687b 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -28,12 +28,8 @@ impl Shape for fj::Sketch { let face = match self.chain() { fj::Chain::Circle(circle) => { - let half_edge = { - let mut half_edge = PartialHalfEdge::new(objects); - half_edge.update_as_circle_from_radius(circle.radius()); - - Partial::from_partial(half_edge) - }; + let half_edge = + PartialHalfEdge::make_circle(circle.radius(), objects); let exterior = { let mut cycle = PartialCycle::new(objects); cycle.half_edges.push(half_edge); From 0a68de0e947d45606b3e3b9a768cbe0c95125704 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:11:40 +0100 Subject: [PATCH 10/43] Simplify `PartialHalfEdge` construction --- crates/fj-kernel/src/algorithms/approx/edge.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/approx/edge.rs b/crates/fj-kernel/src/algorithms/approx/edge.rs index 9e5cbaf244..76988c7c47 100644 --- a/crates/fj-kernel/src/algorithms/approx/edge.rs +++ b/crates/fj-kernel/src/algorithms/approx/edge.rs @@ -377,12 +377,8 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xz_plane(); - let half_edge = { - let half_edge = - PartialHalfEdge::make_circle(1., &mut services.objects); - - half_edge.build(&mut services.objects) - }; + let half_edge = PartialHalfEdge::make_circle(1., &mut services.objects) + .build(&mut services.objects); let tolerance = 1.; let approx = (&half_edge, surface.deref()).approx(tolerance); From a4d10c24e3a446c1166a1c19416b730fe5f0ed9d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:12:22 +0100 Subject: [PATCH 11/43] Update variable name --- crates/fj-kernel/src/builder/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 5da66c1223..1709d3a533 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -44,12 +44,12 @@ impl HalfEdgeBuilder for PartialHalfEdge { objects: &mut Service, ) -> Partial { let curve = Curve::circle_from_radius(radius); - let points_curve = + let boundary = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); Partial::from_partial(PartialHalfEdge { curve: Some(curve), - boundary: points_curve.map(Some), + boundary: boundary.map(Some), start_vertex: Vertex::new().insert(objects), global_form: GlobalEdge::new().insert(objects), }) From 629bfde3e707bad05a59631955155e10ccd88c1c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:16:38 +0100 Subject: [PATCH 12/43] Update variable name --- crates/fj-operations/src/sketch.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 55ac44687b..0e557c7d7c 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -128,11 +128,11 @@ impl Shape for fj::Sketch { segment.endpoint, fj_math::Scalar::from_f64(angle.rad()), ); - for circle_minmax_angle in + for circle_min_max_angle in [0., PI / 2., PI, 3. * PI / 2.] { let mm_angle = fj_math::Scalar::from_f64( - circle_minmax_angle, + circle_min_max_angle, ); if arc.start_angle < mm_angle && mm_angle < arc.end_angle @@ -141,9 +141,11 @@ impl Shape for fj::Sketch { arc.center + [ arc.radius - * circle_minmax_angle.cos(), + * circle_min_max_angle + .cos(), arc.radius - * circle_minmax_angle.sin(), + * circle_min_max_angle + .sin(), ], ); } From f957f5b6149bab3b579b891e3f5a8c3e51eef55e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:18:34 +0100 Subject: [PATCH 13/43] Prepare code for follow-on change --- crates/fj-operations/src/sketch.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 0e557c7d7c..bbd23c56f0 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -4,7 +4,7 @@ use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{Objects, Sketch}, + objects::{HalfEdge, Objects, Sketch}, partial::{ Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject, PartialSketch, @@ -63,23 +63,28 @@ impl Shape for fj::Sketch { .circular_tuple_windows(); for ((start, route), (end, _)) in segments { - let mut half_edge = Partial::new(objects); - cycle.add_half_edge(half_edge.clone()); - - match route { + let half_edge = match route { fj::SketchSegmentRoute::Direct => { + let mut half_edge: Partial = + Partial::new(objects); half_edge .write() .update_as_line_segment(start, end); + half_edge } fj::SketchSegmentRoute::Arc { angle } => { + let mut half_edge: Partial = + Partial::new(objects); half_edge.write().update_as_arc( start, end, angle.rad(), ); + half_edge } - } + }; + + cycle.add_half_edge(half_edge); } Partial::from_partial(cycle) From 41501879260eb2fe74137737d4c41d832b0f77de Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:22:57 +0100 Subject: [PATCH 14/43] Add `HalfEdgeBuilder::make_arc` Replace `HalfEdgeBuilder::update_as_arc`. --- crates/fj-kernel/src/builder/edge.rs | 27 ++++++++++++--------------- crates/fj-operations/src/sketch.rs | 8 +++----- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 1709d3a533..c5589931ab 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -23,12 +23,12 @@ pub trait HalfEdgeBuilder { /// # Panics /// /// Panics if the given angle is not within the range (-2pi, 2pi) radians. - fn update_as_arc( - &mut self, + fn make_arc( start: impl Into>, end: impl Into>, angle_rad: impl Into, - ) -> Curve; + objects: &mut Service, + ) -> Partial; /// Update partial half-edge to be a line segment fn update_as_line_segment( @@ -55,12 +55,12 @@ impl HalfEdgeBuilder for PartialHalfEdge { }) } - fn update_as_arc( - &mut self, + fn make_arc( start: impl Into>, end: impl Into>, angle_rad: impl Into, - ) -> Curve { + objects: &mut Service, + ) -> Partial { 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"); @@ -70,18 +70,15 @@ impl HalfEdgeBuilder for PartialHalfEdge { let curve = Curve::circle_from_center_and_radius(arc.center, arc.radius); - self.curve = Some(curve); - let points_curve = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); - for (point_boundary, point_curve) in - self.boundary.each_mut_ext().zip_ext(points_curve) - { - *point_boundary = Some(point_curve); - } - - curve + Partial::from_partial(PartialHalfEdge { + curve: Some(curve), + boundary: points_curve.map(Some), + start_vertex: Vertex::new().insert(objects), + global_form: GlobalEdge::new().insert(objects), + }) } fn update_as_line_segment( diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index bbd23c56f0..8fe66f172e 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -73,14 +73,12 @@ impl Shape for fj::Sketch { half_edge } fj::SketchSegmentRoute::Arc { angle } => { - let mut half_edge: Partial = - Partial::new(objects); - half_edge.write().update_as_arc( + PartialHalfEdge::make_arc( start, end, angle.rad(), - ); - half_edge + objects, + ) } }; From fcc34127aca8c7910e3f59a1140e723b815d1fab Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:24:07 +0100 Subject: [PATCH 15/43] Update variable name --- crates/fj-kernel/src/builder/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index c5589931ab..7a71529676 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -70,12 +70,12 @@ impl HalfEdgeBuilder for PartialHalfEdge { let curve = Curve::circle_from_center_and_radius(arc.center, arc.radius); - let points_curve = + let boundary = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); Partial::from_partial(PartialHalfEdge { curve: Some(curve), - boundary: points_curve.map(Some), + boundary: boundary.map(Some), start_vertex: Vertex::new().insert(objects), global_form: GlobalEdge::new().insert(objects), }) From 632f0b4d58a38bdf74eb735663377baaa24f077f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:25:58 +0100 Subject: [PATCH 16/43] Refactor --- crates/fj-kernel/src/builder/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 7a71529676..f208561713 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -1,5 +1,5 @@ use fj_interop::ext::ArrayExt; -use fj_math::{Point, Scalar}; +use fj_math::{Arc, Point, Scalar}; use crate::{ geometry::curve::Curve, @@ -66,7 +66,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { panic!("arc angle must be in the range (-2pi, 2pi) radians"); } - let arc = fj_math::Arc::from_endpoints_and_angle(start, end, angle_rad); + let arc = Arc::from_endpoints_and_angle(start, end, angle_rad); let curve = Curve::circle_from_center_and_radius(arc.center, arc.radius); From 7ceb38f27c57a97dc17c320b12547fd3eb38d7de Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:28:23 +0100 Subject: [PATCH 17/43] Move code to prepare for follow-on change --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 778ee0d99e..a8b4250410 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -38,18 +38,8 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { (edge.curve(), surface).sweep_with_cache(path, cache, objects), ); - // Now we're ready to create the edges. - let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = - array::from_fn(|_| { - let edge = Partial::new(objects); - face.exterior.write().add_half_edge(edge.clone()); - edge - }); - - // Those edges aren't fully defined yet. We'll do that shortly, but - // first we have to figure a few things out. - // - // Let's start with the global vertices and edges. + // Next, we need to define the boundaries of the face. Let's start with + // the global vertices and edges. let (global_vertices, global_edges) = { let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); let (edge_right, [_, c]) = @@ -63,7 +53,7 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { ) }; - // Next, let's figure out the surface coordinates of the edge vertices. + // Let's figure out the surface coordinates of the edge vertices. let surface_points = { let [a, b] = edge.boundary(); @@ -84,6 +74,14 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { [[a, b], [c, d], [b, a], [d, c]] }; + // Now we're ready to create the edges. + let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = + array::from_fn(|_| { + let edge = Partial::new(objects); + face.exterior.write().add_half_edge(edge.clone()); + edge + }); + // Armed with all of that, we can set the edge's vertices. [ edge_bottom.write(), From 6bb5b6ab7c853b8b12b634a262706bfa4d95c9f5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:31:42 +0100 Subject: [PATCH 18/43] Make variable name more accurate --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index a8b4250410..f2e6108f3b 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -77,9 +77,9 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { // Now we're ready to create the edges. let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = array::from_fn(|_| { - let edge = Partial::new(objects); - face.exterior.write().add_half_edge(edge.clone()); - edge + let half_edge = Partial::new(objects); + face.exterior.write().add_half_edge(half_edge.clone()); + half_edge }); // Armed with all of that, we can set the edge's vertices. From b66c957d568b597272af503c50908a79a3d57f05 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:38:40 +0100 Subject: [PATCH 19/43] Refactor code to simplify it --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index f2e6108f3b..b84597992b 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -1,5 +1,3 @@ -use std::array; - use fj_interop::{ext::ArrayExt, mesh::Color}; use fj_math::{Point, Scalar, Vector}; use itertools::Itertools; @@ -74,33 +72,31 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { [[a, b], [c, d], [b, a], [d, c]] }; - // Now we're ready to create the edges. - let [mut edge_bottom, mut edge_up, mut edge_top, mut edge_down] = - array::from_fn(|_| { - let half_edge = Partial::new(objects); - face.exterior.write().add_half_edge(half_edge.clone()); - half_edge - }); - - // Armed with all of that, we can set the edge's vertices. - [ - edge_bottom.write(), - edge_up.write(), - edge_top.write(), - edge_down.write(), - ] - .zip_ext(boundaries) - .zip_ext(global_vertices) - .map(|((mut half_edge, boundary), global_vertex)| { - for (a, b) in half_edge.boundary.each_mut_ext().zip_ext(boundary) { - *a = Some(b); - } - - // Writing to the start vertices is enough. Neighboring half- - // edges share surface vertices, so writing the start vertex of - // each half-edge writes to all vertices. - half_edge.start_vertex = global_vertex; - }); + // Armed with all of that, we're ready to create the edges. + let [mut edge_bottom, mut edge_up, edge_top, mut edge_down] = + boundaries.zip_ext(global_vertices).map( + |(boundary, global_vertex)| { + let mut half_edge = Partial::::new(objects); + + for (a, b) in half_edge + .write() + .boundary + .each_mut_ext() + .zip_ext(boundary) + { + *a = Some(b); + } + + // Writing to the start vertices is enough. Neighboring + // half-edges share surface vertices, so writing the start + // vertex of each half-edge writes to all vertices. + half_edge.write().start_vertex = global_vertex; + + face.exterior.write().add_half_edge(half_edge.clone()); + + half_edge + }, + ); // With the vertices set, we can now update the curves. // From 678dfeb6acd65ac93ca390f4588ce001bdcf90bb Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:41:23 +0100 Subject: [PATCH 20/43] Remove comment What the comment describes was new when I wrote it, so it felt worth calling out. Now everything has settled down, and if this isn't properly explained, this comment is not thr right place to do it. --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index b84597992b..71ae4f652b 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -87,9 +87,6 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { *a = Some(b); } - // Writing to the start vertices is enough. Neighboring - // half-edges share surface vertices, so writing the start - // vertex of each half-edge writes to all vertices. half_edge.write().start_vertex = global_vertex; face.exterior.write().add_half_edge(half_edge.clone()); From 8c609f8b8e9e3f57854f74b7281ecce640475ba8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:52:25 +0100 Subject: [PATCH 21/43] Update variable names --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 71ae4f652b..e153213c72 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -40,14 +40,14 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { // the global vertices and edges. let (global_vertices, global_edges) = { let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); - let (edge_right, [_, c]) = + let (edge_up, [_, c]) = b.clone().sweep_with_cache(path, cache, objects); - let (edge_left, [_, d]) = + let (edge_down, [_, d]) = a.clone().sweep_with_cache(path, cache, objects); ( [a, b, c, d], - [edge.global_form().clone(), edge_right, edge_left], + [edge.global_form().clone(), edge_up, edge_down], ) }; From 2a80634d084cf17541065d69c0dd5777ac8cb082 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 12:56:17 +0100 Subject: [PATCH 22/43] Refactor to prepare for follow-on change --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index e153213c72..b97792317c 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -5,7 +5,7 @@ use itertools::Itertools; use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{Face, HalfEdge, Objects, Surface, Vertex}, + objects::{Face, GlobalEdge, HalfEdge, Objects, Surface, Vertex}, partial::{Partial, PartialFace, PartialObject}, services::Service, storage::Handle, @@ -47,7 +47,12 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { ( [a, b, c, d], - [edge.global_form().clone(), edge_up, edge_down], + [ + Some(edge.global_form().clone()), + Some(edge_up), + Some(edge_down), + None, + ], ) }; @@ -73,27 +78,26 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { }; // Armed with all of that, we're ready to create the edges. - let [mut edge_bottom, mut edge_up, edge_top, mut edge_down] = - boundaries.zip_ext(global_vertices).map( - |(boundary, global_vertex)| { - let mut half_edge = Partial::::new(objects); + let [edge_bottom, edge_up, edge_top, edge_down] = boundaries + .zip_ext(global_vertices) + .zip_ext(global_edges) + .map(|((boundary, global_vertex), global_edge)| { + let mut half_edge = Partial::::new(objects); - for (a, b) in half_edge - .write() - .boundary - .each_mut_ext() - .zip_ext(boundary) - { - *a = Some(b); - } + for (a, b) in + half_edge.write().boundary.each_mut_ext().zip_ext(boundary) + { + *a = Some(b); + } - half_edge.write().start_vertex = global_vertex; + half_edge.write().start_vertex = global_vertex; + half_edge.write().global_form = global_edge + .unwrap_or_else(|| GlobalEdge::new().insert(objects)); - face.exterior.write().add_half_edge(half_edge.clone()); + face.exterior.write().add_half_edge(half_edge.clone()); - half_edge - }, - ); + half_edge + }); // With the vertices set, we can now update the curves. // @@ -101,27 +105,15 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { // even if the original edge was a circle, it's still going to be a line // when projected into the new surface. For the side edges, because // we're sweeping along a straight path. - for ((mut half_edge, start), (_, end)) in [ - edge_bottom.clone(), - edge_up.clone(), - edge_top.clone(), - edge_down.clone(), - ] - .zip_ext(surface_points) - .into_iter() - .circular_tuple_windows() + for ((mut half_edge, start), (_, end)) in + [edge_bottom, edge_up, edge_top.clone(), edge_down] + .zip_ext(surface_points) + .into_iter() + .circular_tuple_windows() { half_edge.write().update_as_line_segment(start, end); } - // Finally, we can make sure that all edges refer to the correct global - // edges. - [edge_bottom.write(), edge_up.write(), edge_down.write()] - .zip_ext(global_edges) - .map(|(mut half_edge, global_edge)| { - half_edge.global_form = global_edge; - }); - // And we're done creating the face! All that's left to do is build our // return values. let face = face.build(objects).insert(objects); From 4e89719a64bdb84eda90663245afb650142f390e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:19:27 +0100 Subject: [PATCH 23/43] Refactor to prepare for follow-on change --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index b97792317c..f599d67b30 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -1,6 +1,5 @@ use fj_interop::{ext::ArrayExt, mesh::Color}; use fj_math::{Point, Scalar, Vector}; -use itertools::Itertools; use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, @@ -68,6 +67,11 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { ] .map(Point::from) }; + let surface_points_next = { + let mut points = surface_points; + points.rotate_left(1); + points + }; // Now, the boundaries of each edge. let boundaries = { @@ -78,10 +82,12 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { }; // Armed with all of that, we're ready to create the edges. - let [edge_bottom, edge_up, edge_top, edge_down] = boundaries + let [_edge_bottom, _edge_up, edge_top, _edge_down] = boundaries + .zip_ext(surface_points) + .zip_ext(surface_points_next) .zip_ext(global_vertices) .zip_ext(global_edges) - .map(|((boundary, global_vertex), global_edge)| { + .map(|((((boundary, start), end), global_vertex), global_edge)| { let mut half_edge = Partial::::new(objects); for (a, b) in @@ -93,27 +99,13 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { half_edge.write().start_vertex = global_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); + half_edge.write().update_as_line_segment(start, end); face.exterior.write().add_half_edge(half_edge.clone()); half_edge }); - // With the vertices set, we can now update the curves. - // - // Those are all line segments. For the bottom and top curve, because - // even if the original edge was a circle, it's still going to be a line - // when projected into the new surface. For the side edges, because - // we're sweeping along a straight path. - for ((mut half_edge, start), (_, end)) in - [edge_bottom, edge_up, edge_top.clone(), edge_down] - .zip_ext(surface_points) - .into_iter() - .circular_tuple_windows() - { - half_edge.write().update_as_line_segment(start, end); - } - // And we're done creating the face! All that's left to do is build our // return values. let face = face.build(objects).insert(objects); From 460c7d9d86c001dc69ccc56e303cdf24b55a413d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:26:49 +0100 Subject: [PATCH 24/43] Prepare builder method for change to constructor --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 6 +++++- crates/fj-kernel/src/builder/cycle.rs | 2 +- crates/fj-kernel/src/builder/edge.rs | 4 +++- crates/fj-operations/src/sketch.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index f599d67b30..10e2cbcdcb 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -99,7 +99,11 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { half_edge.write().start_vertex = global_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); - half_edge.write().update_as_line_segment(start, end); + half_edge.write().update_as_line_segment( + start, + end, + Some(boundary), + ); face.exterior.write().add_half_edge(half_edge.clone()); diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index b5c72470a3..b0dd7dc0ac 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -76,7 +76,7 @@ impl CycleBuilder for PartialCycle { .circular_tuple_windows() .zip(&mut self.half_edges) { - half_edge.write().update_as_line_segment(start, end); + half_edge.write().update_as_line_segment(start, end, None); } half_edges diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index f208561713..a5ffaa70ed 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -35,6 +35,7 @@ pub trait HalfEdgeBuilder { &mut self, start: Point<2>, end: Point<2>, + boundary: Option<[Point<1>; 2]>, ) -> Curve; } @@ -85,10 +86,11 @@ impl HalfEdgeBuilder for PartialHalfEdge { &mut self, start: Point<2>, end: Point<2>, + boundary: Option<[Point<1>; 2]>, ) -> Curve { let points_surface = [start, end]; - let path = if let [Some(start), Some(end)] = self.boundary { + let path = if let Some([start, end]) = boundary { let points = [start, end].zip_ext(points_surface); let path = Curve::line_from_points_with_coords(points); diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 8fe66f172e..252ab2bb9d 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -69,7 +69,7 @@ impl Shape for fj::Sketch { Partial::new(objects); half_edge .write() - .update_as_line_segment(start, end); + .update_as_line_segment(start, end, None); half_edge } fj::SketchSegmentRoute::Arc { angle } => { From b60cfa6bde63cf09de8fcab248362e58f0d80a25 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:26:49 +0100 Subject: [PATCH 25/43] Prepare builder method for change to constructor --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 6 ------ crates/fj-kernel/src/builder/edge.rs | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 10e2cbcdcb..886daebb1a 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -90,12 +90,6 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { .map(|((((boundary, start), end), global_vertex), global_edge)| { let mut half_edge = Partial::::new(objects); - for (a, b) in - half_edge.write().boundary.each_mut_ext().zip_ext(boundary) - { - *a = Some(b); - } - half_edge.write().start_vertex = global_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index a5ffaa70ed..0c172622cb 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -88,6 +88,10 @@ impl HalfEdgeBuilder for PartialHalfEdge { end: Point<2>, boundary: Option<[Point<1>; 2]>, ) -> Curve { + if let Some(boundary) = boundary { + self.boundary = boundary.map(Some); + } + let points_surface = [start, end]; let path = if let Some([start, end]) = boundary { From 2ab91216623d6e6148dbb057587c53dc851a0149 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:30:54 +0100 Subject: [PATCH 26/43] Simplify trait method arguments --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 8 +++----- crates/fj-kernel/src/builder/cycle.rs | 2 +- crates/fj-kernel/src/builder/edge.rs | 8 ++------ crates/fj-operations/src/sketch.rs | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 886daebb1a..23c453bc41 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -93,11 +93,9 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { half_edge.write().start_vertex = global_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); - half_edge.write().update_as_line_segment( - start, - end, - Some(boundary), - ); + half_edge + .write() + .update_as_line_segment([start, end], Some(boundary)); face.exterior.write().add_half_edge(half_edge.clone()); diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index b0dd7dc0ac..9e4c8702be 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -76,7 +76,7 @@ impl CycleBuilder for PartialCycle { .circular_tuple_windows() .zip(&mut self.half_edges) { - half_edge.write().update_as_line_segment(start, end, None); + half_edge.write().update_as_line_segment([start, end], None); } half_edges diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 0c172622cb..71fb837266 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -33,8 +33,7 @@ pub trait HalfEdgeBuilder { /// Update partial half-edge to be a line segment fn update_as_line_segment( &mut self, - start: Point<2>, - end: Point<2>, + points_surface: [Point<2>; 2], boundary: Option<[Point<1>; 2]>, ) -> Curve; } @@ -84,16 +83,13 @@ impl HalfEdgeBuilder for PartialHalfEdge { fn update_as_line_segment( &mut self, - start: Point<2>, - end: Point<2>, + points_surface: [Point<2>; 2], boundary: Option<[Point<1>; 2]>, ) -> Curve { if let Some(boundary) = boundary { self.boundary = boundary.map(Some); } - let points_surface = [start, end]; - let path = if let Some([start, end]) = boundary { let points = [start, end].zip_ext(points_surface); diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 252ab2bb9d..94ac6e0da4 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -69,7 +69,7 @@ impl Shape for fj::Sketch { Partial::new(objects); half_edge .write() - .update_as_line_segment(start, end, None); + .update_as_line_segment([start, end], None); half_edge } fj::SketchSegmentRoute::Arc { angle } => { From 4fa5bc9cdfa94f1f8beb827df378271954803fac Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:31:51 +0100 Subject: [PATCH 27/43] Merge variables --- crates/fj-kernel/src/builder/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 71fb837266..bcb458d969 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -90,8 +90,8 @@ impl HalfEdgeBuilder for PartialHalfEdge { self.boundary = boundary.map(Some); } - let path = if let Some([start, end]) = boundary { - let points = [start, end].zip_ext(points_surface); + let path = if let Some(boundary) = boundary { + let points = boundary.zip_ext(points_surface); let path = Curve::line_from_points_with_coords(points); self.curve = Some(path); From af908519de354ef6cff1d435cf0e7fdf718d210b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:38:22 +0100 Subject: [PATCH 28/43] Simplify builder method --- crates/fj-kernel/src/builder/edge.rs | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index bcb458d969..b85a7148a7 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -86,29 +86,15 @@ impl HalfEdgeBuilder for PartialHalfEdge { points_surface: [Point<2>; 2], boundary: Option<[Point<1>; 2]>, ) -> Curve { - if let Some(boundary) = boundary { - self.boundary = boundary.map(Some); - } - - let path = if let Some(boundary) = boundary { - let points = boundary.zip_ext(points_surface); - - let path = Curve::line_from_points_with_coords(points); - self.curve = Some(path); + let boundary = + boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from)); - path - } else { - let (path, _) = Curve::line_from_points(points_surface); - self.curve = Some(path); + self.boundary = boundary.map(Some); - for (vertex, position) in - self.boundary.each_mut_ext().zip_ext([0., 1.]) - { - *vertex = Some([position].into()); - } + let points = boundary.zip_ext(points_surface); - path - }; + let path = Curve::line_from_points_with_coords(points); + self.curve = Some(path); path } From 5e06c95cc8a8006353a36aa7eb3bc95e9876e823 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:38:44 +0100 Subject: [PATCH 29/43] Update variable name --- crates/fj-kernel/src/builder/edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index b85a7148a7..7289f1c310 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -93,9 +93,9 @@ impl HalfEdgeBuilder for PartialHalfEdge { let points = boundary.zip_ext(points_surface); - let path = Curve::line_from_points_with_coords(points); - self.curve = Some(path); + let curve = Curve::line_from_points_with_coords(points); + self.curve = Some(curve); - path + curve } } From 037718a4284c6b61b2dc8db2337b32b592693ef6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:42:28 +0100 Subject: [PATCH 30/43] Refactor code to simplify it --- crates/fj-kernel/src/builder/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 0facf369ae..496ffe3b92 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -85,10 +85,8 @@ impl ObjectArgument for Vec { F: FnMut(T, T) -> R, T: Clone, { - let mut prev = Vec::new(); - for i in 0..self.len() { - prev.push(self[(i + self.len() - 1) % self.len()].clone()); - } + let mut prev = self.clone(); + prev.rotate_right(1); let mut ret = Vec::new(); for (i, item) in self.into_iter().enumerate() { From fdcde3248975214812e058457890cf90b33dfc5e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:43:23 +0100 Subject: [PATCH 31/43] Refactor code to simplify it --- crates/fj-kernel/src/builder/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 496ffe3b92..f1446082bc 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -89,8 +89,7 @@ impl ObjectArgument for Vec { prev.rotate_right(1); let mut ret = Vec::new(); - for (i, item) in self.into_iter().enumerate() { - let prev = prev[i].clone(); + for (item, prev) in self.into_iter().zip(prev) { ret.push(f(item, prev)); } From 9b1d0e1e4decc39f51f08969344deee3a777f681 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:44:21 +0100 Subject: [PATCH 32/43] Refactor code to simplify it --- crates/fj-kernel/src/builder/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index f1446082bc..96805a5633 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -133,9 +133,8 @@ macro_rules! impl_object_argument_for_arrays { F: FnMut(T, T) -> R, T: Clone, { - let prev: [_; $len] = array::from_fn(|i| { - self[(i + self.len() - 1) % self.len()].clone() - }); + let mut prev = self.clone(); + prev.rotate_right(1); let mut i = 0; self.map(|item| { From 5250203c099d5c7be70e4af38bfc417b904fa38f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:47:16 +0100 Subject: [PATCH 33/43] Add `ObjectArguments::map_with_next` --- crates/fj-kernel/src/builder/mod.rs | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 96805a5633..5447b2d143 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -45,6 +45,14 @@ pub trait ObjectArgument: IntoIterator { where F: FnMut(T) -> R; + /// Create a return value by mapping the implementing type + /// + /// Provides access to the (circular) next item. + fn map_with_next(self, f: F) -> Self::SameSize + where + F: FnMut(T, T) -> R, + T: Clone; + /// Create a return value by mapping the implementing type /// /// Provides access to the (circular) previous item. @@ -80,6 +88,22 @@ impl ObjectArgument for Vec { ret } + fn map_with_next(self, mut f: F) -> Self::SameSize + where + F: FnMut(T, T) -> R, + T: Clone, + { + let mut next = self.clone(); + next.rotate_left(1); + + let mut ret = Vec::new(); + for (item, next) in self.into_iter().zip(next) { + ret.push(f(item, next)); + } + + ret + } + fn map_with_prev(self, mut f: F) -> Self::SameSize where F: FnMut(T, T) -> R, @@ -128,6 +152,23 @@ macro_rules! impl_object_argument_for_arrays { self.map(f) } + fn map_with_next(self, mut f: F) -> Self::SameSize + where + F: FnMut(T, T) -> R, + T: Clone, + { + let mut next = self.clone(); + next.rotate_left(1); + + let mut i = 0; + self.map(|item| { + let next = next[i].clone(); + i += 1; + + f(item, next) + }) + } + fn map_with_prev(self, mut f: F) -> Self::SameSize where F: FnMut(T, T) -> R, From 68d7e459b41b5c82554b39424af525699ef36dd4 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:50:15 +0100 Subject: [PATCH 34/43] Make trait method more convenient to call --- crates/fj-kernel/src/builder/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 7289f1c310..b2862494a0 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -33,7 +33,7 @@ pub trait HalfEdgeBuilder { /// Update partial half-edge to be a line segment fn update_as_line_segment( &mut self, - points_surface: [Point<2>; 2], + points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, ) -> Curve; } @@ -83,7 +83,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { fn update_as_line_segment( &mut self, - points_surface: [Point<2>; 2], + points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, ) -> Curve { let boundary = From ebfa61c36e2df9426e499fb6b1b4650b907e36e8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:51:04 +0100 Subject: [PATCH 35/43] Simplify builder method --- crates/fj-kernel/src/builder/cycle.rs | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 9e4c8702be..3093848bdf 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -1,5 +1,4 @@ use fj_math::Point; -use itertools::Itertools; use crate::{ objects::{HalfEdge, Objects}, @@ -30,7 +29,7 @@ pub trait CycleBuilder { ) -> O::SameSize> where O: ObjectArgument

, - P: Into>; + P: Clone + Into>; /// Connect the cycles to the provided half-edges /// @@ -59,27 +58,16 @@ impl CycleBuilder for PartialCycle { ) -> O::SameSize> where O: ObjectArgument

, - P: Into>, + P: Clone + Into>, { - let mut start_positions = Vec::new(); - let half_edges = points.map(|point| { - start_positions.push(point.into()); + points.map_with_next(|start, end| { + let mut half_edge = Partial::::new(objects); + half_edge.write().update_as_line_segment([start, end], None); - let half_edge = Partial::new(objects); self.add_half_edge(half_edge.clone()); half_edge - }); - - for ((start, end), half_edge) in start_positions - .into_iter() - .circular_tuple_windows() - .zip(&mut self.half_edges) - { - half_edge.write().update_as_line_segment([start, end], None); - } - - half_edges + }) } fn connect_to_edges( From b019e82a9de23a64d2629969759f89a7df5f0159 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:55:43 +0100 Subject: [PATCH 36/43] Add `HalfEdgeBuilder::make_line_segment` Replace `HalfEdgeBuilder::update_as_line_segment`. --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 11 +++++----- crates/fj-kernel/src/builder/cycle.rs | 6 ++--- crates/fj-kernel/src/builder/edge.rs | 22 ++++++++++--------- crates/fj-operations/src/sketch.rs | 13 +++++------ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 23c453bc41..190b0d6ea0 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -5,7 +5,7 @@ use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, objects::{Face, GlobalEdge, HalfEdge, Objects, Surface, Vertex}, - partial::{Partial, PartialFace, PartialObject}, + partial::{PartialFace, PartialHalfEdge, PartialObject}, services::Service, storage::Handle, }; @@ -88,14 +88,15 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { .zip_ext(global_vertices) .zip_ext(global_edges) .map(|((((boundary, start), end), global_vertex), global_edge)| { - let mut half_edge = Partial::::new(objects); + let mut half_edge = PartialHalfEdge::make_line_segment( + [start, end], + Some(boundary), + objects, + ); half_edge.write().start_vertex = global_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); - half_edge - .write() - .update_as_line_segment([start, end], Some(boundary)); face.exterior.write().add_half_edge(half_edge.clone()); diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 3093848bdf..be75ed4d09 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -2,7 +2,7 @@ use fj_math::Point; use crate::{ objects::{HalfEdge, Objects}, - partial::{Partial, PartialCycle}, + partial::{Partial, PartialCycle, PartialHalfEdge}, services::Service, }; @@ -61,8 +61,8 @@ impl CycleBuilder for PartialCycle { P: Clone + Into>, { points.map_with_next(|start, end| { - let mut half_edge = Partial::::new(objects); - half_edge.write().update_as_line_segment([start, end], None); + let half_edge = + PartialHalfEdge::make_line_segment([start, end], None, objects); self.add_half_edge(half_edge.clone()); diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index b2862494a0..f1cd7733d7 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -31,11 +31,11 @@ pub trait HalfEdgeBuilder { ) -> Partial; /// Update partial half-edge to be a line segment - fn update_as_line_segment( - &mut self, + fn make_line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, - ) -> Curve; + objects: &mut Service, + ) -> Partial; } impl HalfEdgeBuilder for PartialHalfEdge { @@ -81,21 +81,23 @@ impl HalfEdgeBuilder for PartialHalfEdge { }) } - fn update_as_line_segment( - &mut self, + fn make_line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, - ) -> Curve { + objects: &mut Service, + ) -> Partial { let boundary = boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from)); - self.boundary = boundary.map(Some); - let points = boundary.zip_ext(points_surface); let curve = Curve::line_from_points_with_coords(points); - self.curve = Some(curve); - curve + Partial::from_partial(PartialHalfEdge { + curve: Some(curve), + boundary: boundary.map(Some), + start_vertex: Vertex::new().insert(objects), + global_form: GlobalEdge::new().insert(objects), + }) } } diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 94ac6e0da4..da40fd640b 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -4,7 +4,7 @@ use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{HalfEdge, Objects, Sketch}, + objects::{Objects, Sketch}, partial::{ Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject, PartialSketch, @@ -65,12 +65,11 @@ impl Shape for fj::Sketch { for ((start, route), (end, _)) in segments { let half_edge = match route { fj::SketchSegmentRoute::Direct => { - let mut half_edge: Partial = - Partial::new(objects); - half_edge - .write() - .update_as_line_segment([start, end], None); - half_edge + PartialHalfEdge::make_line_segment( + [start, end], + None, + objects, + ) } fj::SketchSegmentRoute::Arc { angle } => { PartialHalfEdge::make_arc( From 7f72057c7bfe18a0a9e7dd0556e39b14f73431cb Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:58:12 +0100 Subject: [PATCH 37/43] Update variable name --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 190b0d6ea0..1bd9922ad8 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -87,14 +87,14 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { .zip_ext(surface_points_next) .zip_ext(global_vertices) .zip_ext(global_edges) - .map(|((((boundary, start), end), global_vertex), global_edge)| { + .map(|((((boundary, start), end), start_vertex), global_edge)| { let mut half_edge = PartialHalfEdge::make_line_segment( [start, end], Some(boundary), objects, ); - half_edge.write().start_vertex = global_vertex; + half_edge.write().start_vertex = start_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); From 428ab91b8a51a8619d40e4aabec3fd89d1373c65 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 13:58:41 +0100 Subject: [PATCH 38/43] Simplify variable name --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 1bd9922ad8..2b1bab68ad 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -37,7 +37,7 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { // Next, we need to define the boundaries of the face. Let's start with // the global vertices and edges. - let (global_vertices, global_edges) = { + let (vertices, global_edges) = { let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); let (edge_up, [_, c]) = b.clone().sweep_with_cache(path, cache, objects); @@ -85,7 +85,7 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { let [_edge_bottom, _edge_up, edge_top, _edge_down] = boundaries .zip_ext(surface_points) .zip_ext(surface_points_next) - .zip_ext(global_vertices) + .zip_ext(vertices) .zip_ext(global_edges) .map(|((((boundary, start), end), start_vertex), global_edge)| { let mut half_edge = PartialHalfEdge::make_line_segment( From b4218639012c3336177a07811e814a5f54ee5fe9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 14:01:11 +0100 Subject: [PATCH 39/43] Refactor code to simplify it --- crates/fj-kernel/src/builder/edge.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index f1cd7733d7..7055650570 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -88,10 +88,9 @@ impl HalfEdgeBuilder for PartialHalfEdge { ) -> Partial { let boundary = boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from)); - - let points = boundary.zip_ext(points_surface); - - let curve = Curve::line_from_points_with_coords(points); + let curve = Curve::line_from_points_with_coords( + boundary.zip_ext(points_surface), + ); Partial::from_partial(PartialHalfEdge { curve: Some(curve), From 0a0f9711505829ffa3c6a0cb3d2818a07fcbe7bd Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 14:02:43 +0100 Subject: [PATCH 40/43] Make builder method more flexible --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 2 +- crates/fj-kernel/src/builder/cycle.rs | 8 ++++++-- crates/fj-kernel/src/builder/edge.rs | 7 ++++++- crates/fj-operations/src/sketch.rs | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 2b1bab68ad..7f4da6036a 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -91,10 +91,10 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { let mut half_edge = PartialHalfEdge::make_line_segment( [start, end], Some(boundary), + Some(start_vertex), objects, ); - half_edge.write().start_vertex = start_vertex; half_edge.write().global_form = global_edge .unwrap_or_else(|| GlobalEdge::new().insert(objects)); diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index be75ed4d09..277a50216d 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -61,8 +61,12 @@ impl CycleBuilder for PartialCycle { P: Clone + Into>, { points.map_with_next(|start, end| { - let half_edge = - PartialHalfEdge::make_line_segment([start, end], None, objects); + let half_edge = PartialHalfEdge::make_line_segment( + [start, end], + None, + None, + objects, + ); self.add_half_edge(half_edge.clone()); diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 7055650570..f42a0f9d0b 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -7,6 +7,7 @@ use crate::{ objects::{GlobalEdge, HalfEdge, Objects, Vertex}, partial::{Partial, PartialHalfEdge}, services::Service, + storage::Handle, }; /// Builder API for [`PartialHalfEdge`] @@ -34,6 +35,7 @@ pub trait HalfEdgeBuilder { fn make_line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, + start_vertex: Option>, objects: &mut Service, ) -> Partial; } @@ -84,6 +86,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { fn make_line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, + start_vertex: Option>, objects: &mut Service, ) -> Partial { let boundary = @@ -91,11 +94,13 @@ impl HalfEdgeBuilder for PartialHalfEdge { let curve = Curve::line_from_points_with_coords( boundary.zip_ext(points_surface), ); + let start_vertex = + start_vertex.unwrap_or_else(|| Vertex::new().insert(objects)); Partial::from_partial(PartialHalfEdge { curve: Some(curve), boundary: boundary.map(Some), - start_vertex: Vertex::new().insert(objects), + start_vertex, global_form: GlobalEdge::new().insert(objects), }) } diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index da40fd640b..746c0e59ed 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -68,6 +68,7 @@ impl Shape for fj::Sketch { PartialHalfEdge::make_line_segment( [start, end], None, + None, objects, ) } From f2d6eb9353ba8c3805a41f24f35603816d87ceac Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 14:02:43 +0100 Subject: [PATCH 41/43] Make builder method more flexible --- crates/fj-kernel/src/algorithms/sweep/edge.rs | 8 +++----- crates/fj-kernel/src/builder/cycle.rs | 1 + crates/fj-kernel/src/builder/edge.rs | 6 +++++- crates/fj-operations/src/sketch.rs | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 7f4da6036a..5ed392b5a7 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -4,7 +4,7 @@ use fj_math::{Point, Scalar, Vector}; use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{Face, GlobalEdge, HalfEdge, Objects, Surface, Vertex}, + objects::{Face, HalfEdge, Objects, Surface, Vertex}, partial::{PartialFace, PartialHalfEdge, PartialObject}, services::Service, storage::Handle, @@ -88,16 +88,14 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { .zip_ext(vertices) .zip_ext(global_edges) .map(|((((boundary, start), end), start_vertex), global_edge)| { - let mut half_edge = PartialHalfEdge::make_line_segment( + let half_edge = PartialHalfEdge::make_line_segment( [start, end], Some(boundary), Some(start_vertex), + global_edge, objects, ); - half_edge.write().global_form = global_edge - .unwrap_or_else(|| GlobalEdge::new().insert(objects)); - face.exterior.write().add_half_edge(half_edge.clone()); half_edge diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 277a50216d..2ee669fec0 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -65,6 +65,7 @@ impl CycleBuilder for PartialCycle { [start, end], None, None, + None, objects, ); diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index f42a0f9d0b..867f4dd757 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -36,6 +36,7 @@ pub trait HalfEdgeBuilder { points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, start_vertex: Option>, + global_form: Option>, objects: &mut Service, ) -> Partial; } @@ -87,6 +88,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, start_vertex: Option>, + global_form: Option>, objects: &mut Service, ) -> Partial { let boundary = @@ -96,12 +98,14 @@ impl HalfEdgeBuilder for PartialHalfEdge { ); let start_vertex = start_vertex.unwrap_or_else(|| Vertex::new().insert(objects)); + let global_form = + global_form.unwrap_or_else(|| GlobalEdge::new().insert(objects)); Partial::from_partial(PartialHalfEdge { curve: Some(curve), boundary: boundary.map(Some), start_vertex, - global_form: GlobalEdge::new().insert(objects), + global_form, }) } } diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 746c0e59ed..fea504801b 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -69,6 +69,7 @@ impl Shape for fj::Sketch { [start, end], None, None, + None, objects, ) } From 356f7d1fbeb4295137ded5d5280e8220ac82e7c9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 14:17:08 +0100 Subject: [PATCH 42/43] Update doc comments --- crates/fj-kernel/src/builder/edge.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 867f4dd757..d87e1a632b 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -12,14 +12,13 @@ use crate::{ /// Builder API for [`PartialHalfEdge`] pub trait HalfEdgeBuilder { - /// Update partial half-edge to be a circle, from the given radius + /// Create a circle fn make_circle( radius: impl Into, objects: &mut Service, ) -> Partial; - /// Update partial half-edge to be an arc, spanning the given angle in - /// radians + /// Create an arc /// /// # Panics /// @@ -31,7 +30,7 @@ pub trait HalfEdgeBuilder { objects: &mut Service, ) -> Partial; - /// Update partial half-edge to be a line segment + /// Create a line segment fn make_line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, From 6c2e50d67d08874f797021ba30b7c91e0da9aea8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 9 Mar 2023 14:18:56 +0100 Subject: [PATCH 43/43] Add `HalfEdgeBuilder::make_half_edge` --- crates/fj-kernel/src/builder/edge.rs | 49 ++++++++++++++++++---------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index d87e1a632b..7eb5625b78 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -38,6 +38,15 @@ pub trait HalfEdgeBuilder { global_form: Option>, objects: &mut Service, ) -> Partial; + + /// Create a half-edge + fn make_half_edge( + curve: Curve, + boundary: [Point<1>; 2], + start_vertex: Option>, + global_form: Option>, + objects: &mut Service, + ) -> Partial; } impl HalfEdgeBuilder for PartialHalfEdge { @@ -49,12 +58,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { let boundary = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); - Partial::from_partial(PartialHalfEdge { - curve: Some(curve), - boundary: boundary.map(Some), - start_vertex: Vertex::new().insert(objects), - global_form: GlobalEdge::new().insert(objects), - }) + Self::make_half_edge(curve, boundary, None, None, objects) } fn make_arc( @@ -75,12 +79,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { let boundary = [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); - Partial::from_partial(PartialHalfEdge { - curve: Some(curve), - boundary: boundary.map(Some), - start_vertex: Vertex::new().insert(objects), - global_form: GlobalEdge::new().insert(objects), - }) + Self::make_half_edge(curve, boundary, None, None, objects) } fn make_line_segment( @@ -95,16 +94,30 @@ impl HalfEdgeBuilder for PartialHalfEdge { let curve = Curve::line_from_points_with_coords( boundary.zip_ext(points_surface), ); - let start_vertex = - start_vertex.unwrap_or_else(|| Vertex::new().insert(objects)); - let global_form = - global_form.unwrap_or_else(|| GlobalEdge::new().insert(objects)); + Self::make_half_edge( + curve, + boundary, + start_vertex, + global_form, + objects, + ) + } + + fn make_half_edge( + curve: Curve, + boundary: [Point<1>; 2], + start_vertex: Option>, + global_form: Option>, + objects: &mut Service, + ) -> Partial { Partial::from_partial(PartialHalfEdge { curve: Some(curve), boundary: boundary.map(Some), - start_vertex, - global_form, + start_vertex: start_vertex + .unwrap_or_else(|| Vertex::new().insert(objects)), + global_form: global_form + .unwrap_or_else(|| GlobalEdge::new().insert(objects)), }) } }