diff --git a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs index a702b6035..383e6fa45 100644 --- a/crates/fj-kernel/src/algorithms/intersect/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/curve_face.rs @@ -185,10 +185,19 @@ mod tests { [ 1., -1.], ]; - let face = PartialFace::default() - .with_exterior_polygon_from_points(surface.clone(), exterior) - .with_interior_polygon_from_points(surface, interior) - .build(&mut services.objects); + let face = { + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), + exterior, + ); + face.with_interior_polygon_from_points( + Partial::from_full_entry_point(surface), + interior, + ); + + face.build(&mut services.objects) + }; let expected = CurveFaceIntersection::from_intervals([[[1.], [2.]], [[4.], [5.]]]); diff --git a/crates/fj-kernel/src/algorithms/intersect/face_face.rs b/crates/fj-kernel/src/algorithms/intersect/face_face.rs index 247eb0b1b..3f38743e6 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_face.rs @@ -93,9 +93,13 @@ mod tests { services.objects.surfaces.xz_plane(), ] .map(|surface| { - PartialFace::default() - .with_exterior_polygon_from_points(surface, points) - .build(&mut services.objects) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + points, + ); + + face.build(&mut services.objects) }); let intersection = @@ -120,9 +124,13 @@ mod tests { services.objects.surfaces.xz_plane(), ]; let [a, b] = surfaces.clone().map(|surface| { - PartialFace::default() - .with_exterior_polygon_from_points(surface, points) - .build(&mut services.objects) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + points, + ); + + face.build(&mut services.objects) }); let intersection = diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index 9b91005b8..122c689c6 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -139,7 +139,7 @@ mod tests { builder::FaceBuilder, insert::Insert, iter::ObjectIters, - partial::{PartialFace, PartialObject}, + partial::{Partial, PartialFace, PartialObject}, services::Services, }; @@ -148,11 +148,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [1., 1.], [0., 2.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [1., 1.], [0., 2.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([2., 1.]); @@ -166,11 +167,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [2., 1.], [0., 2.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [2., 1.], [0., 2.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 1.]); @@ -187,11 +189,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[4., 2.], [0., 4.], [0., 0.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[4., 2.], [0., 4.], [0., 0.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 2.]); @@ -208,11 +211,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [2., 1.], [3., 0.], [3., 4.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 1.]); @@ -229,11 +233,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [2., 1.], [3., 1.], [0., 2.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 1.]); @@ -250,11 +255,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [2., 1.], [3., 1.], [4., 0.], [4., 5.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [2., 1.], [3., 1.], [4., 0.], [4., 5.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 1.]); @@ -271,11 +277,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [2., 0.], [0., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [2., 0.], [0., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 0.]); @@ -301,11 +308,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [1., 0.], [0., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [1., 0.], [0., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let point = Point::from([1., 0.]); diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs index 3c4ef18e0..3050d5724 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs @@ -155,7 +155,7 @@ mod tests { builder::FaceBuilder, insert::Insert, iter::ObjectIters, - partial::{PartialFace, PartialObject}, + partial::{Partial, PartialFace, PartialObject}, services::Services, }; @@ -166,11 +166,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.yz_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([-1., 0., 0.], &mut services.objects); @@ -185,11 +186,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.yz_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([1., 0., 0.], &mut services.objects); @@ -207,11 +209,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.yz_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([0., 0., 2.], &mut services.objects); @@ -226,11 +229,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.yz_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([1., 1., 0.], &mut services.objects); @@ -256,11 +260,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.yz_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([1., 1., 1.], &mut services.objects); @@ -284,11 +289,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -305,11 +311,12 @@ mod tests { let ray = HorizontalRayToTheRight::from([0., 0., 0.]); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[-1., -1.], [1., -1.], [1., 1.], [-1., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects) .translate([0., 0., 1.], &mut services.objects); diff --git a/crates/fj-kernel/src/algorithms/sweep/face.rs b/crates/fj-kernel/src/algorithms/sweep/face.rs index 0d0bb546a..0cb5b7bf0 100644 --- a/crates/fj-kernel/src/algorithms/sweep/face.rs +++ b/crates/fj-kernel/src/algorithms/sweep/face.rs @@ -112,16 +112,23 @@ mod tests { .build(&mut services.objects) .sweep(UP, &mut services.objects); - let bottom = PartialFace::default() - .with_exterior_polygon_from_points(surface.clone(), TRIANGLE) + let mut bottom = PartialFace::default(); + bottom.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), + TRIANGLE, + ); + let bottom = bottom .build(&mut services.objects) .insert(&mut services.objects) .reverse(&mut services.objects); - let top = PartialFace::default() - .with_exterior_polygon_from_points( + let mut top = PartialFace::default(); + top.with_exterior_polygon_from_points( + Partial::from_full_entry_point( surface.translate(UP, &mut services.objects), - TRIANGLE, - ) + ), + TRIANGLE, + ); + let top = top .build(&mut services.objects) .insert(&mut services.objects); @@ -165,16 +172,23 @@ mod tests { .build(&mut services.objects) .sweep(DOWN, &mut services.objects); - let bottom = PartialFace::default() - .with_exterior_polygon_from_points( + let mut bottom = PartialFace::default(); + bottom.with_exterior_polygon_from_points( + Partial::from_full_entry_point( surface.clone().translate(DOWN, &mut services.objects), - TRIANGLE, - ) + ), + TRIANGLE, + ); + let bottom = bottom .build(&mut services.objects) .insert(&mut services.objects) .reverse(&mut services.objects); - let top = PartialFace::default() - .with_exterior_polygon_from_points(surface, TRIANGLE) + let mut top = PartialFace::default(); + top.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + TRIANGLE, + ); + let top = top .build(&mut services.objects) .insert(&mut services.objects); diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 3805207ee..3776989ba 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -80,7 +80,7 @@ mod tests { builder::FaceBuilder, insert::Insert, objects::Face, - partial::{PartialFace, PartialObject}, + partial::{Partial, PartialFace, PartialObject}, services::Services, storage::Handle, }; @@ -97,8 +97,12 @@ mod tests { let d = [0., 1.]; let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points(surface, [a, b, c, d]) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [a, b, c, d], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -132,9 +136,16 @@ mod tests { let h = [3., 1.]; let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points(surface.clone(), [a, b, c, d]) - .with_interior_polygon_from_points(surface.clone(), [e, f, g, h]) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), + [a, b, c, d], + ); + face.with_interior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), + [e, f, g, h], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); @@ -190,8 +201,12 @@ mod tests { let e = [0.0, 1.0]; let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points(surface.clone(), [a, b, c, d, e]) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), + [a, b, c, d, e], + ); + 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 46e946dcd..9badbcfc4 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -4,7 +4,6 @@ use fj_math::Point; use crate::{ objects::{Surface, SurfaceVertex}, partial::{Partial, PartialCycle, PartialHalfEdge, PartialSurfaceVertex}, - storage::Handle, }; use super::HalfEdgeBuilder; @@ -13,28 +12,28 @@ use super::HalfEdgeBuilder; pub trait CycleBuilder { /// Update the partial cycle with a polygonal chain from the provided points fn with_poly_chain( - self, + &mut self, vertices: impl IntoIterator, - ) -> Self; + ); /// Update the partial cycle with a polygonal chain from the provided points fn with_poly_chain_from_points( - self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self; + ); /// Update the partial cycle by closing it with a line segment /// /// Builds a line segment from the last and first vertex, closing the cycle. - fn close_with_line_segment(self) -> Self; + fn close_with_line_segment(&mut self); } impl CycleBuilder for PartialCycle { fn with_poly_chain( - mut self, + &mut self, vertices: impl IntoIterator, - ) -> Self { + ) { let vertices = vertices.into_iter(); let mut previous: Option> = @@ -82,24 +81,23 @@ impl CycleBuilder for PartialCycle { } self.half_edges.extend(half_edges); - self } fn with_poly_chain_from_points( - self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self { + ) { self.with_poly_chain(points.into_iter().map(|position| { PartialSurfaceVertex { position: Some(position.into()), - surface: Partial::from_full_entry_point(surface.clone()), + surface: surface.clone(), ..Default::default() } - })) + })); } - fn close_with_line_segment(mut self) -> Self { + fn close_with_line_segment(&mut self) { let first = self.half_edges.first(); let last = self.half_edges.last(); @@ -114,7 +112,7 @@ impl CycleBuilder for PartialCycle { }); let [Some([first, _]), Some([_, last])] = vertices else { - return self; + return; }; let mut half_edge = PartialHalfEdge::default(); @@ -138,6 +136,5 @@ impl CycleBuilder for PartialCycle { half_edge.update_as_line_segment(); self.half_edges.push(Partial::from_partial(half_edge)); - self } } diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index a12dbb0ca..7cf91a0f9 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -6,7 +6,7 @@ use crate::{ partial::{Partial, PartialGlobalEdge, PartialHalfEdge}, }; -use super::{CurveBuilder, SurfaceVertexBuilder}; +use super::CurveBuilder; /// Builder API for [`PartialHalfEdge`] pub trait HalfEdgeBuilder { @@ -69,7 +69,6 @@ impl HalfEdgeBuilder for PartialHalfEdge { let mut surface_form = vertex.surface_form.write(); surface_form.position = Some(point.into()); surface_form.surface = surface.clone(); - surface_form.infer_global_position(); } self.update_as_line_segment() @@ -87,14 +86,12 @@ impl HalfEdgeBuilder for PartialHalfEdge { let mut curve = self.curve(); curve.write().update_as_line_from_points(points_surface); + self.global_form.write().curve = curve.read().global_form.clone(); for (vertex, position) in self.vertices.each_mut_ext().zip_ext([0., 1.]) { vertex.write().position = Some([position].into()); - vertex.write().curve = curve.clone(); } - - self.global_form.write().curve = curve.read().global_form.clone(); } } diff --git a/crates/fj-kernel/src/builder/face.rs b/crates/fj-kernel/src/builder/face.rs index 2eb68d7c5..30605c8e3 100644 --- a/crates/fj-kernel/src/builder/face.rs +++ b/crates/fj-kernel/src/builder/face.rs @@ -3,7 +3,6 @@ use fj_math::Point; use crate::{ objects::Surface, partial::{Partial, PartialCycle, PartialFace}, - storage::Handle, }; use super::CycleBuilder; @@ -12,43 +11,41 @@ use super::CycleBuilder; pub trait FaceBuilder { /// Update the [`PartialFace`] with an exterior polygon fn with_exterior_polygon_from_points( - self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self; + ); /// Update the [`PartialFace`] with an interior polygon fn with_interior_polygon_from_points( - self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self; + ); } impl FaceBuilder for PartialFace { fn with_exterior_polygon_from_points( - mut self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self { - self.exterior = Partial::from_partial( - PartialCycle::default() - .with_poly_chain_from_points(surface, points) - .close_with_line_segment(), - ); - self + ) { + let mut cycle = PartialCycle::default(); + cycle.with_poly_chain_from_points(surface, points); + cycle.close_with_line_segment(); + + self.exterior = Partial::from_partial(cycle); } fn with_interior_polygon_from_points( - mut self, - surface: Handle, + &mut self, + surface: Partial, points: impl IntoIterator>>, - ) -> Self { - self.interiors = vec![Partial::from_partial( - PartialCycle::default() - .with_poly_chain_from_points(surface, points) - .close_with_line_segment(), - )]; - self + ) { + let mut cycle = PartialCycle::default(); + cycle.with_poly_chain_from_points(surface, points); + cycle.close_with_line_segment(); + + self.interiors = vec![Partial::from_partial(cycle)]; } } diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index 74f946bbe..eecedc379 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -10,11 +10,10 @@ use crate::{ FaceBuilder, HalfEdgeBuilder, SurfaceBuilder, SurfaceVertexBuilder, }, insert::Insert, - objects::{Face, FaceSet, HalfEdge, Objects, Shell, SurfaceVertex, Vertex}, + objects::{Face, FaceSet, HalfEdge, Objects, Shell}, partial::{ - Partial, PartialCurve, PartialCycle, PartialFace, PartialGlobalEdge, - PartialHalfEdge, PartialObject, PartialSurface, PartialSurfaceVertex, - PartialVertex, + Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject, + PartialSurface, PartialSurfaceVertex, }, services::Service, storage::Handle, @@ -54,10 +53,13 @@ impl ShellBuilder { let surface = objects.surfaces.xy_plane().translate([Z, Z, -h], objects); - PartialFace::default().with_exterior_polygon_from_points( - surface, + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), [[-h, -h], [h, -h], [h, h], [-h, h]], - ) + ); + + face }; let (sides, top_edges) = { @@ -127,56 +129,28 @@ impl ShellBuilder { let from = from.read(); from.surface_form.clone() }; - let to_surface = PartialSurfaceVertex { - position: Some( - from_surface.read().position.unwrap() - + [Z, edge_length], - ), - surface: surface.clone(), - ..Default::default() - }; + let to_position = from_surface.read().position.unwrap() + + [Z, edge_length]; - let vertices = [ - PartialVertex { - curve: Partial::from_partial(PartialCurve { - surface: from_surface.read().surface.clone(), - ..Default::default() - }), - surface_form: from_surface.clone(), - ..Default::default() - }, - PartialVertex { - curve: Partial::from_partial(PartialCurve { - surface: to_surface.surface.clone(), - ..Default::default() - }), - surface_form: Partial::from_partial(to_surface), - ..Default::default() - }, - ] - .map(Partial::::from_partial); + let mut half_edge = PartialHalfEdge::default(); - let global_curve = { - let [vertex, _] = &vertices; - vertex.read().curve.read().global_form.clone() - }; - let global_vertices = - vertices.each_ref_ext().map(|vertex| { - vertex - .read() - .surface_form - .read() - .global_form - .clone() - }); + half_edge.curve().write().surface = surface.clone(); + + { + let [from, to] = &mut half_edge.vertices; + from.write().surface_form = from_surface.clone(); + + let mut to = to.write(); + let mut to_surface = to.surface_form.write(); + to_surface.position = Some(to_position); + to_surface.surface = surface.clone(); + + half_edge.global_form.write().vertices = [ + from_surface.read().global_form.clone(), + to_surface.global_form.clone(), + ]; + } - let mut half_edge = PartialHalfEdge { - vertices, - global_form: Partial::from_partial(PartialGlobalEdge { - curve: global_curve, - vertices: global_vertices, - }), - }; half_edge.update_as_line_segment(); Partial::from_partial(half_edge) @@ -201,74 +175,46 @@ impl ShellBuilder { side_up_prev.read().vertices.clone(); let [to, _] = bottom.read().vertices.clone(); - let to = to.read().surface_form.clone(); - let from = PartialSurfaceVertex { - position: Some( - to.read().position.unwrap() - + [Z, edge_length], - ), - surface: surface.clone(), - global_form: from - .read() - .surface_form - .read() - .global_form - .clone(), - }; + let from_global = from + .read() + .surface_form + .read() + .global_form + .clone(); + let to_surface = to.read().surface_form.clone(); + + let mut half_edge = PartialHalfEdge::default(); - let curve = PartialCurve { - global_form: side_up_prev + half_edge.curve().write().surface = surface.clone(); + half_edge.curve().write().global_form = + side_up_prev .read() .curve() .read() .global_form - .clone(), - ..Default::default() - }; - - let vertices = [ - PartialVertex { - curve: Partial::from_partial( - PartialCurve { - surface: from.surface.clone(), - ..curve.clone() - }, - ), - surface_form: Partial::from_partial(from), - ..Default::default() - }, - PartialVertex { - curve: Partial::from_partial( - PartialCurve { - surface: to.read().surface.clone(), - ..curve.clone() - }, - ), - surface_form: to.clone(), - ..Default::default() - }, - ] - .map(Partial::::from_partial); - - let global_vertices = - vertices.each_ref_ext().map(|vertex| { - vertex - .read() - .surface_form - .read() - .global_form - .clone() - }); - - let mut half_edge = PartialHalfEdge { - vertices, - global_form: Partial::from_partial( - PartialGlobalEdge { - vertices: global_vertices, - curve: curve.global_form, - }, - ), - }; + .clone(); + + { + let [from, to] = &mut half_edge.vertices; + + let mut from = from.write(); + let mut from_surface = + from.surface_form.write(); + from_surface.position = Some( + to_surface.read().position.unwrap() + + [Z, edge_length], + ); + from_surface.surface = surface.clone(); + from_surface.global_form = from_global.clone(); + + to.write().surface_form = to_surface.clone(); + + half_edge.global_form.write().vertices = [ + from_global, + to_surface.read().global_form.clone(), + ]; + } + half_edge.update_as_line_segment(); Partial::from_partial(half_edge) @@ -285,49 +231,25 @@ impl ShellBuilder { let [_, from] = side_up.read().vertices.clone(); let [to, _] = side_down.read().vertices.clone(); - let from = from.read().surface_form.clone(); - let to = to.read().surface_form.clone(); + let from_surface = from.read().surface_form.clone(); + let to_surface = to.read().surface_form.clone(); - let from = PartialVertex { - curve: Partial::from_partial(PartialCurve { - surface: from.read().surface.clone(), - ..Default::default() - }), - surface_form: from.clone(), - ..Default::default() - }; - let to = PartialVertex { - curve: Partial::from_partial(PartialCurve { - surface: to.read().surface.clone(), - ..Default::default() - }), - surface_form: to.clone(), - ..Default::default() - }; + let mut half_edge = PartialHalfEdge::default(); - let vertices = - [from, to].map(Partial::::from_partial); - let global_curve = { - let [vertex, _] = &vertices; - vertex.read().curve.read().global_form.clone() - }; - let global_vertices = - vertices.each_ref_ext().map(|vertex| { - vertex - .read() - .surface_form - .read() - .global_form - .clone() - }); + half_edge.curve().write().surface = + from_surface.read().surface.clone(); + + half_edge.global_form.write().vertices = [ + from_surface.read().global_form.clone(), + to_surface.read().global_form.clone(), + ]; + + { + let [from, to] = &mut half_edge.vertices; + from.write().surface_form = from_surface; + to.write().surface_form = to_surface; + } - let mut half_edge = PartialHalfEdge { - vertices, - global_form: Partial::from_partial(PartialGlobalEdge { - curve: global_curve, - vertices: global_vertices, - }), - }; half_edge.update_as_line_segment(); Partial::from_partial(half_edge) @@ -354,8 +276,9 @@ impl ShellBuilder { }; let top = { - let surface = - objects.surfaces.xy_plane().translate([Z, Z, h], objects); + let surface = Partial::from_full_entry_point( + objects.surfaces.xy_plane().translate([Z, Z, h], objects), + ); let mut top_edges = top_edges; top_edges.reverse(); @@ -381,9 +304,8 @@ impl ShellBuilder { Partial::from_partial(PartialSurfaceVertex { position: Some(point.into()), - surface: Partial::from_full_entry_point( - surface.clone(), - ), + surface: surface.clone(), + global_form: global_vertex, }) }); @@ -397,43 +319,24 @@ impl ShellBuilder { .array_windows_ext() .zip(top_edges) { - let global_edge = edge.read().global_form.clone(); + let global_form = edge.read().global_form.clone(); - let vertices = edge - .read() - .vertices - .each_ref_ext() - .into_iter_fixed() - .zip(surface_vertices.clone()) - .collect::<[_; 2]>() - .map( - |(vertex, surface_form): ( - _, - Partial, - )| PartialVertex { - position: vertex.read().position, - curve: Partial::from_partial(PartialCurve { - surface: surface_form.read().surface.clone(), + let mut half_edge = PartialHalfEdge::default(); - global_form: vertex - .read() - .curve - .read() - .global_form - .clone(), - ..Default::default() - }), - surface_form: surface_form.clone(), - }, - ); + half_edge.curve().write().surface = surface.clone(); + half_edge.curve().write().global_form = + global_form.read().curve.clone(); + + half_edge.global_form = global_form; + + for (vertex, surface_form) in half_edge + .vertices + .each_mut_ext() + .zip_ext(surface_vertices.each_ref_ext()) + { + vertex.write().surface_form = surface_form.clone(); + } - let mut half_edge = PartialHalfEdge { - vertices: vertices.map(Partial::from_partial), - global_form: Partial::from_partial(PartialGlobalEdge { - curve: global_edge.read().curve.clone(), - vertices: global_edge.read().vertices.clone(), - }), - }; half_edge.update_as_line_segment(); edges.push(Partial::from_partial(half_edge)); diff --git a/crates/fj-kernel/src/builder/sketch.rs b/crates/fj-kernel/src/builder/sketch.rs index 3f94b6692..701c39857 100644 --- a/crates/fj-kernel/src/builder/sketch.rs +++ b/crates/fj-kernel/src/builder/sketch.rs @@ -3,7 +3,7 @@ use fj_math::Point; use crate::{ insert::Insert, objects::{Face, FaceSet, Objects, Sketch, Surface}, - partial::{PartialFace, PartialObject}, + partial::{Partial, PartialFace, PartialObject}, services::Service, storage::Handle, }; @@ -35,10 +35,14 @@ impl SketchBuilder { points: impl IntoIterator>>, objects: &mut Service, ) -> Self { - self.faces.extend([PartialFace::default() - .with_exterior_polygon_from_points(surface, points) - .build(objects) - .insert(objects)]); + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + points, + ); + let face = face.build(objects).insert(objects); + + self.faces.extend([face]); self } diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 066f49c5b..649a86726 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -407,14 +407,18 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let object = PartialCycle::default() - .with_poly_chain_from_points( - surface, + let object = { + let mut cycle = PartialCycle::default(); + cycle.with_poly_chain_from_points( + Partial::from_full_entry_point(surface), [[0., 0.], [1., 0.], [0., 1.]], - ) - .close_with_line_segment() - .build(&mut services.objects) - .insert(&mut services.objects); + ); + cycle.close_with_line_segment(); + + cycle + .build(&mut services.objects) + .insert(&mut services.objects) + }; assert_eq!(3, object.curve_iter().count()); assert_eq!(1, object.cycle_iter().count()); @@ -434,11 +438,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let object = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [1., 0.], [0., 1.]], - ) + let mut object = PartialFace::default(); + object.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [1., 0.], [0., 1.]], + ); + let object = object .build(&mut services.objects) .insert(&mut services.objects); @@ -551,11 +556,12 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xy_plane(); - let face = PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[0., 0.], [1., 0.], [0., 1.]], - ) + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + [[0., 0.], [1., 0.], [0., 1.]], + ); + let face = face .build(&mut services.objects) .insert(&mut services.objects); let object = Sketch::builder() diff --git a/crates/fj-kernel/src/validate/cycle.rs b/crates/fj-kernel/src/validate/cycle.rs index 82cf04de6..f0851fff8 100644 --- a/crates/fj-kernel/src/validate/cycle.rs +++ b/crates/fj-kernel/src/validate/cycle.rs @@ -77,13 +77,18 @@ mod tests { fn cycle_half_edge_connections() { let mut services = Services::new(); - let valid = PartialCycle::default() - .with_poly_chain_from_points( - services.objects.surfaces.xy_plane(), + let valid = { + let mut cycle = PartialCycle::default(); + cycle.with_poly_chain_from_points( + Partial::from_full_entry_point( + services.objects.surfaces.xy_plane(), + ), [[0., 0.], [1., 0.], [0., 1.]], - ) - .close_with_line_segment() - .build(&mut services.objects); + ); + cycle.close_with_line_segment(); + + cycle.build(&mut services.objects) + }; let invalid = { let mut half_edges = valid .half_edges() diff --git a/crates/fj-kernel/src/validate/face.rs b/crates/fj-kernel/src/validate/face.rs index 80795932b..05660334c 100644 --- a/crates/fj-kernel/src/validate/face.rs +++ b/crates/fj-kernel/src/validate/face.rs @@ -108,7 +108,7 @@ mod tests { builder::{CycleBuilder, FaceBuilder}, insert::Insert, objects::Face, - partial::{PartialCycle, PartialFace, PartialObject}, + partial::{Partial, PartialCycle, PartialFace, PartialObject}, services::Services, validate::Validate, }; @@ -119,26 +119,33 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); - let valid = PartialFace::default() - .with_exterior_polygon_from_points( - surface.clone(), + let valid = { + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), [[0., 0.], [3., 0.], [0., 3.]], - ) - .with_interior_polygon_from_points( - surface, + ); + face.with_interior_polygon_from_points( + Partial::from_full_entry_point(surface), [[1., 1.], [1., 2.], [2., 1.]], - ) - .build(&mut services.objects); + ); + + face.build(&mut services.objects) + }; let invalid = { - let interiors = [PartialCycle::default() - .with_poly_chain_from_points( + let mut cycle = PartialCycle::default(); + cycle.with_poly_chain_from_points( + Partial::from_full_entry_point( services.objects.surfaces.xz_plane(), - [[1., 1.], [1., 2.], [2., 1.]], - ) - .close_with_line_segment() + ), + [[1., 1.], [1., 2.], [2., 1.]], + ); + cycle.close_with_line_segment(); + let cycle = cycle .build(&mut services.objects) - .insert(&mut services.objects)]; + .insert(&mut services.objects); + let interiors = [cycle]; Face::new(valid.exterior().clone(), interiors, valid.color()) }; @@ -152,16 +159,18 @@ mod tests { let surface = services.objects.surfaces.xy_plane(); - let valid = PartialFace::default() - .with_exterior_polygon_from_points( - surface.clone(), + let valid = { + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface.clone()), [[0., 0.], [3., 0.], [0., 3.]], - ) - .with_interior_polygon_from_points( - surface, + ); + face.with_interior_polygon_from_points( + Partial::from_full_entry_point(surface), [[1., 1.], [1., 2.], [2., 1.]], - ) - .build(&mut services.objects); + ); + face.build(&mut services.objects) + }; let invalid = { let interiors = valid .interiors() diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 7409fe863..4fb98eb79 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -1,13 +1,12 @@ -use std::{array, ops::Deref}; +use std::ops::Deref; -use fj_interop::{debug::DebugInfo, ext::ArrayExt, mesh::Color}; +use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ builder::{FaceBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{Objects, Sketch, Vertex}, + objects::{Objects, Sketch}, partial::{ - Partial, PartialCurve, PartialCycle, PartialFace, PartialGlobalEdge, - PartialHalfEdge, PartialObject, PartialSurfaceVertex, PartialVertex, + Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject, }, services::Service, }; @@ -27,45 +26,18 @@ impl Shape for fj::Sketch { let face = match self.chain() { fj::Chain::Circle(circle) => { - // Circles have just a single round edge with no vertices. So - // none need to be added here. - let half_edge = { let surface = Partial::from_full_entry_point(surface); - let curve = Partial::from_partial(PartialCurve { - surface: surface.clone(), - ..Default::default() - }); - let vertices = array::from_fn(|_| { - Partial::from_partial(PartialVertex { - curve: curve.clone(), - surface_form: Partial::from_partial( - PartialSurfaceVertex { - surface: surface.clone(), - ..Default::default() - }, - ), - ..Default::default() - }) - }); - let global_vertices = vertices.each_ref_ext().map( - |vertex: &Partial| { - vertex - .read() - .surface_form - .read() - .global_form - .clone() - }, - ); - let mut half_edge = PartialHalfEdge { - vertices, - global_form: Partial::from_partial(PartialGlobalEdge { - curve: curve.read().global_form.clone(), - vertices: global_vertices, - }), - }; + let mut half_edge = PartialHalfEdge::default(); + + half_edge.curve().write().surface = surface.clone(); + + for vertex in &mut half_edge.vertices { + vertex.write().surface_form.write().surface = + surface.clone(); + } + half_edge.update_as_circle_from_radius(circle.radius()); Partial::from_partial(half_edge) @@ -87,8 +59,11 @@ impl Shape for fj::Sketch { .map(|fj::SketchSegment::LineTo { point }| point) .map(Point::from); - let mut face = PartialFace::default() - .with_exterior_polygon_from_points(surface, points); + let mut face = PartialFace::default(); + face.with_exterior_polygon_from_points( + Partial::from_full_entry_point(surface), + points, + ); face.color = Some(Color(self.color())); face.build(objects).insert(objects)