-
-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #866 from hannobraun/builder
Add new builder API
- Loading branch information
Showing
18 changed files
with
358 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
use fj_math::Point; | ||
|
||
use crate::objects::{Cycle, Edge, Surface}; | ||
|
||
/// API for building a [`Cycle`] | ||
pub struct CycleBuilder { | ||
surface: Surface, | ||
} | ||
|
||
impl CycleBuilder { | ||
/// Construct an instance of `CycleBuilder` | ||
/// | ||
/// Also see [`Cycle::build`]. | ||
pub fn new(surface: Surface) -> Self { | ||
Self { surface } | ||
} | ||
|
||
/// Create a polygon from a list of points | ||
pub fn polygon_from_points( | ||
&self, | ||
points: impl IntoIterator<Item = impl Into<Point<2>>>, | ||
) -> Cycle { | ||
let mut points: Vec<_> = points.into_iter().map(Into::into).collect(); | ||
|
||
// A polygon is closed, so we need to add the first point at the end | ||
// again, for the next step. | ||
if let Some(point) = points.first().cloned() { | ||
points.push(point); | ||
} | ||
|
||
let mut edges = Vec::new(); | ||
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]]; | ||
|
||
edges.push( | ||
Edge::build().line_segment_from_points(&self.surface, points), | ||
); | ||
} | ||
|
||
Cycle::new().with_edges(edges) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use fj_math::{Circle, Line, Point, Scalar, Vector}; | ||
|
||
use crate::{ | ||
local::Local, | ||
objects::{Curve, Edge, GlobalVertex, Surface, Vertex, VerticesOfEdge}, | ||
}; | ||
|
||
/// API for building an [`Edge`] | ||
pub struct EdgeBuilder; | ||
|
||
impl EdgeBuilder { | ||
/// Create a circle from the given radius | ||
pub fn circle_from_radius(&self, radius: Scalar) -> Edge { | ||
let curve_local = Curve::Circle(Circle { | ||
center: Point::origin(), | ||
a: Vector::from([radius, Scalar::ZERO]), | ||
b: Vector::from([Scalar::ZERO, radius]), | ||
}); | ||
let curve_canonical = Curve::Circle(Circle { | ||
center: Point::origin(), | ||
a: Vector::from([radius, Scalar::ZERO, Scalar::ZERO]), | ||
b: Vector::from([Scalar::ZERO, radius, Scalar::ZERO]), | ||
}); | ||
|
||
Edge::new( | ||
Local::new(curve_local, curve_canonical), | ||
VerticesOfEdge::none(), | ||
) | ||
} | ||
|
||
/// Create a line segment from two points | ||
pub fn line_segment_from_points( | ||
&self, | ||
surface: &Surface, | ||
points: [impl Into<Point<2>>; 2], | ||
) -> Edge { | ||
let points = points.map(Into::into); | ||
|
||
let global_vertices = points.map(|position| { | ||
let position = surface.point_from_surface_coords(position); | ||
GlobalVertex::from_position(position) | ||
}); | ||
|
||
let curve_local = Curve::Line(Line::from_points(points)); | ||
let curve_canonical = { | ||
let points = | ||
global_vertices.map(|global_vertex| global_vertex.position()); | ||
Curve::Line(Line::from_points(points)) | ||
}; | ||
|
||
let vertices = { | ||
let [a, b] = global_vertices; | ||
[ | ||
Vertex::new(Point::from([0.]), a), | ||
Vertex::new(Point::from([1.]), b), | ||
] | ||
}; | ||
|
||
Edge::new( | ||
Local::new(curve_local, curve_canonical), | ||
VerticesOfEdge::from_vertices(vertices), | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use std::ops::Deref; | ||
|
||
use fj_math::Point; | ||
|
||
use crate::objects::{Cycle, Face, Surface}; | ||
|
||
/// API for building a [`Face`] | ||
pub struct FaceBuilder { | ||
surface: Surface, | ||
} | ||
|
||
impl FaceBuilder { | ||
/// Construct an instance of `FaceBuilder` | ||
/// | ||
/// Also see [`Face::build`]. | ||
pub fn new(surface: Surface) -> Self { | ||
Self { surface } | ||
} | ||
|
||
/// Construct a polygon from a list of points | ||
pub fn polygon_from_points( | ||
&self, | ||
points: impl IntoIterator<Item = impl Into<Point<2>>>, | ||
) -> FacePolygon { | ||
let face = Face::new(self.surface) | ||
.with_exteriors([ | ||
Cycle::build(self.surface).polygon_from_points(points) | ||
]); | ||
|
||
FacePolygon { face } | ||
} | ||
} | ||
|
||
/// A polygon | ||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] | ||
pub struct FacePolygon { | ||
face: Face, | ||
} | ||
|
||
impl FacePolygon { | ||
/// Add a hole to the polygon | ||
pub fn with_hole( | ||
mut self, | ||
points: impl IntoIterator<Item = impl Into<Point<2>>>, | ||
) -> Self { | ||
let surface = *self.face.surface(); | ||
self.face = self.face.with_interiors([ | ||
Cycle::build(surface).polygon_from_points(points) | ||
]); | ||
|
||
self | ||
} | ||
|
||
/// Consume the `Polygon` and return the [`Face`] it wraps | ||
pub fn into_face(self) -> Face { | ||
self.face | ||
} | ||
} | ||
|
||
impl From<FacePolygon> for Face { | ||
fn from(polygon: FacePolygon) -> Self { | ||
polygon.into_face() | ||
} | ||
} | ||
|
||
impl Deref for FacePolygon { | ||
type Target = Face; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.face | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//! API for building objects | ||
mod cycle; | ||
mod edge; | ||
mod face; | ||
mod solid; | ||
|
||
pub use self::{ | ||
cycle::CycleBuilder, | ||
edge::EdgeBuilder, | ||
face::{FaceBuilder, FacePolygon}, | ||
solid::SolidBuilder, | ||
}; |
Oops, something went wrong.