#![forbid(unsafe_code)]
use num_traits::Float;
use std::error::Error as StdError;
use std::fmt::Debug;
use std::hash::Hash;
pub trait CoordinateScalar: Float {}
impl<T: Float> CoordinateScalar for T {}
pub trait GeometryHandle: Clone + Eq + Hash + Debug {}
impl<T: Clone + Eq + Hash + Debug> GeometryHandle for T {}
pub trait GeometryBackend {
type Coordinate: CoordinateScalar;
type VertexHandle: GeometryHandle;
type EdgeHandle: GeometryHandle;
type FaceHandle: GeometryHandle;
type Error: StdError;
fn backend_name(&self) -> &'static str;
}
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) -> impl Iterator<Item = Self::VertexHandle> + '_;
fn edges(&self) -> impl Iterator<Item = Self::EdgeHandle> + '_;
fn faces(&self) -> impl 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,
) -> Option<(Self::VertexHandle, Self::VertexHandle)>;
fn edge_adjacent_faces(
&self,
edge: &Self::EdgeHandle,
) -> EdgeAdjacentFacesResult<Self::VertexHandle, Self::FaceHandle, 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;
fn euler_characteristic(&self) -> i128 {
let vertices = self.vertex_count() as i128;
let edges = self.edge_count() as i128;
let faces = self.face_count() as i128;
vertices - edges + faces
}
}
#[derive(Debug, Clone)]
pub struct FlipResult<E, F> {
pub new_edge: E,
pub affected_faces: Vec<F>,
}
impl<E, F> FlipResult<E, F> {
pub const fn new(new_edge: E, affected_faces: Vec<F>) -> Self {
Self {
new_edge,
affected_faces,
}
}
}
#[derive(Debug, Clone)]
pub struct EdgeAdjacentFaces<V, F> {
pub endpoints: (V, V),
pub faces: (F, F),
pub opposite_vertices: (V, V),
}
pub type EdgeAdjacentFacesResult<V, F, E> = Result<Option<EdgeAdjacentFaces<V, F>>, E>;
impl<V, F> EdgeAdjacentFaces<V, F> {
pub const fn new(endpoints: (V, V), faces: (F, F), opposite_vertices: (V, V)) -> Self {
Self {
endpoints,
faces,
opposite_vertices,
}
}
}
#[derive(Debug, Clone)]
pub struct SubdivisionResult<V, F> {
pub new_vertex: V,
pub new_faces: Vec<F>,
pub removed_face: F,
}
impl<V, F> SubdivisionResult<V, F> {
pub const fn new(new_vertex: V, new_faces: Vec<F>, removed_face: F) -> Self {
Self {
new_vertex,
new_faces,
removed_face,
}
}
}
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>;
fn flip_edge(
&mut self,
edge: Self::EdgeHandle,
) -> Result<FlipResult<Self::EdgeHandle, Self::FaceHandle>, Self::Error>;
fn can_flip_edge(&self, edge: &Self::EdgeHandle) -> bool;
fn subdivide_face(
&mut self,
face: Self::FaceHandle,
point: &[Self::Coordinate],
) -> Result<SubdivisionResult<Self::VertexHandle, Self::FaceHandle>, Self::Error>;
fn clear(&mut self) -> Result<(), Self::Error>;
fn reserve_capacity(&mut self, vertices: usize, faces: usize) -> Result<(), Self::Error>;
}