diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 47441023a..5b59cc6d5 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -5,10 +5,9 @@ use itertools::Itertools; use crate::{ algorithms::{reverse::Reverse, transform::TransformObject}, - builder::CycleBuilder, geometry::curve::GlobalPath, - objects::{Face, Shell}, - operations::Insert, + objects::{Cycle, Face, Shell}, + operations::{BuildCycle, Insert, JoinCycle}, services::Services, storage::Handle, }; @@ -82,13 +81,14 @@ impl Sweep for Handle { )); } - let top_cycle = CycleBuilder::connect_to_edges(top_edges, services) - .build(services); + let top_cycle = Cycle::empty() + .add_joined_edges(top_edges, services) + .insert(services); if i == 0 { - exterior = Some(top_cycle.insert(services)); + exterior = Some(top_cycle); } else { - interiors.push(top_cycle.insert(services)); + interiors.push(top_cycle); }; } diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs deleted file mode 100644 index c0a848daf..000000000 --- a/crates/fj-kernel/src/builder/cycle.rs +++ /dev/null @@ -1,76 +0,0 @@ -use fj_math::Point; -use itertools::Itertools; - -use crate::{ - geometry::curve::Curve, - objects::{Cycle, HalfEdge}, - operations::{BuildHalfEdge, Insert, UpdateHalfEdge}, - services::Services, - storage::Handle, -}; - -/// Builder API for [`Cycle`] -#[derive(Default)] -pub struct CycleBuilder { - half_edges: Vec, -} - -impl CycleBuilder { - /// Create an instance of `CycleBuilder` - pub fn new() -> Self { - Self::default() - } - - /// Create a cycle whose half-edges are connected to the provided half-edges - /// - /// The half-edges of the new circle will be coincident with the provided - /// half-edges, but will point in the opposite direction. - /// - /// Assumes that the provided half-edges, once translated into local - /// equivalents of this cycle, form a cycle themselves. - pub fn connect_to_edges(edges: Es, services: &mut Services) -> Self - where - Es: IntoIterator, Curve, [Point<1>; 2])>, - Es::IntoIter: Clone + ExactSizeIterator, - { - let half_edges = edges - .into_iter() - .circular_tuple_windows() - .map(|((prev, _, _), (half_edge, curve, boundary))| { - HalfEdge::unjoined(curve, boundary, services) - .replace_start_vertex(prev.start_vertex().clone()) - .replace_global_form(half_edge.global_form().clone()) - }) - .collect(); - - Self { half_edges } - } - - /// Create a polygon - pub fn polygon(points: Ps, services: &mut Services) -> Self - where - P: Into>, - Ps: IntoIterator, - Ps::IntoIter: Clone + ExactSizeIterator, - { - let half_edges = points - .into_iter() - .map(Into::into) - .circular_tuple_windows() - .map(|(start, end)| { - HalfEdge::line_segment([start, end], None, services) - }) - .collect(); - - Self { half_edges } - } - - /// Build the cycle - pub fn build(self, services: &mut Services) -> Cycle { - let half_edges = self - .half_edges - .into_iter() - .map(|half_edge| half_edge.insert(services)); - Cycle::new(half_edges) - } -} diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs deleted file mode 100644 index 453523ff1..000000000 --- a/crates/fj-kernel/src/builder/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! API for building objects - -mod cycle; - -pub use self::cycle::CycleBuilder; diff --git a/crates/fj-kernel/src/lib.rs b/crates/fj-kernel/src/lib.rs index 952e0fb27..0996e6dd3 100644 --- a/crates/fj-kernel/src/lib.rs +++ b/crates/fj-kernel/src/lib.rs @@ -88,7 +88,6 @@ #![warn(missing_docs)] pub mod algorithms; -pub mod builder; pub mod geometry; pub mod objects; pub mod operations; diff --git a/crates/fj-kernel/src/operations/join/cycle.rs b/crates/fj-kernel/src/operations/join/cycle.rs index 52b6ddb4f..1b591a854 100644 --- a/crates/fj-kernel/src/operations/join/cycle.rs +++ b/crates/fj-kernel/src/operations/join/cycle.rs @@ -1,13 +1,24 @@ use std::ops::RangeInclusive; +use fj_math::Point; +use itertools::Itertools; + use crate::{ - objects::Cycle, - operations::{Insert, UpdateCycle, UpdateHalfEdge}, + geometry::curve::Curve, + objects::{Cycle, HalfEdge}, + operations::{BuildHalfEdge, Insert, UpdateCycle, UpdateHalfEdge}, services::Services, + storage::Handle, }; /// Join a [`Cycle`] to another pub trait JoinCycle { + /// Create a cycle that is joined to the provided edges + fn add_joined_edges(&self, edges: Es, services: &mut Services) -> Self + where + Es: IntoIterator, Curve, [Point<1>; 2])>, + Es::IntoIter: Clone + ExactSizeIterator; + /// Join the cycle to another /// /// Joins the cycle to the other at the provided ranges. The ranges specify @@ -47,6 +58,21 @@ pub trait JoinCycle { } impl JoinCycle for Cycle { + fn add_joined_edges(&self, edges: Es, services: &mut Services) -> Self + where + Es: IntoIterator, Curve, [Point<1>; 2])>, + Es::IntoIter: Clone + ExactSizeIterator, + { + self.add_half_edges(edges.into_iter().circular_tuple_windows().map( + |((prev, _, _), (half_edge, curve, boundary))| { + HalfEdge::unjoined(curve, boundary, services) + .replace_start_vertex(prev.start_vertex().clone()) + .replace_global_form(half_edge.global_form().clone()) + .insert(services) + }, + )) + } + fn join_to( &self, other: &Cycle,