diff --git a/crates/fj-kernel/src/algorithms/approx/edges.rs b/crates/fj-kernel/src/algorithms/approx/edges.rs index 074cd947c..b24237e64 100644 --- a/crates/fj-kernel/src/algorithms/approx/edges.rs +++ b/crates/fj-kernel/src/algorithms/approx/edges.rs @@ -13,7 +13,7 @@ pub fn approx_edge( // the same vertex would be understood to refer to very close, but distinct // vertices. let vertices = vertices.convert(|vertex| { - geometry::Point::new(*vertex.local(), vertex.canonical().point) + geometry::Point::new(*vertex.local(), vertex.canonical().position()) }); if let Some([a, b]) = vertices { points.insert(0, a); @@ -36,7 +36,7 @@ mod test { use crate::{ geometry, - objects::{Vertex, VerticesOfEdge}, + objects::{GlobalVertex, VerticesOfEdge}, shape::LocalForm, }; @@ -47,8 +47,8 @@ mod test { let c = Point::from([3., 5., 8.]); let d = Point::from([5., 8., 13.]); - let v1 = Vertex::from_point(a); - let v2 = Vertex::from_point(d); + let v1 = GlobalVertex::from_position(a); + let v2 = GlobalVertex::from_position(d); let vertices = VerticesOfEdge::from_vertices([ LocalForm::new(Point::from([0.]), v1), diff --git a/crates/fj-kernel/src/algorithms/sweep.rs b/crates/fj-kernel/src/algorithms/sweep.rs index f14d2f29e..34f1b4a78 100644 --- a/crates/fj-kernel/src/algorithms/sweep.rs +++ b/crates/fj-kernel/src/algorithms/sweep.rs @@ -2,7 +2,9 @@ use fj_math::{Point, Scalar, Transform, Triangle, Vector}; use crate::{ iter::ObjectIters, - objects::{Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge}, + objects::{ + Curve, Cycle, Edge, Face, GlobalVertex, Surface, VerticesOfEdge, + }, shape::LocalForm, }; @@ -87,14 +89,14 @@ fn create_top_face( fn create_non_continuous_side_face( path: Vector<3>, is_sweep_along_negative_direction: bool, - vertices_bottom: [Vertex; 2], + vertices_bottom: [GlobalVertex; 2], color: [u8; 4], target: &mut Vec, ) { let vertices = { let vertices_top = vertices_bottom.map(|vertex| { - let point = vertex.point + path; - Vertex { point } + let position = vertex.position() + path; + GlobalVertex::from_position(position) }); let [[a, b], [c, d]] = [vertices_bottom, vertices_top]; @@ -107,7 +109,7 @@ fn create_non_continuous_side_face( }; let surface = { - let [a, b, _, c] = vertices.map(|vertex| vertex.point); + let [a, b, _, c] = vertices.map(|vertex| vertex.position()); Surface::plane_from_points([a, b, c]) }; @@ -131,7 +133,7 @@ fn create_non_continuous_side_face( let curve = { let local = Curve::line_from_points([a.0, b.0]); - let global = [a, b].map(|vertex| vertex.1.point); + let global = [a, b].map(|vertex| vertex.1.position()); let global = Curve::line_from_points(global); LocalForm::new(local, global) diff --git a/crates/fj-kernel/src/algorithms/transform.rs b/crates/fj-kernel/src/algorithms/transform.rs index cb2916d02..57e8cdd40 100644 --- a/crates/fj-kernel/src/algorithms/transform.rs +++ b/crates/fj-kernel/src/algorithms/transform.rs @@ -1,7 +1,7 @@ use fj_math::Transform; use crate::{ - objects::{Cycle, CyclesInFace, Edge, Face, FaceBRep, Vertex}, + objects::{Cycle, CyclesInFace, Edge, Face, FaceBRep, GlobalVertex}, shape::LocalForm, }; @@ -58,11 +58,11 @@ pub fn transform_cycles( let vertices = edge.canonical().clone().vertices.map(|vertex| { - let point = vertex.canonical().point; - let point = transform.transform_point(&point); + let position = vertex.canonical().position(); + let position = transform.transform_point(&position); let local = *vertex.local(); - let canonical = Vertex { point }; + let canonical = GlobalVertex::from_position(position); LocalForm::new(local, canonical) }); @@ -91,11 +91,11 @@ pub fn transform_cycles( LocalForm::canonical_only(curve) }; let vertices = edge.vertices.clone().map(|vertex| { - let point = vertex.canonical().point; - let point = transform.transform_point(&point); + let position = vertex.canonical().position(); + let position = transform.transform_point(&position); let local = *vertex.local(); - let canonical = Vertex { point }; + let canonical = GlobalVertex::from_position(position); LocalForm::new(local, canonical) }); diff --git a/crates/fj-kernel/src/iter.rs b/crates/fj-kernel/src/iter.rs index 8f76769a2..0e5177a77 100644 --- a/crates/fj-kernel/src/iter.rs +++ b/crates/fj-kernel/src/iter.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; -use crate::objects::{Curve, Cycle, Edge, Face, Surface, Vertex}; +use crate::objects::{Curve, Cycle, Edge, Face, GlobalVertex, Surface}; /// Access iterators over all objects of a shape, or part of it /// @@ -25,7 +25,7 @@ pub trait ObjectIters { fn surface_iter(&self) -> Iter; /// Iterate over all vertices - fn vertex_iter(&self) -> Iter; + fn vertex_iter(&self) -> Iter; } impl ObjectIters for Curve<3> { @@ -49,7 +49,7 @@ impl ObjectIters for Curve<3> { Iter::empty() } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { Iter::empty() } } @@ -99,7 +99,7 @@ impl ObjectIters for Cycle<3> { iter } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { let mut iter = Iter::empty(); for edge in self.edges() { @@ -155,7 +155,7 @@ impl ObjectIters for Edge<3> { iter } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { let mut iter = Iter::empty().with(self.curve().vertex_iter()); for vertex in self.vertices().into_iter().flatten() { @@ -227,7 +227,7 @@ impl ObjectIters for Face { Iter::empty() } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { if let Face::Face(face) = self { let mut iter = Iter::empty().with(face.surface().vertex_iter()); @@ -263,12 +263,12 @@ impl ObjectIters for Surface { Iter::from_object(*self) } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { Iter::empty() } } -impl ObjectIters for Vertex { +impl ObjectIters for GlobalVertex { fn curve_iter(&self) -> Iter> { Iter::empty() } @@ -289,7 +289,7 @@ impl ObjectIters for Vertex { Iter::empty() } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { Iter::from_object(*self) } } @@ -354,7 +354,7 @@ where iter } - fn vertex_iter(&self) -> Iter { + fn vertex_iter(&self) -> Iter { let mut iter = Iter::empty(); for face in self.into_iter() { @@ -405,7 +405,7 @@ impl Iterator for Iter { #[cfg(test)] mod tests { - use crate::objects::{Curve, Cycle, Edge, Face, Surface, Vertex}; + use crate::objects::{Curve, Cycle, Edge, Face, GlobalVertex, Surface}; use super::ObjectIters as _; @@ -478,7 +478,7 @@ mod tests { #[test] fn vertex() { - let vertex = Vertex::from_point([0., 0., 0.]); + let vertex = GlobalVertex::from_position([0., 0., 0.]); assert_eq!(0, vertex.curve_iter().count()); assert_eq!(0, vertex.cycle_iter().count()); diff --git a/crates/fj-kernel/src/objects/edge.rs b/crates/fj-kernel/src/objects/edge.rs index 8d8e79892..490ab709e 100644 --- a/crates/fj-kernel/src/objects/edge.rs +++ b/crates/fj-kernel/src/objects/edge.rs @@ -4,7 +4,7 @@ use fj_math::{Circle, Line, Point, Scalar, Vector}; use crate::shape::LocalForm; -use super::{Curve, Vertex}; +use super::{Curve, GlobalVertex}; /// An edge of a shape #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] @@ -36,7 +36,7 @@ impl Edge { /// /// This is a convenience method that saves the caller from dealing with the /// [`Handle`]s. - pub fn vertices(&self) -> Option<[Vertex; 2]> { + pub fn vertices(&self) -> Option<[GlobalVertex; 2]> { self.vertices .0 .as_ref() @@ -76,18 +76,18 @@ impl Edge<3> { pub fn line_segment_from_points( vertices: [impl Into>; 2], ) -> Self { - let vertices = vertices.map(|point| { - let point = point.into(); - Vertex { point } + let vertices = vertices.map(|position| { + let position = position.into(); + GlobalVertex::from_position(position) }); Self::line_segment_from_vertices(vertices) } /// Create a line segment from two vertices - pub fn line_segment_from_vertices([a, b]: [Vertex; 2]) -> Self { + pub fn line_segment_from_vertices([a, b]: [GlobalVertex; 2]) -> Self { let curve = { - let points = [a, b].map(|vertex| vertex.point); + let points = [a, b].map(|vertex| vertex.position()); Curve::Line(Line::from_points(points)) }; @@ -107,7 +107,7 @@ impl fmt::Display for Edge { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.vertices() { Some(vertices) => { - let [a, b] = vertices.map(|vertex| vertex.point); + let [a, b] = vertices.map(|vertex| vertex.position()); write!(f, "edge from {:?} to {:?}", a, b)? } None => write!(f, "continuous edge")?, @@ -121,16 +121,20 @@ impl fmt::Display for Edge { /// The vertices that bound an edge #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct VerticesOfEdge(Option<[LocalForm, Vertex>; 2]>); +pub struct VerticesOfEdge(Option<[LocalForm, GlobalVertex>; 2]>); impl VerticesOfEdge { /// Construct an instance of `VerticesOfEdge` from zero or two vertices - pub fn new(vertices: Option<[LocalForm, Vertex>; 2]>) -> Self { + pub fn new( + vertices: Option<[LocalForm, GlobalVertex>; 2]>, + ) -> Self { Self(vertices) } /// Construct an instance of `VerticesOfEdge` from two vertices - pub fn from_vertices(vertices: [LocalForm, Vertex>; 2]) -> Self { + pub fn from_vertices( + vertices: [LocalForm, GlobalVertex>; 2], + ) -> Self { Self(Some(vertices)) } @@ -164,12 +168,14 @@ impl VerticesOfEdge { /// # Panics /// /// Panics, if the edge has no vertices. - pub fn expect_vertices(self) -> [LocalForm, Vertex>; 2] { + pub fn expect_vertices(self) -> [LocalForm, GlobalVertex>; 2] { self.0.expect("Expected edge to have vertices") } /// Iterate over the vertices, if any - pub fn iter(&self) -> impl Iterator, Vertex>> { + pub fn iter( + &self, + ) -> impl Iterator, GlobalVertex>> { self.0.iter().flatten() } @@ -188,7 +194,9 @@ impl VerticesOfEdge { /// Map each vertex using the provided function pub fn map(self, f: F) -> Self where - F: FnMut(LocalForm, Vertex>) -> LocalForm, Vertex>, + F: FnMut( + LocalForm, GlobalVertex>, + ) -> LocalForm, GlobalVertex>, { Self(self.convert(f)) } @@ -196,7 +204,7 @@ impl VerticesOfEdge { /// Convert each vertex using the provided function pub fn convert(self, f: F) -> Option<[T; 2]> where - F: FnMut(LocalForm, Vertex>) -> T, + F: FnMut(LocalForm, GlobalVertex>) -> T, { self.0.map(|vertices| vertices.map(f)) } @@ -204,7 +212,7 @@ impl VerticesOfEdge { /// Convert each vertex using the provided fallible function pub fn try_convert(self, f: F) -> Result, E> where - F: FnMut(LocalForm, Vertex>) -> Result, + F: FnMut(LocalForm, GlobalVertex>) -> Result, { // Can be cleaned up using `try_map`, once that is stable: // https://doc.rust-lang.org/std/primitive.array.html#method.try_map diff --git a/crates/fj-kernel/src/objects/vertex.rs b/crates/fj-kernel/src/objects/global_vertex.rs similarity index 74% rename from crates/fj-kernel/src/objects/vertex.rs rename to crates/fj-kernel/src/objects/global_vertex.rs index 9252c8e69..d3447455d 100644 --- a/crates/fj-kernel/src/objects/vertex.rs +++ b/crates/fj-kernel/src/objects/global_vertex.rs @@ -19,15 +19,19 @@ use fj_math::Point; /// between distinct vertices can be configured using /// [`Shape::with_minimum_distance`]. #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct Vertex { - /// The point that defines the location of the vertex - pub point: Point<3>, +pub struct GlobalVertex { + position: Point<3>, } -impl Vertex { +impl GlobalVertex { /// Construct a `Vertex` from a point - pub fn from_point(point: impl Into>) -> Self { - let point = point.into(); - Self { point } + pub fn from_position(position: impl Into>) -> Self { + let position = position.into(); + Self { position } + } + + /// The position of the vertex + pub fn position(&self) -> Point<3> { + self.position } } diff --git a/crates/fj-kernel/src/objects/mod.rs b/crates/fj-kernel/src/objects/mod.rs index 7f05c7904..8ecfb7665 100644 --- a/crates/fj-kernel/src/objects/mod.rs +++ b/crates/fj-kernel/src/objects/mod.rs @@ -8,14 +8,14 @@ mod curve; mod cycle; mod edge; mod face; +mod global_vertex; mod surface; -mod vertex; pub use self::{ curve::Curve, cycle::Cycle, edge::{Edge, VerticesOfEdge}, face::{CyclesInFace, Face, FaceBRep}, + global_vertex::GlobalVertex, surface::{Surface, SweptCurve}, - vertex::Vertex, }; diff --git a/crates/fj-kernel/src/validation/coherence.rs b/crates/fj-kernel/src/validation/coherence.rs index 10d9ecb52..f5f2b7ccd 100644 --- a/crates/fj-kernel/src/validation/coherence.rs +++ b/crates/fj-kernel/src/validation/coherence.rs @@ -19,7 +19,7 @@ pub fn validate_edge( for vertex in edge.vertices.iter() { let local = *vertex.local(); let local_as_canonical = edge.curve().point_from_curve_coords(local); - let canonical = vertex.canonical().point; + let canonical = vertex.canonical().position(); let distance = (local_as_canonical - canonical).magnitude(); if distance > max_distance { diff --git a/crates/fj-kernel/src/validation/mod.rs b/crates/fj-kernel/src/validation/mod.rs index 484adccc6..eaafc96f5 100644 --- a/crates/fj-kernel/src/validation/mod.rs +++ b/crates/fj-kernel/src/validation/mod.rs @@ -141,7 +141,7 @@ mod tests { use fj_math::{Point, Scalar}; use crate::{ - objects::{Curve, Edge, Vertex, VerticesOfEdge}, + objects::{Curve, Edge, GlobalVertex, VerticesOfEdge}, shape::LocalForm, validation::{validate, ValidationConfig, ValidationError}, }; @@ -156,8 +156,8 @@ mod tests { LocalForm::canonical_only(curve) }; - let a = Vertex { point: a }; - let b = Vertex { point: b }; + let a = GlobalVertex::from_position(a); + let b = GlobalVertex::from_position(b); let deviation = Scalar::from_f64(0.25); @@ -203,11 +203,11 @@ mod tests { }; // Adding a vertex should work. - shape.push(Vertex { point: a }); + shape.push(GlobalVertex::from_position(a)); validate(shape.clone(), &config)?; // Adding a second vertex that is considered identical should fail. - shape.push(Vertex { point: b }); + shape.push(GlobalVertex::from_position(b)); let result = validate(shape, &config); assert!(matches!(result, Err(ValidationError::Uniqueness(_)))); diff --git a/crates/fj-kernel/src/validation/uniqueness.rs b/crates/fj-kernel/src/validation/uniqueness.rs index 311e21e1b..516740d81 100644 --- a/crates/fj-kernel/src/validation/uniqueness.rs +++ b/crates/fj-kernel/src/validation/uniqueness.rs @@ -2,15 +2,16 @@ use std::{collections::HashSet, fmt}; use fj_math::Scalar; -use crate::objects::Vertex; +use crate::objects::GlobalVertex; pub fn validate_vertex( - vertex: &Vertex, - vertices: &HashSet, + vertex: &GlobalVertex, + vertices: &HashSet, min_distance: Scalar, ) -> Result<(), UniquenessIssues> { for existing in vertices { - if (existing.point - vertex.point).magnitude() < min_distance { + if (existing.position() - vertex.position()).magnitude() < min_distance + { return Err(UniquenessIssues { duplicate_vertex: Some(*existing), }); @@ -34,7 +35,7 @@ pub fn validate_vertex( #[derive(Debug, Default, thiserror::Error)] pub struct UniquenessIssues { /// Duplicate vertex found - pub duplicate_vertex: Option, + pub duplicate_vertex: Option, } impl fmt::Display for UniquenessIssues {