From 56b26bcf0bc426c6c894d870aac5fc12aeb5dc6c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 12:44:05 +0200 Subject: [PATCH 01/18] Move `CycleBuilder` to `partial::objects` --- crates/fj-kernel/src/builder/mod.rs | 5 ++--- crates/fj-kernel/src/objects/cycle.rs | 2 +- crates/fj-kernel/src/partial/mod.rs | 1 + crates/fj-kernel/src/{builder => partial/objects}/cycle.rs | 0 crates/fj-kernel/src/partial/objects/mod.rs | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) rename crates/fj-kernel/src/{builder => partial/objects}/cycle.rs (100%) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index f8e4aa1fb..70b8e6fcf 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -1,12 +1,11 @@ //! API for building objects -mod cycle; mod face; mod shell; mod sketch; mod solid; pub use self::{ - cycle::CycleBuilder, face::FaceBuilder, shell::ShellBuilder, - sketch::SketchBuilder, solid::SolidBuilder, + face::FaceBuilder, shell::ShellBuilder, sketch::SketchBuilder, + solid::SolidBuilder, }; diff --git a/crates/fj-kernel/src/objects/cycle.rs b/crates/fj-kernel/src/objects/cycle.rs index 6b1316709..cb2d44238 100644 --- a/crates/fj-kernel/src/objects/cycle.rs +++ b/crates/fj-kernel/src/objects/cycle.rs @@ -2,7 +2,7 @@ use fj_math::{Scalar, Winding}; use pretty_assertions::assert_eq; use crate::{ - builder::CycleBuilder, + partial::CycleBuilder, path::SurfacePath, stores::{Handle, Stores}, }; diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index f3f5fc076..3ede53530 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -42,6 +42,7 @@ pub use self::{ maybe_partial::MaybePartial, objects::{ curve::PartialCurve, + cycle::CycleBuilder, edge::{PartialGlobalEdge, PartialHalfEdge}, vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, }, diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs similarity index 100% rename from crates/fj-kernel/src/builder/cycle.rs rename to crates/fj-kernel/src/partial/objects/cycle.rs diff --git a/crates/fj-kernel/src/partial/objects/mod.rs b/crates/fj-kernel/src/partial/objects/mod.rs index 1270703f0..34f8c8e01 100644 --- a/crates/fj-kernel/src/partial/objects/mod.rs +++ b/crates/fj-kernel/src/partial/objects/mod.rs @@ -1,4 +1,5 @@ pub mod curve; +pub mod cycle; pub mod edge; pub mod vertex; From cb1077c50114275cddc8aa50f255383980ca798c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 12:45:33 +0200 Subject: [PATCH 02/18] Rename `CycleBuilder` to `PartialCycle` It doesn't really deserve the name yet, but I'm working on that. --- crates/fj-kernel/src/objects/cycle.rs | 6 +++--- crates/fj-kernel/src/partial/mod.rs | 2 +- crates/fj-kernel/src/partial/objects/cycle.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/objects/cycle.rs b/crates/fj-kernel/src/objects/cycle.rs index cb2d44238..7cd72f8dd 100644 --- a/crates/fj-kernel/src/objects/cycle.rs +++ b/crates/fj-kernel/src/objects/cycle.rs @@ -2,7 +2,7 @@ use fj_math::{Scalar, Winding}; use pretty_assertions::assert_eq; use crate::{ - partial::CycleBuilder, + partial::PartialCycle, path::SurfacePath, stores::{Handle, Stores}, }; @@ -18,8 +18,8 @@ pub struct Cycle { impl Cycle { /// Build a `Cycle` using [`CycleBuilder`] - pub fn builder(stores: &Stores, surface: Handle) -> CycleBuilder { - CycleBuilder { + pub fn builder(stores: &Stores, surface: Handle) -> PartialCycle { + PartialCycle { stores, surface, half_edges: Vec::new(), diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index 3ede53530..87567f44d 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -42,7 +42,7 @@ pub use self::{ maybe_partial::MaybePartial, objects::{ curve::PartialCurve, - cycle::CycleBuilder, + cycle::PartialCycle, edge::{PartialGlobalEdge, PartialHalfEdge}, vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, }, diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 726db2716..591ecd15e 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -9,7 +9,7 @@ use crate::{ /// API for building a [`Cycle`] /// /// Also see [`Cycle::builder`]. -pub struct CycleBuilder<'a> { +pub struct PartialCycle<'a> { /// The stores that the created objects are put in pub stores: &'a Stores, @@ -20,7 +20,7 @@ pub struct CycleBuilder<'a> { pub half_edges: Vec, } -impl<'a> CycleBuilder<'a> { +impl<'a> PartialCycle<'a> { /// Build the [`Cycle`] with the given half-edge pub fn with_half_edges( mut self, From 15b01a0ec61cf4c27e6348b3cf557b6c119e0f5c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 12:53:26 +0200 Subject: [PATCH 03/18] Add `MaybePartial::vertices` --- crates/fj-kernel/src/partial/maybe_partial.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/maybe_partial.rs b/crates/fj-kernel/src/partial/maybe_partial.rs index 6d72c1d3e..16fb45f0b 100644 --- a/crates/fj-kernel/src/partial/maybe_partial.rs +++ b/crates/fj-kernel/src/partial/maybe_partial.rs @@ -1,7 +1,10 @@ use fj_math::Point; use crate::{ - objects::{Curve, GlobalCurve, GlobalEdge, Surface, SurfaceVertex, Vertex}, + objects::{ + Curve, GlobalCurve, GlobalEdge, HalfEdge, Surface, SurfaceVertex, + Vertex, + }, stores::{Handle, Stores}, }; @@ -101,6 +104,16 @@ impl MaybePartial { } } +impl MaybePartial { + /// Access the vertices + pub fn vertices(&self) -> Option<[MaybePartial; 2]> { + match self { + Self::Full(full) => Some(full.vertices().clone().map(Into::into)), + Self::Partial(partial) => partial.vertices.clone(), + } + } +} + impl MaybePartial { /// Access the position pub fn position(&self) -> Option> { From 90971e83cc46549b91a8ec3205be5f6881303c2b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 12:55:49 +0200 Subject: [PATCH 04/18] Refactor --- crates/fj-kernel/src/partial/objects/cycle.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 591ecd15e..7ebc02db5 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -40,9 +40,10 @@ impl<'a> PartialCycle<'a> { .last() .map(|half_edge| { let [_, last] = half_edge.vertices(); + let last = last.surface_form(); - let vertex = last.surface_form().clone(); - let position = last.surface_form().position(); + let vertex = last.clone(); + let position = last.position(); (position, Some(vertex)) }) From f715b1ea81dbd7a01fcb3737cdeaa1ed7c3b2917 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:02:21 +0200 Subject: [PATCH 05/18] Improve readability --- crates/fj-kernel/src/partial/objects/cycle.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 7ebc02db5..42cdd8e0c 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -106,9 +106,10 @@ impl<'a> PartialCycle<'a> { let first = self.half_edges.first(); let last = self.half_edges.last(); - if let [Some([first, _]), Some([_, last])] = [first, last] - .map(|option| option.map(|half_edge| half_edge.vertices())) - { + let vertices = [first, last] + .map(|option| option.map(|half_edge| half_edge.vertices())); + + if let [Some([first, _]), Some([_, last])] = vertices { let vertices = [last, first].map(|vertex| vertex.surface_form().position()); self.half_edges.push( From 1ed49a438479977a5f8312b22818856db04e18b3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:05:37 +0200 Subject: [PATCH 06/18] Accept partial half-edges in `PartialCycle` --- crates/fj-kernel/src/partial/objects/cycle.rs | 57 +++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 42cdd8e0c..6c2e75d2b 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -2,7 +2,7 @@ use fj_math::Point; use crate::{ objects::{Curve, Cycle, HalfEdge, Surface, SurfaceVertex, Vertex}, - partial::HasPartial, + partial::{HasPartial, MaybePartial}, stores::{Handle, Stores}, }; @@ -17,16 +17,17 @@ pub struct PartialCycle<'a> { pub surface: Handle, /// The half-edges that make up the [`Cycle`] - pub half_edges: Vec, + pub half_edges: Vec>, } impl<'a> PartialCycle<'a> { /// Build the [`Cycle`] with the given half-edge pub fn with_half_edges( mut self, - half_edge: impl IntoIterator, + half_edge: impl IntoIterator>>, ) -> Self { - self.half_edges.extend(half_edge); + self.half_edges + .extend(half_edge.into_iter().map(Into::into)); self } @@ -39,18 +40,27 @@ impl<'a> PartialCycle<'a> { .half_edges .last() .map(|half_edge| { - let [_, last] = half_edge.vertices(); - let last = last.surface_form(); + let [_, last] = half_edge.vertices().expect( + "Need half-edge vertices to extend cycle with poly-chain", + ); + let last = last.surface_form().expect( + "Need surface vertex to extend cycle with poly-chain", + ); let vertex = last.clone(); - let position = last.position(); + let position = last.position().expect( + "Need surface position to extend cycle with poly-chain", + ); (position, Some(vertex)) }) .into_iter() .chain(points.into_iter().map(|point| (point.into(), None))); - let mut previous: Option<(Point<2>, Option)> = None; + let mut previous: Option<( + Point<2>, + Option>, + )> = None; for (position, vertex) in iter { if let Some((previous_position, previous_vertex)) = previous { @@ -58,13 +68,13 @@ impl<'a> PartialCycle<'a> { SurfaceVertex::partial() .with_surface(self.surface.clone()) .with_position(previous_position) - .build(self.stores) + .into() }); let to = vertex.unwrap_or_else(|| { SurfaceVertex::partial() .with_surface(self.surface.clone()) .with_position(position) - .build(self.stores) + .into() }); previous = Some((position, Some(to.clone()))); @@ -87,7 +97,7 @@ impl<'a> PartialCycle<'a> { HalfEdge::partial() .with_curve(curve) .with_vertices([from, to]) - .build(self.stores), + .into(), ); continue; @@ -106,16 +116,24 @@ impl<'a> PartialCycle<'a> { let first = self.half_edges.first(); let last = self.half_edges.last(); - let vertices = [first, last] - .map(|option| option.map(|half_edge| half_edge.vertices())); + let vertices = [first, last].map(|option| { + option.map(|half_edge| { + half_edge.vertices().expect("Need vertices to close cycle") + }) + }); if let [Some([first, _]), Some([_, last])] = vertices { - let vertices = - [last, first].map(|vertex| vertex.surface_form().position()); + let vertices = [last, first].map(|vertex| { + vertex + .surface_form() + .expect("Need surface vertex to close cycle") + .position() + .expect("Need surface position to close cycle") + }); self.half_edges.push( HalfEdge::partial() .as_line_segment_from_points(self.surface.clone(), vertices) - .build(self.stores), + .into(), ); } @@ -124,6 +142,11 @@ impl<'a> PartialCycle<'a> { /// Finish building the [`Cycle`] pub fn build(self) -> Cycle { - Cycle::new(self.surface, self.half_edges) + let half_edges = self + .half_edges + .into_iter() + .map(|half_edge| half_edge.into_full(self.stores)); + + Cycle::new(self.surface, half_edges) } } From 911b9bf3c4cfa45d1577af0ffc3da45b34d34e87 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:08:17 +0200 Subject: [PATCH 07/18] Refactor --- crates/fj-kernel/src/partial/objects/cycle.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 6c2e75d2b..1615b1c2d 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -81,8 +81,7 @@ impl<'a> PartialCycle<'a> { let curve = Curve::partial() .with_surface(self.surface.clone()) - .as_line_from_points([previous_position, position]) - .build(self.stores); + .as_line_from_points([previous_position, position]); let [from, to] = [(0., from), (1., to)].map(|(position, surface_form)| { @@ -90,7 +89,6 @@ impl<'a> PartialCycle<'a> { .with_curve(curve.clone()) .with_position([position]) .with_surface_form(surface_form) - .build(self.stores) }); self.half_edges.push( From 5b9fc1070f87be0a959aa4fd7255d6db4d0f0fad Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:09:59 +0200 Subject: [PATCH 08/18] Only require `&Stores` in `PartialCycle::build` --- crates/fj-kernel/src/builder/face.rs | 8 ++++---- crates/fj-kernel/src/builder/shell.rs | 4 ++-- crates/fj-kernel/src/iter.rs | 4 ++-- crates/fj-kernel/src/objects/cycle.rs | 9 ++------- crates/fj-kernel/src/partial/objects/cycle.rs | 11 ++++------- 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index 547728cc9..7cf6b6fc0 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -32,10 +32,10 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.exterior = Some( - Cycle::builder(self.stores, self.surface.clone()) + Cycle::builder(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() - .build(), + .build(self.stores), ); self } @@ -46,10 +46,10 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.interiors.push( - Cycle::builder(self.stores, self.surface.clone()) + Cycle::builder(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() - .build(), + .build(self.stores), ); self } diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index b2873d77c..c8b4dde53 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -167,9 +167,9 @@ impl<'a> ShellBuilder<'a> { .zip(sides_down) .zip(surfaces) .map(|((((bottom, side_up), top), side_down), surface)| { - let cycle = Cycle::builder(self.stores, surface) + let cycle = Cycle::builder(surface) .with_half_edges([bottom, side_up, top, side_down]) - .build(); + .build(self.stores); Face::from_exterior(cycle) }); diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 671f75e6c..83b45a5cd 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -398,10 +398,10 @@ mod tests { let stores = Stores::new(); let surface = stores.surfaces.insert(Surface::xy_plane()); - let object = Cycle::builder(&stores, surface) + let object = Cycle::builder(surface) .with_poly_chain_from_points([[0., 0.], [1., 0.], [0., 1.]]) .close_with_line_segment() - .build(); + .build(&stores); assert_eq!(3, object.curve_iter().count()); assert_eq!(1, object.cycle_iter().count()); diff --git a/crates/fj-kernel/src/objects/cycle.rs b/crates/fj-kernel/src/objects/cycle.rs index 7cd72f8dd..c0b3a4755 100644 --- a/crates/fj-kernel/src/objects/cycle.rs +++ b/crates/fj-kernel/src/objects/cycle.rs @@ -1,11 +1,7 @@ use fj_math::{Scalar, Winding}; use pretty_assertions::assert_eq; -use crate::{ - partial::PartialCycle, - path::SurfacePath, - stores::{Handle, Stores}, -}; +use crate::{partial::PartialCycle, path::SurfacePath, stores::Handle}; use super::{HalfEdge, Surface}; @@ -18,9 +14,8 @@ pub struct Cycle { impl Cycle { /// Build a `Cycle` using [`CycleBuilder`] - pub fn builder(stores: &Stores, surface: Handle) -> PartialCycle { + pub fn builder(surface: Handle) -> PartialCycle { PartialCycle { - stores, surface, half_edges: Vec::new(), } diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 1615b1c2d..a6615e144 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -9,10 +9,7 @@ use crate::{ /// API for building a [`Cycle`] /// /// Also see [`Cycle::builder`]. -pub struct PartialCycle<'a> { - /// The stores that the created objects are put in - pub stores: &'a Stores, - +pub struct PartialCycle { /// The surface that the [`Cycle`] is defined in pub surface: Handle, @@ -20,7 +17,7 @@ pub struct PartialCycle<'a> { pub half_edges: Vec>, } -impl<'a> PartialCycle<'a> { +impl PartialCycle { /// Build the [`Cycle`] with the given half-edge pub fn with_half_edges( mut self, @@ -139,11 +136,11 @@ impl<'a> PartialCycle<'a> { } /// Finish building the [`Cycle`] - pub fn build(self) -> Cycle { + pub fn build(self, stores: &Stores) -> Cycle { let half_edges = self .half_edges .into_iter() - .map(|half_edge| half_edge.into_full(self.stores)); + .map(|half_edge| half_edge.into_full(stores)); Cycle::new(self.surface, half_edges) } From 4f46d900594d015c0a29f472f01ff491236e30df Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:11:43 +0200 Subject: [PATCH 09/18] Refactor The only purpose of this change is to make an upcoming one smaller. --- crates/fj-kernel/src/partial/objects/cycle.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index a6615e144..eb7ac1799 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -61,15 +61,17 @@ impl PartialCycle { for (position, vertex) in iter { if let Some((previous_position, previous_vertex)) = previous { + let surface = self.surface.clone(); + let from = previous_vertex.unwrap_or_else(|| { SurfaceVertex::partial() - .with_surface(self.surface.clone()) + .with_surface(surface.clone()) .with_position(previous_position) .into() }); let to = vertex.unwrap_or_else(|| { SurfaceVertex::partial() - .with_surface(self.surface.clone()) + .with_surface(surface.clone()) .with_position(position) .into() }); @@ -77,7 +79,7 @@ impl PartialCycle { previous = Some((position, Some(to.clone()))); let curve = Curve::partial() - .with_surface(self.surface.clone()) + .with_surface(surface.clone()) .as_line_from_points([previous_position, position]); let [from, to] = From 744f0651dad0912905cc700adc85dbee7a771c02 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:13:31 +0200 Subject: [PATCH 10/18] Refactor The only purpose of this change is to make an upcoming one smaller. --- crates/fj-kernel/src/partial/objects/cycle.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index eb7ac1799..2f9178cf4 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -127,9 +127,11 @@ impl PartialCycle { .position() .expect("Need surface position to close cycle") }); + let surface = self.surface.clone(); + self.half_edges.push( HalfEdge::partial() - .as_line_segment_from_points(self.surface.clone(), vertices) + .as_line_segment_from_points(surface, vertices) .into(), ); } From 25a52c5330f0a53c536cf8bc3f0fb4488273d519 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:14:52 +0200 Subject: [PATCH 11/18] Refactor The only purpose of this change is to make an upcoming one smaller. --- crates/fj-kernel/src/partial/objects/cycle.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 2f9178cf4..345c9f31a 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -141,11 +141,12 @@ impl PartialCycle { /// Finish building the [`Cycle`] pub fn build(self, stores: &Stores) -> Cycle { + let surface = self.surface; let half_edges = self .half_edges .into_iter() .map(|half_edge| half_edge.into_full(stores)); - Cycle::new(self.surface, half_edges) + Cycle::new(surface, half_edges) } } From f81eab7b2041f759f5b46e797b1ef37757a13311 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:17:22 +0200 Subject: [PATCH 12/18] Add `PartialCycle::with_surface` --- crates/fj-kernel/src/partial/objects/cycle.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 345c9f31a..76ae72fc6 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -18,6 +18,12 @@ pub struct PartialCycle { } impl PartialCycle { + /// Update the partial cycle with the given surface + pub fn with_surface(mut self, surface: Handle) -> Self { + self.surface = surface; + self + } + /// Build the [`Cycle`] with the given half-edge pub fn with_half_edges( mut self, From 320378fdba430fcd614f94673a60b8abebbf246a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:18:47 +0200 Subject: [PATCH 13/18] Make surface in `PartialCycle` optional --- crates/fj-kernel/src/builder/face.rs | 6 ++++-- crates/fj-kernel/src/builder/shell.rs | 3 ++- crates/fj-kernel/src/iter.rs | 3 ++- crates/fj-kernel/src/objects/cycle.rs | 4 ++-- crates/fj-kernel/src/partial/objects/cycle.rs | 14 +++++++++----- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index 7cf6b6fc0..682abac9d 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -32,7 +32,8 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.exterior = Some( - Cycle::builder(self.surface.clone()) + Cycle::builder() + .with_surface(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() .build(self.stores), @@ -46,7 +47,8 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.interiors.push( - Cycle::builder(self.surface.clone()) + Cycle::builder() + .with_surface(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() .build(self.stores), diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index c8b4dde53..015a66f01 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -167,7 +167,8 @@ impl<'a> ShellBuilder<'a> { .zip(sides_down) .zip(surfaces) .map(|((((bottom, side_up), top), side_down), surface)| { - let cycle = Cycle::builder(surface) + let cycle = Cycle::builder() + .with_surface(surface) .with_half_edges([bottom, side_up, top, side_down]) .build(self.stores); diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 83b45a5cd..467382ce6 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -398,7 +398,8 @@ mod tests { let stores = Stores::new(); let surface = stores.surfaces.insert(Surface::xy_plane()); - let object = Cycle::builder(surface) + let object = Cycle::builder() + .with_surface(surface) .with_poly_chain_from_points([[0., 0.], [1., 0.], [0., 1.]]) .close_with_line_segment() .build(&stores); diff --git a/crates/fj-kernel/src/objects/cycle.rs b/crates/fj-kernel/src/objects/cycle.rs index c0b3a4755..bbb850fd0 100644 --- a/crates/fj-kernel/src/objects/cycle.rs +++ b/crates/fj-kernel/src/objects/cycle.rs @@ -14,9 +14,9 @@ pub struct Cycle { impl Cycle { /// Build a `Cycle` using [`CycleBuilder`] - pub fn builder(surface: Handle) -> PartialCycle { + pub fn builder() -> PartialCycle { PartialCycle { - surface, + surface: None, half_edges: Vec::new(), } } diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 76ae72fc6..fe0d97914 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -11,7 +11,7 @@ use crate::{ /// Also see [`Cycle::builder`]. pub struct PartialCycle { /// The surface that the [`Cycle`] is defined in - pub surface: Handle, + pub surface: Option>, /// The half-edges that make up the [`Cycle`] pub half_edges: Vec>, @@ -20,7 +20,7 @@ pub struct PartialCycle { impl PartialCycle { /// Update the partial cycle with the given surface pub fn with_surface(mut self, surface: Handle) -> Self { - self.surface = surface; + self.surface = Some(surface); self } @@ -67,7 +67,10 @@ impl PartialCycle { for (position, vertex) in iter { if let Some((previous_position, previous_vertex)) = previous { - let surface = self.surface.clone(); + let surface = self + .surface + .clone() + .expect("Need surface to extend cycle with poly-chain"); let from = previous_vertex.unwrap_or_else(|| { SurfaceVertex::partial() @@ -133,7 +136,8 @@ impl PartialCycle { .position() .expect("Need surface position to close cycle") }); - let surface = self.surface.clone(); + let surface = + self.surface.clone().expect("Need surface to close cycle"); self.half_edges.push( HalfEdge::partial() @@ -147,7 +151,7 @@ impl PartialCycle { /// Finish building the [`Cycle`] pub fn build(self, stores: &Stores) -> Cycle { - let surface = self.surface; + let surface = self.surface.expect("Need surface to build `Cycle`"); let half_edges = self .half_edges .into_iter() From 19c6b8e10877de882604548fc4cd82b84d3acfd9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:20:32 +0200 Subject: [PATCH 14/18] Derive traits for `PartialCycle` --- crates/fj-kernel/src/partial/objects/cycle.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index fe0d97914..ac5058fef 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -9,6 +9,7 @@ use crate::{ /// API for building a [`Cycle`] /// /// Also see [`Cycle::builder`]. +#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialCycle { /// The surface that the [`Cycle`] is defined in pub surface: Option>, From 67a9ac3ba79839543f760c3525a24c8aea6ec300 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:23:18 +0200 Subject: [PATCH 15/18] Add conversion from `&Cycle` to `PartialCycle` --- crates/fj-kernel/src/partial/objects/cycle.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index ac5058fef..1541e2493 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -161,3 +161,12 @@ impl PartialCycle { Cycle::new(surface, half_edges) } } + +impl From<&Cycle> for PartialCycle { + fn from(cycle: &Cycle) -> Self { + Self { + surface: Some(cycle.surface().clone()), + half_edges: cycle.half_edges().cloned().map(Into::into).collect(), + } + } +} From 10a2040f42ab2f11fc7ab138ab77a7476370c25e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:23:45 +0200 Subject: [PATCH 16/18] Make `PartialCycle` a partial object --- crates/fj-kernel/src/partial/objects/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/mod.rs b/crates/fj-kernel/src/partial/objects/mod.rs index 34f8c8e01..8b1411c93 100644 --- a/crates/fj-kernel/src/partial/objects/mod.rs +++ b/crates/fj-kernel/src/partial/objects/mod.rs @@ -5,14 +5,15 @@ pub mod vertex; use crate::{ objects::{ - Curve, GlobalEdge, GlobalVertex, HalfEdge, SurfaceVertex, Vertex, + Curve, Cycle, GlobalEdge, GlobalVertex, HalfEdge, SurfaceVertex, Vertex, }, stores::Stores, }; use super::{ - HasPartial, MaybePartial, Partial, PartialCurve, PartialGlobalEdge, - PartialGlobalVertex, PartialHalfEdge, PartialSurfaceVertex, PartialVertex, + HasPartial, MaybePartial, Partial, PartialCurve, PartialCycle, + PartialGlobalEdge, PartialGlobalVertex, PartialHalfEdge, + PartialSurfaceVertex, PartialVertex, }; macro_rules! impl_traits { @@ -41,6 +42,7 @@ macro_rules! impl_traits { impl_traits!( Curve, PartialCurve; + Cycle, PartialCycle; GlobalEdge, PartialGlobalEdge; GlobalVertex, PartialGlobalVertex; HalfEdge, PartialHalfEdge; From c12af06141664c70845701015044ea7c940de9f9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:25:11 +0200 Subject: [PATCH 17/18] Remove `Cycle::builder` --- crates/fj-kernel/src/builder/face.rs | 5 +++-- crates/fj-kernel/src/builder/shell.rs | 2 +- crates/fj-kernel/src/iter.rs | 2 +- crates/fj-kernel/src/objects/cycle.rs | 10 +--------- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index 682abac9d..fd0a9858d 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -2,6 +2,7 @@ use fj_math::Point; use crate::{ objects::{Cycle, Face, Surface}, + partial::HasPartial, stores::{Handle, Stores}, }; @@ -32,7 +33,7 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.exterior = Some( - Cycle::builder() + Cycle::partial() .with_surface(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() @@ -47,7 +48,7 @@ impl<'a> FaceBuilder<'a> { points: impl IntoIterator>>, ) -> Self { self.interiors.push( - Cycle::builder() + Cycle::partial() .with_surface(self.surface.clone()) .with_poly_chain_from_points(points) .close_with_line_segment() diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index 015a66f01..cfa6997fc 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -167,7 +167,7 @@ impl<'a> ShellBuilder<'a> { .zip(sides_down) .zip(surfaces) .map(|((((bottom, side_up), top), side_down), surface)| { - let cycle = Cycle::builder() + let cycle = Cycle::partial() .with_surface(surface) .with_half_edges([bottom, side_up, top, side_down]) .build(self.stores); diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 467382ce6..4b82d404c 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -398,7 +398,7 @@ mod tests { let stores = Stores::new(); let surface = stores.surfaces.insert(Surface::xy_plane()); - let object = Cycle::builder() + let object = Cycle::partial() .with_surface(surface) .with_poly_chain_from_points([[0., 0.], [1., 0.], [0., 1.]]) .close_with_line_segment() diff --git a/crates/fj-kernel/src/objects/cycle.rs b/crates/fj-kernel/src/objects/cycle.rs index bbb850fd0..29f37b2e0 100644 --- a/crates/fj-kernel/src/objects/cycle.rs +++ b/crates/fj-kernel/src/objects/cycle.rs @@ -1,7 +1,7 @@ use fj_math::{Scalar, Winding}; use pretty_assertions::assert_eq; -use crate::{partial::PartialCycle, path::SurfacePath, stores::Handle}; +use crate::{path::SurfacePath, stores::Handle}; use super::{HalfEdge, Surface}; @@ -13,14 +13,6 @@ pub struct Cycle { } impl Cycle { - /// Build a `Cycle` using [`CycleBuilder`] - pub fn builder() -> PartialCycle { - PartialCycle { - surface: None, - half_edges: Vec::new(), - } - } - /// Create a new cycle /// /// # Panics From 4cc12e710b5f46eb4f38faadde09d852034731b8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 5 Oct 2022 13:28:03 +0200 Subject: [PATCH 18/18] Update documentation of `PartialCycle` --- crates/fj-kernel/src/partial/objects/cycle.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 1541e2493..40a1a74e2 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -6,9 +6,9 @@ use crate::{ stores::{Handle, Stores}, }; -/// API for building a [`Cycle`] +/// A partial [`Cycle`] /// -/// Also see [`Cycle::builder`]. +/// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialCycle { /// The surface that the [`Cycle`] is defined in @@ -25,7 +25,7 @@ impl PartialCycle { self } - /// Build the [`Cycle`] with the given half-edge + /// Update the partial cycle with the given half-edges pub fn with_half_edges( mut self, half_edge: impl IntoIterator>>, @@ -35,7 +35,7 @@ impl PartialCycle { self } - /// Build the [`Cycle`] with a polygonal chain from the provided points + /// Update the partial cycle with a polygonal chain from the provided points pub fn with_poly_chain_from_points( mut self, points: impl IntoIterator>>, @@ -116,7 +116,7 @@ impl PartialCycle { self } - /// Close the [`Cycle`] with a line segment + /// Update the partial cycle by closing it with a line segment /// /// Builds a line segment from the last and first vertex, closing the cycle. pub fn close_with_line_segment(mut self) -> Self { @@ -150,7 +150,7 @@ impl PartialCycle { self } - /// Finish building the [`Cycle`] + /// Build a full [`Cycle`] from the partial cycle pub fn build(self, stores: &Stores) -> Cycle { let surface = self.surface.expect("Need surface to build `Cycle`"); let half_edges = self