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)? } };