From 4ed8c815a6121d0f4c7fd3b18defaec355f292e7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 9 Nov 2022 22:22:42 +0100 Subject: [PATCH] Separate building and inserting objects This provides more flexibility, making it possible to use the partial object and builder infrastructure, without automatically opting into validation. This can be useful, especially in unit tests. --- .../fj-kernel/src/algorithms/approx/curve.rs | 13 ++++++--- .../src/algorithms/intersect/face_face.rs | 16 ++++++---- .../src/algorithms/intersect/face_point.rs | 25 +++++++++++----- .../src/algorithms/intersect/ray_face.rs | 10 ++++++- .../algorithms/intersect/surface_surface.rs | 7 +++-- .../fj-kernel/src/algorithms/reverse/face.rs | 6 ++-- crates/fj-kernel/src/algorithms/sweep/edge.rs | 23 +++++++++++---- crates/fj-kernel/src/algorithms/sweep/face.rs | 13 +++++++-- .../fj-kernel/src/algorithms/sweep/vertex.rs | 10 +++++-- .../src/algorithms/transform/face.rs | 6 ++-- .../fj-kernel/src/algorithms/transform/mod.rs | 12 +++++--- .../src/algorithms/triangulate/mod.rs | 10 +++++-- crates/fj-kernel/src/builder/edge.rs | 4 ++- crates/fj-kernel/src/builder/shell.rs | 21 ++++++++++++++ crates/fj-kernel/src/builder/sketch.rs | 3 ++ crates/fj-kernel/src/iter.rs | 19 ++++++++---- crates/fj-kernel/src/partial/maybe_partial.rs | 13 +++++++-- crates/fj-kernel/src/partial/objects/curve.rs | 17 +++-------- crates/fj-kernel/src/partial/objects/cycle.rs | 4 +-- crates/fj-kernel/src/partial/objects/edge.rs | 15 +++------- crates/fj-kernel/src/partial/objects/face.rs | 9 ++---- crates/fj-kernel/src/partial/objects/mod.rs | 11 +++---- .../fj-kernel/src/partial/objects/vertex.rs | 28 ++++-------------- crates/fj-kernel/src/partial/traits.rs | 7 ++--- crates/fj-kernel/src/validate/cycle.rs | 7 +++-- crates/fj-kernel/src/validate/edge.rs | 29 ++++++++++++------- crates/fj-kernel/src/validate/face.rs | 4 ++- crates/fj-kernel/src/validate/vertex.rs | 7 +++-- crates/fj-operations/src/difference_2d.rs | 4 ++- crates/fj-operations/src/sketch.rs | 6 +++- 30 files changed, 220 insertions(+), 139 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/approx/curve.rs b/crates/fj-kernel/src/algorithms/approx/curve.rs index 2f06121a04..16f9e26e4f 100644 --- a/crates/fj-kernel/src/algorithms/approx/curve.rs +++ b/crates/fj-kernel/src/algorithms/approx/curve.rs @@ -198,6 +198,7 @@ mod tests { use crate::{ algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint}, builder::CurveBuilder, + insert::Insert, objects::{Curve, Objects, Surface}, partial::HasPartial, path::GlobalPath, @@ -215,7 +216,8 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface)) .update_as_line_from_points([[1., 1.], [2., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let range = RangeOnPath::from([[0.], [1.]]); let approx = (&curve, range).approx(1.); @@ -236,7 +238,8 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface)) .update_as_line_from_points([[1., 1.], [1., 2.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let range = RangeOnPath::from([[0.], [1.]]); let approx = (&curve, range).approx(1.); @@ -255,7 +258,8 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface.clone())) .update_as_line_from_points([[0., 1.], [1., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let range = RangeOnPath::from([[0.], [TAU]]); let tolerance = 1.; @@ -287,7 +291,8 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface)) .update_as_circle_from_radius(1.) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let range = RangeOnPath::from([[0.], [TAU]]); let tolerance = 1.; diff --git a/crates/fj-kernel/src/algorithms/intersect/face_face.rs b/crates/fj-kernel/src/algorithms/intersect/face_face.rs index 66b41ac301..9207a208e3 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_face.rs @@ -68,8 +68,10 @@ mod tests { use crate::{ algorithms::intersect::CurveFaceIntersection, builder::{CurveBuilder, FaceBuilder}, + insert::Insert, objects::{Curve, Face, Objects}, partial::HasPartial, + validate::ValidationError, }; use super::FaceFaceIntersection; @@ -122,12 +124,14 @@ mod tests { let intersection = FaceFaceIntersection::compute([&a, &b], &objects)?; - let expected_curves = surfaces.try_map_ext(|surface| { - Curve::partial() - .with_surface(Some(surface)) - .update_as_line_from_points([[0., 0.], [1., 0.]]) - .build(&objects) - })?; + let expected_curves = + surfaces.try_map_ext(|surface| -> Result<_, ValidationError> { + Ok(Curve::partial() + .with_surface(Some(surface)) + .update_as_line_from_points([[0., 0.], [1., 0.]]) + .build(&objects)? + .insert(&objects)?) + })?; let expected_intervals = CurveFaceIntersection::from_intervals([[[-1.], [1.]]]); assert_eq!( diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index 6fa3d17b90..22c50b3f8e 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -137,6 +137,7 @@ mod tests { use crate::{ algorithms::intersect::{face_point::FacePointIntersection, Intersect}, builder::FaceBuilder, + insert::Insert, iter::ObjectIters, objects::{Face, Objects}, partial::HasPartial, @@ -150,7 +151,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([2., 1.]); let intersection = (&face, &point).intersect(); @@ -167,7 +169,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -187,7 +190,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 2.]); let intersection = (&face, &point).intersect(); @@ -212,7 +216,8 @@ mod tests { [3., 0.], [3., 4.], ]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -238,7 +243,8 @@ mod tests { [3., 1.], [0., 2.], ]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -265,7 +271,8 @@ mod tests { [4., 0.], [4., 5.], ]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 1.]); let intersection = (&face, &point).intersect(); @@ -285,7 +292,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 0.]); let intersection = (&face, &point).intersect(); @@ -314,7 +322,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let point = Point::from([1., 0.]); let intersection = (&face, &point).intersect(); diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs index 38201c3720..f5526972f0 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs @@ -153,6 +153,7 @@ mod tests { transform::TransformObject, }, builder::FaceBuilder, + insert::Insert, iter::ObjectIters, objects::{Face, Objects}, partial::HasPartial, @@ -174,6 +175,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([-1., 0., 0.], &objects)?; assert_eq!((&ray, &face).intersect(), None); @@ -196,6 +198,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([1., 0., 0.], &objects)?; assert_eq!( @@ -221,6 +224,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([0., 0., 2.], &objects)?; assert_eq!((&ray, &face).intersect(), None); @@ -243,6 +247,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([1., 1., 0.], &objects)?; let edge = face @@ -276,6 +281,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([1., 1., 1.], &objects)?; let vertex = face @@ -306,7 +312,8 @@ mod tests { [1., 1.], [-1., 1.], ]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!( (&ray, &face).intersect(), @@ -332,6 +339,7 @@ mod tests { [-1., 1.], ]) .build(&objects)? + .insert(&objects)? .translate([0., 0., 1.], &objects)?; assert_eq!((&ray, &face).intersect(), None); diff --git a/crates/fj-kernel/src/algorithms/intersect/surface_surface.rs b/crates/fj-kernel/src/algorithms/intersect/surface_surface.rs index 869e7cc4a0..7481608f93 100644 --- a/crates/fj-kernel/src/algorithms/intersect/surface_surface.rs +++ b/crates/fj-kernel/src/algorithms/intersect/surface_surface.rs @@ -93,6 +93,7 @@ mod tests { use crate::{ algorithms::transform::TransformObject, builder::CurveBuilder, + insert::Insert, objects::{Curve, Objects}, partial::HasPartial, }; @@ -124,11 +125,13 @@ mod tests { let expected_xy = Curve::partial() .with_surface(Some(xy.clone())) .update_as_u_axis() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let expected_xz = Curve::partial() .with_surface(Some(xz.clone())) .update_as_u_axis() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!( SurfaceSurfaceIntersection::compute([xy, xz], &objects)?, diff --git a/crates/fj-kernel/src/algorithms/reverse/face.rs b/crates/fj-kernel/src/algorithms/reverse/face.rs index 9f7a206073..4af2dfd6b0 100644 --- a/crates/fj-kernel/src/algorithms/reverse/face.rs +++ b/crates/fj-kernel/src/algorithms/reverse/face.rs @@ -1,4 +1,5 @@ use crate::{ + insert::Insert, objects::{Face, Objects}, partial::HasPartial, storage::Handle, @@ -15,10 +16,11 @@ impl Reverse for Handle { .map(|cycle| cycle.clone().reverse(objects)) .collect::, _>>()?; - Face::partial() + Ok(Face::partial() .with_exterior(exterior) .with_interiors(interiors) .with_color(self.color()) - .build(objects) + .build(objects)? + .insert(objects)?) } } diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index b4659507a3..e2d98a1754 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -3,6 +3,7 @@ use fj_math::{Line, Scalar, Vector}; use crate::{ algorithms::{reverse::Reverse, transform::TransformObject}, + insert::Insert, objects::{ Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, SurfaceVertex, Vertex, @@ -176,10 +177,11 @@ impl Sweep for (Handle, Color) { objects.cycles.insert(Cycle::new(edges))? }; - Face::partial() + Ok(Face::partial() .with_exterior(cycle) .with_color(color) - .build(objects) + .build(objects)? + .insert(objects)?) } } @@ -191,6 +193,7 @@ mod tests { use crate::{ algorithms::{reverse::Reverse, sweep::Sweep}, builder::HalfEdgeBuilder, + insert::Insert, objects::{Cycle, Face, HalfEdge, Objects, SurfaceVertex, Vertex}, partial::HasPartial, }; @@ -204,7 +207,8 @@ mod tests { objects.surfaces.xy_plane(), [[0., 0.], [1., 0.]], ) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let face = (half_edge, Color::default()).sweep([0., 0., 1.], &objects)?; @@ -218,7 +222,8 @@ mod tests { surface.clone(), [[0., 0.], [1., 0.]], ) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let side_up = HalfEdge::partial() .with_surface(surface.clone()) .with_back_vertex(Vertex::partial().with_surface_form( @@ -228,7 +233,8 @@ mod tests { SurfaceVertex::partial().with_position(Some([1., 1.])), )) .update_as_line_segment() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let top = HalfEdge::partial() .with_surface(surface.clone()) .with_back_vertex(Vertex::partial().with_surface_form( @@ -239,6 +245,7 @@ mod tests { )) .update_as_line_segment() .build(&objects)? + .insert(&objects)? .reverse(&objects)?; let side_down = HalfEdge::partial() @@ -251,13 +258,17 @@ mod tests { )) .update_as_line_segment() .build(&objects)? + .insert(&objects)? .reverse(&objects)?; let cycle = objects .cycles .insert(Cycle::new([bottom, side_up, top, side_down]))?; - Face::partial().with_exterior(cycle).build(&objects)? + Face::partial() + .with_exterior(cycle) + .build(&objects)? + .insert(&objects)? }; assert_eq!(face, expected_face); diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 3919832f7e..cc99370b6d 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -85,6 +85,7 @@ mod tests { use crate::{ algorithms::{reverse::Reverse, transform::TransformObject}, builder::{FaceBuilder, HalfEdgeBuilder}, + insert::Insert, objects::{Face, HalfEdge, Objects, Sketch}, partial::HasPartial, }; @@ -111,11 +112,13 @@ mod tests { .with_surface(surface.clone()) .with_exterior_polygon_from_points(TRIANGLE) .build(&objects)? + .insert(&objects)? .reverse(&objects)?; let top = Face::partial() .with_surface(surface.translate(UP, &objects)?) .with_exterior_polygon_from_points(TRIANGLE) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert!(solid.find_face(&bottom).is_some()); assert!(solid.find_face(&top).is_some()); @@ -129,7 +132,8 @@ mod tests { objects.surfaces.xy_plane(), [a, b], ) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; (half_edge, Color::default()).sweep(UP, &objects) }) .collect::, _>>()?; @@ -155,11 +159,13 @@ mod tests { .with_surface(surface.clone().translate(DOWN, &objects)?) .with_exterior_polygon_from_points(TRIANGLE) .build(&objects)? + .insert(&objects)? .reverse(&objects)?; let top = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points(TRIANGLE) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert!(solid.find_face(&bottom).is_some()); assert!(solid.find_face(&top).is_some()); @@ -174,6 +180,7 @@ mod tests { [a, b], ) .build(&objects)? + .insert(&objects)? .reverse(&objects)?; (half_edge, Color::default()).sweep(DOWN, &objects) }) diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index e99c493bc7..0e2d69e4a3 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -169,6 +169,7 @@ mod tests { use crate::{ algorithms::sweep::Sweep, builder::{CurveBuilder, HalfEdgeBuilder}, + insert::Insert, objects::{Curve, HalfEdge, Objects, Vertex}, partial::HasPartial, }; @@ -181,18 +182,21 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface.clone())) .update_as_u_axis() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let vertex = Vertex::partial() .with_position(Some([0.])) .with_curve(curve) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let half_edge = (vertex, surface.clone()).sweep([0., 0., 1.], &objects)?; let expected_half_edge = HalfEdge::partial() .update_as_line_segment_from_points(surface, [[0., 0.], [0., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!(half_edge, expected_half_edge); Ok(()) } diff --git a/crates/fj-kernel/src/algorithms/transform/face.rs b/crates/fj-kernel/src/algorithms/transform/face.rs index 833eaebaa7..58c4612a3e 100644 --- a/crates/fj-kernel/src/algorithms/transform/face.rs +++ b/crates/fj-kernel/src/algorithms/transform/face.rs @@ -1,6 +1,7 @@ use fj_math::Transform; use crate::{ + insert::Insert, objects::{Face, FaceSet, Objects}, partial::{HasPartial, PartialFace}, validate::ValidationError, @@ -26,11 +27,12 @@ impl TransformObject for PartialFace { let interiors = self .interiors() .map(|cycle| -> Result<_, ValidationError> { - cycle + Ok(cycle .into_partial() .transform(transform, objects)? .with_surface(surface.clone()) - .build(objects) + .build(objects)? + .insert(objects)?) }) .collect::, _>>()?; diff --git a/crates/fj-kernel/src/algorithms/transform/mod.rs b/crates/fj-kernel/src/algorithms/transform/mod.rs index f262a2750f..5e370e1988 100644 --- a/crates/fj-kernel/src/algorithms/transform/mod.rs +++ b/crates/fj-kernel/src/algorithms/transform/mod.rs @@ -13,10 +13,11 @@ mod vertex; use fj_math::{Transform, Vector}; use crate::{ + insert::Insert, objects::Objects, partial::{HasPartial, MaybePartial, Partial}, storage::Handle, - validate::ValidationError, + validate::{Validate, ValidationError}, }; /// Transform an object @@ -61,17 +62,20 @@ pub trait TransformObject: Sized { impl TransformObject for Handle where - T: HasPartial, + T: HasPartial + Insert, T::Partial: TransformObject, + ValidationError: From<::Error>, { fn transform( self, transform: &Transform, objects: &Objects, ) -> Result { - self.to_partial() + Ok(self + .to_partial() .transform(transform, objects)? - .build(objects) + .build(objects)? + .insert(objects)?) } } diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 6f9579c70e..a1a0ebe50d 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -85,6 +85,7 @@ mod tests { use crate::{ algorithms::approx::{Approx, Tolerance}, builder::FaceBuilder, + insert::Insert, objects::{Face, Objects}, partial::HasPartial, storage::Handle, @@ -105,7 +106,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([a, b, c, d]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let a = Point::from(a).to_xyz(); let b = Point::from(b).to_xyz(); @@ -141,7 +143,8 @@ mod tests { .with_surface(surface.clone()) .with_exterior_polygon_from_points([a, b, c, d]) .with_interior_polygon_from_points([e, f, g, h]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let triangles = triangulate(face)?; @@ -201,7 +204,8 @@ mod tests { let face = Face::partial() .with_surface(surface.clone()) .with_exterior_polygon_from_points([a, b, c, d, e]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let triangles = triangulate(face)?; diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index c97699b4fa..674183e119 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -2,6 +2,7 @@ use fj_interop::ext::ArrayExt; use fj_math::{Point, Scalar}; use crate::{ + insert::Insert, objects::{ Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex, VerticesInNormalizedOrder, @@ -89,7 +90,8 @@ impl HalfEdgeBuilder for PartialHalfEdge { .with_position(Some(path.point_from_path_coords(a_curve))) .with_surface(curve.surface()) .with_global_form(Some(global_vertex)) - .build(objects)?; + .build(objects)? + .insert(objects)?; let [back, front] = [a_curve, b_curve].map(|point_curve| { Vertex::partial() diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index 867519507b..34534a0227 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -6,6 +6,7 @@ use fj_math::Scalar; use crate::{ algorithms::transform::TransformObject, builder::{FaceBuilder, HalfEdgeBuilder}, + insert::Insert, objects::{ Curve, Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface, SurfaceVertex, Vertex, @@ -64,6 +65,8 @@ impl<'a> ShellBuilder<'a> { ]) .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }; let (sides, top_edges) = { @@ -97,6 +100,8 @@ impl<'a> ShellBuilder<'a> { ) .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }) .collect::>(); @@ -120,6 +125,8 @@ impl<'a> ShellBuilder<'a> { .update_as_line_segment() .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }) .collect::>(); @@ -157,6 +164,8 @@ impl<'a> ShellBuilder<'a> { .update_as_line_segment() .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }) .collect::>() }; @@ -180,6 +189,8 @@ impl<'a> ShellBuilder<'a> { .update_as_line_segment() .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }) .collect::>(); @@ -192,12 +203,16 @@ impl<'a> ShellBuilder<'a> { let cycle = Cycle::partial() .with_half_edges([bottom, side_up, top, side_down]) .build(self.objects) + .unwrap() + .insert(self.objects) .unwrap(); Face::partial() .with_exterior(cycle) .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }); (sides, tops) @@ -232,6 +247,8 @@ impl<'a> ShellBuilder<'a> { )) .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }); [a.clone(), b, c, d, a] @@ -259,6 +276,8 @@ impl<'a> ShellBuilder<'a> { .with_global_form(edge.global_form().clone()) .update_as_line_segment() .build(self.objects) + .unwrap() + .insert(self.objects) .unwrap(), ); } @@ -269,6 +288,8 @@ impl<'a> ShellBuilder<'a> { ) .build(self.objects) .unwrap() + .insert(self.objects) + .unwrap() }; self.faces.extend([bottom]); diff --git a/crates/fj-kernel/src/builder/sketch.rs b/crates/fj-kernel/src/builder/sketch.rs index aad2b9620f..34c66efd2c 100644 --- a/crates/fj-kernel/src/builder/sketch.rs +++ b/crates/fj-kernel/src/builder/sketch.rs @@ -1,6 +1,7 @@ use fj_math::Point; use crate::{ + insert::Insert, objects::{Face, FaceSet, Objects, Sketch, Surface}, partial::HasPartial, storage::Handle, @@ -51,6 +52,8 @@ impl<'a> SketchBuilder<'a> { .with_surface(surface.clone()) .with_exterior_polygon_from_points(points) .build(self.objects) + .unwrap() + .insert(self.objects) .unwrap()]); self } diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 2b73c8bd3b..61d91aa1d7 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -361,6 +361,7 @@ impl Iterator for Iter { mod tests { use crate::{ builder::{CurveBuilder, CycleBuilder, FaceBuilder, HalfEdgeBuilder}, + insert::Insert, objects::{ Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Objects, Shell, Sketch, Solid, SurfaceVertex, Vertex, @@ -378,7 +379,8 @@ mod tests { let object = Curve::partial() .with_surface(Some(surface)) .update_as_u_axis() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!(1, object.curve_iter().count()); assert_eq!(0, object.cycle_iter().count()); @@ -406,7 +408,8 @@ mod tests { [[0., 0.], [1., 0.], [0., 1.]], ) .close_with_line_segment() - .build(&objects)?; + .build(&objects)? + .insert(&objects); assert_eq!(3, object.curve_iter().count()); assert_eq!(1, object.cycle_iter().count()); @@ -431,7 +434,8 @@ mod tests { let object = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!(3, object.curve_iter().count()); assert_eq!(1, object.cycle_iter().count()); @@ -501,7 +505,8 @@ mod tests { objects.surfaces.xy_plane(), [[0., 0.], [1., 0.]], ) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; assert_eq!(1, object.curve_iter().count()); assert_eq!(0, object.cycle_iter().count()); @@ -547,7 +552,8 @@ mod tests { let face = Face::partial() .with_surface(surface) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let object = Sketch::builder(&objects).with_faces([face]).build(); assert_eq!(3, object.curve_iter().count()); @@ -613,7 +619,8 @@ mod tests { let curve = Curve::partial() .with_surface(Some(surface.clone())) .update_as_u_axis() - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; let global_vertex = objects .global_vertices .insert(GlobalVertex::from_position([0., 0., 0.]))?; diff --git a/crates/fj-kernel/src/partial/maybe_partial.rs b/crates/fj-kernel/src/partial/maybe_partial.rs index ecc6ad9eec..4a232fb714 100644 --- a/crates/fj-kernel/src/partial/maybe_partial.rs +++ b/crates/fj-kernel/src/partial/maybe_partial.rs @@ -1,13 +1,14 @@ use fj_math::Point; use crate::{ + insert::Insert, objects::{ Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, Surface, SurfaceVertex, Vertex, }, path::SurfacePath, storage::Handle, - validate::ValidationError, + validate::{Validate, ValidationError}, }; use super::{HasPartial, Partial}; @@ -91,9 +92,15 @@ impl MaybePartial { pub fn into_full( self, objects: &Objects, - ) -> Result, ValidationError> { + ) -> Result, ValidationError> + where + T: Insert, + ValidationError: From<::Error>, + { match self { - Self::Partial(partial) => partial.build(objects), + Self::Partial(partial) => { + Ok(partial.build(objects)?.insert(objects)?) + } Self::Full(full) => Ok(full), } } diff --git a/crates/fj-kernel/src/partial/objects/curve.rs b/crates/fj-kernel/src/partial/objects/curve.rs index f8840e1a01..6c08f77fd3 100644 --- a/crates/fj-kernel/src/partial/objects/curve.rs +++ b/crates/fj-kernel/src/partial/objects/curve.rs @@ -80,10 +80,7 @@ impl PartialCurve { } /// Build a full [`Curve`] from the partial curve - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { + pub fn build(self, objects: &Objects) -> Result { let path = self.path.expect("Can't build `Curve` without path"); let surface = self.surface.expect("Can't build `Curve` without surface"); @@ -94,9 +91,7 @@ impl PartialCurve { } .into_full(objects)?; - Ok(objects - .curves - .insert(Curve::new(surface, path, global_form))?) + Ok(Curve::new(surface, path, global_form)) } } @@ -128,12 +123,8 @@ impl PartialGlobalCurve { } /// Build a full [`GlobalCurve`] from the partial global curve - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { - let global_curve = objects.global_curves.insert(GlobalCurve)?; - Ok(global_curve) + pub fn build(self, _: &Objects) -> Result { + Ok(GlobalCurve) } } diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index d27531b531..bbefef9672 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -86,7 +86,7 @@ impl PartialCycle { pub fn build( mut self, objects: &Objects, - ) -> Result, ValidationError> { + ) -> Result { // Check that the cycle is closed. This will lead to a panic further // down anyway, but that panic would be super-confusing. This one should // be a bit more explicit on what is wrong. @@ -142,7 +142,7 @@ impl PartialCycle { half_edges.push(half_edge); } - Ok(objects.cycles.insert(Cycle::new(half_edges))?) + Ok(Cycle::new(half_edges)) } } diff --git a/crates/fj-kernel/src/partial/objects/edge.rs b/crates/fj-kernel/src/partial/objects/edge.rs index fb8d268ad0..f2d7e3cea7 100644 --- a/crates/fj-kernel/src/partial/objects/edge.rs +++ b/crates/fj-kernel/src/partial/objects/edge.rs @@ -102,10 +102,7 @@ impl PartialHalfEdge { } /// Build a full [`HalfEdge`] from the partial half-edge - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { + pub fn build(self, objects: &Objects) -> Result { let curve = self.curve.into_full(objects)?; let vertices = self.vertices.try_map_ext(|vertex| { vertex @@ -120,9 +117,7 @@ impl PartialHalfEdge { }) .into_full(objects)?; - Ok(objects - .half_edges - .insert(HalfEdge::new(vertices, global_form))?) + Ok(HalfEdge::new(vertices, global_form)) } } @@ -202,16 +197,14 @@ impl PartialGlobalEdge { pub fn build( self, objects: &Objects, - ) -> Result, ValidationError> { + ) -> Result { let curve = self.curve.into_full(objects)?; let vertices = self .vertices .expect("Can't build `GlobalEdge` without vertices") .try_map_ext(|global_vertex| global_vertex.into_full(objects))?; - Ok(objects - .global_edges - .insert(GlobalEdge::new(curve, vertices))?) + Ok(GlobalEdge::new(curve, vertices)) } } diff --git a/crates/fj-kernel/src/partial/objects/face.rs b/crates/fj-kernel/src/partial/objects/face.rs index c2dbf2a333..f2dcc8460b 100644 --- a/crates/fj-kernel/src/partial/objects/face.rs +++ b/crates/fj-kernel/src/partial/objects/face.rs @@ -84,10 +84,7 @@ impl PartialFace { } /// Construct a polygon from a list of points - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { + pub fn build(self, objects: &Objects) -> Result { let exterior = self.exterior.into_full(objects)?; let interiors = self .interiors @@ -96,9 +93,7 @@ impl PartialFace { .collect::, _>>()?; let color = self.color.unwrap_or_default(); - Ok(objects - .faces - .insert(Face::new(exterior, interiors, color))?) + Ok(Face::new(exterior, interiors, color)) } } diff --git a/crates/fj-kernel/src/partial/objects/mod.rs b/crates/fj-kernel/src/partial/objects/mod.rs index 5ab9c57b7b..277752a94b 100644 --- a/crates/fj-kernel/src/partial/objects/mod.rs +++ b/crates/fj-kernel/src/partial/objects/mod.rs @@ -4,12 +4,9 @@ pub mod edge; pub mod face; pub mod vertex; -use crate::{ - objects::{ - Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, - Objects, SurfaceVertex, Vertex, - }, - storage::Handle, +use crate::objects::{ + Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, + Objects, SurfaceVertex, Vertex, }; use super::{ @@ -34,7 +31,7 @@ macro_rules! impl_traits { fn build(self, objects: &Objects) -> Result< - Handle, + Self::Full, crate::validate::ValidationError > { diff --git a/crates/fj-kernel/src/partial/objects/vertex.rs b/crates/fj-kernel/src/partial/objects/vertex.rs index f3cd84539a..e7693ca502 100644 --- a/crates/fj-kernel/src/partial/objects/vertex.rs +++ b/crates/fj-kernel/src/partial/objects/vertex.rs @@ -76,10 +76,7 @@ impl PartialVertex { /// Panics, if position has not been provided. /// /// Panics, if curve has not been provided. - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { + pub fn build(self, objects: &Objects) -> Result { let position = self .position .expect("Cant' build `Vertex` without position"); @@ -98,11 +95,7 @@ impl PartialVertex { }) .into_full(objects)?; - Ok(objects.vertices.insert(Vertex::new( - position, - curve, - surface_form, - ))?) + Ok(Vertex::new(position, curve, surface_form)) } } @@ -185,7 +178,7 @@ impl PartialSurfaceVertex { pub fn build( self, objects: &Objects, - ) -> Result, ValidationError> { + ) -> Result { let position = self .position .expect("Can't build `SurfaceVertex` without position"); @@ -200,11 +193,7 @@ impl PartialSurfaceVertex { }) .into_full(objects)?; - Ok(objects.surface_vertices.insert(SurfaceVertex::new( - position, - surface, - global_form, - ))?) + Ok(SurfaceVertex::new(position, surface, global_form)) } } @@ -251,17 +240,12 @@ impl PartialGlobalVertex { } /// Build a full [`GlobalVertex`] from the partial global vertex - pub fn build( - self, - objects: &Objects, - ) -> Result, ValidationError> { + pub fn build(self, _: &Objects) -> Result { let position = self .position .expect("Can't build a `GlobalVertex` without a position"); - Ok(objects - .global_vertices - .insert(GlobalVertex::from_position(position))?) + Ok(GlobalVertex::from_position(position)) } } diff --git a/crates/fj-kernel/src/partial/traits.rs b/crates/fj-kernel/src/partial/traits.rs index e18bf1c4a4..c0b1a1d54a 100644 --- a/crates/fj-kernel/src/partial/traits.rs +++ b/crates/fj-kernel/src/partial/traits.rs @@ -1,4 +1,4 @@ -use crate::{objects::Objects, storage::Handle, validate::ValidationError}; +use crate::{objects::Objects, validate::ValidationError}; /// Implemented for objects that a partial object type exists for /// @@ -80,8 +80,5 @@ pub trait Partial: Default + for<'a> From<&'a Self::Full> { /// Calling `build` on a partial object that can't infer its missing parts /// is considered a programmer error, hence why this method doesn't return a /// [`Result`]. - fn build( - self, - objects: &Objects, - ) -> Result, ValidationError>; + fn build(self, objects: &Objects) -> Result; } diff --git a/crates/fj-kernel/src/validate/cycle.rs b/crates/fj-kernel/src/validate/cycle.rs index d20c74750e..45824c3013 100644 --- a/crates/fj-kernel/src/validate/cycle.rs +++ b/crates/fj-kernel/src/validate/cycle.rs @@ -67,9 +67,10 @@ impl CycleValidationError { mod tests { use crate::{ builder::{CycleBuilder, HalfEdgeBuilder, VertexBuilder}, + insert::Insert, objects::{Cycle, Objects}, partial::HasPartial, - validate::Validate, + validate::{Validate, ValidationError}, }; #[test] @@ -102,7 +103,9 @@ mod tests { let half_edges = half_edges .into_iter() - .map(|half_edge| half_edge.build(&objects)) + .map(|half_edge| -> anyhow::Result<_, ValidationError> { + Ok(half_edge.build(&objects)?.insert(&objects)?) + }) .collect::, _>>()?; Cycle::new(half_edges) diff --git a/crates/fj-kernel/src/validate/edge.rs b/crates/fj-kernel/src/validate/edge.rs index ab105ea324..7a4b837d1f 100644 --- a/crates/fj-kernel/src/validate/edge.rs +++ b/crates/fj-kernel/src/validate/edge.rs @@ -202,9 +202,10 @@ mod tests { use crate::{ builder::{HalfEdgeBuilder, VertexBuilder}, + insert::Insert, objects::{GlobalCurve, HalfEdge, Objects}, partial::HasPartial, - validate::Validate, + validate::{Validate, ValidationError}, }; #[test] @@ -223,7 +224,8 @@ mod tests { .to_partial() // Arranging for an equal but not identical curve here. .with_curve(valid.curve().to_partial()) - .build(&objects)?; + .build(&objects)? + .insert(&objects)?; HalfEdge::new(vertices, valid.global_form().clone()) }; @@ -250,7 +252,8 @@ mod tests { .global_form() .to_partial() .with_curve(Some(objects.global_curves.insert(GlobalCurve)?)) - .build(&objects)?, + .build(&objects)? + .insert(&objects)?, ); assert!(valid.validate().is_ok()); @@ -282,7 +285,8 @@ mod tests { // Creating equal but not identical vertices here. .map(|vertex| vertex.to_partial()), )) - .build(&objects)?, + .build(&objects)? + .insert(&objects)?, ); assert!(valid.validate().is_ok()); @@ -302,13 +306,16 @@ mod tests { ) .build(&objects)?; let invalid = HalfEdge::new( - valid.vertices().clone().try_map_ext(|vertex| { - vertex - .to_partial() - .with_position(Some([0.])) - .infer_surface_form() - .build(&objects) - })?, + valid.vertices().clone().try_map_ext( + |vertex| -> anyhow::Result<_, ValidationError> { + Ok(vertex + .to_partial() + .with_position(Some([0.])) + .infer_surface_form() + .build(&objects)? + .insert(&objects)?) + }, + )?, valid.global_form().clone(), ); diff --git a/crates/fj-kernel/src/validate/face.rs b/crates/fj-kernel/src/validate/face.rs index 098b5ea28a..6ef0345a28 100644 --- a/crates/fj-kernel/src/validate/face.rs +++ b/crates/fj-kernel/src/validate/face.rs @@ -106,6 +106,7 @@ mod tests { use crate::{ algorithms::reverse::Reverse, builder::{CycleBuilder, FaceBuilder}, + insert::Insert, objects::{Cycle, Face, Objects}, partial::HasPartial, validate::Validate, @@ -127,7 +128,8 @@ mod tests { [[1., 1.], [1., 2.], [2., 1.]], ) .close_with_line_segment() - .build(&objects)?]; + .build(&objects)? + .insert(&objects)?]; Face::new(valid.exterior().clone(), interiors, valid.color()) }; diff --git a/crates/fj-kernel/src/validate/vertex.rs b/crates/fj-kernel/src/validate/vertex.rs index 39d6d082dd..0ef103fe98 100644 --- a/crates/fj-kernel/src/validate/vertex.rs +++ b/crates/fj-kernel/src/validate/vertex.rs @@ -180,6 +180,7 @@ impl SurfaceVertexValidationError { mod tests { use crate::{ builder::{CurveBuilder, SurfaceVertexBuilder}, + insert::Insert, objects::{Curve, GlobalVertex, Objects, SurfaceVertex, Vertex}, partial::HasPartial, validate::Validate, @@ -204,7 +205,8 @@ mod tests { .surface_form() .to_partial() .with_surface(Some(objects.surfaces.xz_plane())) - .build(&objects)?, + .build(&objects)? + .insert(&objects)?, ); assert!(valid.validate().is_ok()); @@ -233,7 +235,8 @@ mod tests { .to_partial() .with_position(Some([1., 0.])) .infer_global_form() - .build(&objects)?, + .build(&objects)? + .insert(&objects)?, ); assert!(valid.validate().is_ok()); diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index 341ac2b305..54b60414a3 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use fj_interop::{debug::DebugInfo, ext::ArrayExt, mesh::Color}; use fj_kernel::{ algorithms::reverse::Reverse, + insert::Insert, iter::ObjectIters, objects::{Face, Objects, Sketch}, partial::HasPartial, @@ -83,7 +84,8 @@ impl Shape for fj::Difference2d { .with_exterior(exterior) .with_interiors(interiors) .with_color(Color(self.color())) - .build(objects)?, + .build(objects)? + .insert(objects)?, ); } diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 83ab1911c4..90e596d2ff 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ builder::{FaceBuilder, HalfEdgeBuilder}, + insert::Insert, objects::{Cycle, Face, HalfEdge, Objects, Sketch}, partial::HasPartial, validate::ValidationError, @@ -29,13 +30,15 @@ impl Shape for fj::Sketch { let half_edge = HalfEdge::partial() .with_surface(surface) .update_as_circle_from_radius(circle.radius(), objects)? - .build(objects)?; + .build(objects)? + .insert(objects)?; let cycle = objects.cycles.insert(Cycle::new([half_edge]))?; Face::partial() .with_exterior(cycle) .with_color(Color(self.color())) .build(objects)? + .insert(objects)? } fj::Chain::PolyChain(poly_chain) => { let points = @@ -46,6 +49,7 @@ impl Shape for fj::Sketch { .with_exterior_polygon_from_points(points) .with_color(Color(self.color())) .build(objects)? + .insert(objects)? } };