From f5c7922d03d14447ed0fe63abcbad7e74648f1a3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 26 Jan 2023 16:41:28 +0100 Subject: [PATCH 1/4] Add unit tests --- crates/fj-math/src/line.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/crates/fj-math/src/line.rs b/crates/fj-math/src/line.rs index 900006f581..c2a6c513fa 100644 --- a/crates/fj-math/src/line.rs +++ b/crates/fj-math/src/line.rs @@ -181,6 +181,30 @@ mod tests { use super::Line; + #[test] + fn from_points_with_line_coords() { + let line = Line::from_points_with_line_coords([ + ([0.], [0., 0.]), + ([1.], [1., 0.]), + ]); + assert_eq!(line.origin(), Point::from([0., 0.])); + assert_eq!(line.direction(), Vector::from([1., 0.])); + + let line = Line::from_points_with_line_coords([ + ([1.], [0., 1.]), + ([0.], [1., 1.]), + ]); + assert_eq!(line.origin(), Point::from([1., 1.])); + assert_eq!(line.direction(), Vector::from([-1., 0.])); + + let line = Line::from_points_with_line_coords([ + ([-1.], [0., 2.]), + ([0.], [1., 2.]), + ]); + assert_eq!(line.origin(), Point::from([1., 2.])); + assert_eq!(line.direction(), Vector::from([1., 0.])); + } + #[test] fn is_coincident_with() { let (line, _) = Line::from_points([[0., 0.], [1., 0.]]); From 6f62cd0fa8911294f768a23adcaa5e817e5ec762 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 26 Jan 2023 12:39:25 +0100 Subject: [PATCH 2/4] Add `SurfacePath::from_points_with_line_coords` --- crates/fj-kernel/src/geometry/path.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/fj-kernel/src/geometry/path.rs b/crates/fj-kernel/src/geometry/path.rs index 01fefdf2aa..f84b143b29 100644 --- a/crates/fj-kernel/src/geometry/path.rs +++ b/crates/fj-kernel/src/geometry/path.rs @@ -58,6 +58,13 @@ impl SurfacePath { (Self::Line(line), coords) } + /// Create a line from two points that include line coordinates + pub fn from_points_with_line_coords( + points: [(impl Into>, impl Into>); 2], + ) -> Self { + Self::Line(Line::from_points_with_line_coords(points)) + } + /// Convert a point on the path into surface coordinates pub fn point_from_path_coords( &self, From 121df1e5d4c4b363a769d0ba54deebcfd31644b4 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 26 Jan 2023 12:42:50 +0100 Subject: [PATCH 3/4] Add new `CurveBuilder` method --- crates/fj-kernel/src/builder/curve.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/fj-kernel/src/builder/curve.rs b/crates/fj-kernel/src/builder/curve.rs index c094c14a5b..acc790cf13 100644 --- a/crates/fj-kernel/src/builder/curve.rs +++ b/crates/fj-kernel/src/builder/curve.rs @@ -38,6 +38,14 @@ pub trait CurveBuilder { &mut self, points: [impl Into>; 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>, impl Into>); 2], + ) -> SurfacePath; } impl CurveBuilder for PartialCurve { @@ -82,4 +90,13 @@ impl CurveBuilder for PartialCurve { self.path = Some(path.into()); path } + + fn update_as_line_from_points_with_line_coords( + &mut self, + points: [(impl Into>, impl Into>); 2], + ) -> SurfacePath { + let path = SurfacePath::from_points_with_line_coords(points); + self.path = Some(path.into()); + path + } } From 88821a6a51fd3ba8b4b75fd463516c2912b26695 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 26 Jan 2023 15:33:32 +0100 Subject: [PATCH 4/4] Respect boundary when updating as line segment Previously, `HalfEdgeBuilder::update_as_line_segment` would always update the boundary after inferring a line segment. With this change, it respects the existing boundary, changing its inferrence of the line segment accordingly. --- crates/fj-kernel/src/builder/edge.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 3f608935fd..247addb01f 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -150,6 +150,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { } fn update_as_line_segment(&mut self) { + let boundary = self.vertices.each_ref_ext().map(|vertex| vertex.0); let points_surface = self.vertices.each_ref_ext().map(|vertex| { vertex .1 @@ -158,13 +159,23 @@ impl HalfEdgeBuilder for PartialHalfEdge { .expect("Can't infer line segment without surface position") }); - self.curve - .write() - .update_as_line_from_points(points_surface); - - for (vertex, position) in self.vertices.each_mut_ext().zip_ext([0., 1.]) - { - vertex.0 = Some([position].into()); + 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), + ); + } else { + self.curve + .write() + .update_as_line_from_points(points_surface); + + for (vertex, position) in + self.vertices.each_mut_ext().zip_ext([0., 1.]) + { + vertex.0 = Some([position].into()); + } } self.infer_global_form();