From 7f287bff4827e17caa92356ee6f55b977d4ec6ff Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 21 Sep 2022 11:27:02 +0200 Subject: [PATCH] Split `FaceBuilder` method into two --- .../src/algorithms/intersect/curve_face.rs | 3 +- .../src/algorithms/intersect/face_face.rs | 6 ++-- .../src/algorithms/intersect/face_point.rs | 34 ++++++++++++++----- .../src/algorithms/intersect/ray_face.rs | 21 ++++++++---- crates/fj-kernel/src/algorithms/sweep/face.rs | 12 ++++--- .../src/algorithms/triangulate/mod.rs | 9 +++-- crates/fj-kernel/src/builder/face.rs | 28 +++++++++++---- crates/fj-kernel/src/builder/shell.rs | 3 +- crates/fj-kernel/src/builder/sketch.rs | 3 +- crates/fj-kernel/src/iter.rs | 6 ++-- crates/fj-kernel/src/objects/face.rs | 6 +++- crates/fj-operations/src/sketch.rs | 3 +- 12 files changed, 97 insertions(+), 37 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs index 1f355df13e..2223257e99 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs @@ -187,7 +187,8 @@ mod tests { ]; let face = Face::builder(&stores, surface) - .build_polygon_from_points(exterior) + .with_exterior_polygon_from_points(exterior) + .build() .with_hole(interior) .into_face(); diff --git a/crates/fj-kernel/src/algorithms/intersect/face_face.rs b/crates/fj-kernel/src/algorithms/intersect/face_face.rs index 806700be74..9e5aad5ebc 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_face.rs @@ -84,7 +84,8 @@ mod tests { let surfaces = [Surface::xy_plane(), Surface::xz_plane()]; let [a, b] = surfaces.map(|surface| { Face::builder(&stores, surface) - .build_polygon_from_points(points) + .with_exterior_polygon_from_points(points) + .build() .into_face() }); @@ -107,7 +108,8 @@ mod tests { let surfaces = [Surface::xy_plane(), Surface::xz_plane()]; let [a, b] = surfaces.map(|surface| { Face::builder(&stores, surface) - .build_polygon_from_points(points) + .with_exterior_polygon_from_points(points) + .build() .into_face() }); diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index 92742d0f31..c27e18091c 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -143,7 +143,8 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]]) + .with_exterior_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]]) + .build() .into_face(); let point = Point::from([2., 1.]); @@ -156,7 +157,8 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]]) + .with_exterior_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]]) + .build() .into_face(); let point = Point::from([1., 1.]); @@ -172,7 +174,8 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]]) + .with_exterior_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]]) + .build() .into_face(); let point = Point::from([1., 2.]); @@ -188,7 +191,13 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [2., 1.], [3., 0.], [3., 4.]]) + .with_exterior_polygon_from_points([ + [0., 0.], + [2., 1.], + [3., 0.], + [3., 4.], + ]) + .build() .into_face(); let point = Point::from([1., 1.]); @@ -204,7 +213,13 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [2., 1.], [3., 1.], [0., 2.]]) + .with_exterior_polygon_from_points([ + [0., 0.], + [2., 1.], + [3., 1.], + [0., 2.], + ]) + .build() .into_face(); let point = Point::from([1., 1.]); @@ -220,13 +235,14 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [0., 0.], [2., 1.], [3., 1.], [4., 0.], [4., 5.], ]) + .build() .into_face(); let point = Point::from([1., 1.]); @@ -242,7 +258,8 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]]) + .with_exterior_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]]) + .build() .into_face(); let point = Point::from([1., 0.]); @@ -267,7 +284,8 @@ mod tests { let stores = Stores::new(); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .build() .into_face(); let point = Point::from([1., 0.]); diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs index 0201a4efda..7ce478fdc3 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs @@ -169,12 +169,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::yz_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([-1., 0., 0.], &stores); @@ -188,12 +189,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::yz_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([1., 0., 0.], &stores); @@ -210,12 +212,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::yz_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([0., 0., 2.], &stores); @@ -229,12 +232,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::yz_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([1., 1., 0.], &stores); @@ -259,12 +263,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::yz_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([1., 1., 1.], &stores); @@ -287,12 +292,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face(); assert_eq!( @@ -308,12 +314,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let face = Face::builder(&stores, Surface::xy_plane()) - .build_polygon_from_points([ + .with_exterior_polygon_from_points([ [-1., -1.], [1., -1.], [1., 1.], [-1., 1.], ]) + .build() .into_face() .translate([0., 0., 1.], &stores); diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 4715edb2d4..535ede82ee 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -95,11 +95,13 @@ mod tests { .sweep(UP, &stores); let bottom = Face::builder(&stores, surface) - .build_polygon_from_points(TRIANGLE) + .with_exterior_polygon_from_points(TRIANGLE) + .build() .into_face() .reverse(); let top = Face::builder(&stores, surface.translate(UP, &stores)) - .build_polygon_from_points(TRIANGLE) + .with_exterior_polygon_from_points(TRIANGLE) + .build() .into_face(); assert!(solid.find_face(&bottom).is_some()); @@ -130,11 +132,13 @@ mod tests { .sweep(DOWN, &stores); let bottom = Face::builder(&stores, surface.translate(DOWN, &stores)) - .build_polygon_from_points(TRIANGLE) + .with_exterior_polygon_from_points(TRIANGLE) + .build() .into_face() .reverse(); let top = Face::builder(&stores, surface) - .build_polygon_from_points(TRIANGLE) + .with_exterior_polygon_from_points(TRIANGLE) + .build() .into_face(); assert!(solid.find_face(&bottom).is_some()); diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index d29ae4752f..26445c39b5 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -101,7 +101,8 @@ mod tests { let surface = Surface::xy_plane(); let face = Face::builder(&stores, surface) - .build_polygon_from_points([a, b, c, d]) + .with_exterior_polygon_from_points([a, b, c, d]) + .build() .into_face(); let a = Point::from(a).to_xyz(); @@ -135,7 +136,8 @@ mod tests { let surface = Surface::xy_plane(); let face = Face::builder(&stores, surface) - .build_polygon_from_points([a, b, c, d]) + .with_exterior_polygon_from_points([a, b, c, d]) + .build() .with_hole([e, f, g, h]) .into_face(); @@ -188,7 +190,8 @@ mod tests { let surface = Surface::xy_plane(); let face = Face::builder(&stores, surface) - .build_polygon_from_points([a, b, c, d, e]) + .with_exterior_polygon_from_points([a, b, c, d, e]) + .build() .into_face(); let triangles = triangulate(face)?; diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index b08c49ba44..f0fcb389f3 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -16,16 +16,32 @@ pub struct FaceBuilder<'a> { /// The surface that the [`Face`] is defined in pub surface: Surface, + + /// The exterior cycle that bounds the [`Face`] on the outside + /// + /// Must be provided by the caller, directly or using one of the `with_` + /// methods, before [`FaceBuilder::build`] is called. + pub exterior: Option, } impl<'a> FaceBuilder<'a> { - /// Construct a polygon from a list of points - pub fn build_polygon_from_points( - self, + /// Build the [`Face`] with an exterior polygon from the provided points + pub fn with_exterior_polygon_from_points( + mut self, points: impl IntoIterator>>, - ) -> FacePolygon<'a> { - let exterior = Cycle::builder(self.stores, self.surface) - .build_polygon_from_points(points); + ) -> Self { + self.exterior = Some( + Cycle::builder(self.stores, self.surface) + .build_polygon_from_points(points), + ); + self + } + + /// Construct a polygon from a list of points + pub fn build(self) -> FacePolygon<'a> { + let exterior = self + .exterior + .expect("Can't build `Face` without exterior cycle"); let face = Face::new(self.surface, exterior); FacePolygon { diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index 7a9698ad9c..705697e9ed 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -38,7 +38,8 @@ impl<'a> ShellBuilder<'a> { let faces = planes.map(|plane| { Face::builder(self.stores, plane) - .build_polygon_from_points(points) + .with_exterior_polygon_from_points(points) + .build() .into_face() }); diff --git a/crates/fj-kernel/src/builder/sketch.rs b/crates/fj-kernel/src/builder/sketch.rs index 8b39b55b86..2f993524fd 100644 --- a/crates/fj-kernel/src/builder/sketch.rs +++ b/crates/fj-kernel/src/builder/sketch.rs @@ -23,7 +23,8 @@ impl<'a> SketchBuilder<'a> { points: impl IntoIterator>>, ) -> Sketch { let face = Face::builder(self.stores, self.surface) - .build_polygon_from_points(points) + .with_exterior_polygon_from_points(points) + .build() .into_face(); Sketch::new().with_faces([face]) } diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 39424bb701..a38a3a3e1e 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -403,7 +403,8 @@ mod tests { let surface = Surface::xy_plane(); let object = Face::builder(&stores, surface) - .build_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .build() .into_face(); assert_eq!(3, object.curve_iter().count()); @@ -500,7 +501,8 @@ mod tests { let surface = Surface::xy_plane(); let face = Face::builder(&stores, surface) - .build_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) + .build() .into_face(); let object = Sketch::new().with_faces([face]); diff --git a/crates/fj-kernel/src/objects/face.rs b/crates/fj-kernel/src/objects/face.rs index 21a94387dd..540257d0b5 100644 --- a/crates/fj-kernel/src/objects/face.rs +++ b/crates/fj-kernel/src/objects/face.rs @@ -67,7 +67,11 @@ pub struct Face { impl Face { /// Build a `Face` using [`FaceBuilder`] pub fn builder(stores: &Stores, surface: Surface) -> FaceBuilder { - FaceBuilder { stores, surface } + FaceBuilder { + stores, + surface, + exterior: None, + } } /// Construct a new instance of `Face` diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 40e21bb3ea..2dc3e0d0f5 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -37,7 +37,8 @@ impl Shape for fj::Sketch { poly_chain.to_points().into_iter().map(Point::from); Face::builder(stores, surface) - .build_polygon_from_points(points) + .with_exterior_polygon_from_points(points) + .build() .into_face() .with_color(Color(self.color())) }