use super::{AsCell, CellId, PointId};
use crate::shapes::GeoKind;
use russell_lab::sort4;
use std::collections::{HashMap, HashSet};
use std::fmt;
pub type FaceKey = (usize, usize, usize, usize);
#[derive(Clone, Debug)]
pub struct Face {
pub kind: GeoKind,
pub points: Vec<PointId>,
pub marker: i32,
}
impl Face {
pub fn key(&self) -> FaceKey {
let mut key = if self.points.len() > 3 {
(self.points[0], self.points[1], self.points[2], self.points[3])
} else {
(self.points[0], self.points[1], self.points[2], usize::MAX)
};
sort4(&mut key);
key
}
}
#[derive(Clone, Debug)]
pub struct Faces<'a> {
pub all: Vec<&'a Face>,
}
pub type MapFaceToCells = HashMap<FaceKey, Vec<(CellId, usize)>>;
pub type MapPointToFaces = HashMap<PointId, HashSet<FaceKey>>;
impl AsCell for Face {
fn kind(&self) -> GeoKind {
self.kind
}
fn marker(&self) -> i32 {
self.marker
}
fn points(&self) -> &[PointId] {
&self.points
}
}
impl fmt::Display for Face {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.points.len() == 3 {
let (a, b, c, _) = self.key();
write!(f, "({}, {}, {}, MAX)", a, b, c).unwrap();
} else {
write!(f, "{:?}", self.key()).unwrap();
}
Ok(())
}
}
impl<'a> fmt::Display for Faces<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for i in 0..self.all.len() {
if i > 0 {
write!(f, ", ").unwrap();
}
write!(f, "{}", self.all[i]).unwrap();
}
Ok(())
}
}