mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-25 08:35:51 +00:00
Merge pull request #417 from hannobraun/get_handle
Add `Shape::get_handle`, `Shape::get_handle_or_insert`
This commit is contained in:
commit
6f83081eb1
@ -6,7 +6,7 @@ use super::{
|
|||||||
stores::{
|
stores::{
|
||||||
Curves, Cycles, Edges, Faces, Points, Stores, Surfaces, Vertices,
|
Curves, Cycles, Edges, Faces, Points, Stores, Surfaces, Vertices,
|
||||||
},
|
},
|
||||||
Geometry, Object, Topology, ValidationResult,
|
Geometry, Handle, Object, Topology, ValidationResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The boundary representation of a shape
|
/// The boundary representation of a shape
|
||||||
@ -68,6 +68,45 @@ impl Shape {
|
|||||||
Ok(handle)
|
Ok(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the handle of an object
|
||||||
|
///
|
||||||
|
/// Returns the handle that refers to the given object, if it is part of the
|
||||||
|
/// shape. Returns `None`, if it isn't.
|
||||||
|
///
|
||||||
|
/// # Implementation note
|
||||||
|
///
|
||||||
|
/// If `object` is present multiple times, the handle of the first that is
|
||||||
|
/// found is returned. This is weird. It would be better, if objects were
|
||||||
|
/// unique, but currently they are stored in `Vec`s.
|
||||||
|
///
|
||||||
|
/// This probably isn't worth thinking too much about right now. At some
|
||||||
|
/// point, we need smarter and probably more performant object storage
|
||||||
|
/// anyway.
|
||||||
|
pub fn get_handle<T>(&self, object: &T) -> Option<Handle<T>>
|
||||||
|
where
|
||||||
|
T: Object,
|
||||||
|
{
|
||||||
|
self.stores
|
||||||
|
.get::<T>()
|
||||||
|
.iter()
|
||||||
|
.find(|obj| &obj.get() == object)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get handle of an identical object, if it exists, or add the object
|
||||||
|
///
|
||||||
|
/// In any case, returns a handle that refers to an object that is identical
|
||||||
|
/// to the provided object.
|
||||||
|
pub fn get_handle_or_insert<T>(&mut self, object: T) -> ValidationResult<T>
|
||||||
|
where
|
||||||
|
T: Object,
|
||||||
|
{
|
||||||
|
if let Some(handle) = self.get_handle(&object) {
|
||||||
|
return Ok(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.insert(object)
|
||||||
|
}
|
||||||
|
|
||||||
/// Access the shape's geometry
|
/// Access the shape's geometry
|
||||||
pub fn geometry(&mut self) -> Geometry {
|
pub fn geometry(&mut self) -> Geometry {
|
||||||
Geometry {
|
Geometry {
|
||||||
@ -93,3 +132,70 @@ impl Default for Shape {
|
|||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use fj_math::Point;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
geometry::{Curve, Surface},
|
||||||
|
shape::Shape,
|
||||||
|
topology::{Cycle, Edge, Face, Vertex},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
|
||||||
|
fn get_handle() -> anyhow::Result<()> {
|
||||||
|
let mut shape = Shape::new();
|
||||||
|
|
||||||
|
let point = Point::from([1., 0., 0.]);
|
||||||
|
let curve = Curve::x_axis();
|
||||||
|
let surface = Surface::x_y_plane();
|
||||||
|
|
||||||
|
assert!(shape.get_handle(&point).is_none());
|
||||||
|
assert!(shape.get_handle(&curve).is_none());
|
||||||
|
assert!(shape.get_handle(&surface).is_none());
|
||||||
|
|
||||||
|
let point = shape.insert(point)?;
|
||||||
|
let curve = shape.insert(curve)?;
|
||||||
|
let surface = shape.insert(surface)?;
|
||||||
|
|
||||||
|
assert!(shape.get_handle(&point.get()).as_ref() == Some(&point));
|
||||||
|
assert!(shape.get_handle(&curve.get()).as_ref() == Some(&curve));
|
||||||
|
assert!(shape.get_handle(&surface.get()).as_ref() == Some(&surface));
|
||||||
|
|
||||||
|
let vertex = Vertex { point };
|
||||||
|
let edge = Edge {
|
||||||
|
curve,
|
||||||
|
vertices: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(shape.get_handle(&vertex).is_none());
|
||||||
|
assert!(shape.get_handle(&edge).is_none());
|
||||||
|
|
||||||
|
let vertex = shape.insert(vertex)?;
|
||||||
|
let edge = shape.insert(edge)?;
|
||||||
|
|
||||||
|
assert!(shape.get_handle(&vertex.get()).as_ref() == Some(&vertex));
|
||||||
|
assert!(shape.get_handle(&edge.get()).as_ref() == Some(&edge));
|
||||||
|
|
||||||
|
let cycle = Cycle { edges: vec![edge] };
|
||||||
|
assert!(shape.get_handle(&cycle).is_none());
|
||||||
|
|
||||||
|
let cycle = shape.insert(cycle)?;
|
||||||
|
assert!(shape.get_handle(&cycle.get()).as_ref() == Some(&cycle));
|
||||||
|
|
||||||
|
let face = Face::Face {
|
||||||
|
surface,
|
||||||
|
exteriors: Vec::new(),
|
||||||
|
interiors: Vec::new(),
|
||||||
|
color: [0, 0, 0, 0],
|
||||||
|
};
|
||||||
|
assert!(shape.get_handle(&face).is_none());
|
||||||
|
|
||||||
|
let face = shape.insert(face)?;
|
||||||
|
assert!(shape.get_handle(&face.get()).as_ref() == Some(&face));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,7 +8,10 @@ use crate::{
|
|||||||
use super::validate::Validate;
|
use super::validate::Validate;
|
||||||
|
|
||||||
/// Marker trait for geometric and topological objects
|
/// Marker trait for geometric and topological objects
|
||||||
pub trait Object: 'static + Validate + private::Sealed {}
|
pub trait Object:
|
||||||
|
'static + Clone + PartialEq + Validate + private::Sealed
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl private::Sealed for Point<3> {}
|
impl private::Sealed for Point<3> {}
|
||||||
impl private::Sealed for Curve {}
|
impl private::Sealed for Curve {}
|
||||||
|
@ -28,7 +28,7 @@ pub struct Stores {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stores {
|
impl Stores {
|
||||||
pub fn get<T>(&mut self) -> Store<T>
|
pub fn get<T>(&self) -> Store<T>
|
||||||
where
|
where
|
||||||
T: Object,
|
T: Object,
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user