Merge pull request #1615 from hannobraun/builder

Move all responsibilities of `CurveBuilder` to `HalfEdgeBuilder`
This commit is contained in:
Hanno Braun 2023-02-24 15:17:42 +01:00 committed by GitHub
commit 44a7642324
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 120 deletions

View File

@ -1,100 +1,9 @@
use fj_math::{Point, Scalar};
use crate::{geometry::path::SurfacePath, partial::PartialCurve};
use crate::partial::PartialCurve;
/// Builder API for [`PartialCurve`]
pub trait CurveBuilder {
/// Update partial curve to represent the u-axis of the surface it is on
///
/// Returns the updated path.
fn update_as_u_axis(&mut self) -> SurfacePath;
/// Update partial curve to represent the v-axis of the surface it is on
///
/// Returns the updated path.
fn update_as_v_axis(&mut self) -> SurfacePath;
/// Update partial curve to be a circle, from the provided radius
///
/// Returns the updated path.
fn update_as_circle_from_radius(
&mut self,
radius: impl Into<Scalar>,
) -> SurfacePath;
/// Update partial curve to be a circle, from the provided radius
///
/// Returns the updated path.
fn update_as_circle_from_center_and_radius(
&mut self,
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
) -> SurfacePath;
/// Update partial curve to be a line, from the provided points
///
/// Returns the updated path.
fn update_as_line_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
) -> SurfacePath;
/// Update partial curve to be a line, from provided points and line coords
///
/// Returns the updated path.
fn update_as_line_from_points_with_line_coords(
&mut self,
points: [(impl Into<Point<1>>, impl Into<Point<2>>); 2],
) -> SurfacePath;
// No methods are currently defined. This trait serves as a placeholder, to
// make it clear where to add such methods, once necessary.
}
impl CurveBuilder for PartialCurve {
fn update_as_u_axis(&mut self) -> SurfacePath {
let path = SurfacePath::u_axis();
self.path = Some(path.into());
path
}
fn update_as_v_axis(&mut self) -> SurfacePath {
let path = SurfacePath::v_axis();
self.path = Some(path.into());
path
}
fn update_as_circle_from_radius(
&mut self,
radius: impl Into<Scalar>,
) -> SurfacePath {
let path = SurfacePath::circle_from_radius(radius);
self.path = Some(path.into());
path
}
fn update_as_circle_from_center_and_radius(
&mut self,
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
) -> SurfacePath {
let path = SurfacePath::circle_from_center_and_radius(center, radius);
self.path = Some(path.into());
path
}
fn update_as_line_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
) -> SurfacePath {
let (path, _) = SurfacePath::line_from_points(points);
self.path = Some(path.into());
path
}
fn update_as_line_from_points_with_line_coords(
&mut self,
points: [(impl Into<Point<1>>, impl Into<Point<2>>); 2],
) -> SurfacePath {
let path = SurfacePath::from_points_with_line_coords(points);
self.path = Some(path.into());
path
}
}
impl CurveBuilder for PartialCurve {}

View File

