use std::collections::{btree_set, BTreeSet};
use fj_interop::mesh::Color;
use fj_math::Winding;
use crate::{
objects::{Cycle, Surface},
storage::Handle,
};
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Face {
surface: Handle<Surface>,
exterior: Handle<Cycle>,
interiors: Vec<Handle<Cycle>>,
color: Option<Color>,
}
impl Face {
pub fn new(
surface: Handle<Surface>,
exterior: Handle<Cycle>,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
color: Option<Color>,
) -> Self {
let interiors = interiors.into_iter().collect();
Self {
surface,
exterior,
interiors,
color,
}
}
pub fn surface(&self) -> &Handle<Surface> {
&self.surface
}
pub fn exterior(&self) -> &Handle<Cycle> {
&self.exterior
}
pub fn interiors(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
self.interiors.iter()
}
pub fn all_cycles(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
[self.exterior()].into_iter().chain(self.interiors())
}
pub fn color(&self) -> Option<Color> {
self.color
}
pub fn coord_handedness(&self) -> Handedness {
match self.exterior().winding() {
Winding::Ccw => Handedness::RightHanded,
Winding::Cw => Handedness::LeftHanded,
}
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct FaceSet {
inner: BTreeSet<Handle<Face>>,
}
impl FaceSet {
pub fn new() -> Self {
Self::default()
}
pub fn find(&self, face: &Handle<Face>) -> Option<Handle<Face>> {
for f in self {
if f == face {
return Some(f.clone());
}
}
None
}
}
impl Extend<Handle<Face>> for FaceSet {
fn extend<T: IntoIterator<Item = Handle<Face>>>(&mut self, iter: T) {
self.inner.extend(iter);
}
}
impl FromIterator<Handle<Face>> for FaceSet {
fn from_iter<T: IntoIterator<Item = Handle<Face>>>(iter: T) -> Self {
let mut faces = Self::new();
faces.extend(iter);
faces
}
}
impl IntoIterator for FaceSet {
type Item = Handle<Face>;
type IntoIter = btree_set::IntoIter<Handle<Face>>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a> IntoIterator for &'a FaceSet {
type Item = &'a Handle<Face>;
type IntoIter = btree_set::Iter<'a, Handle<Face>>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter()
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Handedness {
LeftHanded,
RightHanded,
}