diff --git a/crates/fj-kernel/src/builder/curve.rs b/crates/fj-kernel/src/builder/curve.rs index cc904b321..9f03f186d 100644 --- a/crates/fj-kernel/src/builder/curve.rs +++ b/crates/fj-kernel/src/builder/curve.rs @@ -5,52 +5,38 @@ use crate::{geometry::path::SurfacePath, partial::PartialCurve}; /// Builder API for [`PartialCurve`] pub trait CurveBuilder { /// Update partial curve to represent the u-axis of the surface it is on - fn update_as_u_axis(&mut self) -> &mut Self; + fn update_as_u_axis(&mut self); /// Update partial curve to represent the v-axis of the surface it is on - fn update_as_v_axis(&mut self) -> &mut Self; + fn update_as_v_axis(&mut self); /// Update partial curve to be a circle, from the provided radius - fn update_as_circle_from_radius( - &mut self, - radius: impl Into, - ) -> &mut Self; + fn update_as_circle_from_radius(&mut self, radius: impl Into); /// Update partial curve to be a line, from the provided points - fn update_as_line_from_points( - &mut self, - points: [impl Into>; 2], - ) -> &mut Self; + fn update_as_line_from_points(&mut self, points: [impl Into>; 2]); } impl CurveBuilder for PartialCurve { - fn update_as_u_axis(&mut self) -> &mut Self { + fn update_as_u_axis(&mut self) { let a = Point::origin(); let b = a + Vector::unit_u(); self.update_as_line_from_points([a, b]) } - fn update_as_v_axis(&mut self) -> &mut Self { + fn update_as_v_axis(&mut self) { let a = Point::origin(); let b = a + Vector::unit_v(); self.update_as_line_from_points([a, b]) } - fn update_as_circle_from_radius( - &mut self, - radius: impl Into, - ) -> &mut Self { + fn update_as_circle_from_radius(&mut self, radius: impl Into) { self.path = Some(SurfacePath::circle_from_radius(radius)); - self } - fn update_as_line_from_points( - &mut self, - points: [impl Into>; 2], - ) -> &mut Self { + fn update_as_line_from_points(&mut self, points: [impl Into>; 2]) { self.path = Some(SurfacePath::line_from_points(points)); - self } } diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 9df0a0caf..a12dbb0ca 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -11,27 +11,21 @@ use super::{CurveBuilder, SurfaceVertexBuilder}; /// Builder API for [`PartialHalfEdge`] pub trait HalfEdgeBuilder { /// Update partial half-edge to be a circle, from the given radius - fn update_as_circle_from_radius( - &mut self, - radius: impl Into, - ) -> &mut Self; + fn update_as_circle_from_radius(&mut self, radius: impl Into); /// Update partial half-edge to be a line segment, from the given points fn update_as_line_segment_from_points( &mut self, surface: Partial, points: [impl Into>; 2], - ) -> &mut Self; + ); /// Update partial half-edge to be a line segment - fn update_as_line_segment(&mut self) -> &mut Self; + fn update_as_line_segment(&mut self); } impl HalfEdgeBuilder for PartialHalfEdge { - fn update_as_circle_from_radius( - &mut self, - radius: impl Into, - ) -> &mut Self { + fn update_as_circle_from_radius(&mut self, radius: impl Into) { let mut curve = self.curve(); curve.write().update_as_circle_from_radius(radius); @@ -61,15 +55,13 @@ impl HalfEdgeBuilder for PartialHalfEdge { let global_vertex = surface_vertex.read().global_form.clone(); self.global_form.write().vertices = [global_vertex.clone(), global_vertex]; - - self } fn update_as_line_segment_from_points( &mut self, surface: Partial, points: [impl Into>; 2], - ) -> &mut Self { + ) { for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) { let mut vertex = vertex.write(); vertex.curve.write().surface = surface.clone(); @@ -83,7 +75,7 @@ impl HalfEdgeBuilder for PartialHalfEdge { self.update_as_line_segment() } - fn update_as_line_segment(&mut self) -> &mut Self { + fn update_as_line_segment(&mut self) { let points_surface = self.vertices.each_ref_ext().map(|vertex| { vertex .read() @@ -103,8 +95,6 @@ impl HalfEdgeBuilder for PartialHalfEdge { } self.global_form.write().curve = curve.read().global_form.clone(); - - self } } diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index 1b30d88de..74f946bbe 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -6,9 +6,11 @@ use iter_fixed::IntoIteratorFixed; use crate::{ algorithms::transform::TransformObject, - builder::{FaceBuilder, HalfEdgeBuilder, SurfaceBuilder}, + builder::{ + FaceBuilder, HalfEdgeBuilder, SurfaceBuilder, SurfaceVertexBuilder, + }, insert::Insert, - objects::{Face, FaceSet, HalfEdge, Objects, Shell, Vertex}, + objects::{Face, FaceSet, HalfEdge, Objects, Shell, SurfaceVertex, Vertex}, partial::{ Partial, PartialCurve, PartialCycle, PartialFace, PartialGlobalEdge, PartialHalfEdge, PartialObject, PartialSurface, PartialSurfaceVertex, @@ -52,72 +54,62 @@ impl ShellBuilder { let surface = objects.surfaces.xy_plane().translate([Z, Z, -h], objects); - PartialFace::default() - .with_exterior_polygon_from_points( - surface, - [[-h, -h], [h, -h], [h, h], [-h, h]], - ) - .build(objects) - .insert(objects) + PartialFace::default().with_exterior_polygon_from_points( + surface, + [[-h, -h], [h, -h], [h, h], [-h, h]], + ) }; let (sides, top_edges) = { let surfaces = bottom - .exterior() - .half_edges() + .exterior + .read() + .half_edges + .iter() .map(|half_edge| { - let [a, b] = half_edge - .vertices() - .clone() - .map(|vertex| vertex.global_form().position()); + let [a, b] = + half_edge.read().vertices.clone().map(|mut vertex| { + vertex + .write() + .surface_form + .write() + .infer_global_position() + }); let c = a + [Z, Z, edge_length]; - PartialSurface::plane_from_points([a, b, c]) - .build(objects) - .insert(objects) + Partial::from_partial(PartialSurface::plane_from_points([ + a, b, c, + ])) }) .collect::>(); let bottoms = bottom - .exterior() - .half_edges() + .exterior + .read() + .half_edges + .iter() .zip(&surfaces) .map(|(half_edge, surface)| { - let global_edge = Partial::from_full_entry_point( - half_edge.global_form().clone(), - ) - .read() - .clone(); + let global_edge = half_edge.read().global_form.clone(); + + let mut half_edge = PartialHalfEdge::default(); + + half_edge.curve().write().global_form = + global_edge.read().curve.clone(); + + for (vertex, global_form) in half_edge + .vertices + .iter_mut() + .zip(&global_edge.read().vertices) + { + vertex.write().surface_form.write().global_form = + global_form.clone(); + } + + half_edge.global_form = global_edge; - let mut half_edge = PartialHalfEdge { - vertices: global_edge.vertices.clone().map( - |global_vertex| { - Partial::from_partial(PartialVertex { - curve: Partial::from_partial( - PartialCurve { - global_form: global_edge - .curve - .clone(), - ..Default::default() - }, - ), - surface_form: Partial::from_partial( - PartialSurfaceVertex { - global_form: global_vertex, - ..Default::default() - }, - ), - ..Default::default() - }) - }, - ), - global_form: Partial::from_partial(PartialGlobalEdge { - curve: global_edge.curve, - vertices: global_edge.vertices, - }), - }; half_edge.update_as_line_segment_from_points( - Partial::from_full_entry_point(surface.clone()), + surface.clone(), [[Z, Z], [edge_length, Z]], ); @@ -130,34 +122,35 @@ impl ShellBuilder { .into_iter() .zip(&surfaces) .map(|(bottom, surface): (Partial, _)| { - let [_, from] = &bottom.read().vertices; - - let from = from.read().surface_form.clone(); - let to = PartialSurfaceVertex { + let from_surface = { + let [_, from] = &bottom.read().vertices; + let from = from.read(); + from.surface_form.clone() + }; + let to_surface = PartialSurfaceVertex { position: Some( - from.read().position.unwrap() + [Z, edge_length], - ), - surface: Partial::from_full_entry_point( - surface.clone(), + from_surface.read().position.unwrap() + + [Z, edge_length], ), + surface: surface.clone(), ..Default::default() }; let vertices = [ PartialVertex { curve: Partial::from_partial(PartialCurve { - surface: from.read().surface.clone(), + surface: from_surface.read().surface.clone(), ..Default::default() }), - surface_form: from.clone(), + surface_form: from_surface.clone(), ..Default::default() }, PartialVertex { curve: Partial::from_partial(PartialCurve { - surface: to.surface.clone(), + surface: to_surface.surface.clone(), ..Default::default() }), - surface_form: Partial::from_partial(to), + surface_form: Partial::from_partial(to_surface), ..Default::default() }, ] @@ -214,9 +207,7 @@ impl ShellBuilder { to.read().position.unwrap() + [Z, edge_length], ), - surface: Partial::from_full_entry_point( - surface.clone(), - ), + surface: surface.clone(), global_form: from .read() .surface_form @@ -352,11 +343,10 @@ impl ShellBuilder { let mut cycle = PartialCycle::default(); cycle.half_edges.extend([bottom, side_up, top, side_down]); - let face = PartialFace { + PartialFace { exterior: Partial::from_partial(cycle), ..Default::default() - }; - face.build(objects).insert(objects) + } }) .collect::>(); @@ -389,15 +379,13 @@ impl ShellBuilder { .global_form .clone(); - PartialSurfaceVertex { + Partial::from_partial(PartialSurfaceVertex { position: Some(point.into()), surface: Partial::from_full_entry_point( surface.clone(), ), global_form: global_vertex, - } - .build(objects) - .insert(objects) + }) }); [a.clone(), b, c, d, a] @@ -418,24 +406,26 @@ impl ShellBuilder { .into_iter_fixed() .zip(surface_vertices.clone()) .collect::<[_; 2]>() - .map(|(vertex, surface_form)| PartialVertex { - position: vertex.read().position, - curve: Partial::from_partial(PartialCurve { - surface: Partial::from_full_entry_point( - surface_form.surface().clone(), - ), - global_form: vertex - .read() - .curve - .read() - .global_form - .clone(), - ..Default::default() - }), - surface_form: Partial::from_full_entry_point( - surface_form, - ), - }); + .map( + |(vertex, surface_form): ( + _, + Partial, + )| PartialVertex { + position: vertex.read().position, + curve: Partial::from_partial(PartialCurve { + surface: surface_form.read().surface.clone(), + + global_form: vertex + .read() + .curve + .read() + .global_form + .clone(), + ..Default::default() + }), + surface_form: surface_form.clone(), + }, + ); let mut half_edge = PartialHalfEdge { vertices: vertices.map(Partial::from_partial), @@ -449,16 +439,19 @@ impl ShellBuilder { edges.push(Partial::from_partial(half_edge)); } - let face = PartialFace { + PartialFace { exterior: Partial::from_partial(PartialCycle::new(edges)), ..Default::default() - }; - face.build(objects).insert(objects) + } }; - self.faces.extend([bottom]); - self.faces.extend(sides); - self.faces.extend([top]); + self.faces.extend( + [bottom] + .into_iter() + .chain(sides) + .chain([top]) + .map(|face| face.build(objects).insert(objects)), + ); self } diff --git a/crates/fj-kernel/src/builder/vertex.rs b/crates/fj-kernel/src/builder/vertex.rs index dcf1bac7a..6f26651ac 100644 --- a/crates/fj-kernel/src/builder/vertex.rs +++ b/crates/fj-kernel/src/builder/vertex.rs @@ -1,3 +1,5 @@ +use fj_math::Point; + use crate::partial::{ PartialGlobalVertex, PartialSurfaceVertex, PartialVertex, }; @@ -13,12 +15,15 @@ impl VertexBuilder for PartialVertex {} /// Builder API for [`PartialSurfaceVertex`] pub trait SurfaceVertexBuilder { /// Infer the position of the surface vertex' global form - fn infer_global_position(&mut self) -> &mut Self; + /// + /// Updates the global vertex referenced by this surface vertex with the + /// inferred position, and also returns the position. + fn infer_global_position(&mut self) -> Point<3>; } impl SurfaceVertexBuilder for PartialSurfaceVertex { - fn infer_global_position(&mut self) -> &mut Self { - let position = self + fn infer_global_position(&mut self) -> Point<3> { + let position_surface = self .position .expect("Can't infer global position without surface position"); let surface = self @@ -27,10 +32,11 @@ impl SurfaceVertexBuilder for PartialSurfaceVertex { .geometry .expect("Can't infer global position without surface geometry"); - self.global_form.write().position = - Some(surface.point_from_surface_coords(position)); + let position_global = + surface.point_from_surface_coords(position_surface); + self.global_form.write().position = Some(position_global); - self + position_global } }