@ -10,12 +10,23 @@ use crate::{
partial::{MaybeSurfacePath, Partial, PartialGlobalEdge, PartialHalfEdge},
};
use super::CurveBuilder;
/// Builder API for [`PartialHalfEdge`]
pub trait HalfEdgeBuilder {
/// Update partial half-edge to represent the u-axis of the surface it is on
///
/// Returns the updated path.
fn update_as_u_axis(&mut self) -> SurfacePath;
/// Update partial curve to represent the v-axis of the surface it is on
///
/// Returns the updated path.
fn update_as_v_axis(&mut self) -> SurfacePath;
/// Update partial half-edge to be a circle, from the given radius
fn update_as_circle_from_radius(&mut self, radius: impl Into<Scalar>);
fn update_as_circle_from_radius(
&mut self,
radius: impl Into<Scalar>,
) -> SurfacePath;
/// Update partial half-edge to be an arc, spanning the given angle in
/// radians
@ -29,10 +40,10 @@ pub trait HalfEdgeBuilder {
fn update_as_line_segment_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
);
) -> SurfacePath;
/// Update partial half-edge to be a line segment
fn update_as_line_segment(&mut self);
fn update_as_line_segment(&mut self) -> SurfacePath;
/// Infer the global form of the half-edge
///
@ -63,8 +74,24 @@ pub trait HalfEdgeBuilder {
}
impl HalfEdgeBuilder for PartialHalfEdge {
fn update_as_circle_from_radius(&mut self, radius: impl Into<Scalar>) {
let path = self.curve.write().update_as_circle_from_radius(radius);
fn update_as_u_axis(&mut self) -> SurfacePath {
let path = SurfacePath::u_axis();
self.curve.write().path = Some(path.into());
path
}
fn update_as_v_axis(&mut self) -> SurfacePath {
let path = SurfacePath::v_axis();
self.curve.write().path = Some(path.into());
path
}
fn update_as_circle_from_radius(
&mut self,
radius: impl Into<Scalar>,
) -> SurfacePath {
let path = SurfacePath::circle_from_radius(radius);
self.curve.write().path = Some(path.into());
let [a_curve, b_curve] =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
@ -85,6 +112,8 @@ impl HalfEdgeBuilder for PartialHalfEdge {
}
self.infer_global_form();
path
}
fn update_as_arc(&mut self, angle_rad: impl Into<Scalar>) {
@ -102,10 +131,9 @@ impl HalfEdgeBuilder for PartialHalfEdge {
let arc = fj_math::Arc::from_endpoints_and_angle(start, end, angle_rad);
let path = self
.curve
.write()
.update_as_circle_from_center_and_radius(arc.center, arc.radius);
let path =
SurfacePath::circle_from_center_and_radius(arc.center, arc.radius);
self.curve.write().path = Some(path.into());
let [a_curve, b_curve] =
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
@ -124,7 +152,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
fn update_as_line_segment_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
) {
) -> SurfacePath {
for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
let mut surface_form = vertex.1.write();
surface_form.position = Some(point.into());
@ -133,7 +161,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
self.update_as_line_segment()
}
fn update_as_line_segment(&mut self) {
fn update_as_line_segment(&mut self) -> SurfacePath {
let boundary = self.vertices.each_ref_ext().map(|vertex| vertex.0);
let points_surface = self.vertices.each_ref_ext().map(|vertex| {
vertex
@ -143,26 +171,29 @@ impl HalfEdgeBuilder for PartialHalfEdge {
.expect("Can't infer line segment without surface position")
});
if let [Some(start), Some(end)] = boundary {
let boundary = [start, end];
self.curve
.write()
.update_as_line_from_points_with_line_coords(
boundary.zip_ext(points_surface),
);
let path = if let [Some(start), Some(end)] = boundary {
let points = [start, end].zip_ext(points_surface);
let path = SurfacePath::from_points_with_line_coords(points);
self.curve.write().path = Some(path.into());
path
} else {
self.curve
.write()
.update_as_line_from_points(points_surface);
let (path, _) = SurfacePath::line_from_points(points_surface);
self.curve.write().path = Some(path.into());
for (vertex, position) in
self.vertices.each_mut_ext().zip_ext([0., 1.])
{
vertex.0 = Some([position].into());
}
}
path
};
self.infer_global_form();
path
}
fn infer_global_form(&mut self) -> Partial<GlobalEdge> {

View File

@ -84,7 +84,7 @@ impl Shape for fj::Sketch {
},
);
line_segments.into_iter().for_each(|mut half_edge| {
half_edge.write().update_as_line_segment()
half_edge.write().update_as_line_segment();
});
arcs.into_iter().for_each(|(mut half_edge, angle)| {
half_edge.write().update_as_arc(angle.rad())