From 0e4ce8f9bb130824df60d9db9b0a8aabda398741 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 15:02:48 +0200 Subject: [PATCH 1/7] Update doc comments --- crates/fj-kernel/src/builder/edge.rs | 8 ++++---- crates/fj-kernel/src/builder/vertex.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index c2c6899f4..49907a45d 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -9,19 +9,19 @@ use crate::{ stores::Stores, }; -/// API for building an [`HalfEdge`] +/// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::builder`]. pub struct HalfEdgeBuilder<'a> { /// The stores that the created objects are put in pub stores: &'a Stores, - /// The surface that the [`HalfEdge`] is defined in + /// The surface that the [`HalfEdge`]'s [`Curve`] is defined in pub surface: Surface, } impl<'a> HalfEdgeBuilder<'a> { - /// Build a circle from the given radius + /// Finish building the [`HalfEdge`] as a circle from the given radius pub fn build_circle_from_radius( self, radius: impl Into, @@ -63,7 +63,7 @@ impl<'a> HalfEdgeBuilder<'a> { HalfEdge::new(curve, vertices, global_form) } - /// Build a line segment from two points + /// Finish building the [`HalfEdge`] as a line segment from the given points pub fn build_line_segment_from_points( self, points: [impl Into>; 2], diff --git a/crates/fj-kernel/src/builder/vertex.rs b/crates/fj-kernel/src/builder/vertex.rs index 88a0dc193..50587c19c 100644 --- a/crates/fj-kernel/src/builder/vertex.rs +++ b/crates/fj-kernel/src/builder/vertex.rs @@ -38,7 +38,7 @@ impl VertexBuilder { self } - /// Build a vertex from a curve position + /// Finish building the [`Vertex`] pub fn build(self) -> Vertex { let surface_form = self.surface_form.unwrap_or_else(|| { SurfaceVertexBuilder { From 96a4d9f90dc6659bcaa7303fce67a0b03648ec9c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 15:34:43 +0200 Subject: [PATCH 2/7] Add `HalfEdgeBuilder::with_curve` --- crates/fj-kernel/src/builder/edge.rs | 19 +++++++++++++++---- crates/fj-kernel/src/objects/edge.rs | 6 +++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 49907a45d..8995d67d4 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -18,16 +18,27 @@ pub struct HalfEdgeBuilder<'a> { /// The surface that the [`HalfEdge`]'s [`Curve`] is defined in pub surface: Surface, + + /// The curve that the [`HalfEdge`] is defined in + pub curve: Option, } impl<'a> HalfEdgeBuilder<'a> { + /// Build the [`HalfEdge`] with the given curve + pub fn with_curve(mut self, curve: Curve) -> Self { + self.curve = Some(curve); + self + } + /// Finish building the [`HalfEdge`] as a circle from the given radius pub fn build_circle_from_radius( self, radius: impl Into, ) -> HalfEdge { - let curve = Curve::builder(self.stores, self.surface) - .build_circle_from_radius(radius); + let curve = self.curve.unwrap_or_else(|| { + Curve::builder(self.stores, self.surface) + .build_circle_from_radius(radius) + }); let vertices = { let [a_curve, b_curve] = @@ -91,7 +102,7 @@ impl<'a> HalfEdgeBuilder<'a> { ) }; - let curve = { + let curve = self.curve.unwrap_or_else(|| { let path = SurfacePath::Line(Line::from_points(points)); let global_form = { let points = global_vertices @@ -102,7 +113,7 @@ impl<'a> HalfEdgeBuilder<'a> { }; Curve::new(self.surface, path, global_form) - }; + }); let vertices = { let [a_global, b_global] = global_vertices; diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index ee955d787..6632a5e0b 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -18,7 +18,11 @@ pub struct HalfEdge { impl HalfEdge { /// Build a `HalfEdge` using [`HalfEdgeBuilder`] pub fn builder(stores: &Stores, surface: Surface) -> HalfEdgeBuilder { - HalfEdgeBuilder { stores, surface } + HalfEdgeBuilder { + stores, + surface, + curve: None, + } } /// Create a new instance of `HalfEdge` From 5db2b3feafb574ec8dbdf10e2cfcd864e892bf61 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 15:40:45 +0200 Subject: [PATCH 3/7] Add `HalfEdgeBuilder::with_vertices` --- crates/fj-kernel/src/builder/edge.rs | 17 +++++++++++++---- crates/fj-kernel/src/objects/edge.rs | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 8995d67d4..474ad07c1 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -21,6 +21,9 @@ pub struct HalfEdgeBuilder<'a> { /// The curve that the [`HalfEdge`] is defined in pub curve: Option, + + /// The vertices that bound this [`HalfEdge`] in the [`Curve`] + pub vertices: Option<[Vertex; 2]>, } impl<'a> HalfEdgeBuilder<'a> { @@ -30,6 +33,12 @@ impl<'a> HalfEdgeBuilder<'a> { self } + /// Build the [`HalfEdge`] with the given vertices + pub fn with_vertices(mut self, vertices: [Vertex; 2]) -> Self { + self.vertices = Some(vertices); + self + } + /// Finish building the [`HalfEdge`] as a circle from the given radius pub fn build_circle_from_radius( self, @@ -40,7 +49,7 @@ impl<'a> HalfEdgeBuilder<'a> { .build_circle_from_radius(radius) }); - let vertices = { + let vertices = self.vertices.unwrap_or_else(|| { let [a_curve, b_curve] = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); @@ -66,7 +75,7 @@ impl<'a> HalfEdgeBuilder<'a> { ) }, ) - }; + }); let global_form = GlobalEdge::builder() .build_from_curve_and_vertices(&curve, &vertices); @@ -115,7 +124,7 @@ impl<'a> HalfEdgeBuilder<'a> { Curve::new(self.surface, path, global_form) }); - let vertices = { + let vertices = self.vertices.unwrap_or_else(|| { let [a_global, b_global] = global_vertices; let [a_surface, b_surface] = surface_vertices; @@ -133,7 +142,7 @@ impl<'a> HalfEdgeBuilder<'a> { b_global, ), ] - }; + }); let global_form = GlobalEdge::builder() .build_from_curve_and_vertices(&curve, &vertices); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 6632a5e0b..6ef2af8a4 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -22,6 +22,7 @@ impl HalfEdge { stores, surface, curve: None, + vertices: None, } } From 3a6ad5fd31025d33b1e795847ce8849f7421501e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 16:06:42 +0200 Subject: [PATCH 4/7] Add `HalfEdgeBuilder::with_global_form` --- crates/fj-kernel/src/builder/edge.rs | 24 ++++++++++++++++++++---- crates/fj-kernel/src/objects/edge.rs | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 474ad07c1..a4bab91f3 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -24,6 +24,12 @@ pub struct HalfEdgeBuilder<'a> { /// The vertices that bound this [`HalfEdge`] in the [`Curve`] pub vertices: Option<[Vertex; 2]>, + + /// The global form of the [`HalfEdge`] + /// + /// Can be provided to the builder, if available, or computed by one of the + /// build methods. + pub global_form: Option, } impl<'a> HalfEdgeBuilder<'a> { @@ -39,6 +45,12 @@ impl<'a> HalfEdgeBuilder<'a> { self } + /// Build the [`HalfEdge`] with the provided global form + pub fn with_global_form(mut self, global_form: GlobalEdge) -> Self { + self.global_form = Some(global_form); + self + } + /// Finish building the [`HalfEdge`] as a circle from the given radius pub fn build_circle_from_radius( self, @@ -77,8 +89,10 @@ impl<'a> HalfEdgeBuilder<'a> { ) }); - let global_form = GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices); + let global_form = self.global_form.unwrap_or_else(|| { + GlobalEdge::builder() + .build_from_curve_and_vertices(&curve, &vertices) + }); HalfEdge::new(curve, vertices, global_form) } @@ -144,8 +158,10 @@ impl<'a> HalfEdgeBuilder<'a> { ] }); - let global_form = GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices); + let global_form = self.global_form.unwrap_or_else(|| { + GlobalEdge::builder() + .build_from_curve_and_vertices(&curve, &vertices) + }); HalfEdge::new(curve, vertices, global_form) } diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 6ef2af8a4..b435d5584 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -23,6 +23,7 @@ impl HalfEdge { surface, curve: None, vertices: None, + global_form: None, } } From c419be9ae1967bb650bc9830236d99c0e73f8b17 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 16:10:31 +0200 Subject: [PATCH 5/7] Add `HalfEdgeBuilder::build` --- crates/fj-kernel/src/builder/edge.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index a4bab91f3..85aa30e00 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -165,6 +165,21 @@ impl<'a> HalfEdgeBuilder<'a> { HalfEdge::new(curve, vertices, global_form) } + + /// Finish building the [`HalfEdge`] + pub fn build(self) -> HalfEdge { + let curve = self.curve.expect("Can't build `HalfEdge` without curve"); + let vertices = self + .vertices + .expect("Can't build `HalfEdge` without vertices"); + + let global_form = self.global_form.unwrap_or_else(|| { + GlobalEdge::builder() + .build_from_curve_and_vertices(&curve, &vertices) + }); + + HalfEdge::new(curve, vertices, global_form) + } } /// API for building a [`GlobalEdge`] From 1c4abd195787d231acee3f47af122db8a2aadb6c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 16:15:33 +0200 Subject: [PATCH 6/7] Add `HalfEdgeBuilder::as_circle_from_radius` Replaces `build_circle_from_radius`. --- crates/fj-kernel/src/builder/edge.rs | 25 +++++++++---------------- crates/fj-operations/src/sketch.rs | 3 ++- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 85aa30e00..01710938e 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -51,17 +51,12 @@ impl<'a> HalfEdgeBuilder<'a> { self } - /// Finish building the [`HalfEdge`] as a circle from the given radius - pub fn build_circle_from_radius( - self, - radius: impl Into, - ) -> HalfEdge { - let curve = self.curve.unwrap_or_else(|| { - Curve::builder(self.stores, self.surface) - .build_circle_from_radius(radius) - }); + /// Build the [`HalfEdge`] as a circle from the given radius + pub fn as_circle_from_radius(mut self, radius: impl Into) -> Self { + let curve = Curve::builder(self.stores, self.surface) + .build_circle_from_radius(radius); - let vertices = self.vertices.unwrap_or_else(|| { + let vertices = { let [a_curve, b_curve] = [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); @@ -87,14 +82,12 @@ impl<'a> HalfEdgeBuilder<'a> { ) }, ) - }); + }; - let global_form = self.global_form.unwrap_or_else(|| { - GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices) - }); + self.curve = Some(curve); + self.vertices = Some(vertices); - HalfEdge::new(curve, vertices, global_form) + self } /// Finish building the [`HalfEdge`] as a line segment from the given points diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 1995f1f8e..eab95e706 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -27,7 +27,8 @@ impl Shape for fj::Sketch { // none need to be added here. let half_edge = HalfEdge::builder(stores, surface) - .build_circle_from_radius(circle.radius()); + .as_circle_from_radius(circle.radius()) + .build(); let cycle = Cycle::new(surface, [half_edge]); Face::from_exterior(cycle).with_color(Color(self.color())) From 133575c5bb3ab40576153599fdcd56474219de75 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 16:22:17 +0200 Subject: [PATCH 7/7] Add `HalfEdgeBuilder::as_line_segment_from_points` Repalces `build_line_segment_from_points`. --- .../src/algorithms/intersect/curve_edge.rs | 12 ++++++---- crates/fj-kernel/src/algorithms/sweep/edge.rs | 15 ++++++++---- crates/fj-kernel/src/algorithms/sweep/face.rs | 6 +++-- .../fj-kernel/src/algorithms/sweep/vertex.rs | 3 ++- crates/fj-kernel/src/builder/cycle.rs | 6 +++-- crates/fj-kernel/src/builder/edge.rs | 24 +++++++++---------- crates/fj-kernel/src/iter.rs | 3 ++- 7 files changed, 41 insertions(+), 28 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs index db6e5316a..47746980a 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs @@ -88,7 +88,8 @@ mod tests { let surface = Surface::xy_plane(); let curve = Curve::builder(&stores, surface).build_u_axis(); let half_edge = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[1., -1.], [1., 1.]]); + .as_line_segment_from_points([[1., -1.], [1., 1.]]) + .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -107,7 +108,8 @@ mod tests { let surface = Surface::xy_plane(); let curve = Curve::builder(&stores, surface).build_u_axis(); let half_edge = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[-1., -1.], [-1., 1.]]); + .as_line_segment_from_points([[-1., -1.], [-1., 1.]]) + .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -126,7 +128,8 @@ mod tests { let surface = Surface::xy_plane(); let curve = Curve::builder(&stores, surface).build_u_axis(); let half_edge = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[-1., -1.], [1., -1.]]); + .as_line_segment_from_points([[-1., -1.], [1., -1.]]) + .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -140,7 +143,8 @@ mod tests { let surface = Surface::xy_plane(); let curve = Curve::builder(&stores, surface).build_u_axis(); let half_edge = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[-1., 0.], [1., 0.]]); + .as_line_segment_from_points([[-1., 0.], [1., 0.]]) + .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index bcb5c5eb3..bbb680784 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -192,7 +192,8 @@ mod tests { let stores = Stores::new(); let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) - .build_line_segment_from_points([[0., 0.], [1., 0.]]); + .as_line_segment_from_points([[0., 0.], [1., 0.]]) + .build(); let face = (half_edge, Color::default()).sweep([0., 0., 1.], &stores); @@ -200,15 +201,19 @@ mod tests { let surface = Surface::xz_plane(); let bottom = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[0., 0.], [1., 0.]]); + .as_line_segment_from_points([[0., 0.], [1., 0.]]) + .build(); let top = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[0., 1.], [1., 1.]]) + .as_line_segment_from_points([[0., 1.], [1., 1.]]) + .build() .reverse(); let left = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[0., 0.], [0., 1.]]) + .as_line_segment_from_points([[0., 0.], [0., 1.]]) + .build() .reverse(); let right = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[1., 0.], [1., 1.]]); + .as_line_segment_from_points([[1., 0.], [1., 1.]]) + .build(); let cycle = Cycle::new(surface, [bottom, right, top, left]); diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 36906cfbd..9872e0466 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -113,7 +113,8 @@ mod tests { let [a, b] = [window[0], window[1]]; let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) - .build_line_segment_from_points([a, b]); + .as_line_segment_from_points([a, b]) + .build(); (half_edge, Color::default()).sweep(UP, &stores) }); @@ -148,7 +149,8 @@ mod tests { let [a, b] = [window[0], window[1]]; let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) - .build_line_segment_from_points([a, b]) + .as_line_segment_from_points([a, b]) + .build() .reverse(); (half_edge, Color::default()).sweep(DOWN, &stores) }); diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index 9de2da1a4..2aad1162d 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -166,7 +166,8 @@ mod tests { let half_edge = (vertex, surface).sweep([0., 0., 1.], &stores); let expected_half_edge = HalfEdge::builder(&stores, surface) - .build_line_segment_from_points([[0., 0.], [0., 1.]]); + .as_line_segment_from_points([[0., 0.], [0., 1.]]) + .build(); assert_eq!(half_edge, expected_half_edge); } diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index cd67cb684..a31a333f3 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -53,7 +53,8 @@ impl<'a> CycleBuilder<'a> { self.half_edges.push( HalfEdge::builder(self.stores, self.surface) - .build_line_segment_from_points(points), + .as_line_segment_from_points(points) + .build(), ); } @@ -74,7 +75,8 @@ impl<'a> CycleBuilder<'a> { [last, first].map(|vertex| vertex.surface_form().position()); self.half_edges.push( HalfEdge::builder(self.stores, self.surface) - .build_line_segment_from_points(vertices), + .as_line_segment_from_points(vertices) + .build(), ); } diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 01710938e..707b8965c 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -90,11 +90,11 @@ impl<'a> HalfEdgeBuilder<'a> { self } - /// Finish building the [`HalfEdge`] as a line segment from the given points - pub fn build_line_segment_from_points( - self, + /// Build the [`HalfEdge`] as a line segment from the given points + pub fn as_line_segment_from_points( + mut self, points: [impl Into>; 2], - ) -> HalfEdge { + ) -> Self { let points = points.map(Into::into); let global_vertices = points.map(|position| { @@ -118,7 +118,7 @@ impl<'a> HalfEdgeBuilder<'a> { ) }; - let curve = self.curve.unwrap_or_else(|| { + let curve = { let path = SurfacePath::Line(Line::from_points(points)); let global_form = { let points = global_vertices @@ -129,9 +129,9 @@ impl<'a> HalfEdgeBuilder<'a> { }; Curve::new(self.surface, path, global_form) - }); + }; - let vertices = self.vertices.unwrap_or_else(|| { + let vertices = { let [a_global, b_global] = global_vertices; let [a_surface, b_surface] = surface_vertices; @@ -149,14 +149,12 @@ impl<'a> HalfEdgeBuilder<'a> { b_global, ), ] - }); + }; - let global_form = self.global_form.unwrap_or_else(|| { - GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices) - }); + self.curve = Some(curve); + self.vertices = Some(vertices); - HalfEdge::new(curve, vertices, global_form) + self } /// Finish building the [`HalfEdge`] diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 288a85cd7..70902efa0 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -462,7 +462,8 @@ mod tests { let stores = Stores::new(); let object = HalfEdge::builder(&stores, Surface::xy_plane()) - .build_line_segment_from_points([[0., 0.], [1., 0.]]); + .as_line_segment_from_points([[0., 0.], [1., 0.]]) + .build(); assert_eq!(1, object.curve_iter().count()); assert_eq!(0, object.cycle_iter().count());