From 4f2e39bf9bfdd984c97da833bae0a2a1c2f0f9d7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:42:22 +0200 Subject: [PATCH 01/25] Move `builder::edge` to `partial` The new `partial::edge` doesn't follow the style of the `partial` module yet. I'm working on that. --- crates/fj-kernel/src/builder/mod.rs | 9 ++------- crates/fj-kernel/src/objects/edge.rs | 2 +- crates/fj-kernel/src/{builder => partial}/edge.rs | 0 crates/fj-kernel/src/partial/mod.rs | 2 ++ 4 files changed, 5 insertions(+), 8 deletions(-) rename crates/fj-kernel/src/{builder => partial}/edge.rs (100%) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index f71b4b476..f8e4aa1fb 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -1,17 +1,12 @@ //! API for building objects mod cycle; -mod edge; mod face; mod shell; mod sketch; mod solid; pub use self::{ - cycle::CycleBuilder, - edge::{GlobalEdgeBuilder, HalfEdgeBuilder}, - face::FaceBuilder, - shell::ShellBuilder, - sketch::SketchBuilder, - solid::SolidBuilder, + cycle::CycleBuilder, face::FaceBuilder, shell::ShellBuilder, + sketch::SketchBuilder, solid::SolidBuilder, }; diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index b435d5584..39b91ac18 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -1,7 +1,7 @@ use std::fmt; use crate::{ - builder::{GlobalEdgeBuilder, HalfEdgeBuilder}, + partial::{GlobalEdgeBuilder, HalfEdgeBuilder}, stores::{Handle, Stores}, }; diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/partial/edge.rs similarity index 100% rename from crates/fj-kernel/src/builder/edge.rs rename to crates/fj-kernel/src/partial/edge.rs diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index 6877e5943..829653a80 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -26,10 +26,12 @@ //! convenient API. mod curve; +mod edge; mod vertex; pub use self::{ curve::{PartialCurve, PartialGlobalCurve}, + edge::{GlobalEdgeBuilder, HalfEdgeBuilder}, vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, }; From 12e3453e9ffbfaf8509ae113891ecb08cef10f5f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:45:08 +0200 Subject: [PATCH 02/25] Derive `Default` for `GlobalEdgeBuilder` --- crates/fj-kernel/src/objects/edge.rs | 2 +- crates/fj-kernel/src/partial/edge.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 39b91ac18..209f24df9 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -122,7 +122,7 @@ pub struct GlobalEdge { impl GlobalEdge { /// Build a `GlobalEdge` using [`GlobalEdgeBuilder`] pub fn builder() -> GlobalEdgeBuilder { - GlobalEdgeBuilder + GlobalEdgeBuilder::default() } /// Create a new instance diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index e5262dd70..c4bf66a47 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -180,6 +180,7 @@ impl<'a> HalfEdgeBuilder<'a> { /// API for building a [`GlobalEdge`] /// /// Also see [`GlobalEdge::builder`]. +#[derive(Default)] pub struct GlobalEdgeBuilder; impl GlobalEdgeBuilder { From 238c24c09e53db0180713e52f1157acd5cb914bd Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:49:41 +0200 Subject: [PATCH 03/25] Split `GlobalEdgeBuilder` method --- .../fj-kernel/src/algorithms/validate/mod.rs | 3 +- crates/fj-kernel/src/partial/edge.rs | 46 ++++++++++++++----- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/validate/mod.rs b/crates/fj-kernel/src/algorithms/validate/mod.rs index 20f880c8f..eb622a28f 100644 --- a/crates/fj-kernel/src/algorithms/validate/mod.rs +++ b/crates/fj-kernel/src/algorithms/validate/mod.rs @@ -237,7 +237,8 @@ mod tests { let vertices = [a, b]; let global_edge = GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices); + .from_curve_and_vertices(&curve, &vertices) + .build(&stores); let half_edge = HalfEdge::new(curve, vertices, global_edge); let result = diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index c4bf66a47..d19d7110f 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -6,7 +6,7 @@ use crate::{ SurfaceVertex, Vertex, }, path::{GlobalPath, SurfacePath}, - stores::Stores, + stores::{Handle, Stores}, }; /// API for building a [`HalfEdge`] @@ -170,7 +170,8 @@ impl<'a> HalfEdgeBuilder<'a> { let global_form = self.global_form.unwrap_or_else(|| { GlobalEdge::builder() - .build_from_curve_and_vertices(&curve, &vertices) + .from_curve_and_vertices(&curve, &vertices) + .build(self.stores) }); HalfEdge::new(curve, vertices, global_form) @@ -181,18 +182,41 @@ impl<'a> HalfEdgeBuilder<'a> { /// /// Also see [`GlobalEdge::builder`]. #[derive(Default)] -pub struct GlobalEdgeBuilder; +pub struct GlobalEdgeBuilder { + /// The curve that the [`GlobalEdge`] is defined in + /// + /// Must be provided before [`PartialGlobalEdge::build`] is called. + pub curve: Option>, + + /// The vertices that bound the [`GlobalEdge`] in the curve + /// + /// Must be provided before [`PartialGlobalEdge::build`] is called. + pub vertices: Option<[GlobalVertex; 2]>, +} impl GlobalEdgeBuilder { - /// Build a [`GlobalEdge`] from the provided curve and vertices - pub fn build_from_curve_and_vertices( - self, + /// Update partial global edge from the given curve and vertices + pub fn from_curve_and_vertices( + mut self, curve: &Curve, vertices: &[Vertex; 2], - ) -> GlobalEdge { - GlobalEdge::new( - curve.global_form().clone(), - vertices.clone().map(|vertex| *vertex.global_form()), - ) + ) -> Self { + self.curve = Some(curve.global_form().clone()); + self.vertices = + Some(vertices.clone().map(|vertex| *vertex.global_form())); + + self + } + + /// Build a full [`GlobalEdge`] from the partial global edge + pub fn build(self, _: &Stores) -> GlobalEdge { + let curve = self + .curve + .expect("Can't build `GlobalEdge` without `GlobalCurve`"); + let vertices = self + .vertices + .expect("Can't build `GlobalEdge` without vertices"); + + GlobalEdge::new(curve, vertices) } } From 1b649d4cc06771b1da38f45c5d8546bacf37cae8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:52:07 +0200 Subject: [PATCH 04/25] Rename `GlobalEdgeBuilder` to `PartialGlobalEdge` --- crates/fj-kernel/src/objects/edge.rs | 8 ++++---- crates/fj-kernel/src/partial/edge.rs | 4 ++-- crates/fj-kernel/src/partial/mod.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 209f24df9..c8a6f65b5 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -1,7 +1,7 @@ use std::fmt; use crate::{ - partial::{GlobalEdgeBuilder, HalfEdgeBuilder}, + partial::{HalfEdgeBuilder, PartialGlobalEdge}, stores::{Handle, Stores}, }; @@ -120,9 +120,9 @@ pub struct GlobalEdge { } impl GlobalEdge { - /// Build a `GlobalEdge` using [`GlobalEdgeBuilder`] - pub fn builder() -> GlobalEdgeBuilder { - GlobalEdgeBuilder::default() + /// Build a `GlobalEdge` using [`PartialGlobalEdge`] + pub fn builder() -> PartialGlobalEdge { + PartialGlobalEdge::default() } /// Create a new instance diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index d19d7110f..d242e2617 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -182,7 +182,7 @@ impl<'a> HalfEdgeBuilder<'a> { /// /// Also see [`GlobalEdge::builder`]. #[derive(Default)] -pub struct GlobalEdgeBuilder { +pub struct PartialGlobalEdge { /// The curve that the [`GlobalEdge`] is defined in /// /// Must be provided before [`PartialGlobalEdge::build`] is called. @@ -194,7 +194,7 @@ pub struct GlobalEdgeBuilder { pub vertices: Option<[GlobalVertex; 2]>, } -impl GlobalEdgeBuilder { +impl PartialGlobalEdge { /// Update partial global edge from the given curve and vertices pub fn from_curve_and_vertices( mut self, diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index 829653a80..ee32b0913 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -31,7 +31,7 @@ mod vertex; pub use self::{ curve::{PartialCurve, PartialGlobalCurve}, - edge::{GlobalEdgeBuilder, HalfEdgeBuilder}, + edge::{HalfEdgeBuilder, PartialGlobalEdge}, vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, }; From bbcc1e8f3830b6b205d0b13ce8510578926723ab Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:52:57 +0200 Subject: [PATCH 05/25] Rename `GlobalEdge::builder` --- crates/fj-kernel/src/algorithms/validate/mod.rs | 2 +- crates/fj-kernel/src/objects/edge.rs | 2 +- crates/fj-kernel/src/partial/edge.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/validate/mod.rs b/crates/fj-kernel/src/algorithms/validate/mod.rs index eb622a28f..6966f8683 100644 --- a/crates/fj-kernel/src/algorithms/validate/mod.rs +++ b/crates/fj-kernel/src/algorithms/validate/mod.rs @@ -236,7 +236,7 @@ mod tests { ); let vertices = [a, b]; - let global_edge = GlobalEdge::builder() + let global_edge = GlobalEdge::partial() .from_curve_and_vertices(&curve, &vertices) .build(&stores); let half_edge = HalfEdge::new(curve, vertices, global_edge); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index c8a6f65b5..ee9657f5d 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -121,7 +121,7 @@ pub struct GlobalEdge { impl GlobalEdge { /// Build a `GlobalEdge` using [`PartialGlobalEdge`] - pub fn builder() -> PartialGlobalEdge { + pub fn partial() -> PartialGlobalEdge { PartialGlobalEdge::default() } diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index d242e2617..9344bdc9a 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -169,7 +169,7 @@ impl<'a> HalfEdgeBuilder<'a> { .expect("Can't build `HalfEdge` without vertices"); let global_form = self.global_form.unwrap_or_else(|| { - GlobalEdge::builder() + GlobalEdge::partial() .from_curve_and_vertices(&curve, &vertices) .build(self.stores) }); @@ -180,7 +180,7 @@ impl<'a> HalfEdgeBuilder<'a> { /// API for building a [`GlobalEdge`] /// -/// Also see [`GlobalEdge::builder`]. +/// Also see [`GlobalEdge::partial`]. #[derive(Default)] pub struct PartialGlobalEdge { /// The curve that the [`GlobalEdge`] is defined in From 7db72091e422478b2ed35461dc10b33bf385bfd0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 14:17:20 +0200 Subject: [PATCH 06/25] Derive full set of traits for `PartialGlobalEdge` --- crates/fj-kernel/src/partial/edge.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 9344bdc9a..877052ad9 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -181,7 +181,7 @@ impl<'a> HalfEdgeBuilder<'a> { /// API for building a [`GlobalEdge`] /// /// Also see [`GlobalEdge::partial`]. -#[derive(Default)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialGlobalEdge { /// The curve that the [`GlobalEdge`] is defined in /// From 25d3f12b0a07e9174360dc81306d97f6b4ce8cb9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:59:32 +0200 Subject: [PATCH 07/25] Add conversion to `PartialGlobalEdge` --- crates/fj-kernel/src/partial/edge.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 877052ad9..861c6808f 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -220,3 +220,12 @@ impl PartialGlobalEdge { GlobalEdge::new(curve, vertices) } } + +impl From for PartialGlobalEdge { + fn from(global_edge: GlobalEdge) -> Self { + Self { + curve: Some(global_edge.curve().clone()), + vertices: Some(*global_edge.vertices()), + } + } +} From 07016d2a6bd2e24b4911905ac9d24e412def4576 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:59:53 +0200 Subject: [PATCH 08/25] Integrate `PartialGlobalEdge` into `partial` infra --- crates/fj-kernel/src/partial/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index ee32b0913..6bb8e5389 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -36,7 +36,9 @@ pub use self::{ }; use crate::{ - objects::{Curve, GlobalCurve, GlobalVertex, SurfaceVertex, Vertex}, + objects::{ + Curve, GlobalCurve, GlobalEdge, GlobalVertex, SurfaceVertex, Vertex, + }, stores::{Handle, Stores}, }; @@ -115,6 +117,7 @@ macro_rules! impl_traits { impl_traits!( Curve, PartialCurve; + GlobalEdge, PartialGlobalEdge; GlobalVertex, PartialGlobalVertex; SurfaceVertex, PartialSurfaceVertex; Vertex, PartialVertex; From 5310c1dbb4855148ab74bb0746c1baf6ae30811b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:54:27 +0200 Subject: [PATCH 09/25] Update documentation of `PartialGlobalEdge` --- crates/fj-kernel/src/objects/edge.rs | 5 ++++- crates/fj-kernel/src/partial/edge.rs | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index ee9657f5d..44218cb4c 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -120,7 +120,10 @@ pub struct GlobalEdge { } impl GlobalEdge { - /// Build a `GlobalEdge` using [`PartialGlobalEdge`] + /// Create a [`PartialGlobalEdge`] + /// + /// This function exists just for convenience, and will just return a + /// default [`PartialGlobalEdge`]. pub fn partial() -> PartialGlobalEdge { PartialGlobalEdge::default() } diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 861c6808f..f85c6d032 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -178,9 +178,9 @@ impl<'a> HalfEdgeBuilder<'a> { } } -/// API for building a [`GlobalEdge`] +/// A partial [`GlobalEdge`] /// -/// Also see [`GlobalEdge::partial`]. +/// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialGlobalEdge { /// The curve that the [`GlobalEdge`] is defined in From 14381c06a6556e8a1a73ee7cebed825049960b52 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:57:00 +0200 Subject: [PATCH 10/25] Rename `HalfEdgeBuilder` to `PartialHalfEdge` --- crates/fj-kernel/src/objects/edge.rs | 8 ++++---- crates/fj-kernel/src/partial/edge.rs | 4 ++-- crates/fj-kernel/src/partial/mod.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 44218cb4c..231e9ee47 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -1,7 +1,7 @@ use std::fmt; use crate::{ - partial::{HalfEdgeBuilder, PartialGlobalEdge}, + partial::{PartialGlobalEdge, PartialHalfEdge}, stores::{Handle, Stores}, }; @@ -16,9 +16,9 @@ pub struct HalfEdge { } impl HalfEdge { - /// Build a `HalfEdge` using [`HalfEdgeBuilder`] - pub fn builder(stores: &Stores, surface: Surface) -> HalfEdgeBuilder { - HalfEdgeBuilder { + /// Build a `HalfEdge` using [`PartialHalfEdge`] + pub fn builder(stores: &Stores, surface: Surface) -> PartialHalfEdge { + PartialHalfEdge { stores, surface, curve: None, diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index f85c6d032..15ecfc3c6 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -12,7 +12,7 @@ use crate::{ /// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::builder`]. -pub struct HalfEdgeBuilder<'a> { +pub struct PartialHalfEdge<'a> { /// The stores that the created objects are put in pub stores: &'a Stores, @@ -32,7 +32,7 @@ pub struct HalfEdgeBuilder<'a> { pub global_form: Option, } -impl<'a> HalfEdgeBuilder<'a> { +impl<'a> PartialHalfEdge<'a> { /// Build the [`HalfEdge`] with the given curve pub fn with_curve(mut self, curve: Curve) -> Self { self.curve = Some(curve); diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index 6bb8e5389..ad541da95 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -31,7 +31,7 @@ mod vertex; pub use self::{ curve::{PartialCurve, PartialGlobalCurve}, - edge::{HalfEdgeBuilder, PartialGlobalEdge}, + edge::{PartialGlobalEdge, PartialHalfEdge}, vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, }; From ced8d3776792175879800125e03c628ae2fc923c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 22 Sep 2022 14:58:05 +0200 Subject: [PATCH 11/25] Rename `HalfEdge::builder` to `HalfEdge::partial` --- .../fj-kernel/src/algorithms/intersect/curve_edge.rs | 8 ++++---- crates/fj-kernel/src/algorithms/sweep/edge.rs | 10 +++++----- crates/fj-kernel/src/algorithms/sweep/face.rs | 4 ++-- crates/fj-kernel/src/algorithms/sweep/vertex.rs | 2 +- crates/fj-kernel/src/builder/cycle.rs | 4 ++-- crates/fj-kernel/src/iter.rs | 2 +- crates/fj-kernel/src/objects/edge.rs | 2 +- crates/fj-kernel/src/partial/edge.rs | 2 +- crates/fj-operations/src/sketch.rs | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs index 76cf88a13..4327cc4b8 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs @@ -90,7 +90,7 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::builder(&stores, surface) + let half_edge = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[1., -1.], [1., 1.]]) .build(); @@ -113,7 +113,7 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::builder(&stores, surface) + let half_edge = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[-1., -1.], [-1., 1.]]) .build(); @@ -136,7 +136,7 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::builder(&stores, surface) + let half_edge = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[-1., -1.], [1., -1.]]) .build(); @@ -154,7 +154,7 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::builder(&stores, surface) + let half_edge = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[-1., 0.], [1., 0.]]) .build(); diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index bbb680784..fa7837190 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -191,7 +191,7 @@ mod tests { fn sweep() { let stores = Stores::new(); - let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) + let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) .as_line_segment_from_points([[0., 0.], [1., 0.]]) .build(); @@ -200,18 +200,18 @@ mod tests { let expected_face = { let surface = Surface::xz_plane(); - let bottom = HalfEdge::builder(&stores, surface) + let bottom = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[0., 0.], [1., 0.]]) .build(); - let top = HalfEdge::builder(&stores, surface) + let top = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[0., 1.], [1., 1.]]) .build() .reverse(); - let left = HalfEdge::builder(&stores, surface) + let left = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[0., 0.], [0., 1.]]) .build() .reverse(); - let right = HalfEdge::builder(&stores, surface) + let right = HalfEdge::partial(&stores, surface) .as_line_segment_from_points([[1., 0.], [1., 1.]]) .build(); diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 9872e0466..fa99f0f45 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -112,7 +112,7 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) + let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) .as_line_segment_from_points([a, b]) .build(); (half_edge, Color::default()).sweep(UP, &stores) @@ -148,7 +148,7 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::builder(&stores, Surface::xy_plane()) + let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) .as_line_segment_from_points([a, b]) .build() .reverse(); diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index cb99bd323..0cd69d22c 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -172,7 +172,7 @@ mod tests { let half_edge = (vertex, surface).sweep([0., 0., 1.], &stores); - let expected_half_edge = HalfEdge::builder(&stores, surface) + let expected_half_edge = HalfEdge::partial(&stores, surface) .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 346caef0a..e2e025c86 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -52,7 +52,7 @@ impl<'a> CycleBuilder<'a> { let points = [points[0], points[1]]; self.half_edges.push( - HalfEdge::builder(self.stores, self.surface) + HalfEdge::partial(self.stores, self.surface) .as_line_segment_from_points(points) .build(), ); @@ -74,7 +74,7 @@ impl<'a> CycleBuilder<'a> { let vertices = [last, first].map(|vertex| vertex.surface_form().position()); self.half_edges.push( - HalfEdge::builder(self.stores, self.surface) + HalfEdge::partial(self.stores, self.surface) .as_line_segment_from_points(vertices) .build(), ); diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index aff05ce1c..139d10efd 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -464,7 +464,7 @@ mod tests { fn half_edge() { let stores = Stores::new(); - let object = HalfEdge::builder(&stores, Surface::xy_plane()) + let object = HalfEdge::partial(&stores, Surface::xy_plane()) .as_line_segment_from_points([[0., 0.], [1., 0.]]) .build(); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 231e9ee47..18f7c84a0 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -17,7 +17,7 @@ pub struct HalfEdge { impl HalfEdge { /// Build a `HalfEdge` using [`PartialHalfEdge`] - pub fn builder(stores: &Stores, surface: Surface) -> PartialHalfEdge { + pub fn partial(stores: &Stores, surface: Surface) -> PartialHalfEdge { PartialHalfEdge { stores, surface, diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 15ecfc3c6..c1c0069fa 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -11,7 +11,7 @@ use crate::{ /// API for building a [`HalfEdge`] /// -/// Also see [`HalfEdge::builder`]. +/// Also see [`HalfEdge::partial`]. pub struct PartialHalfEdge<'a> { /// The stores that the created objects are put in pub stores: &'a Stores, diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index eab95e706..10c3e9a0f 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -26,7 +26,7 @@ impl Shape for fj::Sketch { // Circles have just a single round edge with no vertices. So // none need to be added here. - let half_edge = HalfEdge::builder(stores, surface) + let half_edge = HalfEdge::partial(stores, surface) .as_circle_from_radius(circle.radius()) .build(); let cycle = Cycle::new(surface, [half_edge]); From 6c2d6a56e2290872214553e10ee25c6093fc9007 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 11:39:52 +0200 Subject: [PATCH 12/25] Pass `Surface` only into the methods that need it --- .../src/algorithms/intersect/curve_edge.rs | 16 ++++++------- crates/fj-kernel/src/algorithms/sweep/edge.rs | 23 ++++++++++-------- crates/fj-kernel/src/algorithms/sweep/face.rs | 8 +++---- .../fj-kernel/src/algorithms/sweep/vertex.rs | 4 ++-- crates/fj-kernel/src/builder/cycle.rs | 8 +++---- crates/fj-kernel/src/iter.rs | 7 ++++-- crates/fj-kernel/src/objects/edge.rs | 5 ++-- crates/fj-kernel/src/partial/edge.rs | 24 +++++++++---------- crates/fj-operations/src/sketch.rs | 4 ++-- 9 files changed, 51 insertions(+), 48 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs index 4327cc4b8..c54acced6 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs @@ -90,8 +90,8 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[1., -1.], [1., 1.]]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[1., -1.], [1., 1.]]) .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -113,8 +113,8 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[-1., -1.], [-1., 1.]]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[-1., -1.], [-1., 1.]]) .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -136,8 +136,8 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[-1., -1.], [1., -1.]]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[-1., -1.], [1., -1.]]) .build(); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -154,8 +154,8 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[-1., 0.], [1., 0.]]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[-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 fa7837190..941702380 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -191,8 +191,11 @@ mod tests { fn sweep() { let stores = Stores::new(); - let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) - .as_line_segment_from_points([[0., 0.], [1., 0.]]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points( + Surface::xy_plane(), + [[0., 0.], [1., 0.]], + ) .build(); let face = (half_edge, Color::default()).sweep([0., 0., 1.], &stores); @@ -200,19 +203,19 @@ mod tests { let expected_face = { let surface = Surface::xz_plane(); - let bottom = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[0., 0.], [1., 0.]]) + let bottom = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[0., 0.], [1., 0.]]) .build(); - let top = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[0., 1.], [1., 1.]]) + let top = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[0., 1.], [1., 1.]]) .build() .reverse(); - let left = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[0., 0.], [0., 1.]]) + let left = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[0., 0.], [0., 1.]]) .build() .reverse(); - let right = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[1., 0.], [1., 1.]]) + let right = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[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 fa99f0f45..92af6d5fd 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -112,8 +112,8 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) - .as_line_segment_from_points([a, b]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(Surface::xy_plane(), [a, b]) .build(); (half_edge, Color::default()).sweep(UP, &stores) }); @@ -148,8 +148,8 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::partial(&stores, Surface::xy_plane()) - .as_line_segment_from_points([a, b]) + let half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(Surface::xy_plane(), [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 0cd69d22c..2403e29d6 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -172,8 +172,8 @@ mod tests { let half_edge = (vertex, surface).sweep([0., 0., 1.], &stores); - let expected_half_edge = HalfEdge::partial(&stores, surface) - .as_line_segment_from_points([[0., 0.], [0., 1.]]) + let expected_half_edge = HalfEdge::partial(&stores) + .as_line_segment_from_points(surface, [[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 e2e025c86..33342b3e3 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -52,8 +52,8 @@ impl<'a> CycleBuilder<'a> { let points = [points[0], points[1]]; self.half_edges.push( - HalfEdge::partial(self.stores, self.surface) - .as_line_segment_from_points(points) + HalfEdge::partial(self.stores) + .as_line_segment_from_points(self.surface, points) .build(), ); } @@ -74,8 +74,8 @@ impl<'a> CycleBuilder<'a> { let vertices = [last, first].map(|vertex| vertex.surface_form().position()); self.half_edges.push( - HalfEdge::partial(self.stores, self.surface) - .as_line_segment_from_points(vertices) + HalfEdge::partial(self.stores) + .as_line_segment_from_points(self.surface, vertices) .build(), ); } diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 139d10efd..5c8489d16 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -464,8 +464,11 @@ mod tests { fn half_edge() { let stores = Stores::new(); - let object = HalfEdge::partial(&stores, Surface::xy_plane()) - .as_line_segment_from_points([[0., 0.], [1., 0.]]) + let object = HalfEdge::partial(&stores) + .as_line_segment_from_points( + Surface::xy_plane(), + [[0., 0.], [1., 0.]], + ) .build(); assert_eq!(1, object.curve_iter().count()); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 18f7c84a0..d9bc20561 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -5,7 +5,7 @@ use crate::{ stores::{Handle, Stores}, }; -use super::{Curve, GlobalCurve, GlobalVertex, Surface, Vertex}; +use super::{Curve, GlobalCurve, GlobalVertex, Vertex}; /// A half-edge #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] @@ -17,10 +17,9 @@ pub struct HalfEdge { impl HalfEdge { /// Build a `HalfEdge` using [`PartialHalfEdge`] - pub fn partial(stores: &Stores, surface: Surface) -> PartialHalfEdge { + pub fn partial(stores: &Stores) -> PartialHalfEdge { PartialHalfEdge { stores, - surface, curve: None, vertices: None, global_form: None, diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index c1c0069fa..92592e9df 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -16,9 +16,6 @@ pub struct PartialHalfEdge<'a> { /// The stores that the created objects are put in pub stores: &'a Stores, - /// The surface that the [`HalfEdge`]'s [`Curve`] is defined in - pub surface: Surface, - /// The curve that the [`HalfEdge`] is defined in pub curve: Option, @@ -52,9 +49,13 @@ impl<'a> PartialHalfEdge<'a> { } /// Build the [`HalfEdge`] as a circle from the given radius - pub fn as_circle_from_radius(mut self, radius: impl Into) -> Self { + pub fn as_circle_from_radius( + mut self, + surface: Surface, + radius: impl Into, + ) -> Self { let curve = Curve::partial() - .with_surface(self.surface) + .with_surface(surface) .as_circle_from_radius(radius) .build(self.stores); @@ -69,7 +70,7 @@ impl<'a> PartialHalfEdge<'a> { let surface_vertices = [a_curve, b_curve].map(|point_curve| { let point_surface = curve.path().point_from_path_coords(point_curve); - SurfaceVertex::new(point_surface, self.surface, global_vertex) + SurfaceVertex::new(point_surface, surface, global_vertex) }); // Can be cleaned up, once `zip` is stable: @@ -96,13 +97,14 @@ impl<'a> PartialHalfEdge<'a> { /// Build the [`HalfEdge`] as a line segment from the given points pub fn as_line_segment_from_points( mut self, + surface: Surface, points: [impl Into>; 2], ) -> Self { let points = points.map(Into::into); let global_vertices = points.map(|position| { GlobalVertex::partial() - .from_surface_and_position(&self.surface, position) + .from_surface_and_position(&surface, position) .build(self.stores) }); @@ -113,11 +115,7 @@ impl<'a> PartialHalfEdge<'a> { let [a_global, b_global] = global_vertices; [(a_surface, a_global), (b_surface, b_global)].map( |(point_surface, vertex_global)| { - SurfaceVertex::new( - point_surface, - self.surface, - vertex_global, - ) + SurfaceVertex::new(point_surface, surface, vertex_global) }, ) }; @@ -132,7 +130,7 @@ impl<'a> PartialHalfEdge<'a> { )) }; - Curve::new(self.surface, path, global_form) + Curve::new(surface, path, global_form) }; let vertices = { diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 10c3e9a0f..c0c65b3c2 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -26,8 +26,8 @@ impl Shape for fj::Sketch { // Circles have just a single round edge with no vertices. So // none need to be added here. - let half_edge = HalfEdge::partial(stores, surface) - .as_circle_from_radius(circle.radius()) + let half_edge = HalfEdge::partial(stores) + .as_circle_from_radius(surface, circle.radius()) .build(); let cycle = Cycle::new(surface, [half_edge]); From a3425282ed05ee0ba46ff84fa85d35bee1ba7e6a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 14:01:56 +0200 Subject: [PATCH 13/25] Make vertices settable separately --- crates/fj-kernel/src/objects/edge.rs | 2 +- crates/fj-kernel/src/partial/edge.rs | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index d9bc20561..a314ba8b5 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -21,7 +21,7 @@ impl HalfEdge { PartialHalfEdge { stores, curve: None, - vertices: None, + vertices: [None, None], global_form: None, } } diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 92592e9df..ecc2d03ef 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -20,7 +20,7 @@ pub struct PartialHalfEdge<'a> { pub curve: Option, /// The vertices that bound this [`HalfEdge`] in the [`Curve`] - pub vertices: Option<[Vertex; 2]>, + pub vertices: [Option; 2], /// The global form of the [`HalfEdge`] /// @@ -38,7 +38,19 @@ impl<'a> PartialHalfEdge<'a> { /// Build the [`HalfEdge`] with the given vertices pub fn with_vertices(mut self, vertices: [Vertex; 2]) -> Self { - self.vertices = Some(vertices); + self.vertices = vertices.map(Some); + self + } + + /// Update the partial half-edge, starting it from the given vertex + pub fn with_from_vertex(mut self, vertex: Vertex) -> Self { + self.vertices[0] = Some(vertex); + self + } + + /// Update the partial half-edge with the given end vertex + pub fn with_to_vertex(mut self, vertex: Vertex) -> Self { + self.vertices[1] = Some(vertex); self } @@ -89,7 +101,7 @@ impl<'a> PartialHalfEdge<'a> { }; self.curve = Some(curve); - self.vertices = Some(vertices); + self.vertices = vertices.map(Some); self } @@ -154,7 +166,7 @@ impl<'a> PartialHalfEdge<'a> { }; self.curve = Some(curve); - self.vertices = Some(vertices); + self.vertices = vertices.map(Some); self } @@ -162,9 +174,9 @@ impl<'a> PartialHalfEdge<'a> { /// 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 vertices = self.vertices.map(|vertex| { + vertex.expect("Can't build `HalfEdge` without vertices") + }); let global_form = self.global_form.unwrap_or_else(|| { GlobalEdge::partial() From 73bdcdb262078f226c512e91c670e16441b53202 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 17:41:08 +0200 Subject: [PATCH 14/25] Don't create duplicate vertices in `CycleBuilder` This fixes a bug that is hidden currently, but would have been uncovered by one of the following commits. --- crates/fj-kernel/src/builder/cycle.rs | 66 +++++++++++++++++++++------ 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 33342b3e3..8e152822e 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -1,7 +1,7 @@ use fj_math::Point; use crate::{ - objects::{Cycle, HalfEdge, Surface}, + objects::{Curve, Cycle, HalfEdge, Surface, SurfaceVertex, Vertex}, stores::Stores, }; @@ -34,28 +34,64 @@ impl<'a> CycleBuilder<'a> { mut self, points: impl IntoIterator>>, ) -> Self { - let points = self + let iter = self .half_edges .last() .map(|half_edge| { let [_, last] = half_edge.vertices(); - last.surface_form().position() + + let vertex = *last.surface_form(); + let position = last.surface_form().position(); + + (position, Some(vertex)) }) .into_iter() - .chain(points.into_iter().map(Into::into)) - .collect::>(); + .chain(points.into_iter().map(|point| (point.into(), None))); - for points in points.windows(2) { - // Can't panic, as we passed `2` to `windows`. - // - // Can be cleaned up, once `array_windows` is stable. - let points = [points[0], points[1]]; + let mut previous: Option<(Point<2>, Option)> = None; - self.half_edges.push( - HalfEdge::partial(self.stores) - .as_line_segment_from_points(self.surface, points) - .build(), - ); + for (position, vertex) in iter { + if let Some((previous_position, previous_vertex)) = previous { + let from = previous_vertex.unwrap_or_else(|| { + SurfaceVertex::partial() + .with_surface(self.surface) + .with_position(previous_position) + .build(self.stores) + }); + let to = vertex.unwrap_or_else(|| { + SurfaceVertex::partial() + .with_surface(self.surface) + .with_position(position) + .build(self.stores) + }); + + previous = Some((position, Some(to))); + + let curve = Curve::partial() + .with_surface(self.surface) + .as_line_from_points([previous_position, position]) + .build(self.stores); + + let [from, to] = + [(0., from), (1., to)].map(|(position, surface_form)| { + Vertex::partial() + .with_curve(curve.clone()) + .with_position([position]) + .with_surface_form(surface_form) + .build(self.stores) + }); + + self.half_edges.push( + HalfEdge::partial(self.stores) + .with_curve(curve) + .with_vertices([from, to]) + .build(), + ); + + continue; + } + + previous = Some((position, vertex)); } self From 8a9952d4aaa2f6d1deeb09edc9c9edb41ea01728 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 14:22:43 +0200 Subject: [PATCH 15/25] Simplify `PartialHalfEdge::as_circle_from_radius` --- crates/fj-kernel/src/partial/edge.rs | 31 ++++++++-------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index ecc2d03ef..08779c6a9 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -76,28 +76,15 @@ impl<'a> PartialHalfEdge<'a> { [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); let global_vertex = GlobalVertex::partial() - .from_curve_and_position(curve.clone(), a_curve) - .build(self.stores); - - let surface_vertices = [a_curve, b_curve].map(|point_curve| { - let point_surface = - curve.path().point_from_path_coords(point_curve); - SurfaceVertex::new(point_surface, surface, global_vertex) - }); - - // Can be cleaned up, once `zip` is stable: - // https://doc.rust-lang.org/std/primitive.array.html#method.zip - let [a_surface, b_surface] = surface_vertices; - [(a_curve, a_surface), (b_curve, b_surface)].map( - |(point_curve, surface_vertex)| { - Vertex::new( - point_curve, - curve.clone(), - surface_vertex, - global_vertex, - ) - }, - ) + .from_curve_and_position(curve.clone(), a_curve); + + [a_curve, b_curve].map(|point_curve| { + Vertex::partial() + .with_position(point_curve) + .with_curve(curve.clone()) + .with_global_form(global_vertex.clone()) + .build(self.stores) + }) }; self.curve = Some(curve); From 10c1807e0259be335adb5af57ab5e05ae633bd3e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:39:00 +0200 Subject: [PATCH 16/25] Consolidate redundant code --- crates/fj-kernel/src/partial/edge.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 08779c6a9..049afa3d3 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -133,23 +133,20 @@ impl<'a> PartialHalfEdge<'a> { }; let vertices = { + // Can be cleaned up, once `zip` is stable: + // https://doc.rust-lang.org/std/primitive.array.html#method.zip let [a_global, b_global] = global_vertices; let [a_surface, b_surface] = surface_vertices; - - [ - Vertex::new( - Point::from([0.]), - curve.clone(), - a_surface, - a_global, - ), - Vertex::new( - Point::from([1.]), - curve.clone(), - b_surface, - b_global, - ), - ] + [(0., a_surface, a_global), (1., b_surface, b_global)].map( + |(position, surface_form, global_form)| { + Vertex::new( + [position], + curve.clone(), + surface_form, + global_form, + ) + }, + ) }; self.curve = Some(curve); From a2aba5ef1241feaba64ac85940aec3a18ef811ee Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:39:49 +0200 Subject: [PATCH 17/25] Simplify `PartialHalfEdge` method --- crates/fj-kernel/src/partial/edge.rs | 60 +++++----------------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 049afa3d3..169e29f75 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -1,11 +1,9 @@ -use fj_math::{Line, Point, Scalar}; +use fj_math::{Point, Scalar}; use crate::{ objects::{ - Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface, - SurfaceVertex, Vertex, + Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface, Vertex, }, - path::{GlobalPath, SurfacePath}, stores::{Handle, Stores}, }; @@ -99,56 +97,18 @@ impl<'a> PartialHalfEdge<'a> { surface: Surface, points: [impl Into>; 2], ) -> Self { - let points = points.map(Into::into); + let curve = Curve::partial() + .with_surface(surface) + .as_line_from_points(points) + .build(self.stores); - let global_vertices = points.map(|position| { - GlobalVertex::partial() - .from_surface_and_position(&surface, position) + let vertices = [0., 1.].map(|position| { + Vertex::partial() + .with_position([position]) + .with_curve(curve.clone()) .build(self.stores) }); - let surface_vertices = { - // Can be cleaned up, once `zip` is stable: - // https://doc.rust-lang.org/std/primitive.array.html#method.zip - let [a_surface, b_surface] = points; - let [a_global, b_global] = global_vertices; - [(a_surface, a_global), (b_surface, b_global)].map( - |(point_surface, vertex_global)| { - SurfaceVertex::new(point_surface, surface, vertex_global) - }, - ) - }; - - let curve = { - let path = SurfacePath::Line(Line::from_points(points)); - let global_form = { - let points = global_vertices - .map(|global_vertex| global_vertex.position()); - self.stores.global_curves.insert(GlobalCurve::from_path( - GlobalPath::Line(Line::from_points(points)), - )) - }; - - Curve::new(surface, path, global_form) - }; - - let vertices = { - // Can be cleaned up, once `zip` is stable: - // https://doc.rust-lang.org/std/primitive.array.html#method.zip - let [a_global, b_global] = global_vertices; - let [a_surface, b_surface] = surface_vertices; - [(0., a_surface, a_global), (1., b_surface, b_global)].map( - |(position, surface_form, global_form)| { - Vertex::new( - [position], - curve.clone(), - surface_form, - global_form, - ) - }, - ) - }; - self.curve = Some(curve); self.vertices = vertices.map(Some); From 5ac6767e9f92446dd0eb301da7d06cdc1d7e0788 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 14:54:07 +0200 Subject: [PATCH 18/25] Make `PartialHalfEdge`'s `vertices` more flexible --- crates/fj-kernel/src/partial/edge.rs | 35 ++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 169e29f75..bc372494f 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -7,6 +7,8 @@ use crate::{ stores::{Handle, Stores}, }; +use super::MaybePartial; + /// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::partial`]. @@ -18,7 +20,7 @@ pub struct PartialHalfEdge<'a> { pub curve: Option, /// The vertices that bound this [`HalfEdge`] in the [`Curve`] - pub vertices: [Option; 2], + pub vertices: [Option>; 2], /// The global form of the [`HalfEdge`] /// @@ -35,20 +37,29 @@ impl<'a> PartialHalfEdge<'a> { } /// Build the [`HalfEdge`] with the given vertices - pub fn with_vertices(mut self, vertices: [Vertex; 2]) -> Self { - self.vertices = vertices.map(Some); + pub fn with_vertices( + mut self, + vertices: [impl Into>; 2], + ) -> Self { + self.vertices = vertices.map(Into::into).map(Some); self } /// Update the partial half-edge, starting it from the given vertex - pub fn with_from_vertex(mut self, vertex: Vertex) -> Self { - self.vertices[0] = Some(vertex); + pub fn with_from_vertex( + mut self, + vertex: impl Into>, + ) -> Self { + self.vertices[0] = Some(vertex.into()); self } /// Update the partial half-edge with the given end vertex - pub fn with_to_vertex(mut self, vertex: Vertex) -> Self { - self.vertices[1] = Some(vertex); + pub fn with_to_vertex( + mut self, + vertex: impl Into>, + ) -> Self { + self.vertices[1] = Some(vertex.into()); self } @@ -81,12 +92,11 @@ impl<'a> PartialHalfEdge<'a> { .with_position(point_curve) .with_curve(curve.clone()) .with_global_form(global_vertex.clone()) - .build(self.stores) }) }; self.curve = Some(curve); - self.vertices = vertices.map(Some); + self.vertices = vertices.map(Into::into).map(Some); self } @@ -106,11 +116,10 @@ impl<'a> PartialHalfEdge<'a> { Vertex::partial() .with_position([position]) .with_curve(curve.clone()) - .build(self.stores) }); self.curve = Some(curve); - self.vertices = vertices.map(Some); + self.vertices = vertices.map(Into::into).map(Some); self } @@ -119,7 +128,9 @@ impl<'a> PartialHalfEdge<'a> { pub fn build(self) -> HalfEdge { let curve = self.curve.expect("Can't build `HalfEdge` without curve"); let vertices = self.vertices.map(|vertex| { - vertex.expect("Can't build `HalfEdge` without vertices") + vertex + .expect("Can't build `HalfEdge` without vertices") + .into_full(self.stores) }); let global_form = self.global_form.unwrap_or_else(|| { From 0481a4d41a4091f114f5243e7104f491c8242319 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:00:43 +0200 Subject: [PATCH 19/25] Make `PartialHalfEdge`'s `curve` more flexible --- crates/fj-kernel/src/partial/edge.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index bc372494f..8db220eec 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -17,7 +17,7 @@ pub struct PartialHalfEdge<'a> { pub stores: &'a Stores, /// The curve that the [`HalfEdge`] is defined in - pub curve: Option, + pub curve: Option>, /// The vertices that bound this [`HalfEdge`] in the [`Curve`] pub vertices: [Option>; 2], @@ -31,8 +31,8 @@ pub struct PartialHalfEdge<'a> { impl<'a> PartialHalfEdge<'a> { /// Build the [`HalfEdge`] with the given curve - pub fn with_curve(mut self, curve: Curve) -> Self { - self.curve = Some(curve); + pub fn with_curve(mut self, curve: impl Into>) -> Self { + self.curve = Some(curve.into()); self } @@ -77,8 +77,7 @@ impl<'a> PartialHalfEdge<'a> { ) -> Self { let curve = Curve::partial() .with_surface(surface) - .as_circle_from_radius(radius) - .build(self.stores); + .as_circle_from_radius(radius); let vertices = { let [a_curve, b_curve] = @@ -95,7 +94,7 @@ impl<'a> PartialHalfEdge<'a> { }) }; - self.curve = Some(curve); + self.curve = Some(curve.into()); self.vertices = vertices.map(Into::into).map(Some); self @@ -109,8 +108,7 @@ impl<'a> PartialHalfEdge<'a> { ) -> Self { let curve = Curve::partial() .with_surface(surface) - .as_line_from_points(points) - .build(self.stores); + .as_line_from_points(points); let vertices = [0., 1.].map(|position| { Vertex::partial() @@ -118,7 +116,7 @@ impl<'a> PartialHalfEdge<'a> { .with_curve(curve.clone()) }); - self.curve = Some(curve); + self.curve = Some(curve.into()); self.vertices = vertices.map(Into::into).map(Some); self @@ -126,7 +124,10 @@ impl<'a> PartialHalfEdge<'a> { /// Finish building the [`HalfEdge`] pub fn build(self) -> HalfEdge { - let curve = self.curve.expect("Can't build `HalfEdge` without curve"); + let curve = self + .curve + .expect("Can't build `HalfEdge` without curve") + .into_full(self.stores); let vertices = self.vertices.map(|vertex| { vertex .expect("Can't build `HalfEdge` without vertices") From 38d41c6ba11bfa9c338d8cb858a91ce923a15219 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 15:52:28 +0200 Subject: [PATCH 20/25] Pass `&Stores` into `PartialHalfEdge::build` --- .../src/algorithms/intersect/curve_edge.rs | 16 +++++++-------- crates/fj-kernel/src/algorithms/sweep/edge.rs | 20 +++++++++---------- crates/fj-kernel/src/algorithms/sweep/face.rs | 8 ++++---- .../fj-kernel/src/algorithms/sweep/vertex.rs | 4 ++-- crates/fj-kernel/src/builder/cycle.rs | 8 ++++---- crates/fj-kernel/src/iter.rs | 4 ++-- crates/fj-kernel/src/objects/edge.rs | 5 ++--- crates/fj-kernel/src/partial/edge.rs | 15 ++++++-------- crates/fj-operations/src/sketch.rs | 4 ++-- 9 files changed, 40 insertions(+), 44 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs index c54acced6..a8c6e99f3 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs @@ -90,9 +90,9 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(surface, [[1., -1.], [1., 1.]]) - .build(); + .build(&stores); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -113,9 +113,9 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(surface, [[-1., -1.], [-1., 1.]]) - .build(); + .build(&stores); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -136,9 +136,9 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(surface, [[-1., -1.], [1., -1.]]) - .build(); + .build(&stores); let intersection = CurveEdgeIntersection::compute(&curve, &half_edge); @@ -154,9 +154,9 @@ mod tests { .with_surface(surface) .as_u_axis() .build(&stores); - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(surface, [[-1., 0.], [1., 0.]]) - .build(); + .build(&stores); 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 941702380..420883466 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -191,32 +191,32 @@ mod tests { fn sweep() { let stores = Stores::new(); - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points( Surface::xy_plane(), [[0., 0.], [1., 0.]], ) - .build(); + .build(&stores); let face = (half_edge, Color::default()).sweep([0., 0., 1.], &stores); let expected_face = { let surface = Surface::xz_plane(); - let bottom = HalfEdge::partial(&stores) + let bottom = HalfEdge::partial() .as_line_segment_from_points(surface, [[0., 0.], [1., 0.]]) - .build(); - let top = HalfEdge::partial(&stores) + .build(&stores); + let top = HalfEdge::partial() .as_line_segment_from_points(surface, [[0., 1.], [1., 1.]]) - .build() + .build(&stores) .reverse(); - let left = HalfEdge::partial(&stores) + let left = HalfEdge::partial() .as_line_segment_from_points(surface, [[0., 0.], [0., 1.]]) - .build() + .build(&stores) .reverse(); - let right = HalfEdge::partial(&stores) + let right = HalfEdge::partial() .as_line_segment_from_points(surface, [[1., 0.], [1., 1.]]) - .build(); + .build(&stores); 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 92af6d5fd..68a9300c5 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -112,9 +112,9 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(Surface::xy_plane(), [a, b]) - .build(); + .build(&stores); (half_edge, Color::default()).sweep(UP, &stores) }); @@ -148,9 +148,9 @@ mod tests { // https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows let [a, b] = [window[0], window[1]]; - let half_edge = HalfEdge::partial(&stores) + let half_edge = HalfEdge::partial() .as_line_segment_from_points(Surface::xy_plane(), [a, b]) - .build() + .build(&stores) .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 2403e29d6..81b12cc8d 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -172,9 +172,9 @@ mod tests { let half_edge = (vertex, surface).sweep([0., 0., 1.], &stores); - let expected_half_edge = HalfEdge::partial(&stores) + let expected_half_edge = HalfEdge::partial() .as_line_segment_from_points(surface, [[0., 0.], [0., 1.]]) - .build(); + .build(&stores); 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 8e152822e..d3e3a95c6 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -82,10 +82,10 @@ impl<'a> CycleBuilder<'a> { }); self.half_edges.push( - HalfEdge::partial(self.stores) + HalfEdge::partial() .with_curve(curve) .with_vertices([from, to]) - .build(), + .build(self.stores), ); continue; @@ -110,9 +110,9 @@ impl<'a> CycleBuilder<'a> { let vertices = [last, first].map(|vertex| vertex.surface_form().position()); self.half_edges.push( - HalfEdge::partial(self.stores) + HalfEdge::partial() .as_line_segment_from_points(self.surface, vertices) - .build(), + .build(self.stores), ); } diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 5c8489d16..3a23b9bd2 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -464,12 +464,12 @@ mod tests { fn half_edge() { let stores = Stores::new(); - let object = HalfEdge::partial(&stores) + let object = HalfEdge::partial() .as_line_segment_from_points( Surface::xy_plane(), [[0., 0.], [1., 0.]], ) - .build(); + .build(&stores); assert_eq!(1, object.curve_iter().count()); assert_eq!(0, object.cycle_iter().count()); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index a314ba8b5..503775b05 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -2,7 +2,7 @@ use std::fmt; use crate::{ partial::{PartialGlobalEdge, PartialHalfEdge}, - stores::{Handle, Stores}, + stores::Handle, }; use super::{Curve, GlobalCurve, GlobalVertex, Vertex}; @@ -17,9 +17,8 @@ pub struct HalfEdge { impl HalfEdge { /// Build a `HalfEdge` using [`PartialHalfEdge`] - pub fn partial(stores: &Stores) -> PartialHalfEdge { + pub fn partial() -> PartialHalfEdge { PartialHalfEdge { - stores, curve: None, vertices: [None, None], global_form: None, diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 8db220eec..ee05786d5 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -12,10 +12,7 @@ use super::MaybePartial; /// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::partial`]. -pub struct PartialHalfEdge<'a> { - /// The stores that the created objects are put in - pub stores: &'a Stores, - +pub struct PartialHalfEdge { /// The curve that the [`HalfEdge`] is defined in pub curve: Option>, @@ -29,7 +26,7 @@ pub struct PartialHalfEdge<'a> { pub global_form: Option, } -impl<'a> PartialHalfEdge<'a> { +impl PartialHalfEdge { /// Build the [`HalfEdge`] with the given curve pub fn with_curve(mut self, curve: impl Into>) -> Self { self.curve = Some(curve.into()); @@ -123,21 +120,21 @@ impl<'a> PartialHalfEdge<'a> { } /// Finish building the [`HalfEdge`] - pub fn build(self) -> HalfEdge { + pub fn build(self, stores: &Stores) -> HalfEdge { let curve = self .curve .expect("Can't build `HalfEdge` without curve") - .into_full(self.stores); + .into_full(stores); let vertices = self.vertices.map(|vertex| { vertex .expect("Can't build `HalfEdge` without vertices") - .into_full(self.stores) + .into_full(stores) }); let global_form = self.global_form.unwrap_or_else(|| { GlobalEdge::partial() .from_curve_and_vertices(&curve, &vertices) - .build(self.stores) + .build(stores) }); HalfEdge::new(curve, vertices, global_form) diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index c0c65b3c2..1c174367a 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -26,9 +26,9 @@ impl Shape for fj::Sketch { // Circles have just a single round edge with no vertices. So // none need to be added here. - let half_edge = HalfEdge::partial(stores) + let half_edge = HalfEdge::partial() .as_circle_from_radius(surface, circle.radius()) - .build(); + .build(stores); let cycle = Cycle::new(surface, [half_edge]); Face::from_exterior(cycle).with_color(Color(self.color())) From 5c47e5d0123bed8da3932ad02ec55076569ec55c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 16:05:49 +0200 Subject: [PATCH 21/25] Derive `Default` for `PartialHalfEdge` --- crates/fj-kernel/src/objects/edge.rs | 6 +----- crates/fj-kernel/src/partial/edge.rs | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 503775b05..a61910f90 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -18,11 +18,7 @@ pub struct HalfEdge { impl HalfEdge { /// Build a `HalfEdge` using [`PartialHalfEdge`] pub fn partial() -> PartialHalfEdge { - PartialHalfEdge { - curve: None, - vertices: [None, None], - global_form: None, - } + PartialHalfEdge::default() } /// Create a new instance of `HalfEdge` diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index ee05786d5..0b56e9bf0 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -12,6 +12,7 @@ use super::MaybePartial; /// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::partial`]. +#[derive(Default)] pub struct PartialHalfEdge { /// The curve that the [`HalfEdge`] is defined in pub curve: Option>, From 1b0badb4d7679f6ff7581c04f9066d2ee1a324f6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 16:06:41 +0200 Subject: [PATCH 22/25] Derive full set of traits for `PartialHalfEdge` --- crates/fj-kernel/src/partial/edge.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 0b56e9bf0..faca1fc69 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -12,7 +12,7 @@ use super::MaybePartial; /// API for building a [`HalfEdge`] /// /// Also see [`HalfEdge::partial`]. -#[derive(Default)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialHalfEdge { /// The curve that the [`HalfEdge`] is defined in pub curve: Option>, From fcb9c6339bfb9110ffd0aeb896bf79f8dc64a9af Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 16:09:04 +0200 Subject: [PATCH 23/25] Implement conversion to `PartialHalfEdge` --- crates/fj-kernel/src/partial/edge.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index faca1fc69..52115272d 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -142,6 +142,16 @@ impl PartialHalfEdge { } } +impl From for PartialHalfEdge { + fn from(half_edge: HalfEdge) -> Self { + Self { + curve: Some(half_edge.curve().clone().into()), + vertices: half_edge.vertices().clone().map(Into::into).map(Some), + global_form: Some(half_edge.global_form().clone()), + } + } +} + /// A partial [`GlobalEdge`] /// /// See [`crate::partial`] for more information. From 42c12fac38475215c1f5535b2c0f6e36f5b6a84b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 16:10:23 +0200 Subject: [PATCH 24/25] Integrate `PartialHalfEdge` into `partial` infra --- crates/fj-kernel/src/partial/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index ad541da95..6b8fca4fb 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -37,7 +37,8 @@ pub use self::{ use crate::{ objects::{ - Curve, GlobalCurve, GlobalEdge, GlobalVertex, SurfaceVertex, Vertex, + Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, SurfaceVertex, + Vertex, }, stores::{Handle, Stores}, }; @@ -119,6 +120,7 @@ impl_traits!( Curve, PartialCurve; GlobalEdge, PartialGlobalEdge; GlobalVertex, PartialGlobalVertex; + HalfEdge, PartialHalfEdge; SurfaceVertex, PartialSurfaceVertex; Vertex, PartialVertex; From 7270df94e8d8c3c595989f12580987ff58eebaa1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 23 Sep 2022 16:14:26 +0200 Subject: [PATCH 25/25] Update documentation of `PartialHalfEdge` --- crates/fj-kernel/src/objects/edge.rs | 5 ++++- crates/fj-kernel/src/partial/edge.rs | 19 +++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index a61910f90..06ca67168 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -16,7 +16,10 @@ pub struct HalfEdge { } impl HalfEdge { - /// Build a `HalfEdge` using [`PartialHalfEdge`] + /// Create a [`PartialHalfEdge`] + /// + /// This function exists just for convenience, and will just return a + /// default [`PartialHalfEdge`]. pub fn partial() -> PartialHalfEdge { PartialHalfEdge::default() } diff --git a/crates/fj-kernel/src/partial/edge.rs b/crates/fj-kernel/src/partial/edge.rs index 52115272d..aefe4865e 100644 --- a/crates/fj-kernel/src/partial/edge.rs +++ b/crates/fj-kernel/src/partial/edge.rs @@ -9,9 +9,9 @@ use crate::{ use super::MaybePartial; -/// API for building a [`HalfEdge`] +/// A partial [`HalfEdge`] /// -/// Also see [`HalfEdge::partial`]. +/// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialHalfEdge { /// The curve that the [`HalfEdge`] is defined in @@ -22,19 +22,18 @@ pub struct PartialHalfEdge { /// The global form of the [`HalfEdge`] /// - /// Can be provided to the builder, if available, or computed by one of the - /// build methods. + /// Can be computed by [`PartialHalfEdge::build`], if not available. pub global_form: Option, } impl PartialHalfEdge { - /// Build the [`HalfEdge`] with the given curve + /// Update the partial half-edge with the given curve pub fn with_curve(mut self, curve: impl Into>) -> Self { self.curve = Some(curve.into()); self } - /// Build the [`HalfEdge`] with the given vertices + /// Update the partial half-edge with the given vertices pub fn with_vertices( mut self, vertices: [impl Into>; 2], @@ -61,13 +60,13 @@ impl PartialHalfEdge { self } - /// Build the [`HalfEdge`] with the provided global form + /// Update the partial half-edge with the given global form pub fn with_global_form(mut self, global_form: GlobalEdge) -> Self { self.global_form = Some(global_form); self } - /// Build the [`HalfEdge`] as a circle from the given radius + /// Update partial half-edge as a circle, from the given radius pub fn as_circle_from_radius( mut self, surface: Surface, @@ -98,7 +97,7 @@ impl PartialHalfEdge { self } - /// Build the [`HalfEdge`] as a line segment from the given points + /// Update partial half-edge as a line segment, from the given points pub fn as_line_segment_from_points( mut self, surface: Surface, @@ -120,7 +119,7 @@ impl PartialHalfEdge { self } - /// Finish building the [`HalfEdge`] + /// Build a full [`HalfEdge`] from the partial half-edge pub fn build(self, stores: &Stores) -> HalfEdge { let curve = self .curve