Merge pull request #2323 from hannobraun/geometry

Add curve geometry to geometry layer
This commit is contained in:
Hanno Braun 2024-04-26 13:06:39 +02:00 committed by GitHub
commit 3c3d53bfe6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 94 additions and 4 deletions

View File

@ -0,0 +1,36 @@
use crate::{storage::Handle, topology::Surface};
use super::SurfacePath;
/// The geometric definition of a curve
#[derive(Clone)]
pub struct CurveGeom {
/// # The redundant local definitions of the curve geometry
///
/// ## Implementation Note
///
/// Having multiple redundant definitions is undesirable. However, we can't
/// just use one global definition in 3D, as we need the local 2D
/// definitions to approximate and triangulate curves, and we currently
/// don't have the tools to project a global definition into a local
/// context.
///
/// Eventually, it should be possible to define the geometry of a curve
/// once, either locally or globally, and then convert that single
/// definition into (other) local contexts, as needed. There currently is no
/// issue to track that specifically, but there is the following issue,
/// which is a prerequisite for making the required tooling practical:
///
/// <https://github.com/hannobraun/fornjot/issues/2118>
pub definitions: Vec<LocalCurveGeom>,
}
/// The geometric definition of a curve in 2D surface coordinates
#[derive(Clone)]
pub struct LocalCurveGeom {
/// The path that defines the curve on its surface
pub path: SurfacePath,
/// The surface that the curve is defined on
pub surface: Handle<Surface>,
}

View File

@ -4,13 +4,14 @@ use fj_math::Vector;
use crate::{ use crate::{
storage::Handle, storage::Handle,
topology::{HalfEdge, Surface, Topology}, topology::{Curve, HalfEdge, Surface, Topology},
}; };
use super::{GlobalPath, HalfEdgeGeom, SurfaceGeom}; use super::{CurveGeom, GlobalPath, HalfEdgeGeom, SurfaceGeom};
/// Geometric data that is associated with topological objects /// Geometric data that is associated with topological objects
pub struct Geometry { pub struct Geometry {
curve: BTreeMap<Handle<Curve>, CurveGeom>,
half_edge: BTreeMap<Handle<HalfEdge>, HalfEdgeGeom>, half_edge: BTreeMap<Handle<HalfEdge>, HalfEdgeGeom>,
surface: BTreeMap<Handle<Surface>, SurfaceGeom>, surface: BTreeMap<Handle<Surface>, SurfaceGeom>,
@ -25,6 +26,7 @@ impl Geometry {
/// Create a new instance of `Geometry` /// Create a new instance of `Geometry`
pub fn new(topology: &Topology) -> Self { pub fn new(topology: &Topology) -> Self {
let mut self_ = Self { let mut self_ = Self {
curve: BTreeMap::new(),
half_edge: BTreeMap::new(), half_edge: BTreeMap::new(),
surface: BTreeMap::new(), surface: BTreeMap::new(),
@ -60,6 +62,14 @@ impl Geometry {
self_ self_
} }
pub(crate) fn define_curve_inner(
&mut self,
curve: Handle<Curve>,
geometry: CurveGeom,
) {
self.curve.insert(curve, geometry);
}
pub(crate) fn define_half_edge_inner( pub(crate) fn define_half_edge_inner(
&mut self, &mut self,
half_edge: Handle<HalfEdge>, half_edge: Handle<HalfEdge>,
@ -88,6 +98,17 @@ impl Geometry {
self.surface.insert(surface, geometry); self.surface.insert(surface, geometry);
} }
/// # Access the geometry of the provided curve
///
/// ## Panics
///
/// Panics, if the geometry of the curve is not defined.
pub fn of_curve(&self, curve: &Handle<Curve>) -> &CurveGeom {
self.curve
.get(curve)
.expect("Expected geometry of half-edge to be defined")
}
/// # Access the geometry of the provided half-edge /// # Access the geometry of the provided half-edge
/// ///
/// ## Panics /// ## Panics

View File

@ -1,6 +1,7 @@
//! Types that are tied to objects, but aren't objects themselves //! Types that are tied to objects, but aren't objects themselves
mod boundary; mod boundary;
mod curve;
mod geometry; mod geometry;
mod half_edge; mod half_edge;
mod path; mod path;
@ -8,6 +9,7 @@ mod surface;
pub use self::{ pub use self::{
boundary::{CurveBoundary, CurveBoundaryElement}, boundary::{CurveBoundary, CurveBoundaryElement},
curve::{CurveGeom, LocalCurveGeom},
geometry::Geometry, geometry::Geometry,
half_edge::HalfEdgeGeom, half_edge::HalfEdgeGeom,
path::{GlobalPath, SurfacePath}, path::{GlobalPath, SurfacePath},

View File

@ -1,14 +1,20 @@
//! Layer infrastructure for [`Geometry`] //! Layer infrastructure for [`Geometry`]
use crate::{ use crate::{
geometry::{Geometry, HalfEdgeGeom, SurfaceGeom}, geometry::{CurveGeom, Geometry, HalfEdgeGeom, SurfaceGeom},
storage::Handle, storage::Handle,
topology::{HalfEdge, Surface}, topology::{Curve, HalfEdge, Surface},
}; };
use super::{Command, Event, Layer}; use super::{Command, Event, Layer};
impl Layer<Geometry> { impl Layer<Geometry> {
/// Define the geometry of the provided curve
pub fn define_curve(&mut self, curve: Handle<Curve>, geometry: CurveGeom) {
let mut events = Vec::new();
self.process(DefineCurve { curve, geometry }, &mut events);
}
/// Define the geometry of the provided half-edge /// Define the geometry of the provided half-edge
pub fn define_half_edge( pub fn define_half_edge(
&mut self, &mut self,
@ -41,6 +47,31 @@ impl Layer<Geometry> {
} }
} }
/// Define the geometry of a curve
pub struct DefineCurve {
curve: Handle<Curve>,
geometry: CurveGeom,
}
impl Command<Geometry> for DefineCurve {
type Result = ();
type Event = Self;
fn decide(
self,
_: &Geometry,
events: &mut Vec<Self::Event>,
) -> Self::Result {
events.push(self);
}
}
impl Event<Geometry> for DefineCurve {
fn evolve(&self, state: &mut Geometry) {
state.define_curve_inner(self.curve.clone(), self.geometry.clone());
}
}
/// Define the geometry of a half-edge /// Define the geometry of a half-edge
pub struct DefineHalfEdge { pub struct DefineHalfEdge {
half_edge: Handle<HalfEdge>, half_edge: Handle<HalfEdge>,