diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 09ade40ac..901533c47 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -199,8 +199,8 @@ mod tests { algorithms::{reverse::Reverse, sweep::Sweep}, builder::HalfEdgeBuilder, insert::Insert, - objects::{Cycle, Face, HalfEdge, Objects, SurfaceVertex, Vertex}, - partial::HasPartial, + objects::{Cycle, Face, HalfEdge, Objects}, + partial::{HasPartial, PartialSurfaceVertex, PartialVertex}, }; #[test] @@ -218,63 +218,75 @@ mod tests { let face = (half_edge, Color::default()).sweep([0., 0., 1.], &objects)?; - let expected_face = - { - let surface = objects.surfaces.xz_plane(); + let expected_face = { + let surface = objects.surfaces.xz_plane(); - let bottom = HalfEdge::partial() - .update_as_line_segment_from_points( - surface.clone(), - [[0., 0.], [1., 0.]], - ) - .build(&objects)? - .insert(&objects)?; - let side_up = HalfEdge::partial() - .with_surface(surface.clone()) - .with_back_vertex(Vertex::partial().with_surface_form( - bottom.front().surface_form().clone(), - )) - .with_front_vertex(Vertex::partial().with_surface_form( - SurfaceVertex::partial().with_position(Some([1., 1.])), - )) - .update_as_line_segment() - .build(&objects)? - .insert(&objects)?; - let top = HalfEdge::partial() - .with_surface(surface.clone()) - .with_back_vertex(Vertex::partial().with_surface_form( - SurfaceVertex::partial().with_position(Some([0., 1.])), - )) - .with_front_vertex(Vertex::partial().with_surface_form( - side_up.front().surface_form().clone(), - )) - .update_as_line_segment() - .build(&objects)? - .insert(&objects)? - .reverse(&objects)?; - let side_down = - HalfEdge::partial() - .with_surface(surface) - .with_back_vertex(Vertex::partial().with_surface_form( - bottom.back().surface_form().clone(), - )) - .with_front_vertex(Vertex::partial().with_surface_form( - top.front().surface_form().clone(), - )) - .update_as_line_segment() - .build(&objects)? - .insert(&objects)? - .reverse(&objects)?; + let bottom = HalfEdge::partial() + .update_as_line_segment_from_points( + surface.clone(), + [[0., 0.], [1., 0.]], + ) + .build(&objects)? + .insert(&objects)?; + let side_up = HalfEdge::partial() + .with_surface(surface.clone()) + .with_back_vertex(PartialVertex { + surface_form: bottom.front().surface_form().clone().into(), + ..Default::default() + }) + .with_front_vertex(PartialVertex { + surface_form: PartialSurfaceVertex { + position: Some([1., 1.].into()), + ..Default::default() + } + .into(), + ..Default::default() + }) + .update_as_line_segment() + .build(&objects)? + .insert(&objects)?; + let top = HalfEdge::partial() + .with_surface(surface.clone()) + .with_back_vertex(PartialVertex { + surface_form: PartialSurfaceVertex { + position: Some([0., 1.].into()), + ..Default::default() + } + .into(), + ..Default::default() + }) + .with_front_vertex(PartialVertex { + surface_form: side_up.front().surface_form().clone().into(), + ..Default::default() + }) + .update_as_line_segment() + .build(&objects)? + .insert(&objects)? + .reverse(&objects)?; + let side_down = HalfEdge::partial() + .with_surface(surface) + .with_back_vertex(PartialVertex { + surface_form: bottom.back().surface_form().clone().into(), + ..Default::default() + }) + .with_front_vertex(PartialVertex { + surface_form: top.front().surface_form().clone().into(), + ..Default::default() + }) + .update_as_line_segment() + .build(&objects)? + .insert(&objects)? + .reverse(&objects)?; - let cycle = objects - .cycles - .insert(Cycle::new([bottom, side_up, top, side_down]))?; + let cycle = objects + .cycles + .insert(Cycle::new([bottom, side_up, top, side_down]))?; - Face::partial() - .with_exterior(cycle) - .build(&objects)? - .insert(&objects)? - }; + Face::partial() + .with_exterior(cycle) + .build(&objects)? + .insert(&objects)? + }; assert_eq!(face, expected_face); Ok(()) diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index 69c557727..e07754a62 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -170,8 +170,8 @@ mod tests { algorithms::sweep::Sweep, builder::{CurveBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{HalfEdge, Objects, Vertex}, - partial::{HasPartial, PartialCurve}, + objects::{HalfEdge, Objects}, + partial::{HasPartial, PartialCurve, PartialVertex}, }; #[test] @@ -185,11 +185,13 @@ mod tests { }; curve.update_as_u_axis(); let curve = curve.build(&objects)?.insert(&objects)?; - let vertex = Vertex::partial() - .with_position(Some([0.])) - .with_curve(curve) - .build(&objects)? - .insert(&objects)?; + let vertex = PartialVertex { + position: Some([0.].into()), + curve: curve.into(), + ..Default::default() + } + .build(&objects)? + .insert(&objects)?; let half_edge = (vertex, surface.clone()).sweep([0., 0., 1.], &objects)?; diff --git a/crates/fj-kernel/src/algorithms/transform/edge.rs b/crates/fj-kernel/src/algorithms/transform/edge.rs index 5e96fbc03..7daf35f31 100644 --- a/crates/fj-kernel/src/algorithms/transform/edge.rs +++ b/crates/fj-kernel/src/algorithms/transform/edge.rs @@ -22,10 +22,10 @@ impl TransformObject for PartialHalfEdge { .into(); let vertices = self.vertices().try_map_ext( |vertex| -> Result<_, ValidationError> { - Ok(vertex - .into_partial() - .transform(transform, objects)? - .with_curve(curve.clone())) + let mut vertex = + vertex.into_partial().transform(transform, objects)?; + vertex.curve = curve.clone(); + Ok(vertex) }, )?; let global_form = self diff --git a/crates/fj-kernel/src/algorithms/transform/vertex.rs b/crates/fj-kernel/src/algorithms/transform/vertex.rs index b9db0f704..d925898bb 100644 --- a/crates/fj-kernel/src/algorithms/transform/vertex.rs +++ b/crates/fj-kernel/src/algorithms/transform/vertex.rs @@ -14,18 +14,19 @@ impl TransformObject for PartialVertex { transform: &Transform, objects: &Objects, ) -> Result { - let curve = self.curve().transform(transform, objects)?; + let curve = self.curve.transform(transform, objects)?; let surface_form = self - .surface_form() + .surface_form .into_partial() .transform(transform, objects)?; // Don't need to transform `self.position`, as that is in curve // coordinates and thus transforming the curve takes care of it. - Ok(Self::default() - .with_position(self.position()) - .with_curve(curve) - .with_surface_form(surface_form)) + Ok(Self { + position: self.position, + curve, + surface_form: surface_form.into(), + }) } } @@ -36,17 +37,19 @@ impl TransformObject for PartialSurfaceVertex { objects: &Objects, ) -> Result { let surface = self - .surface() + .surface + .clone() .map(|surface| surface.transform(transform, objects)) .transpose()?; - let global_form = self.global_form().transform(transform, objects)?; + let global_form = self.global_form.transform(transform, objects)?; // Don't need to transform `self.position`, as that is in surface // coordinates and thus transforming the surface takes care of it. - Ok(Self::default() - .with_position(self.position()) - .with_surface(surface) - .with_global_form(Some(global_form))) + Ok(Self { + position: self.position, + surface, + global_form, + }) } } @@ -57,9 +60,9 @@ impl TransformObject for PartialGlobalVertex { _: &Objects, ) -> Result { let position = self - .position() + .position .map(|position| transform.transform_point(&position)); - Ok(Self::default().with_position(position)) + Ok(Self { position }) } } diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 64ba97be6..bbdf5a6d6 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -1,8 +1,11 @@ use fj_math::Point; use crate::{ - objects::{HalfEdge, Surface, SurfaceVertex, Vertex}, - partial::{HasPartial, MaybePartial, PartialCurve, PartialCycle}, + objects::{HalfEdge, Surface, SurfaceVertex}, + partial::{ + HasPartial, MaybePartial, PartialCurve, PartialCycle, + PartialSurfaceVertex, PartialVertex, + }, storage::Handle, }; @@ -72,11 +75,10 @@ impl CycleBuilder for PartialCycle { .update_as_line_from_points([position_prev, position_next]); let vertices = [(0., vertex_prev), (1., vertex_next)].map( - |(position, surface_form)| { - Vertex::partial() - .with_curve(curve.clone()) - .with_position(Some([position])) - .with_surface_form(surface_form) + |(position, surface_form)| PartialVertex { + position: Some([position].into()), + curve: curve.clone().into(), + surface_form, }, ); @@ -101,9 +103,11 @@ impl CycleBuilder for PartialCycle { points: impl IntoIterator>>, ) -> Self { self.with_poly_chain(points.into_iter().map(|position| { - SurfaceVertex::partial() - .with_surface(Some(surface.clone())) - .with_position(Some(position)) + PartialSurfaceVertex { + position: Some(position.into()), + surface: Some(surface.clone()), + ..Default::default() + } })) } diff --git a/crates/fj-kernel/src/builder/edge.rs b/crates/fj-kernel/src/builder/edge.rs index 2fc232795..74794c131 100644 --- a/crates/fj-kernel/src/builder/edge.rs +++ b/crates/fj-kernel/src/builder/edge.rs @@ -3,13 +3,10 @@ use iter_fixed::IntoIteratorFixed; use crate::{ insert::Insert, - objects::{ - Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex, - VerticesInNormalizedOrder, - }, + objects::{Curve, Objects, Surface, Vertex, VerticesInNormalizedOrder}, partial::{ - HasPartial, MaybePartial, PartialCurve, PartialGlobalEdge, - PartialHalfEdge, + MaybePartial, PartialCurve, PartialGlobalEdge, PartialGlobalVertex, + PartialHalfEdge, PartialSurfaceVertex, PartialVertex, }, storage::Handle, validate::ValidationError, @@ -82,24 +79,27 @@ impl HalfEdgeBuilder for PartialHalfEdge { .vertices() .map(|[global_form, _]| global_form) .unwrap_or_else(|| { - GlobalVertex::partial() - .update_from_curve_and_position(curve.clone(), a_curve) - .into() + PartialGlobalVertex::from_curve_and_position( + curve.clone(), + a_curve, + ) + .into() }); - let surface_vertex = SurfaceVertex::partial() - .with_position(Some(path.point_from_path_coords(a_curve))) - .with_surface(curve.surface.clone()) - .with_global_form(Some(global_vertex)) - .build(objects)? - .insert(objects)?; + let surface_vertex = PartialSurfaceVertex { + position: Some(path.point_from_path_coords(a_curve)), + surface: curve.surface.clone(), + global_form: global_vertex, + } + .build(objects)? + .insert(objects)?; - let [back, front] = [a_curve, b_curve].map(|point_curve| { - Vertex::partial() - .with_position(Some(point_curve)) - .with_curve(curve.clone()) - .with_surface_form(surface_vertex.clone()) - }); + let [back, front] = + [a_curve, b_curve].map(|point_curve| PartialVertex { + position: Some(point_curve), + curve: curve.clone().into(), + surface_form: surface_vertex.clone().into(), + }); Ok(self.with_curve(curve).with_vertices([back, front])) } @@ -110,11 +110,16 @@ impl HalfEdgeBuilder for PartialHalfEdge { points: [impl Into>; 2], ) -> Self { let vertices = points.map(|point| { - let surface_form = SurfaceVertex::partial() - .with_surface(Some(surface.clone())) - .with_position(Some(point)); + let surface_form = PartialSurfaceVertex { + position: Some(point.into()), + surface: Some(surface.clone()), + ..Default::default() + }; - Vertex::partial().with_surface_form(surface_form) + PartialVertex { + surface_form: surface_form.into(), + ..Default::default() + } }); self.with_surface(surface) @@ -148,10 +153,10 @@ impl HalfEdgeBuilder for PartialHalfEdge { let [back, front] = { let vertices = [(from, 0.), (to, 1.)].map(|(vertex, position)| { - vertex.update_partial(|vertex| { + vertex.update_partial(|mut vertex| { + vertex.position = Some([position].into()); + vertex.curve = curve.clone().into(); vertex - .with_position(Some([position])) - .with_curve(curve.clone()) }) }); @@ -195,14 +200,16 @@ impl HalfEdgeBuilder for PartialHalfEdge { .zip(global_forms) .collect::<[_; 2]>() .map(|(vertex, global_form)| { - vertex.update_partial(|vertex| { - vertex.clone().with_surface_form( - vertex.surface_form().update_partial( - |surface_vertex| { - surface_vertex.with_global_form(global_form) - }, - ), - ) + vertex.update_partial(|mut vertex| { + vertex.surface_form = vertex + .surface_form + .update_partial(|mut surface_vertex| { + if let Some(global_form) = global_form { + surface_vertex.global_form = global_form; + } + surface_vertex + }); + vertex }) }) }; diff --git a/crates/fj-kernel/src/builder/shell.rs b/crates/fj-kernel/src/builder/shell.rs index fcd8a61f3..343b45857 100644 --- a/crates/fj-kernel/src/builder/shell.rs +++ b/crates/fj-kernel/src/builder/shell.rs @@ -8,11 +8,8 @@ use crate::{ algorithms::transform::TransformObject, builder::{FaceBuilder, HalfEdgeBuilder}, insert::Insert, - objects::{ - Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface, SurfaceVertex, - Vertex, - }, - partial::{HasPartial, PartialCurve}, + objects::{Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface}, + partial::{HasPartial, PartialCurve, PartialSurfaceVertex, PartialVertex}, storage::Handle, }; @@ -114,14 +111,22 @@ impl<'a> ShellBuilder<'a> { let [_, from] = bottom.vertices(); let from = from.surface_form().clone(); - let to = SurfaceVertex::partial() - .with_position(Some(from.position() + [Z, edge_length])) - .with_surface(Some(surface.clone())); + let to = PartialSurfaceVertex { + position: Some(from.position() + [Z, edge_length]), + surface: Some(surface.clone()), + ..Default::default() + }; HalfEdge::partial() .with_vertices([ - Vertex::partial().with_surface_form(from), - Vertex::partial().with_surface_form(to), + PartialVertex { + surface_form: from.into(), + ..Default::default() + }, + PartialVertex { + surface_form: to.into(), + ..Default::default() + }, ]) .update_as_line_segment() .build(self.objects) @@ -145,12 +150,11 @@ impl<'a> ShellBuilder<'a> { let [to, _] = bottom.vertices(); let to = to.surface_form().clone(); - let from = SurfaceVertex::partial() - .with_position(Some( - to.position() + [Z, edge_length], - )) - .with_surface(Some(surface.clone())) - .with_global_form(Some(from.global_form().clone())); + let from = PartialSurfaceVertex { + position: Some(to.position() + [Z, edge_length]), + surface: Some(surface.clone()), + global_form: from.global_form().clone().into(), + }; let curve = PartialCurve { global_form: Some( @@ -166,8 +170,14 @@ impl<'a> ShellBuilder<'a> { HalfEdge::partial() .with_curve(curve) .with_vertices([ - Vertex::partial().with_surface_form(from), - Vertex::partial().with_surface_form(to), + PartialVertex { + surface_form: from.into(), + ..Default::default() + }, + PartialVertex { + surface_form: to.into(), + ..Default::default() + }, ]) .update_as_line_segment() .build(self.objects) @@ -189,8 +199,14 @@ impl<'a> ShellBuilder<'a> { let from = from.surface_form().clone(); let to = to.surface_form().clone(); - let from = Vertex::partial().with_surface_form(from); - let to = Vertex::partial().with_surface_form(to); + let from = PartialVertex { + surface_form: from.into(), + ..Default::default() + }; + let to = PartialVertex { + surface_form: to.into(), + ..Default::default() + }; HalfEdge::partial() .with_vertices([from, to]) @@ -250,16 +266,15 @@ impl<'a> ShellBuilder<'a> { .map(|(point, edge)| { let vertex = edge.back(); - SurfaceVertex::partial() - .with_position(Some(point)) - .with_surface(Some(surface.clone())) - .with_global_form(Some( - vertex.global_form().clone(), - )) - .build(self.objects) - .unwrap() - .insert(self.objects) - .unwrap() + PartialSurfaceVertex { + position: Some(point.into()), + surface: Some(surface.clone()), + global_form: vertex.global_form().clone().into(), + } + .build(self.objects) + .unwrap() + .insert(self.objects) + .unwrap() }); [a.clone(), b, c, d, a] @@ -277,10 +292,10 @@ impl<'a> ShellBuilder<'a> { .into_iter_fixed() .zip(surface_vertices.clone()) .collect::<[_; 2]>() - .map(|(vertex, surface_form)| { - Vertex::partial() - .with_position(Some(vertex.position())) - .with_surface_form(surface_form) + .map(|(vertex, surface_form)| PartialVertex { + position: Some(vertex.position()), + surface_form: surface_form.into(), + ..Default::default() }); edges.push( diff --git a/crates/fj-kernel/src/builder/vertex.rs b/crates/fj-kernel/src/builder/vertex.rs index ca2776ff8..879d5533f 100644 --- a/crates/fj-kernel/src/builder/vertex.rs +++ b/crates/fj-kernel/src/builder/vertex.rs @@ -11,47 +11,46 @@ use crate::{ /// Builder API for [`PartialVertex`] pub trait VertexBuilder { /// Remove the surface form of the partial vertex, inferring it on build - fn infer_surface_form(self) -> Self; + fn infer_surface_form(&mut self) -> &mut Self; } impl VertexBuilder for PartialVertex { - fn infer_surface_form(self) -> Self { - self.with_surface_form(PartialSurfaceVertex::default()) + fn infer_surface_form(&mut self) -> &mut Self { + self.surface_form = PartialSurfaceVertex::default().into(); + self } } /// Builder API for [`PartialSurfaceVertex`] pub trait SurfaceVertexBuilder { /// Infer the global form of the partial vertex - fn infer_global_form(self) -> Self; + fn infer_global_form(&mut self) -> &mut Self; } impl SurfaceVertexBuilder for PartialSurfaceVertex { - fn infer_global_form(self) -> Self { - self.with_global_form(Some(GlobalVertex::partial())) + fn infer_global_form(&mut self) -> &mut Self { + self.global_form = GlobalVertex::partial().into(); + self } } /// Builder API for [`PartialGlobalVertex`] pub trait GlobalVertexBuilder { /// Update partial global vertex from the given curve and position on it - fn update_from_curve_and_position( - self, + fn from_curve_and_position( curve: impl Into>, position: impl Into>, ) -> Self; /// Update partial global vertex from the given surface and position on it - fn update_from_surface_and_position( - self, + fn from_surface_and_position( surface: &Surface, position: impl Into>, ) -> Self; } impl GlobalVertexBuilder for PartialGlobalVertex { - fn update_from_curve_and_position( - self, + fn from_curve_and_position( curve: impl Into>, position: impl Into>, ) -> Self { @@ -65,14 +64,16 @@ impl GlobalVertexBuilder for PartialGlobalVertex { ); let position_surface = path.point_from_path_coords(position); - self.update_from_surface_and_position(&surface, position_surface) + + Self::from_surface_and_position(&surface, position_surface) } - fn update_from_surface_and_position( - self, + fn from_surface_and_position( surface: &Surface, position: impl Into>, ) -> Self { - self.with_position(Some(surface.point_from_surface_coords(position))) + PartialGlobalVertex { + position: Some(surface.point_from_surface_coords(position)), + } } } diff --git a/crates/fj-kernel/src/partial/maybe_partial.rs b/crates/fj-kernel/src/partial/maybe_partial.rs index 3db76684d..0fef15070 100644 --- a/crates/fj-kernel/src/partial/maybe_partial.rs +++ b/crates/fj-kernel/src/partial/maybe_partial.rs @@ -217,7 +217,7 @@ impl MaybePartial { pub fn position(&self) -> Option> { match self { Self::Full(full) => Some(full.position()), - Self::Partial(partial) => partial.position(), + Self::Partial(partial) => partial.position, } } @@ -225,7 +225,7 @@ impl MaybePartial { pub fn surface(&self) -> Option> { match self { Self::Full(full) => Some(full.surface().clone()), - Self::Partial(partial) => partial.surface(), + Self::Partial(partial) => partial.surface.clone(), } } @@ -233,7 +233,7 @@ impl MaybePartial { pub fn global_form(&self) -> MaybePartial { match self { Self::Full(full) => full.global_form().clone().into(), - Self::Partial(partial) => partial.global_form(), + Self::Partial(partial) => partial.global_form.clone(), } } } @@ -243,7 +243,7 @@ impl MaybePartial { pub fn surface_form(&self) -> MaybePartial { match self { Self::Full(full) => full.surface_form().clone().into(), - Self::Partial(partial) => partial.surface_form(), + Self::Partial(partial) => partial.surface_form.clone(), } } } diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index a802133e3..eedf39ff8 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -96,9 +96,14 @@ impl PartialCycle { *half_edge = half_edge.clone().merge_with( PartialHalfEdge::default().with_vertices([ - PartialVertex::default().with_surface_form(back_vertex), - PartialVertex::default() - .with_surface_form(front_vertex.clone()), + PartialVertex { + surface_form: back_vertex, + ..Default::default() + }, + PartialVertex { + surface_form: front_vertex.clone().into(), + ..Default::default() + }, ]), ); @@ -111,9 +116,10 @@ impl PartialCycle { let back_vertex = previous_vertex.unwrap_or_default(); *half_edge = half_edge.clone().merge_with( - PartialHalfEdge::default().with_back_vertex( - PartialVertex::default().with_surface_form(back_vertex), - ), + PartialHalfEdge::default().with_back_vertex(PartialVertex { + surface_form: back_vertex, + ..Default::default() + }), ); } diff --git a/crates/fj-kernel/src/partial/objects/edge.rs b/crates/fj-kernel/src/partial/objects/edge.rs index aaaf6d33a..cbace6209 100644 --- a/crates/fj-kernel/src/partial/objects/edge.rs +++ b/crates/fj-kernel/src/partial/objects/edge.rs @@ -54,13 +54,16 @@ impl PartialHalfEdge { }); self.vertices = self.vertices.map(|vertex| { - vertex.update_partial(|vertex| { - let surface_form = - vertex.surface_form().update_partial(|surface_vertex| { - surface_vertex.with_surface(Some(surface.clone())) - }); + vertex.update_partial(|mut vertex| { + let surface_form = vertex.surface_form.clone().update_partial( + |mut surface_vertex| { + surface_vertex.surface = Some(surface.clone()); + surface_vertex + }, + ); - vertex.with_surface_form(surface_form) + vertex.surface_form = surface_form; + vertex }) }); @@ -98,7 +101,10 @@ impl PartialHalfEdge { let curve = self.curve.into_full(objects)?; let vertices = self.vertices.try_map_ext(|vertex| { vertex - .update_partial(|vertex| vertex.with_curve(curve.clone())) + .update_partial(|mut vertex| { + vertex.curve = curve.clone().into(); + vertex + }) .into_full(objects) })?; diff --git a/crates/fj-kernel/src/partial/objects/vertex.rs b/crates/fj-kernel/src/partial/objects/vertex.rs index eaa7ac355..111ddf7fc 100644 --- a/crates/fj-kernel/src/partial/objects/vertex.rs +++ b/crates/fj-kernel/src/partial/objects/vertex.rs @@ -13,53 +13,17 @@ use crate::{ /// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default)] pub struct PartialVertex { - position: Option>, - curve: MaybePartial, - surface_form: MaybePartial, + /// The position of the [`Vertex`] + pub position: Option>, + + /// The curve that the [`Vertex`] is defined in + pub curve: MaybePartial, + + /// The surface form of the [`Vertex`] + pub surface_form: MaybePartial, } impl PartialVertex { - /// Access the position of the [`Vertex`] on the curve - pub fn position(&self) -> Option> { - self.position - } - - /// Access the curve that the [`Vertex`] is defined in - pub fn curve(&self) -> MaybePartial { - self.curve.clone() - } - - /// Access the surface form of the [`Vertex`] - pub fn surface_form(&self) -> MaybePartial { - self.surface_form.clone() - } - - /// Provide a position for the partial vertex - pub fn with_position( - mut self, - position: Option>>, - ) -> Self { - if let Some(position) = position { - self.position = Some(position.into()); - } - self - } - - /// Provide a curve for the partial vertex - pub fn with_curve(mut self, curve: impl Into>) -> Self { - self.curve = curve.into(); - self - } - - /// Provide a surface form for the partial vertex - pub fn with_surface_form( - mut self, - surface_form: impl Into>, - ) -> Self { - self.surface_form = surface_form.into(); - self - } - /// Build a full [`Vertex`] from the partial vertex /// /// # Panics @@ -75,14 +39,15 @@ impl PartialVertex { let surface_form = self .surface_form - .update_partial(|partial| { + .update_partial(|mut partial| { let position = partial.position.unwrap_or_else(|| { curve.path().point_from_path_coords(position) }); + partial.position = Some(position); + partial.surface = Some(curve.surface().clone()); + partial - .with_position(Some(position)) - .with_surface(Some(curve.surface().clone())) }) .into_full(objects)?; @@ -117,57 +82,17 @@ impl From<&Vertex> for PartialVertex { /// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialSurfaceVertex { - position: Option>, - surface: Option>, - global_form: MaybePartial, + /// The position of the [`SurfaceVertex`] + pub position: Option>, + + /// The surface that the [`SurfaceVertex`] is defined in + pub surface: Option>, + + /// The global form of the [`SurfaceVertex`] + pub global_form: MaybePartial, } impl PartialSurfaceVertex { - /// Access the position of the [`SurfaceVertex`] - pub fn position(&self) -> Option> { - self.position - } - - /// Access the surface that the [`SurfaceVertex`] is defined in - pub fn surface(&self) -> Option> { - self.surface.clone() - } - - /// Access the global form of the [`SurfaceVertex`] - pub fn global_form(&self) -> MaybePartial { - self.global_form.clone() - } - - /// Provide a position for the partial surface vertex - pub fn with_position( - mut self, - position: Option>>, - ) -> Self { - if let Some(position) = position { - self.position = Some(position.into()); - } - self - } - - /// Provide a surface for the partial surface vertex - pub fn with_surface(mut self, surface: Option>) -> Self { - if let Some(surface) = surface { - self.surface = Some(surface); - } - self - } - - /// Provide a global form for the partial surface vertex - pub fn with_global_form( - mut self, - global_form: Option>>, - ) -> Self { - if let Some(global_form) = global_form { - self.global_form = global_form.into(); - } - self - } - /// Build a full [`SurfaceVertex`] from the partial surface vertex pub fn build( self, @@ -182,9 +107,9 @@ impl PartialSurfaceVertex { let global_form = self .global_form - .update_partial(|global_form| { - global_form.update_from_surface_and_position(&surface, position) - }) + .merge_with(PartialGlobalVertex::from_surface_and_position( + &surface, position, + )) .into_full(objects)?; Ok(SurfaceVertex::new(position, surface, global_form)) @@ -218,26 +143,11 @@ impl From<&SurfaceVertex> for PartialSurfaceVertex { /// See [`crate::partial`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct PartialGlobalVertex { - position: Option>, + /// The position of the [`GlobalVertex`] + pub position: Option>, } impl PartialGlobalVertex { - /// Access the position of the [`GlobalVertex`] - pub fn position(&self) -> Option> { - self.position - } - - /// Provide a position for the partial global vertex - pub fn with_position( - mut self, - position: Option>>, - ) -> Self { - if let Some(position) = position { - self.position = Some(position.into()); - } - self - } - /// Build a full [`GlobalVertex`] from the partial global vertex pub fn build(self, _: &Objects) -> Result { let position = self diff --git a/crates/fj-kernel/src/validate/cycle.rs b/crates/fj-kernel/src/validate/cycle.rs index 45824c301..b30ddaa9a 100644 --- a/crates/fj-kernel/src/validate/cycle.rs +++ b/crates/fj-kernel/src/validate/cycle.rs @@ -95,7 +95,8 @@ mod tests { // Sever connection between the last and first half-edge in the // cycle. - let first_vertex = first_vertex.into_partial().infer_surface_form(); + let mut first_vertex = first_vertex.into_partial(); + first_vertex.infer_surface_form(); *first_half_edge = first_half_edge .clone() .with_back_vertex(first_vertex) diff --git a/crates/fj-kernel/src/validate/edge.rs b/crates/fj-kernel/src/validate/edge.rs index 7a4b837d1..0a294d415 100644 --- a/crates/fj-kernel/src/validate/edge.rs +++ b/crates/fj-kernel/src/validate/edge.rs @@ -220,12 +220,10 @@ mod tests { .build(&objects)?; let invalid = { let mut vertices = valid.vertices().clone(); - vertices[1] = vertices[1] - .to_partial() - // Arranging for an equal but not identical curve here. - .with_curve(valid.curve().to_partial()) - .build(&objects)? - .insert(&objects)?; + let mut vertex = vertices[1].to_partial(); + // Arranging for an equal but not identical curve here. + vertex.curve = valid.curve().to_partial().into(); + vertices[1] = vertex.build(&objects)?.insert(&objects)?; HalfEdge::new(vertices, valid.global_form().clone()) }; @@ -308,12 +306,10 @@ mod tests { let invalid = HalfEdge::new( 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)?) + let mut vertex = vertex.to_partial(); + vertex.position = Some([0.].into()); + vertex.infer_surface_form(); + Ok(vertex.build(&objects)?.insert(&objects)?) }, )?, valid.global_form().clone(), diff --git a/crates/fj-kernel/src/validate/vertex.rs b/crates/fj-kernel/src/validate/vertex.rs index 6b76257b1..186fab353 100644 --- a/crates/fj-kernel/src/validate/vertex.rs +++ b/crates/fj-kernel/src/validate/vertex.rs @@ -182,7 +182,9 @@ mod tests { builder::{CurveBuilder, SurfaceVertexBuilder}, insert::Insert, objects::{GlobalVertex, Objects, SurfaceVertex, Vertex}, - partial::{HasPartial, PartialCurve}, + partial::{ + HasPartial, PartialCurve, PartialSurfaceVertex, PartialVertex, + }, validate::Validate, }; @@ -196,20 +198,17 @@ mod tests { }; curve.update_as_u_axis(); - let valid = Vertex::partial() - .with_position(Some([0.])) - .with_curve(curve) - .build(&objects)?; - let invalid = Vertex::new( - valid.position(), - valid.curve().clone(), - valid - .surface_form() - .to_partial() - .with_surface(Some(objects.surfaces.xz_plane())) - .build(&objects)? - .insert(&objects)?, - ); + let valid = PartialVertex { + position: Some([0.].into()), + curve: curve.into(), + ..Default::default() + } + .build(&objects)?; + let invalid = Vertex::new(valid.position(), valid.curve().clone(), { + let mut tmp = valid.surface_form().to_partial(); + tmp.surface = Some(objects.surfaces.xz_plane()); + tmp.build(&objects)?.insert(&objects)? + }); assert!(valid.validate().is_ok()); assert!(invalid.validate().is_err()); @@ -228,22 +227,19 @@ mod tests { }; curve.update_as_u_axis(); - Vertex::partial() - .with_position(Some([0.])) - .with_curve(curve) - .build(&objects)? + PartialVertex { + position: Some([0.].into()), + curve: curve.into(), + ..Default::default() + } + .build(&objects)? }; - let invalid = Vertex::new( - valid.position(), - valid.curve().clone(), - valid - .surface_form() - .to_partial() - .with_position(Some([1., 0.])) - .infer_global_form() - .build(&objects)? - .insert(&objects)?, - ); + let invalid = Vertex::new(valid.position(), valid.curve().clone(), { + let mut tmp = valid.surface_form().to_partial(); + tmp.position = Some([1., 0.].into()); + tmp.infer_global_form(); + tmp.build(&objects)?.insert(&objects)? + }); assert!(valid.validate().is_ok()); assert!(invalid.validate().is_err()); @@ -255,10 +251,12 @@ mod tests { fn surface_vertex_position_mismatch() -> anyhow::Result<()> { let objects = Objects::new(); - let valid = SurfaceVertex::partial() - .with_position(Some([0., 0.])) - .with_surface(Some(objects.surfaces.xy_plane())) - .build(&objects)?; + let valid = PartialSurfaceVertex { + position: Some([0., 0.].into()), + surface: Some(objects.surfaces.xy_plane()), + ..Default::default() + } + .build(&objects)?; let invalid = SurfaceVertex::new( valid.position(), valid.surface().clone(),