use std::array;
use crate::{
objects::{Cycle, Face},
operations::Polygon,
storage::Handle,
};
pub trait UpdateFace {
fn update_exterior(
&self,
f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self;
fn add_interiors(
&self,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
) -> Self;
}
impl UpdateFace for Face {
fn update_exterior(
&self,
f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self {
let exterior = f(self.exterior());
Face::new(
self.surface().clone(),
exterior,
self.interiors().cloned(),
self.color(),
)
}
fn add_interiors(
&self,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
) -> Self {
let interiors = self.interiors().cloned().chain(interiors);
Face::new(
self.surface().clone(),
self.exterior().clone(),
interiors,
self.color(),
)
}
}
impl<const D: usize> UpdateFace for Polygon<D> {
fn update_exterior(
&self,
f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self {
let face = self.face.update_exterior(f);
let edges = array::from_fn(|i| {
face.exterior()
.nth_half_edge(i)
.expect("Operation should not have changed length of cycle")
.clone()
});
let vertices = array::from_fn(|i| {
face.exterior()
.nth_half_edge(i)
.expect("Operation should not have changed length of cycle")
.start_vertex()
.clone()
});
Polygon {
face,
edges,
vertices,
}
}
fn add_interiors(
&self,
_: impl IntoIterator<Item = Handle<Cycle>>,
) -> Self {
panic!("Adding interiors to `Polygon` is not supported.")
}
}