use ahash::{AHashMap, AHashSet};
use smallvec::SmallVec;
use crate::{
mesh::{face::Face, half_edge::HalfEdge, vertex::Vertex},
numeric::scalar::Scalar,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct Triangle(pub usize, pub usize, pub usize);
impl Triangle {
#[inline]
pub fn as_array(&self) -> [usize; 3] {
let v = [self.0, self.1, self.2];
[v[0], v[1], v[2]]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Edge(usize, usize);
impl Edge {
#[inline]
pub fn new(a: usize, b: usize) -> Self {
if a < b { Edge(a, b) } else { Edge(b, a) }
}
#[inline]
pub fn a(&self) -> usize {
self.0
}
#[inline]
pub fn b(&self) -> usize {
self.1
}
}
#[derive(Debug, Clone, Default)]
pub struct FaceInfo {
pub face_idx: usize,
pub vertices: Triangle,
}
#[derive(Debug, Clone, Default)]
pub struct FaceSplitMap {
pub face: usize,
pub new_faces: SmallVec<[FaceInfo; 3]>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SplitResultKind {
NoSplit,
SplitFace,
SplitEdge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PointInMeshResult {
Outside,
OnSurface,
Inside,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IntersectionHit<T: Scalar> {
Face(usize, (T, T, T)), Edge(usize, usize, T), Vertex(usize),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IntersectionResult<T: Scalar> {
Miss,
Hit(IntersectionHit<T>, T), }
#[derive(Debug, Clone)]
pub struct SplitResult {
pub kind: SplitResultKind,
pub vertex: usize,
pub new_faces: [usize; 4], }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VertexSource {
A,
B,
}
#[derive(Debug, Clone)]
pub struct VertexRing {
pub center: usize,
pub halfedges_ccw: Vec<usize>, pub neighbors_ccw: Vec<usize>, pub faces_ccw: Vec<Option<usize>>, pub is_border: bool,
}
#[derive(Debug, Clone)]
pub struct PairRing {
pub v0: usize,
pub v1: usize,
pub ring0: VertexRing, pub ring1: VertexRing,
pub idx_v1_in_ring0: Option<usize>,
pub idx_v0_in_ring1: Option<usize>,
pub opposite_a: Option<usize>,
pub opposite_b: Option<usize>,
pub common_neighbors: AHashSet<usize>,
pub union_neighbors: AHashSet<usize>,
pub is_border_edge: bool,
}
pub(crate) type Bucket = SmallVec<[usize; 4]>;
#[derive(Debug, Clone)]
pub struct Mesh<T: Scalar, const N: usize> {
pub vertices: Vec<Vertex<T, N>>,
pub half_edges: Vec<HalfEdge>,
pub faces: Vec<Face>,
pub edge_map: AHashMap<(usize, usize), usize>,
pub half_edge_split_map: AHashMap<usize, (usize, usize)>,
pub(crate) face_split_map: AHashMap<usize, FaceSplitMap>,
pub(crate) vertex_spatial_hash: AHashMap<u128, Bucket>,
pub(crate) cell: f64, pub(crate) hash_inv: f64, }