From f009a98cdb329a0f8a17f3986bf30ddd70dc8c4d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:18:16 +0200 Subject: [PATCH 1/7] Add `Curve` object --- crates/fj-core/src/objects/kinds/curve.rs | 32 +++++++++++++++++++++++ crates/fj-core/src/objects/kinds/mod.rs | 1 + crates/fj-core/src/objects/mod.rs | 1 + 3 files changed, 34 insertions(+) create mode 100644 crates/fj-core/src/objects/kinds/curve.rs diff --git a/crates/fj-core/src/objects/kinds/curve.rs b/crates/fj-core/src/objects/kinds/curve.rs new file mode 100644 index 000000000..f68676e32 --- /dev/null +++ b/crates/fj-core/src/objects/kinds/curve.rs @@ -0,0 +1,32 @@ +/// A curve +/// +/// `Curve` represents a curve in space, but holds no data to define that curve. +/// It is referenced by [`HalfEdge`], which defines the curve in the coordinates +/// of its surface. +/// +/// `Curve` exists to allow identifying which [`HalfEdge`]s are supposed to be +/// coincident in global space. +/// +/// # Equality +/// +/// `Curve` contains no data and exists purely to be used within a `Handle`, +/// where `Handle::id` can be used to compare different instances of `Curve`. +/// +/// If `Curve` had `Eq`/`PartialEq` implementations, it containing no data would +/// mean that all instances of `Curve` would be considered equal. This would be +/// very error-prone. +/// +/// If you need to reference a `Curve` from a struct that needs to derive +/// `Eq`/`Ord`/..., you can use `HandleWrapper` to do that. It will use +/// `Handle::id` to provide those `Eq`/`Ord`/... implementations. +/// +/// [`HalfEdge`]: crate::objects::HalfEdge +#[derive(Clone, Debug, Default, Hash)] +pub struct Curve {} + +impl Curve { + /// Create a new instance + pub fn new() -> Self { + Self::default() + } +} diff --git a/crates/fj-core/src/objects/kinds/mod.rs b/crates/fj-core/src/objects/kinds/mod.rs index cf531b35e..2cba2587d 100644 --- a/crates/fj-core/src/objects/kinds/mod.rs +++ b/crates/fj-core/src/objects/kinds/mod.rs @@ -1,3 +1,4 @@ +pub mod curve; pub mod cycle; pub mod edge; pub mod face; diff --git a/crates/fj-core/src/objects/mod.rs b/crates/fj-core/src/objects/mod.rs index 0de859e33..a91b79fcf 100644 --- a/crates/fj-core/src/objects/mod.rs +++ b/crates/fj-core/src/objects/mod.rs @@ -46,6 +46,7 @@ mod stores; pub use self::{ kinds::{ + curve::Curve, cycle::{Cycle, HalfEdgesOfCycle}, edge::{GlobalEdge, HalfEdge}, face::{Face, FaceSet, Handedness}, From a8f3440566fd0296c5dc83cc74d63588e8ee650e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:19:52 +0200 Subject: [PATCH 2/7] Add curve store to `Objects` --- crates/fj-core/src/objects/stores.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/objects/stores.rs b/crates/fj-core/src/objects/stores.rs index 35ea94e56..620d42598 100644 --- a/crates/fj-core/src/objects/stores.rs +++ b/crates/fj-core/src/objects/stores.rs @@ -6,13 +6,16 @@ use crate::{ }; use super::{ - Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, Surface, - Vertex, + Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, + Surface, Vertex, }; /// The available object stores #[derive(Debug, Default)] pub struct Objects { + /// Store for [`Curve`]s + pub curves: Store, + /// Store for [`Cycle`]s pub cycles: Store, From 3b8bdcf63742be0ad0aa6c0989b4eb2f7392d887 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:29:31 +0200 Subject: [PATCH 3/7] Implement `Validate` for `Curve` --- crates/fj-core/src/validate/curve.rs | 12 ++++++++++++ crates/fj-core/src/validate/mod.rs | 1 + 2 files changed, 13 insertions(+) create mode 100644 crates/fj-core/src/validate/curve.rs diff --git a/crates/fj-core/src/validate/curve.rs b/crates/fj-core/src/validate/curve.rs new file mode 100644 index 000000000..2f40a7820 --- /dev/null +++ b/crates/fj-core/src/validate/curve.rs @@ -0,0 +1,12 @@ +use crate::objects::Curve; + +use super::{Validate, ValidationConfig, ValidationError}; + +impl Validate for Curve { + fn validate_with_config( + &self, + _: &ValidationConfig, + _: &mut Vec, + ) { + } +} diff --git a/crates/fj-core/src/validate/mod.rs b/crates/fj-core/src/validate/mod.rs index 27c8f601c..0f82eb535 100644 --- a/crates/fj-core/src/validate/mod.rs +++ b/crates/fj-core/src/validate/mod.rs @@ -1,5 +1,6 @@ //! Infrastructure for validating objects +mod curve; mod cycle; mod edge; mod face; From 4ca7631dd89e69ac376baa903d0ee264fe9d39e6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:30:48 +0200 Subject: [PATCH 4/7] Support `Curve` in `Object` --- crates/fj-core/src/objects/object.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/objects/object.rs b/crates/fj-core/src/objects/object.rs index d8ca56152..e05685034 100644 --- a/crates/fj-core/src/objects/object.rs +++ b/crates/fj-core/src/objects/object.rs @@ -1,7 +1,7 @@ use crate::{ objects::{ - Cycle, Face, GlobalEdge, HalfEdge, Objects, Region, Shell, Sketch, - Solid, Surface, Vertex, + Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, Region, Shell, + Sketch, Solid, Surface, Vertex, }, storage::{Handle, HandleWrapper, ObjectId}, validate::{Validate, ValidationError}, @@ -91,6 +91,7 @@ macro_rules! object { } object!( + Curve, "curve", curves; Cycle, "cycle", cycles; Face, "face", faces; GlobalEdge, "global edge", global_edges; From d212a1d832a93d884b577574cabc93b8420b267c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:31:02 +0200 Subject: [PATCH 5/7] Implement `Insert` for `Curve` --- crates/fj-core/src/operations/insert.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/insert.rs b/crates/fj-core/src/operations/insert.rs index 8ae9ed1de..2e6f382dc 100644 --- a/crates/fj-core/src/operations/insert.rs +++ b/crates/fj-core/src/operations/insert.rs @@ -1,6 +1,6 @@ use crate::{ objects::{ - Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, + Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, Surface, Vertex, }, services::Services, @@ -43,6 +43,7 @@ macro_rules! impl_insert { } impl_insert!( + Curve, curves; Cycle, cycles; Face, faces; GlobalEdge, global_edges; From bbfd1a5e5063a2416c6d594d67bb774f3b80dde7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:25:19 +0200 Subject: [PATCH 6/7] Implement `TransformObject` for `Curve` --- .../fj-core/src/algorithms/transform/curve.rs | 19 +++++++++++++++++++ .../fj-core/src/algorithms/transform/mod.rs | 1 + 2 files changed, 20 insertions(+) create mode 100644 crates/fj-core/src/algorithms/transform/curve.rs diff --git a/crates/fj-core/src/algorithms/transform/curve.rs b/crates/fj-core/src/algorithms/transform/curve.rs new file mode 100644 index 000000000..d7209c7a9 --- /dev/null +++ b/crates/fj-core/src/algorithms/transform/curve.rs @@ -0,0 +1,19 @@ +use fj_math::Transform; + +use crate::{objects::Curve, services::Services}; + +use super::{TransformCache, TransformObject}; + +impl TransformObject for Curve { + fn transform_with_cache( + self, + _: &Transform, + _: &mut Services, + _: &mut TransformCache, + ) -> Self { + // There's nothing to actually transform here, as `Curve` holds no data. + // We still need this implementation though, as a new `Curve` object + // must be created to represent the new and transformed curve. + Self::new() + } +} diff --git a/crates/fj-core/src/algorithms/transform/mod.rs b/crates/fj-core/src/algorithms/transform/mod.rs index da46c29ef..b13bc49d8 100644 --- a/crates/fj-core/src/algorithms/transform/mod.rs +++ b/crates/fj-core/src/algorithms/transform/mod.rs @@ -1,5 +1,6 @@ //! API for transforming objects +mod curve; mod cycle; mod edge; mod face; From a849efa3db299f807666563c77e6b04e3e0e603a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 14 Jul 2023 10:35:00 +0200 Subject: [PATCH 7/7] Reference `Curve` from `HalfEdge` The intention is to eventually replace `GlobalEdge`. --- crates/fj-core/src/algorithms/transform/edge.rs | 6 +++++- crates/fj-core/src/objects/kinds/edge.rs | 10 +++++++++- crates/fj-core/src/operations/build/edge.rs | 5 +++-- crates/fj-core/src/operations/reverse/cycle.rs | 1 + crates/fj-core/src/operations/update/edge.rs | 2 ++ crates/fj-core/src/validate/edge.rs | 1 + 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/algorithms/transform/edge.rs b/crates/fj-core/src/algorithms/transform/edge.rs index f1b47c28a..b690751d1 100644 --- a/crates/fj-core/src/algorithms/transform/edge.rs +++ b/crates/fj-core/src/algorithms/transform/edge.rs @@ -18,6 +18,10 @@ impl TransformObject for HalfEdge { // coordinates. let path = self.path(); let boundary = self.boundary(); + let curve = self + .curve() + .clone() + .transform_with_cache(transform, services, cache); let start_vertex = self .start_vertex() .clone() @@ -27,7 +31,7 @@ impl TransformObject for HalfEdge { .clone() .transform_with_cache(transform, services, cache); - Self::new(path, boundary, start_vertex, global_form) + Self::new(path, boundary, curve, start_vertex, global_form) } } diff --git a/crates/fj-core/src/objects/kinds/edge.rs b/crates/fj-core/src/objects/kinds/edge.rs index 5154fd799..153f82ac2 100644 --- a/crates/fj-core/src/objects/kinds/edge.rs +++ b/crates/fj-core/src/objects/kinds/edge.rs @@ -2,7 +2,7 @@ use fj_math::Point; use crate::{ geometry::{BoundaryOnCurve, SurfacePath}, - objects::Vertex, + objects::{Curve, Vertex}, storage::{Handle, HandleWrapper}, }; @@ -42,6 +42,7 @@ use crate::{ pub struct HalfEdge { path: SurfacePath, boundary: BoundaryOnCurve, + curve: HandleWrapper, start_vertex: HandleWrapper, global_form: HandleWrapper, } @@ -51,12 +52,14 @@ impl HalfEdge { pub fn new( path: SurfacePath, boundary: impl Into, + curve: Handle, start_vertex: Handle, global_form: Handle, ) -> Self { Self { path, boundary: boundary.into(), + curve: curve.into(), start_vertex: start_vertex.into(), global_form: global_form.into(), } @@ -82,6 +85,11 @@ impl HalfEdge { self.path.point_from_path_coords(start) } + /// Access the curve of the half-edge + pub fn curve(&self) -> &Handle { + &self.curve + } + /// Access the vertex from where this half-edge starts pub fn start_vertex(&self) -> &Handle { &self.start_vertex diff --git a/crates/fj-core/src/operations/build/edge.rs b/crates/fj-core/src/operations/build/edge.rs index 6e850e549..3552ada11 100644 --- a/crates/fj-core/src/operations/build/edge.rs +++ b/crates/fj-core/src/operations/build/edge.rs @@ -3,7 +3,7 @@ use fj_math::{Arc, Point, Scalar}; use crate::{ geometry::{BoundaryOnCurve, SurfacePath}, - objects::{GlobalEdge, HalfEdge, Vertex}, + objects::{Curve, GlobalEdge, HalfEdge, Vertex}, operations::Insert, services::Services, }; @@ -16,10 +16,11 @@ pub trait BuildHalfEdge { boundary: impl Into, services: &mut Services, ) -> HalfEdge { + let curve = Curve::new().insert(services); let start_vertex = Vertex::new().insert(services); let global_form = GlobalEdge::new().insert(services); - HalfEdge::new(path, boundary, start_vertex, global_form) + HalfEdge::new(path, boundary, curve, start_vertex, global_form) } /// Create an arc diff --git a/crates/fj-core/src/operations/reverse/cycle.rs b/crates/fj-core/src/operations/reverse/cycle.rs index 62cac2ef1..7d2fdc3af 100644 --- a/crates/fj-core/src/operations/reverse/cycle.rs +++ b/crates/fj-core/src/operations/reverse/cycle.rs @@ -14,6 +14,7 @@ impl Reverse for Cycle { HalfEdge::new( current.path(), current.boundary().reverse(), + current.curve().clone(), next.start_vertex().clone(), current.global_form().clone(), ) diff --git a/crates/fj-core/src/operations/update/edge.rs b/crates/fj-core/src/operations/update/edge.rs index 91f400759..d065cee69 100644 --- a/crates/fj-core/src/operations/update/edge.rs +++ b/crates/fj-core/src/operations/update/edge.rs @@ -19,6 +19,7 @@ impl UpdateHalfEdge for HalfEdge { HalfEdge::new( self.path(), self.boundary(), + self.curve().clone(), start_vertex, self.global_form().clone(), ) @@ -28,6 +29,7 @@ impl UpdateHalfEdge for HalfEdge { HalfEdge::new( self.path(), self.boundary(), + self.curve().clone(), self.start_vertex().clone(), global_form, ) diff --git a/crates/fj-core/src/validate/edge.rs b/crates/fj-core/src/validate/edge.rs index 9516664b6..899a33b7b 100644 --- a/crates/fj-core/src/validate/edge.rs +++ b/crates/fj-core/src/validate/edge.rs @@ -95,6 +95,7 @@ mod tests { HalfEdge::new( valid.path(), boundary, + valid.curve().clone(), valid.start_vertex().clone(), valid.global_form().clone(), )