diff --git a/crates/fj-kernel/src/algorithms/approx/edge.rs b/crates/fj-kernel/src/algorithms/approx/edge.rs index 53ec893dc..250091818 100644 --- a/crates/fj-kernel/src/algorithms/approx/edge.rs +++ b/crates/fj-kernel/src/algorithms/approx/edge.rs @@ -246,10 +246,13 @@ mod tests { let surface = services.objects.surfaces.xz_plane(); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[1., 1.], [2., 1.], [1., 2.]]); + .update_as_polygon_from_points( + [[1., 1.], [2., 1.], [1., 2.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), @@ -278,10 +281,13 @@ mod tests { .build(&mut services.objects) .insert(&mut services.objects); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[1., 1.], [2., 1.], [1., 2.]]); + .update_as_polygon_from_points( + [[1., 1.], [2., 1.], [1., 2.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), @@ -310,10 +316,13 @@ mod tests { .build(&mut services.objects) .insert(&mut services.objects); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[0., 1.], [1., 1.], [1., 2.]]); + .update_as_polygon_from_points( + [[0., 1.], [1., 1.], [1., 2.]], + &mut services.objects, + ); half_edge.write().boundary[0] = Some(range.boundary[0]); half_edge.write().boundary[1] = Some(range.boundary[1]); @@ -352,7 +361,7 @@ mod tests { let surface = services.objects.surfaces.xz_plane(); let half_edge = { - let mut half_edge = PartialHalfEdge::default(); + let mut half_edge = PartialHalfEdge::new(&mut services.objects); half_edge.update_as_circle_from_radius(1.); let next_vertex = half_edge.start_vertex.clone(); diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs index ae5b67fd4..9bf243118 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_edge.rs @@ -74,7 +74,7 @@ mod tests { use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, geometry::curve::Curve, - partial::PartialCycle, + partial::{PartialCycle, PartialObject}, services::Services, }; @@ -87,10 +87,13 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); let curve = Curve::u_axis(); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[1., -1.], [1., 1.], [0., 1.]]); + .update_as_polygon_from_points( + [[1., -1.], [1., 1.], [0., 1.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), @@ -116,14 +119,13 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); let curve = Curve::u_axis(); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([ - [-1., -1.], - [-1., 1.], - [0., 1.], - ]); + .update_as_polygon_from_points( + [[-1., -1.], [-1., 1.], [0., 1.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), @@ -149,14 +151,13 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); let curve = Curve::u_axis(); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - ]); + .update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), @@ -177,10 +178,13 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); let curve = Curve::u_axis(); let half_edge = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[-1., 0.], [1., 0.], [1., 1.]]); + .update_as_polygon_from_points( + [[-1., 0.], [1., 0.], [1., 1.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs index 61020a75a..db1721a55 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs @@ -180,16 +180,15 @@ mod tests { ]; let face = { - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); face.exterior .write() - .update_as_polygon_from_points(exterior); - face.add_interior() + .update_as_polygon_from_points(exterior, &mut services.objects); + face.add_interior(&mut services.objects) .write() - .update_as_polygon_from_points(interior); + .update_as_polygon_from_points(interior, &mut services.objects); face.build(&mut services.objects) }; diff --git a/crates/fj-kernel/src/algorithms/intersect/face_face.rs b/crates/fj-kernel/src/algorithms/intersect/face_face.rs index 8ef66f4c5..96f54e8b6 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_face.rs @@ -86,11 +86,12 @@ mod tests { services.objects.surfaces.xz_plane(), ] .map(|surface| { - let mut face = PartialFace { - surface: Partial::from(surface), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points(points); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(surface); + face.exterior + .write() + .update_as_polygon_from_points(points, &mut services.objects); face.build(&mut services.objects) }); @@ -116,11 +117,12 @@ mod tests { services.objects.surfaces.xz_plane(), ]; let [a, b] = surfaces.clone().map(|surface| { - let mut face = PartialFace { - surface: Partial::from(surface), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points(points); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(surface); + face.exterior + .write() + .update_as_polygon_from_points(points, &mut services.objects); face.build(&mut services.objects) }); diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index fe3df1800..c761f1ad1 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -148,15 +148,13 @@ mod tests { fn point_is_outside_face() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [1., 1.], - [0., 2.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [1., 1.], [0., 2.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -170,15 +168,13 @@ mod tests { fn ray_hits_vertex_while_passing_outside() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [2., 1.], - [0., 2.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [2., 1.], [0., 2.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -195,15 +191,13 @@ mod tests { fn ray_hits_vertex_at_cycle_seam() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [4., 2.], - [0., 4.], - [0., 0.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[4., 2.], [0., 4.], [0., 0.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -220,16 +214,13 @@ mod tests { fn ray_hits_vertex_while_staying_inside() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [2., 1.], - [3., 0.], - [3., 4.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -246,16 +237,13 @@ mod tests { fn ray_hits_parallel_edge_and_leaves_face_at_vertex() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [2., 1.], - [3., 1.], - [0., 2.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -272,17 +260,13 @@ mod tests { fn ray_hits_parallel_edge_and_does_not_leave_face_there() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [2., 1.], - [3., 1.], - [4., 0.], - [4., 5.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [2., 1.], [3., 1.], [4., 0.], [4., 5.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -299,15 +283,13 @@ mod tests { fn point_is_coincident_with_edge() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [2., 0.], - [0., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [2., 0.], [0., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -330,15 +312,13 @@ mod tests { fn point_is_coincident_with_vertex() { let mut services = Services::new(); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [1., 0.], - [0., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [1., 0.], [0., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs index d0d9caa0c..111e24273 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs @@ -163,16 +163,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.yz_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.yz_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) @@ -187,16 +184,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.yz_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.yz_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) @@ -214,16 +208,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.yz_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.yz_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) @@ -238,16 +229,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.yz_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.yz_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) @@ -270,16 +258,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.yz_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.yz_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) @@ -305,16 +290,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -331,16 +313,13 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [-1., -1.], - [1., -1.], - [1., 1.], - [-1., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects) diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 944e8544b..226213844 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -26,10 +26,8 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { let path = path.into(); // The result of sweeping an edge is a face. Let's create that. - let mut face = PartialFace { - color: Some(color), - ..Default::default() - }; + let mut face = PartialFace::new(objects); + face.color = Some(color); // A face (and everything in it) is defined on a surface. A surface can // be created by sweeping a curve, so let's sweep the curve of the edge @@ -42,10 +40,10 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { } // Now we're ready to create the edges. - let mut edge_bottom = face.exterior.write().add_half_edge(); - let mut edge_up = face.exterior.write().add_half_edge(); - let mut edge_top = face.exterior.write().add_half_edge(); - let mut edge_down = face.exterior.write().add_half_edge(); + let mut edge_bottom = face.exterior.write().add_half_edge(objects); + let mut edge_up = face.exterior.write().add_half_edge(objects); + let mut edge_top = face.exterior.write().add_half_edge(objects); + let mut edge_down = face.exterior.write().add_half_edge(objects); // Those edges aren't fully defined yet. We'll do that shortly, but // first we have to figure a few things out. @@ -129,7 +127,7 @@ impl Sweep for (Handle, &Handle, &Surface, Color) { [edge_bottom.write(), edge_up.write(), edge_down.write()] .zip_ext(global_edges) .map(|(mut half_edge, global_edge)| { - half_edge.global_form = Partial::from(global_edge); + half_edge.global_form = global_edge; }); // And we're done creating the face! All that's left to do is build our diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index c0373826a..3c63a5bac 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -56,11 +56,10 @@ impl Sweep for Handle { let top_surface = bottom_face.surface().clone().translate(path, objects); - let mut top_face = PartialFace { - surface: Partial::from(top_surface.clone()), - color: Some(self.color()), - ..PartialFace::default() - }; + + let mut top_face = PartialFace::new(objects); + top_face.surface = Partial::from(top_surface.clone()); + top_face.color = Some(self.color()); for (i, cycle) in bottom_face.all_cycles().cloned().enumerate() { let cycle = cycle.reverse(objects); @@ -68,7 +67,7 @@ impl Sweep for Handle { let mut top_cycle = if i == 0 { top_face.exterior.clone() } else { - top_face.add_interior() + top_face.add_interior(objects) }; let mut original_edges = Vec::new(); @@ -90,9 +89,11 @@ impl Sweep for Handle { top_edges.push(Partial::from(top_edge)); } - top_cycle - .write() - .connect_to_closed_edges(top_edges, &top_surface.geometry()); + top_cycle.write().connect_to_closed_edges( + top_edges, + &top_surface.geometry(), + objects, + ); for (bottom, top) in original_edges .into_iter() diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index c57d73be9..5406e88b4 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -96,13 +96,11 @@ mod tests { let c = [2., 2.]; let d = [0., 1.]; - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; + let mut face = PartialFace::new(&mut services.objects); + face.surface = Partial::from(services.objects.surfaces.xy_plane()); face.exterior .write() - .update_as_polygon_from_points([a, b, c, d]); + .update_as_polygon_from_points([a, b, c, d], &mut services.objects); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -137,16 +135,15 @@ mod tests { let h = [3., 1.]; let surface = services.objects.surfaces.xy_plane(); - let mut face = PartialFace { - surface: Partial::from(surface.clone()), - ..Default::default() - }; + + let mut face = PartialFace::new(&mut services.objects); + face.surface = Partial::from(surface.clone()); face.exterior .write() - .update_as_polygon_from_points([a, b, c, d]); - face.add_interior() + .update_as_polygon_from_points([a, b, c, d], &mut services.objects); + face.add_interior(&mut services.objects) .write() - .update_as_polygon_from_points([e, f, g, h]); + .update_as_polygon_from_points([e, f, g, h], &mut services.objects); let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -203,13 +200,13 @@ mod tests { let e = [0., 9.]; let surface = services.objects.surfaces.xy_plane(); - let mut face = PartialFace { - surface: Partial::from(surface.clone()), - ..Default::default() - }; - face.exterior - .write() - .update_as_polygon_from_points([a, b, c, d, e]); + + let mut face = PartialFace::new(&mut services.objects); + face.surface = Partial::from(surface.clone()); + face.exterior.write().update_as_polygon_from_points( + [a, b, c, d, e], + &mut services.objects, + ); let face = face .build(&mut services.objects) .insert(&mut services.objects); diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index ddec16daa..fdb390439 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -3,8 +3,9 @@ use itertools::Itertools; use crate::{ geometry::surface::SurfaceGeometry, - objects::HalfEdge, + objects::{HalfEdge, Objects}, partial::{Partial, PartialCycle}, + services::Service, }; use super::{HalfEdgeBuilder, ObjectArgument}; @@ -20,12 +21,16 @@ pub trait CycleBuilder { /// /// If this is the first half-edge being added, it is connected to itself, /// meaning its front and back vertices are the same. - fn add_half_edge(&mut self) -> Partial; + fn add_half_edge( + &mut self, + objects: &mut Service, + ) -> Partial; /// Update cycle as a polygon from the provided points fn update_as_polygon_from_points( &mut self, points: O, + objects: &mut Service, ) -> O::SameSize> where O: ObjectArgument

, @@ -41,6 +46,7 @@ pub trait CycleBuilder { &mut self, edges: O, surface: &SurfaceGeometry, + objects: &mut Service, ) -> O::SameSize> where O: ObjectArgument>; @@ -53,8 +59,11 @@ pub trait CycleBuilder { } impl CycleBuilder for PartialCycle { - fn add_half_edge(&mut self) -> Partial { - let half_edge = Partial::new(); + fn add_half_edge( + &mut self, + objects: &mut Service, + ) -> Partial { + let half_edge = Partial::new(objects); self.half_edges.push(half_edge.clone()); half_edge } @@ -62,6 +71,7 @@ impl CycleBuilder for PartialCycle { fn update_as_polygon_from_points( &mut self, points: O, + objects: &mut Service, ) -> O::SameSize> where O: ObjectArgument

, @@ -70,7 +80,7 @@ impl CycleBuilder for PartialCycle { let mut start_positions = Vec::new(); let half_edges = points.map(|point| { start_positions.push(point.into()); - self.add_half_edge() + self.add_half_edge(objects) }); for ((start, end), half_edge) in start_positions @@ -88,12 +98,13 @@ impl CycleBuilder for PartialCycle { &mut self, edges: O, surface: &SurfaceGeometry, + objects: &mut Service, ) -> O::SameSize> where O: ObjectArgument>, { edges.map_with_prev(|other, prev| { - let mut this = self.add_half_edge(); + let mut this = self.add_half_edge(objects); this.write().update_from_other_edge(&other, &prev, surface); this }) diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 571878f22..c7d461616 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -7,7 +7,7 @@ use crate::{ surface::SurfaceGeometry, }, objects::{HalfEdge, Vertex}, - partial::{MaybeCurve, Partial, PartialGlobalEdge, PartialHalfEdge}, + partial::{MaybeCurve, Partial, PartialHalfEdge}, }; /// Builder API for [`PartialHalfEdge`] @@ -253,11 +253,3 @@ impl HalfEdgeBuilder for PartialHalfEdge { other_prev.read().start_vertex.read().position; } } - -/// Builder API for [`PartialGlobalEdge`] -pub trait GlobalEdgeBuilder { - // No methods are currently defined. This trait serves as a placeholder, to - // make it clear where to add such methods, once necessary. -} - -impl GlobalEdgeBuilder for PartialGlobalEdge {} diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index 9dd4b5502..2ee8339d3 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -1,17 +1,24 @@ use crate::{ - objects::Cycle, + objects::{Cycle, Objects}, partial::{Partial, PartialFace}, + services::Service, }; /// Builder API for [`PartialFace`] pub trait FaceBuilder { /// Add an interior cycle - fn add_interior(&mut self) -> Partial; + fn add_interior( + &mut self, + objects: &mut Service, + ) -> Partial; } impl FaceBuilder for PartialFace { - fn add_interior(&mut self) -> Partial { - let cycle = Partial::new(); + fn add_interior( + &mut self, + objects: &mut Service, + ) -> Partial { + let cycle = Partial::new(objects); self.interiors.push(cycle.clone()); cycle } diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 4c0def19b..c7426ad9c 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -13,14 +13,9 @@ mod vertex; use std::array; pub use self::{ - cycle::CycleBuilder, - edge::{GlobalEdgeBuilder, HalfEdgeBuilder}, - face::FaceBuilder, - shell::ShellBuilder, - sketch::SketchBuilder, - solid::SolidBuilder, - surface::SurfaceBuilder, - vertex::VertexBuilder, + cycle::CycleBuilder, edge::HalfEdgeBuilder, face::FaceBuilder, + shell::ShellBuilder, sketch::SketchBuilder, solid::SolidBuilder, + surface::SurfaceBuilder, vertex::VertexBuilder, }; /// Pass objects to a builder method diff --git a/crates/fj-kernel/src/partial/mod.rs b/crates/fj-kernel/src/partial/mod.rs index 35979ce53..0ccf0c466 100644 --- a/crates/fj-kernel/src/partial/mod.rs +++ b/crates/fj-kernel/src/partial/mod.rs @@ -16,15 +16,9 @@ mod wrapper; pub use self::{ objects::{ - curve::MaybeCurve, - cycle::PartialCycle, - edge::{PartialGlobalEdge, PartialHalfEdge}, - face::PartialFace, - shell::PartialShell, - sketch::PartialSketch, - solid::PartialSolid, - surface::PartialSurface, - vertex::PartialVertex, + curve::MaybeCurve, cycle::PartialCycle, edge::PartialHalfEdge, + face::PartialFace, shell::PartialShell, sketch::PartialSketch, + solid::PartialSolid, surface::PartialSurface, vertex::PartialVertex, }, traits::{HasPartial, PartialObject}, wrapper::{FullToPartialCache, Partial}, diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 7718f52ad..5615a74a1 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -5,7 +5,7 @@ use crate::{ }; /// A partial [`Cycle`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialCycle { /// The half-edges that make up the cycle pub half_edges: Vec>, @@ -14,6 +14,12 @@ pub struct PartialCycle { impl PartialObject for PartialCycle { type Full = Cycle; + fn new(_: &mut Service) -> Self { + Self { + half_edges: Vec::new(), + } + } + fn from_full(cycle: &Self::Full, cache: &mut FullToPartialCache) -> Self { Self { half_edges: cycle diff --git a/crates/fj-kernel/src/partial/objects/edge.rs b/crates/fj-kernel/src/partial/objects/edge.rs index 4b49eb84d..50c9b197c 100644 --- a/crates/fj-kernel/src/partial/objects/edge.rs +++ b/crates/fj-kernel/src/partial/objects/edge.rs @@ -1,9 +1,11 @@ use fj_math::Point; use crate::{ + insert::Insert, objects::{GlobalEdge, HalfEdge, Objects, Vertex}, partial::{FullToPartialCache, MaybeCurve, Partial, PartialObject}, services::Service, + storage::Handle, }; /// A partial [`HalfEdge`] @@ -19,7 +21,7 @@ pub struct PartialHalfEdge { pub start_vertex: Partial, /// The global form of the half-edge - pub global_form: Partial, + pub global_form: Handle, } impl PartialHalfEdge { @@ -45,6 +47,15 @@ impl PartialHalfEdge { impl PartialObject for PartialHalfEdge { type Full = HalfEdge; + fn new(objects: &mut Service) -> Self { + Self { + curve: None, + boundary: [None; 2], + start_vertex: Partial::new(objects), + global_form: GlobalEdge::new().insert(objects), + } + } + fn from_full( half_edge: &Self::Full, cache: &mut FullToPartialCache, @@ -56,10 +67,7 @@ impl PartialObject for PartialHalfEdge { half_edge.start_vertex().clone(), cache, ), - global_form: Partial::from_full( - half_edge.global_form().clone(), - cache, - ), + global_form: half_edge.global_form().clone(), } } @@ -76,39 +84,7 @@ impl PartialObject for PartialHalfEdge { point.expect("Can't build `HalfEdge` without boundary positions") }); let start_vertex = self.start_vertex.build(objects); - let global_form = self.global_form.build(objects); - - HalfEdge::new(curve, boundary, start_vertex, global_form) - } -} - -impl Default for PartialHalfEdge { - fn default() -> Self { - let curve = None; - let start_vertex = Partial::default(); - let global_form = Partial::default(); - - Self { - curve, - boundary: [None; 2], - start_vertex, - global_form, - } - } -} - -/// A partial [`GlobalEdge`] -#[derive(Clone, Debug, Default)] -pub struct PartialGlobalEdge {} - -impl PartialObject for PartialGlobalEdge { - type Full = GlobalEdge; - - fn from_full(_: &Self::Full, _: &mut FullToPartialCache) -> Self { - Self {} - } - fn build(self, _: &mut Service) -> Self::Full { - GlobalEdge::new() + HalfEdge::new(curve, boundary, start_vertex, self.global_form) } } diff --git a/crates/fj-kernel/src/partial/objects/face.rs b/crates/fj-kernel/src/partial/objects/face.rs index 86b03bf0f..ba751b7d7 100644 --- a/crates/fj-kernel/src/partial/objects/face.rs +++ b/crates/fj-kernel/src/partial/objects/face.rs @@ -8,7 +8,7 @@ use crate::{ }; /// A partial [`Face`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialFace { /// The surface that the face is defined in pub surface: Partial, @@ -28,6 +28,15 @@ pub struct PartialFace { impl PartialObject for PartialFace { type Full = Face; + fn new(objects: &mut Service) -> Self { + Self { + surface: Partial::new(objects), + exterior: Partial::new(objects), + interiors: Vec::new(), + color: None, + } + } + fn from_full(face: &Self::Full, cache: &mut FullToPartialCache) -> Self { Self { surface: Partial::from_full(face.surface().clone(), cache), diff --git a/crates/fj-kernel/src/partial/objects/shell.rs b/crates/fj-kernel/src/partial/objects/shell.rs index 6802310a3..b7f3fcc1d 100644 --- a/crates/fj-kernel/src/partial/objects/shell.rs +++ b/crates/fj-kernel/src/partial/objects/shell.rs @@ -5,7 +5,7 @@ use crate::{ }; /// A partial [`Shell`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialShell { /// The faces that make up the shell pub faces: Vec>, @@ -14,6 +14,10 @@ pub struct PartialShell { impl PartialObject for PartialShell { type Full = Shell; + fn new(_: &mut Service) -> Self { + Self { faces: Vec::new() } + } + fn from_full(shell: &Self::Full, cache: &mut FullToPartialCache) -> Self { Self { faces: shell diff --git a/crates/fj-kernel/src/partial/objects/sketch.rs b/crates/fj-kernel/src/partial/objects/sketch.rs index 2481543fb..74066ce33 100644 --- a/crates/fj-kernel/src/partial/objects/sketch.rs +++ b/crates/fj-kernel/src/partial/objects/sketch.rs @@ -5,7 +5,7 @@ use crate::{ }; /// A partial [`Sketch`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialSketch { /// The faces that make up the sketch pub faces: Vec>, @@ -14,6 +14,10 @@ pub struct PartialSketch { impl PartialObject for PartialSketch { type Full = Sketch; + fn new(_: &mut Service) -> Self { + Self { faces: Vec::new() } + } + fn from_full(sketch: &Self::Full, cache: &mut FullToPartialCache) -> Self { Self { faces: sketch diff --git a/crates/fj-kernel/src/partial/objects/solid.rs b/crates/fj-kernel/src/partial/objects/solid.rs index 6384d8bc9..6ab762ccb 100644 --- a/crates/fj-kernel/src/partial/objects/solid.rs +++ b/crates/fj-kernel/src/partial/objects/solid.rs @@ -5,7 +5,7 @@ use crate::{ }; /// A partial [`Solid`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialSolid { /// The shells that make up the solid pub shells: Vec>, @@ -14,6 +14,10 @@ pub struct PartialSolid { impl PartialObject for PartialSolid { type Full = Solid; + fn new(_: &mut Service) -> Self { + Self { shells: Vec::new() } + } + fn from_full(solid: &Self::Full, cache: &mut FullToPartialCache) -> Self { Self { shells: solid diff --git a/crates/fj-kernel/src/partial/objects/surface.rs b/crates/fj-kernel/src/partial/objects/surface.rs index 0c85241e2..c2eec099a 100644 --- a/crates/fj-kernel/src/partial/objects/surface.rs +++ b/crates/fj-kernel/src/partial/objects/surface.rs @@ -6,7 +6,7 @@ use crate::{ }; /// A partial [`Surface`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialSurface { /// The surface's geometry pub geometry: Option, @@ -15,6 +15,10 @@ pub struct PartialSurface { impl PartialObject for PartialSurface { type Full = Surface; + fn new(_: &mut Service) -> Self { + Self { geometry: None } + } + fn from_full(surface: &Self::Full, _: &mut FullToPartialCache) -> Self { Self { geometry: Some(surface.geometry()), diff --git a/crates/fj-kernel/src/partial/objects/vertex.rs b/crates/fj-kernel/src/partial/objects/vertex.rs index fc6be85ec..00cd408fd 100644 --- a/crates/fj-kernel/src/partial/objects/vertex.rs +++ b/crates/fj-kernel/src/partial/objects/vertex.rs @@ -7,7 +7,7 @@ use crate::{ }; /// A partial [`Vertex`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PartialVertex { /// The position of the vertex pub position: Option>, @@ -16,6 +16,10 @@ pub struct PartialVertex { impl PartialObject for PartialVertex { type Full = Vertex; + fn new(_: &mut Service) -> Self { + Self { position: None } + } + fn from_full( global_vertex: &Self::Full, _: &mut FullToPartialCache, diff --git a/crates/fj-kernel/src/partial/traits.rs b/crates/fj-kernel/src/partial/traits.rs index 089b2eb82..0a61347f8 100644 --- a/crates/fj-kernel/src/partial/traits.rs +++ b/crates/fj-kernel/src/partial/traits.rs @@ -11,10 +11,13 @@ pub trait HasPartial { } /// Implemented for partial objects -pub trait PartialObject: Clone + Debug + Default { +pub trait PartialObject: Clone + Debug { /// The type representing the full object type Full: HasPartial; + /// Construct a default partial object + fn new(objects: &mut Service) -> Self; + /// Construct a partial object from a full one fn from_full(full: &Self::Full, cache: &mut FullToPartialCache) -> Self; @@ -35,7 +38,6 @@ macro_rules! impl_trait { impl_trait!( Cycle, PartialCycle; Face, PartialFace; - GlobalEdge, PartialGlobalEdge; HalfEdge, PartialHalfEdge; Shell, PartialShell; Sketch, PartialSketch; diff --git a/crates/fj-kernel/src/partial/wrapper.rs b/crates/fj-kernel/src/partial/wrapper.rs index 5effa6bb3..d42353bda 100644 --- a/crates/fj-kernel/src/partial/wrapper.rs +++ b/crates/fj-kernel/src/partial/wrapper.rs @@ -29,8 +29,8 @@ pub struct Partial { impl Partial { /// Construct a `Partial` with a default inner partial object - pub fn new() -> Self { - Self::from_partial(T::Partial::default()) + pub fn new(objects: &mut Service) -> Self { + Self::from_partial(T::Partial::new(objects)) } /// Construct a `Partial` from a partial object @@ -142,12 +142,6 @@ impl Clone for Partial { } } -impl Default for Partial { - fn default() -> Self { - Self::new() - } -} - impl From> for Partial { fn from(full: Handle) -> Self { let mut cache = FullToPartialCache::default(); diff --git a/crates/fj-kernel/src/validate/edge.rs b/crates/fj-kernel/src/validate/edge.rs index bacc0fd61..e8ca480c5 100644 --- a/crates/fj-kernel/src/validate/edge.rs +++ b/crates/fj-kernel/src/validate/edge.rs @@ -78,7 +78,7 @@ mod tests { use crate::{ builder::{CycleBuilder, HalfEdgeBuilder}, objects::HalfEdge, - partial::PartialCycle, + partial::{PartialCycle, PartialObject}, services::Services, validate::{HalfEdgeValidationError, Validate, ValidationError}, }; @@ -90,10 +90,13 @@ mod tests { let valid = { let surface = services.objects.surfaces.xy_plane(); - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(&mut services.objects); let [mut half_edge, next_half_edge, _] = cycle - .update_as_polygon_from_points([[0., 0.], [1., 0.], [1., 1.]]); + .update_as_polygon_from_points( + [[0., 0.], [1., 0.], [1., 1.]], + &mut services.objects, + ); half_edge.write().infer_vertex_positions_if_necessary( &surface.geometry(), next_half_edge.read().start_vertex.clone(), diff --git a/crates/fj-kernel/src/validate/face.rs b/crates/fj-kernel/src/validate/face.rs index 41766b656..1965f197c 100644 --- a/crates/fj-kernel/src/validate/face.rs +++ b/crates/fj-kernel/src/validate/face.rs @@ -151,20 +151,19 @@ mod tests { let mut services = Services::new(); let valid = { - let mut face = PartialFace { - surface: Partial::from(services.objects.surfaces.xy_plane()), - ..Default::default() - }; - face.exterior.write().update_as_polygon_from_points([ - [0., 0.], - [3., 0.], - [0., 3.], - ]); - face.add_interior().write().update_as_polygon_from_points([ - [1., 1.], - [1., 2.], - [2., 1.], - ]); + let mut face = PartialFace::new(&mut services.objects); + + face.surface = Partial::from(services.objects.surfaces.xy_plane()); + face.exterior.write().update_as_polygon_from_points( + [[0., 0.], [3., 0.], [0., 3.]], + &mut services.objects, + ); + face.add_interior(&mut services.objects) + .write() + .update_as_polygon_from_points( + [[1., 1.], [1., 2.], [2., 1.]], + &mut services.objects, + ); face.build(&mut services.objects) }; let invalid = { @@ -200,12 +199,11 @@ mod tests { let valid = { let surface = services.objects.surfaces.xy_plane(); - let mut face = PartialFace { - surface: Partial::from(surface.clone()), - ..Default::default() - }; + let mut face = PartialFace::new(&mut services.objects); + face.surface = Partial::from(surface.clone()); - let mut half_edge = face.exterior.write().add_half_edge(); + let mut half_edge = + face.exterior.write().add_half_edge(&mut services.objects); half_edge.write().update_as_circle_from_radius(1.); let next_vertex = half_edge.read().start_vertex.clone(); half_edge.write().infer_vertex_positions_if_necessary( diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 667cda4e1..40766b1cd 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -31,23 +31,23 @@ impl Shape for fj::Sketch { let surface = Partial::from(surface); let half_edge = { - let mut half_edge = PartialHalfEdge::default(); + let mut half_edge = PartialHalfEdge::new(objects); half_edge.update_as_circle_from_radius(circle.radius()); Partial::from_partial(half_edge) }; let exterior = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(objects); cycle.half_edges.push(half_edge); Partial::from_partial(cycle) }; - PartialFace { - surface, - exterior, - color: Some(Color(self.color())), - ..Default::default() - } + let mut face = PartialFace::new(objects); + face.surface = surface; + face.exterior = exterior; + face.color = Some(Color(self.color())); + + face } fj::Chain::PolyChain(poly_chain) => { let segments = poly_chain.to_segments(); @@ -57,14 +57,14 @@ impl Shape for fj::Sketch { ); let exterior = { - let mut cycle = PartialCycle::default(); + let mut cycle = PartialCycle::new(objects); let half_edges = poly_chain .to_segments() .into_iter() .map(|fj::SketchSegment { endpoint, route }| { let endpoint = Point::from(endpoint); - let half_edge = cycle.add_half_edge(); + let half_edge = cycle.add_half_edge(objects); (half_edge, endpoint, route) }) .collect::>(); @@ -91,12 +91,12 @@ impl Shape for fj::Sketch { Partial::from_partial(cycle) }; - PartialFace { - surface: Partial::from(surface), - exterior, - color: Some(Color(self.color())), - ..Default::default() - } + let mut face = PartialFace::new(objects); + face.surface = Partial::from(surface); + face.exterior = exterior; + face.color = Some(Color(self.color())); + + face } };