use std::hash::Hash;
pub trait CoordinateScalar:
Clone + Copy + PartialEq + PartialOrd + std::fmt::Debug + 'static + num_traits::Float
{
}
impl<T> CoordinateScalar for T where
T: Clone + Copy + PartialEq + PartialOrd + std::fmt::Debug + 'static + num_traits::Float
{
}
pub trait GeometryHandle: Clone + Eq + Hash + std::fmt::Debug {}
impl<T> GeometryHandle for T where T: Clone + Eq + Hash + std::fmt::Debug {}
pub trait GeometryBackend {
type Coordinate: CoordinateScalar;
type VertexHandle: GeometryHandle;
type EdgeHandle: GeometryHandle;
type FaceHandle: GeometryHandle;
type Error: std::error::Error + 'static;
fn backend_name(&self) -> &'static str;
}
pub trait ThreadSafeBackend: GeometryBackend + Send + Sync {}
pub trait TriangulationQuery: GeometryBackend {
fn vertex_count(&self) -> usize;
fn edge_count(&self) -> usize;
fn face_count(&self) -> usize;
fn dimension(&self) -> usize;
fn vertices(&self) -> Box<dyn Iterator<Item = Self::VertexHandle> + '_>;
fn edges(&self) -> Box<dyn Iterator<Item = Self::EdgeHandle> + '_>;
fn faces(&self) -> Box<dyn Iterator<Item = Self::FaceHandle> + '_>;
fn vertex_coordinates(
&self,
vertex: &Self::VertexHandle,
) -> Result<Vec<Self::Coordinate>, Self::Error>;
fn face_vertices(
&self,
face: &Self::FaceHandle,
) -> Result<Vec<Self::VertexHandle>, Self::Error>;
fn edge_endpoints(
&self,
edge: &Self::EdgeHandle,
) -> Result<(Self::VertexHandle, Self::VertexHandle), Self::Error>;
fn adjacent_faces(
&self,
vertex: &Self::VertexHandle,
) -> Result<Vec<Self::FaceHandle>, Self::Error>;
fn incident_edges(
&self,
vertex: &Self::VertexHandle,
) -> Result<Vec<Self::EdgeHandle>, Self::Error>;
fn face_neighbors(&self, face: &Self::FaceHandle)
-> Result<Vec<Self::FaceHandle>, Self::Error>;
fn is_valid(&self) -> bool;
#[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
fn euler_characteristic(&self) -> i32 {
let v = self.vertex_count() as i32;
let e = self.edge_count() as i32;
let f = self.face_count() as i32;
v - e + f
}
}
#[derive(Debug, Clone)]
pub struct FlipResult<V, E, F> {
pub new_edge: E,
pub affected_faces: Vec<F>,
_phantom: std::marker::PhantomData<V>,
}
impl<V, E, F> FlipResult<V, E, F> {
pub const fn new(new_edge: E, affected_faces: Vec<F>) -> Self {
Self {
new_edge,
affected_faces,
_phantom: std::marker::PhantomData,
}
}
}
#[derive(Debug, Clone)]
pub struct SubdivisionResult<V, E, F> {
pub new_vertex: V,
pub new_faces: Vec<F>,
pub removed_face: F,
_phantom: std::marker::PhantomData<E>,
}
impl<V, E, F> SubdivisionResult<V, E, F> {
pub const fn new(new_vertex: V, new_faces: Vec<F>, removed_face: F) -> Self {
Self {
new_vertex,
new_faces,
removed_face,
_phantom: std::marker::PhantomData,
}
}
}
pub trait TriangulationMut: TriangulationQuery {
fn insert_vertex(
&mut self,
coords: &[Self::Coordinate],
) -> Result<Self::VertexHandle, Self::Error>;
fn remove_vertex(
&mut self,
vertex: Self::VertexHandle,
) -> Result<Vec<Self::FaceHandle>, Self::Error>;
fn move_vertex(
&mut self,
vertex: Self::VertexHandle,
new_coords: &[Self::Coordinate],
) -> Result<(), Self::Error>;
#[allow(clippy::type_complexity)]
fn flip_edge(
&mut self,
edge: Self::EdgeHandle,
) -> Result<FlipResult<Self::VertexHandle, Self::EdgeHandle, Self::FaceHandle>, Self::Error>;
fn can_flip_edge(&self, edge: &Self::EdgeHandle) -> bool;
#[allow(clippy::type_complexity)]
fn subdivide_face(
&mut self,
face: Self::FaceHandle,
point: &[Self::Coordinate],
) -> Result<
SubdivisionResult<Self::VertexHandle, Self::EdgeHandle, Self::FaceHandle>,
Self::Error,
>;
fn clear(&mut self);
fn reserve_capacity(&mut self, vertices: usize, faces: usize);
}
pub trait TriangulationFactory<B: GeometryBackend> {
type Config: Clone;
fn create_empty(config: Self::Config) -> Result<B, B::Error>;
fn create_from_points(
points: &[Vec<B::Coordinate>],
config: Self::Config,
) -> Result<B, B::Error>;
fn create_random(
vertex_count: usize,
bounds: (B::Coordinate, B::Coordinate),
config: Self::Config,
) -> Result<B, B::Error>;
}