Merge pull request #1950 from hannobraun/curve

Add `Curve` object
This commit is contained in:
Hanno Braun 2023-07-19 09:07:49 +02:00 committed by GitHub
commit a648c578c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 98 additions and 9 deletions

View File

@ -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()
}
}

View File

@ -18,6 +18,10 @@ impl TransformObject for HalfEdge {
// coordinates. // coordinates.
let path = self.path(); let path = self.path();
let boundary = self.boundary(); let boundary = self.boundary();
let curve = self
.curve()
.clone()
.transform_with_cache(transform, services, cache);
let start_vertex = self let start_vertex = self
.start_vertex() .start_vertex()
.clone() .clone()
@ -27,7 +31,7 @@ impl TransformObject for HalfEdge {
.clone() .clone()
.transform_with_cache(transform, services, cache); .transform_with_cache(transform, services, cache);
Self::new(path, boundary, start_vertex, global_form) Self::new(path, boundary, curve, start_vertex, global_form)
} }
} }

View File

@ -1,5 +1,6 @@
//! API for transforming objects //! API for transforming objects
mod curve;
mod cycle; mod cycle;
mod edge; mod edge;
mod face; mod face;

View File

@ -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<Curve>` 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()
}
}

View File

@ -2,7 +2,7 @@ use fj_math::Point;
use crate::{ use crate::{
geometry::{BoundaryOnCurve, SurfacePath}, geometry::{BoundaryOnCurve, SurfacePath},
objects::Vertex, objects::{Curve, Vertex},
storage::{Handle, HandleWrapper}, storage::{Handle, HandleWrapper},
}; };
@ -42,6 +42,7 @@ use crate::{
pub struct HalfEdge { pub struct HalfEdge {
path: SurfacePath, path: SurfacePath,
boundary: BoundaryOnCurve, boundary: BoundaryOnCurve,
curve: HandleWrapper<Curve>,
start_vertex: HandleWrapper<Vertex>, start_vertex: HandleWrapper<Vertex>,
global_form: HandleWrapper<GlobalEdge>, global_form: HandleWrapper<GlobalEdge>,
} }
@ -51,12 +52,14 @@ impl HalfEdge {
pub fn new( pub fn new(
path: SurfacePath, path: SurfacePath,
boundary: impl Into<BoundaryOnCurve>, boundary: impl Into<BoundaryOnCurve>,
curve: Handle<Curve>,
start_vertex: Handle<Vertex>, start_vertex: Handle<Vertex>,
global_form: Handle<GlobalEdge>, global_form: Handle<GlobalEdge>,
) -> Self { ) -> Self {
Self { Self {
path, path,
boundary: boundary.into(), boundary: boundary.into(),
curve: curve.into(),
start_vertex: start_vertex.into(), start_vertex: start_vertex.into(),
global_form: global_form.into(), global_form: global_form.into(),
} }
@ -82,6 +85,11 @@ impl HalfEdge {
self.path.point_from_path_coords(start) self.path.point_from_path_coords(start)
} }
/// Access the curve of the half-edge
pub fn curve(&self) -> &Handle<Curve> {
&self.curve
}
/// Access the vertex from where this half-edge starts /// Access the vertex from where this half-edge starts
pub fn start_vertex(&self) -> &Handle<Vertex> { pub fn start_vertex(&self) -> &Handle<Vertex> {
&self.start_vertex &self.start_vertex

View File

@ -1,3 +1,4 @@
pub mod curve;
pub mod cycle; pub mod cycle;
pub mod edge; pub mod edge;
pub mod face; pub mod face;

View File

@ -46,6 +46,7 @@ mod stores;
pub use self::{ pub use self::{
kinds::{ kinds::{
curve::Curve,
cycle::{Cycle, HalfEdgesOfCycle}, cycle::{Cycle, HalfEdgesOfCycle},
edge::{GlobalEdge, HalfEdge}, edge::{GlobalEdge, HalfEdge},
face::{Face, FaceSet, Handedness}, face::{Face, FaceSet, Handedness},

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
objects::{ objects::{
Cycle, Face, GlobalEdge, HalfEdge, Objects, Region, Shell, Sketch, Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, Region, Shell,
Solid, Surface, Vertex, Sketch, Solid, Surface, Vertex,
}, },
storage::{Handle, HandleWrapper, ObjectId}, storage::{Handle, HandleWrapper, ObjectId},
validate::{Validate, ValidationError}, validate::{Validate, ValidationError},
@ -91,6 +91,7 @@ macro_rules! object {
} }
object!( object!(
Curve, "curve", curves;
Cycle, "cycle", cycles; Cycle, "cycle", cycles;
Face, "face", faces; Face, "face", faces;
GlobalEdge, "global edge", global_edges; GlobalEdge, "global edge", global_edges;

View File

@ -6,13 +6,16 @@ use crate::{
}; };
use super::{ use super::{
Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, Surface, Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid,
Vertex, Surface, Vertex,
}; };
/// The available object stores /// The available object stores
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Objects { pub struct Objects {
/// Store for [`Curve`]s
pub curves: Store<Curve>,
/// Store for [`Cycle`]s /// Store for [`Cycle`]s
pub cycles: Store<Cycle>, pub cycles: Store<Cycle>,

View File

@ -3,7 +3,7 @@ use fj_math::{Arc, Point, Scalar};
use crate::{ use crate::{
geometry::{BoundaryOnCurve, SurfacePath}, geometry::{BoundaryOnCurve, SurfacePath},
objects::{GlobalEdge, HalfEdge, Vertex}, objects::{Curve, GlobalEdge, HalfEdge, Vertex},
operations::Insert, operations::Insert,
services::Services, services::Services,
}; };
@ -16,10 +16,11 @@ pub trait BuildHalfEdge {
boundary: impl Into<BoundaryOnCurve>, boundary: impl Into<BoundaryOnCurve>,
services: &mut Services, services: &mut Services,
) -> HalfEdge { ) -> HalfEdge {
let curve = Curve::new().insert(services);
let start_vertex = Vertex::new().insert(services); let start_vertex = Vertex::new().insert(services);
let global_form = GlobalEdge::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 /// Create an arc

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
objects::{ objects::{
Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid, Curve, Cycle, Face, GlobalEdge, HalfEdge, Region, Shell, Sketch, Solid,
Surface, Vertex, Surface, Vertex,
}, },
services::Services, services::Services,
@ -43,6 +43,7 @@ macro_rules! impl_insert {
} }
impl_insert!( impl_insert!(
Curve, curves;
Cycle, cycles; Cycle, cycles;
Face, faces; Face, faces;
GlobalEdge, global_edges; GlobalEdge, global_edges;

View File

@ -14,6 +14,7 @@ impl Reverse for Cycle {
HalfEdge::new( HalfEdge::new(
current.path(), current.path(),
current.boundary().reverse(), current.boundary().reverse(),
current.curve().clone(),
next.start_vertex().clone(), next.start_vertex().clone(),
current.global_form().clone(), current.global_form().clone(),
) )

View File

@ -19,6 +19,7 @@ impl UpdateHalfEdge for HalfEdge {
HalfEdge::new( HalfEdge::new(
self.path(), self.path(),
self.boundary(), self.boundary(),
self.curve().clone(),
start_vertex, start_vertex,
self.global_form().clone(), self.global_form().clone(),
) )
@ -28,6 +29,7 @@ impl UpdateHalfEdge for HalfEdge {
HalfEdge::new( HalfEdge::new(
self.path(), self.path(),
self.boundary(), self.boundary(),
self.curve().clone(),
self.start_vertex().clone(), self.start_vertex().clone(),
global_form, global_form,
) )

View File

@ -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<ValidationError>,
) {
}
}

View File

@ -95,6 +95,7 @@ mod tests {
HalfEdge::new( HalfEdge::new(
valid.path(), valid.path(),
boundary, boundary,
valid.curve().clone(),
valid.start_vertex().clone(), valid.start_vertex().clone(),
valid.global_form().clone(), valid.global_form().clone(),
) )

View File

@ -1,5 +1,6 @@
//! Infrastructure for validating objects //! Infrastructure for validating objects
mod curve;
mod cycle; mod cycle;
mod edge; mod edge;
mod face; mod face;