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::partial::PartialCurve;
use crate::{geometry::path::SurfacePath, partial::PartialCurve};
/// Builder API for [`PartialCurve`] /// Builder API for [`PartialCurve`]
pub trait CurveBuilder { pub trait CurveBuilder {
/// Update partial curve to represent the u-axis of the surface it is on // No methods are currently defined. This trait serves as a placeholder, to
/// // make it clear where to add such methods, once necessary.
/// 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;
} }
impl CurveBuilder for PartialCurve { 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
}
}

View File

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