diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index a4bf8aebe..730162d1f 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -1,9 +1,10 @@ //! Intersection between faces and points in 2D +use fj_interop::ext::ArrayExt; use fj_math::Point; use crate::{ - objects::{Face, HalfEdge, Vertex}, + objects::{Face, HalfEdge, SurfaceVertex}, storage::Handle, }; @@ -48,13 +49,17 @@ impl Intersect for (&Handle, &Point<2>) { )); } (Some(RaySegmentIntersection::RayStartsOnOnFirstVertex), _) => { - let vertex = half_edge.vertices()[0].clone(); + let [vertex, _] = half_edge.boundary().zip_ext( + half_edge.surface_vertices().map(Clone::clone) + ); return Some( FacePointIntersection::PointIsOnVertex(vertex) ); } (Some(RaySegmentIntersection::RayStartsOnSecondVertex), _) => { - let vertex = half_edge.vertices()[1].clone(); + let [_, vertex] = half_edge.boundary().zip_ext( + half_edge.surface_vertices().map(Clone::clone) + ); return Some( FacePointIntersection::PointIsOnVertex(vertex) ); @@ -125,11 +130,12 @@ pub enum FacePointIntersection { PointIsOnEdge(Handle), /// The point is coincident with a vertex - PointIsOnVertex(Vertex), + PointIsOnVertex((Point<1>, Handle)), } #[cfg(test)] mod tests { + use fj_interop::ext::ArrayExt; use fj_math::Point; use pretty_assertions::assert_eq; @@ -342,12 +348,15 @@ mod tests { let vertex = face .exterior() .half_edges() - .flat_map(|half_edge| half_edge.vertices()) - .find(|vertex| { - vertex.surface_form().position() == Point::from([1., 0.]) + .flat_map(|half_edge| { + half_edge + .boundary() + .zip_ext(half_edge.surface_vertices().map(Clone::clone)) }) - .unwrap() - .clone(); + .find(|(_, surface_vertex)| { + surface_vertex.position() == Point::from([1., 0.]) + }) + .unwrap(); assert_eq!( intersection, Some(FacePointIntersection::PointIsOnVertex(vertex)) diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs index d5f8aece9..de54e5cc4 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_face.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_face.rs @@ -5,7 +5,7 @@ use fj_math::{Plane, Point, Scalar}; use crate::{ algorithms::intersect::face_point::FacePointIntersection, geometry::path::GlobalPath, - objects::{Face, HalfEdge, Vertex}, + objects::{Face, HalfEdge, SurfaceVertex}, storage::Handle, }; @@ -136,11 +136,12 @@ pub enum RayFaceIntersection { RayHitsEdge(Handle), /// The ray hits a vertex - RayHitsVertex(Vertex), + RayHitsVertex((Point<1>, Handle)), } #[cfg(test)] mod tests { + use fj_interop::ext::ArrayExt; use fj_math::Point; use crate::{ @@ -287,12 +288,15 @@ mod tests { let vertex = face .exterior() .half_edges() - .flat_map(|half_edge| half_edge.vertices()) - .find(|vertex| { - vertex.surface_form().position() == Point::from([-1., -1.]) + .flat_map(|half_edge| { + half_edge + .boundary() + .zip_ext(half_edge.surface_vertices().map(Clone::clone)) }) - .unwrap() - .clone(); + .find(|(_, surface_vertex)| { + surface_vertex.position() == Point::from([-1., -1.]) + }) + .unwrap(); assert_eq!( (&ray, &face).intersect(), Some(RayFaceIntersection::RayHitsVertex(vertex)) diff --git a/crates/fj-kernel/src/algorithms/reverse/edge.rs b/crates/fj-kernel/src/algorithms/reverse/edge.rs index 062835590..1a9023356 100644 --- a/crates/fj-kernel/src/algorithms/reverse/edge.rs +++ b/crates/fj-kernel/src/algorithms/reverse/edge.rs @@ -1,3 +1,5 @@ +use fj_interop::ext::ArrayExt; + use crate::{ insert::Insert, objects::{HalfEdge, Objects}, @@ -10,7 +12,9 @@ use super::Reverse; impl Reverse for Handle { fn reverse(self, objects: &mut Service) -> Self { let vertices = { - let [a, b] = self.vertices().clone(); + let [a, b] = self + .boundary() + .zip_ext(self.surface_vertices().map(Clone::clone)); [b, a] }; diff --git a/crates/fj-kernel/src/algorithms/sweep/edge.rs b/crates/fj-kernel/src/algorithms/sweep/edge.rs index 29e69290d..e3b90745a 100644 --- a/crates/fj-kernel/src/algorithms/sweep/edge.rs +++ b/crates/fj-kernel/src/algorithms/sweep/edge.rs @@ -8,7 +8,6 @@ use crate::{ insert::Insert, objects::{ Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, SurfaceVertex, - Vertex, }, partial::{Partial, PartialFace, PartialObject}, services::Service, @@ -57,39 +56,43 @@ impl Sweep for (Handle, Color) { .insert(objects) }; - let vertices = { + let boundary = { let points_surface = points_curve_and_surface .map(|(_, point_surface)| point_surface); - edge.vertices() - .each_ref_ext() + edge.boundary() + .zip_ext(edge.surface_vertices()) .into_iter_fixed() .zip(points_surface) .collect::<[_; 2]>() - .map(|(vertex, point_surface)| { + .map(|((point, surface_vertex), point_surface)| { let surface_vertex = SurfaceVertex::new( point_surface, surface.clone(), - vertex.surface_form().global_form().clone(), + surface_vertex.global_form().clone(), ) .insert(objects); - Vertex::new(vertex.position(), surface_vertex) + (point, surface_vertex) }) }; - HalfEdge::new(curve, vertices, edge.global_form().clone()) + HalfEdge::new(curve, boundary, edge.global_form().clone()) .insert(objects) }; - let side_edges = bottom_edge.vertices().clone().map(|vertex| { - (vertex, surface.clone()).sweep_with_cache(path, cache, objects) - }); + let side_edges = bottom_edge + .boundary() + .zip_ext(bottom_edge.surface_vertices()) + .map(|(point, surface_vertex)| { + (point, surface_vertex.clone(), surface.clone()) + .sweep_with_cache(path, cache, objects) + }); let top_edge = { let surface_vertices = side_edges.clone().map(|edge| { - let [_, vertex] = edge.vertices(); - vertex.surface_form().clone() + let [_, surface_vertex] = edge.surface_vertices(); + surface_vertex.clone() }); let points_curve_and_surface = bottom_edge @@ -122,14 +125,13 @@ impl Sweep for (Handle, Color) { ) .insert(objects); - let vertices = bottom_edge + let boundary = bottom_edge .boundary() .into_iter_fixed() .zip(surface_vertices) - .collect::<[_; 2]>() - .map(|(point, surface_form)| Vertex::new(point, surface_form)); + .collect::<[_; 2]>(); - HalfEdge::new(curve, vertices, global).insert(objects) + HalfEdge::new(curve, boundary, global).insert(objects) }; let cycle = { @@ -144,15 +146,13 @@ impl Sweep for (Handle, Color) { while i < edges.len() { let j = (i + 1) % edges.len(); - let [_, prev_last] = edges[i].vertices(); - let [next_first, _] = edges[j].vertices(); + let [_, prev_last] = edges[i].surface_vertices(); + let [next_first, _] = edges[j].surface_vertices(); // Need to compare surface forms here, as the global forms might // be coincident when sweeping circles, despite the vertices // being different! - if prev_last.surface_form().id() - != next_first.surface_form().id() - { + if prev_last.id() != next_first.id() { edges[j] = edges[j].clone().reverse(objects); } diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index f17a56aec..558a93fdb 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -5,7 +5,7 @@ use crate::{ insert::Insert, objects::{ Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, - Surface, SurfaceVertex, Vertex, + Surface, SurfaceVertex, }, services::Service, storage::Handle, @@ -13,7 +13,7 @@ use crate::{ use super::{Sweep, SweepCache}; -impl Sweep for (Vertex, Handle) { +impl Sweep for (Point<1>, Handle, Handle) { type Swept = Handle; fn sweep_with_cache( @@ -22,7 +22,7 @@ impl Sweep for (Vertex, Handle) { cache: &mut SweepCache, objects: &mut Service, ) -> Self::Swept { - let (vertex, surface) = self; + let (point, surface_vertex, surface) = self; let path = path.into(); // The result of sweeping a `Vertex` is an `Edge`. Seems @@ -60,8 +60,7 @@ impl Sweep for (Vertex, Handle) { // With that out of the way, let's start by creating the `GlobalEdge`, // as that is the most straight-forward part of this operations, and // we're going to need it soon anyway. - let (edge_global, vertices_global) = vertex - .surface_form() + let (edge_global, vertices_global) = surface_vertex .global_form() .clone() .sweep_with_cache(path, cache, objects); @@ -81,8 +80,8 @@ impl Sweep for (Vertex, Handle) { // straight-forward: The start of the edge is at zero, the end is at // one. let points_surface = [ - Point::from([vertex.position().t, Scalar::ZERO]), - Point::from([vertex.position().t, Scalar::ONE]), + Point::from([point.t, Scalar::ZERO]), + Point::from([point.t, Scalar::ONE]), ]; // Armed with those coordinates, creating the `Curve` of the output @@ -99,20 +98,20 @@ impl Sweep for (Vertex, Handle) { let [_, global_form] = vertices_global; [ - vertex.surface_form().clone(), + surface_vertex, SurfaceVertex::new(position, surface, global_form) .insert(objects), ] }; // And now the vertices. Again, nothing wild here. - let vertices = vertices_surface.map(|surface_form| { - Vertex::new([surface_form.position().v], surface_form) + let boundary = vertices_surface.map(|surface_vertex| { + (Point::from([surface_vertex.position().v]), surface_vertex) }); // And finally, creating the output `Edge` is just a matter of // assembling the pieces we've already created. - HalfEdge::new(curve, vertices, edge_global).insert(objects) + HalfEdge::new(curve, boundary, edge_global).insert(objects) } } @@ -158,7 +157,7 @@ mod tests { insert::Insert, partial::{ Partial, PartialCurve, PartialGlobalVertex, PartialHalfEdge, - PartialObject, PartialSurfaceVertex, PartialVertex, + PartialObject, PartialSurfaceVertex, }, services::Services, }; @@ -168,24 +167,26 @@ mod tests { let mut services = Services::new(); let surface = services.objects.surfaces.xz_plane(); - let mut curve = PartialCurve { - surface: Partial::from(surface.clone()), - ..Default::default() - }; - curve.update_as_u_axis(); - let vertex = PartialVertex { - position: Some([0.].into()), - surface_form: Partial::from_partial(PartialSurfaceVertex { + let (position, surface_vertex) = { + let mut curve = PartialCurve { + surface: Partial::from(surface.clone()), + ..Default::default() + }; + curve.update_as_u_axis(); + + let surface_form = Partial::from_partial(PartialSurfaceVertex { position: Some(Point::from([0., 0.])), surface: Partial::from(surface.clone()), global_form: Partial::from_partial(PartialGlobalVertex { position: Some(Point::from([0., 0., 0.])), }), - }), - } - .build(&mut services.objects); + }) + .build(&mut services.objects); + + (Point::from([0.]), surface_form) + }; - let half_edge = (vertex, surface.clone()) + let half_edge = (position, surface_vertex, surface.clone()) .sweep([0., 0., 1.], &mut services.objects); let expected_half_edge = { diff --git a/crates/fj-kernel/src/algorithms/transform/edge.rs b/crates/fj-kernel/src/algorithms/transform/edge.rs index 7c5829e1c..4c5b7b242 100644 --- a/crates/fj-kernel/src/algorithms/transform/edge.rs +++ b/crates/fj-kernel/src/algorithms/transform/edge.rs @@ -1,3 +1,4 @@ +use fj_interop::ext::ArrayExt; use fj_math::Transform; use crate::{ @@ -18,15 +19,20 @@ impl TransformObject for HalfEdge { .curve() .clone() .transform_with_cache(transform, objects, cache); - let vertices = self.vertices().clone().map(|vertex| { - vertex.transform_with_cache(transform, objects, cache) - }); + let boundary = self.boundary().zip_ext(self.surface_vertices()).map( + |(point, surface_vertex)| { + let surface_vertex = surface_vertex + .clone() + .transform_with_cache(transform, objects, cache); + (point, surface_vertex) + }, + ); let global_form = self .global_form() .clone() .transform_with_cache(transform, objects, cache); - Self::new(curve, vertices, global_form) + Self::new(curve, boundary, global_form) } } diff --git a/crates/fj-kernel/src/algorithms/transform/vertex.rs b/crates/fj-kernel/src/algorithms/transform/vertex.rs index 7b5adf724..8777cf9f8 100644 --- a/crates/fj-kernel/src/algorithms/transform/vertex.rs +++ b/crates/fj-kernel/src/algorithms/transform/vertex.rs @@ -1,32 +1,12 @@ use fj_math::Transform; use crate::{ - objects::{GlobalVertex, Objects, SurfaceVertex, Vertex}, + objects::{GlobalVertex, Objects, SurfaceVertex}, services::Service, }; use super::{TransformCache, TransformObject}; -impl TransformObject for Vertex { - fn transform_with_cache( - self, - transform: &Transform, - objects: &mut Service, - cache: &mut TransformCache, - ) -> Self { - // Don't need to transform position, as that is defined in curve - // coordinates and thus transforming the curve takes care of it. - let position = self.position(); - - let surface_form = self - .surface_form() - .clone() - .transform_with_cache(transform, objects, cache); - - Self::new(position, surface_form) - } -} - impl TransformObject for SurfaceVertex { fn transform_with_cache( self, diff --git a/crates/fj-kernel/src/objects/full/edge.rs b/crates/fj-kernel/src/objects/full/edge.rs index 1372c0900..95f678b35 100644 --- a/crates/fj-kernel/src/objects/full/edge.rs +++ b/crates/fj-kernel/src/objects/full/edge.rs @@ -4,7 +4,7 @@ use fj_interop::ext::ArrayExt; use fj_math::Point; use crate::{ - objects::{Curve, GlobalCurve, GlobalVertex, SurfaceVertex, Vertex}, + objects::{Curve, GlobalCurve, GlobalVertex, SurfaceVertex}, storage::{Handle, HandleWrapper}, }; @@ -12,7 +12,7 @@ use crate::{ #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct HalfEdge { curve: Handle, - vertices: [Vertex; 2], + boundary: [(Point<1>, Handle); 2], global_form: Handle, } @@ -20,12 +20,12 @@ impl HalfEdge { /// Create an instance of `HalfEdge` pub fn new( curve: Handle, - vertices: [Vertex; 2], + boundary: [(Point<1>, Handle); 2], global_form: Handle, ) -> Self { Self { curve, - vertices, + boundary, global_form, } } @@ -37,19 +37,14 @@ impl HalfEdge { /// Access the boundary points of the half-edge on the curve pub fn boundary(&self) -> [Point<1>; 2] { - self.vertices.each_ref_ext().map(|vertex| vertex.position()) - } - - /// Access the vertices that bound the half-edge on the curve - pub fn vertices(&self) -> &[Vertex; 2] { - &self.vertices + self.boundary.each_ref_ext().map(|&(point, _)| point) } /// Access the surface vertices that bound the half-edge pub fn surface_vertices(&self) -> [&Handle; 2] { - self.vertices + self.boundary .each_ref_ext() - .map(|vertex| vertex.surface_form()) + .map(|(_, surface_form)| surface_form) } /// Access the global form of the half-edge diff --git a/crates/fj-kernel/src/objects/full/vertex.rs b/crates/fj-kernel/src/objects/full/vertex.rs index b969135b7..1fee8ba05 100644 --- a/crates/fj-kernel/src/objects/full/vertex.rs +++ b/crates/fj-kernel/src/objects/full/vertex.rs @@ -2,44 +2,6 @@ use fj_math::Point; use crate::{objects::Surface, storage::Handle}; -/// A vertex -/// -/// `Vertex` is defined in terms of a 1-dimensional position on a curve. Each -/// `Vertex` has an associated [`SurfaceVertex`], which defines the 2D position -/// on the surface, and a [`GlobalVertex`] which defines the global 3D position. -/// -/// Both can be accessed through [`Vertex::surface_form`]. -#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct Vertex { - position: Point<1>, - surface_form: Handle, -} - -impl Vertex { - /// Construct an instance of `Vertex` - pub fn new( - position: impl Into>, - surface_form: Handle, - ) -> Self { - let position = position.into(); - - Self { - position, - surface_form, - } - } - - /// Access the position of the vertex on the curve - pub fn position(&self) -> Point<1> { - self.position - } - - /// Access the surface form of this vertex - pub fn surface_form(&self) -> &Handle { - &self.surface_form - } -} - /// A vertex, defined in surface (2D) coordinates #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct SurfaceVertex { diff --git a/crates/fj-kernel/src/objects/mod.rs b/crates/fj-kernel/src/objects/mod.rs index 6036e2b73..9fe7e2f9d 100644 --- a/crates/fj-kernel/src/objects/mod.rs +++ b/crates/fj-kernel/src/objects/mod.rs @@ -87,7 +87,7 @@ pub use self::{ sketch::Sketch, solid::Solid, surface::Surface, - vertex::{GlobalVertex, SurfaceVertex, Vertex}, + vertex::{GlobalVertex, SurfaceVertex}, }, object::{Bare, BehindHandle, Form, Object, WithHandle}, stores::{Objects, Surfaces}, diff --git a/crates/fj-kernel/src/partial/objects/edge.rs b/crates/fj-kernel/src/partial/objects/edge.rs index 4e251124a..b7dbcb117 100644 --- a/crates/fj-kernel/src/partial/objects/edge.rs +++ b/crates/fj-kernel/src/partial/objects/edge.rs @@ -59,9 +59,15 @@ impl PartialObject for PartialHalfEdge { Self { curve: Partial::from_full(half_edge.curve().clone(), cache), vertices: half_edge - .vertices() - .clone() - .map(|vertex| PartialVertex::from_full(&vertex, cache)), + .boundary() + .zip_ext(half_edge.surface_vertices()) + .map(|(position, surface_vertex)| PartialVertex { + position: Some(position), + surface_form: Partial::from_full( + surface_vertex.clone(), + cache, + ), + }), global_form: Partial::from_full( half_edge.global_form().clone(), cache, @@ -103,7 +109,12 @@ impl PartialObject for PartialHalfEdge { Some(position_global); } - vertex.build(objects) + let position = vertex + .position + .expect("Can't build `Vertex` without position"); + let surface_form = vertex.surface_form.build(objects); + + (position, surface_form) }); let global_form = self.global_form.build(objects); diff --git a/crates/fj-kernel/src/partial/objects/vertex.rs b/crates/fj-kernel/src/partial/objects/vertex.rs index 9f117cccf..7ce785a90 100644 --- a/crates/fj-kernel/src/partial/objects/vertex.rs +++ b/crates/fj-kernel/src/partial/objects/vertex.rs @@ -1,12 +1,17 @@ use fj_math::Point; use crate::{ - objects::{GlobalVertex, Objects, Surface, SurfaceVertex, Vertex}, + objects::{GlobalVertex, Objects, Surface, SurfaceVertex}, partial::{FullToPartialCache, Partial, PartialObject}, services::Service, }; -/// A partial [`Vertex`] +/// A partial vertex +/// +/// # Implementation Note +/// +/// This type is a hold-over from when there was still a `Vertex` object. It +/// will be remove too, at some point. #[derive(Clone, Debug)] pub struct PartialVertex { /// The position of the vertex on the curve @@ -16,29 +21,6 @@ pub struct PartialVertex { pub surface_form: Partial, } -impl PartialObject for PartialVertex { - type Full = Vertex; - - fn from_full(vertex: &Self::Full, cache: &mut FullToPartialCache) -> Self { - Self { - position: Some(vertex.position()), - surface_form: Partial::from_full( - vertex.surface_form().clone(), - cache, - ), - } - } - - fn build(self, objects: &mut Service) -> Self::Full { - let position = self - .position - .expect("Can't build `Vertex` without position"); - let surface_form = self.surface_form.build(objects); - - Vertex::new(position, surface_form) - } -} - impl Default for PartialVertex { fn default() -> Self { let surface = Partial::new(); diff --git a/crates/fj-kernel/src/partial/traits.rs b/crates/fj-kernel/src/partial/traits.rs index 6b155e9d5..2b14305c3 100644 --- a/crates/fj-kernel/src/partial/traits.rs +++ b/crates/fj-kernel/src/partial/traits.rs @@ -45,5 +45,4 @@ impl_trait!( Solid, PartialSolid; Surface, PartialSurface; SurfaceVertex, PartialSurfaceVertex; - Vertex, PartialVertex; ); diff --git a/crates/fj-kernel/src/validate/edge.rs b/crates/fj-kernel/src/validate/edge.rs index 6f5f12778..bbcb2765a 100644 --- a/crates/fj-kernel/src/validate/edge.rs +++ b/crates/fj-kernel/src/validate/edge.rs @@ -3,8 +3,8 @@ use fj_math::{Point, Scalar}; use crate::{ objects::{ - GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface, Vertex, - VerticesInNormalizedOrder, + GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface, + SurfaceVertex, VerticesInNormalizedOrder, }, storage::Handle, }; @@ -118,14 +118,18 @@ pub enum HalfEdgeValidationError { /// Mismatch between position of the vertex and position of its surface form #[error( - "`Vertex` position doesn't match position of its surface form\n\ - - `Vertex`: {vertex:#?}\n\ - - `Vertex` position on surface: {curve_position_on_surface:?}\n\ + "Position on curve doesn't match surface vertex position\n\ + - Position on curve: {position_on_curve:#?}\n\ + - Surface vertex: {surface_vertex:#?}\n\ + - Curve position converted to surface: {curve_position_on_surface:?}\n\ - Distance between the positions: {distance}" )] VertexPositionMismatch { - /// The vertex - vertex: Vertex, + /// The position on the curve + position_on_curve: Point<1>, + + /// The surface vertex + surface_vertex: Handle, /// The curve position converted into a surface position curve_position_on_surface: Point<2>, @@ -241,12 +245,14 @@ impl HalfEdgeValidationError { config: &ValidationConfig, errors: &mut Vec, ) { - for vertex in half_edge.vertices() { + for (position_on_curve, surface_vertex) in + half_edge.boundary().zip_ext(half_edge.surface_vertices()) + { let curve_position_on_surface = half_edge .curve() .path() - .point_from_path_coords(vertex.position()); - let surface_position = vertex.surface_form().position(); + .point_from_path_coords(position_on_curve); + let surface_position = surface_vertex.position(); let distance = curve_position_on_surface.distance_to(&surface_position); @@ -254,7 +260,8 @@ impl HalfEdgeValidationError { if distance > config.identical_max_distance { errors.push( Box::new(Self::VertexPositionMismatch { - vertex: vertex.clone(), + position_on_curve, + surface_vertex: surface_vertex.clone(), curve_position_on_surface, distance, }) @@ -274,10 +281,7 @@ mod tests { builder::HalfEdgeBuilder, insert::Insert, objects::{GlobalCurve, HalfEdge}, - partial::{ - FullToPartialCache, Partial, PartialHalfEdge, PartialObject, - PartialVertex, - }, + partial::{Partial, PartialHalfEdge, PartialObject}, services::Services, validate::Validate, }; @@ -295,13 +299,20 @@ mod tests { half_edge.build(&mut services.objects) }; - let invalid = - HalfEdge::new(valid.curve().clone(), valid.vertices().clone(), { - let mut tmp = Partial::from(valid.global_form().clone()); - tmp.write().curve = + let invalid = { + let global_form = { + let mut global_edge = + Partial::from(valid.global_form().clone()); + global_edge.write().curve = Partial::from(GlobalCurve.insert(&mut services.objects)); - tmp.build(&mut services.objects) - }); + global_edge.build(&mut services.objects) + }; + let vertices = valid + .boundary() + .zip_ext(valid.surface_vertices().map(Clone::clone)); + + HalfEdge::new(valid.curve().clone(), vertices, global_form) + }; valid.validate_and_return_first_error()?; assert!(invalid.validate_and_return_first_error().is_err()); @@ -322,10 +333,11 @@ mod tests { half_edge.build(&mut services.objects) }; - let invalid = - HalfEdge::new(valid.curve().clone(), valid.vertices().clone(), { - let mut tmp = Partial::from(valid.global_form().clone()); - tmp.write().vertices = valid + let invalid = { + let global_form = { + let mut global_edge = + Partial::from(valid.global_form().clone()); + global_edge.write().vertices = valid .global_form() .vertices() .access_in_normalized_order() @@ -335,8 +347,14 @@ mod tests { Partial::from(vertex).read().clone(), ) }); - tmp.build(&mut services.objects) - }); + global_edge.build(&mut services.objects) + }; + let vertices = valid + .boundary() + .zip_ext(valid.surface_vertices().map(Clone::clone)); + + HalfEdge::new(valid.curve().clone(), vertices, global_form) + }; valid.validate_and_return_first_error()?; assert!(invalid.validate_and_return_first_error().is_err()); @@ -358,16 +376,17 @@ mod tests { half_edge.build(&mut services.objects) }; let invalid = { - let vertices = valid.vertices().clone().map(|vertex| { - let mut vertex = PartialVertex::from_full( - &vertex, - &mut FullToPartialCache::default(), - ); - vertex.surface_form.write().surface = - Partial::from(services.objects.surfaces.xz_plane()); - - vertex.build(&mut services.objects) - }); + let vertices = valid + .boundary() + .zip_ext(valid.surface_vertices()) + .map(|(point, surface_vertex)| { + let mut surface_vertex = + Partial::from(surface_vertex.clone()); + surface_vertex.write().surface = + Partial::from(services.objects.surfaces.xz_plane()); + + (point, surface_vertex.build(&mut services.objects)) + }); HalfEdge::new( valid.curve().clone(), @@ -396,14 +415,8 @@ mod tests { half_edge.build(&mut services.objects) }; let invalid = { - let vertices = valid.vertices().each_ref_ext().map(|vertex| { - let mut vertex = PartialVertex::from_full( - vertex, - &mut FullToPartialCache::default(), - ); - vertex.position = Some(Point::from([0.])); - - vertex.build(&mut services.objects) + let vertices = valid.surface_vertices().map(|surface_vertex| { + (Point::from([0.]), surface_vertex.clone()) }); HalfEdge::new( @@ -433,14 +446,8 @@ mod tests { half_edge.build(&mut services.objects) }; let invalid = { - let vertices = valid.vertices().clone().map(|vertex| { - let mut vertex = PartialVertex::from_full( - &vertex, - &mut FullToPartialCache::default(), - ); - vertex.position = Some(Point::from([2.])); - - vertex.build(&mut services.objects) + let vertices = valid.surface_vertices().map(|surface_vertex| { + (Point::from([2.]), surface_vertex.clone()) }); HalfEdge::new( diff --git a/crates/fj-kernel/src/validate/vertex.rs b/crates/fj-kernel/src/validate/vertex.rs index bb75f5e98..b8e393774 100644 --- a/crates/fj-kernel/src/validate/vertex.rs +++ b/crates/fj-kernel/src/validate/vertex.rs @@ -1,18 +1,9 @@ use fj_math::{Point, Scalar}; -use crate::objects::{GlobalVertex, SurfaceVertex, Vertex}; +use crate::objects::{GlobalVertex, SurfaceVertex}; use super::{Validate, ValidationConfig, ValidationError}; -impl Validate for Vertex { - fn validate_with_config( - &self, - _: &ValidationConfig, - _: &mut Vec, - ) { - } -} - impl Validate for SurfaceVertex { fn validate_with_config( &self,