From a1ab7617053ff68d8d34fa43829b5ab66807ef27 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 1 Apr 2022 18:47:45 +0200 Subject: [PATCH] Add `CycleBuilder` --- fj-kernel/src/topology/builder.rs | 41 ++++++++++++++++++++++++++++++- fj-kernel/src/topology/edges.rs | 7 +++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/fj-kernel/src/topology/builder.rs b/fj-kernel/src/topology/builder.rs index 9e5949974..55ea4e906 100644 --- a/fj-kernel/src/topology/builder.rs +++ b/fj-kernel/src/topology/builder.rs @@ -5,7 +5,7 @@ use crate::{ shape::{Handle, Shape, ValidationResult}, }; -use super::{Edge, Vertex}; +use super::{Cycle, Edge, Vertex}; /// API for building a [`Vertex`] pub struct VertexBuilder<'r> { @@ -93,3 +93,42 @@ impl<'r> EdgeBuilder<'r> { Ok(edge) } } + +/// API for building a [`Cycle`] +pub struct CycleBuilder<'r> { + shape: &'r mut Shape, +} + +impl<'r> CycleBuilder<'r> { + /// Construct a new instance of `CycleBuilder` + pub fn new(shape: &'r mut Shape) -> Self { + Self { shape } + } + + /// Build a polygon from a list of points + pub fn polygon( + self, + points: impl IntoIterator>>, + ) -> ValidationResult { + // A polygon is closed, so we need to add the first point at the end + // again, for the next step. + let mut points: Vec<_> = points.into_iter().map(Into::into).collect(); + if let Some(point) = points.first().cloned() { + points.push(point); + } + + let mut edges = Vec::new(); + for ab in points.windows(2) { + // Can't panic, as we passed `2` to `windows`. + // + // Can be cleaned up, once `array_windows` is stable. + let points = [ab[0], ab[1]]; + + let edge = + Edge::build(self.shape).line_segment_from_points(points)?; + edges.push(edge); + } + + self.shape.insert(Cycle { edges }) + } +} diff --git a/fj-kernel/src/topology/edges.rs b/fj-kernel/src/topology/edges.rs index 7871481ba..cf5aad58c 100644 --- a/fj-kernel/src/topology/edges.rs +++ b/fj-kernel/src/topology/edges.rs @@ -5,7 +5,7 @@ use crate::{ shape::{Handle, Shape}, }; -use super::{vertices::Vertex, EdgeBuilder}; +use super::{builder::CycleBuilder, vertices::Vertex, EdgeBuilder}; /// A cycle of connected edges /// @@ -29,6 +29,11 @@ pub struct Cycle { } impl Cycle { + /// Build a cycle using the [`CycleBuilder`] API + pub fn build(shape: &mut Shape) -> CycleBuilder { + CycleBuilder::new(shape) + } + /// Access the edges that this cycle refers to /// /// This is a convenience method that saves the caller from dealing with the