mod basics;
mod halfedge;
mod iterator;
pub use iterator::*;
use super::HalfEdgeImplMeshType;
use crate::{
math::IndexType,
mesh::{DefaultEdgePayload, Edge, EdgeBasics, EdgePayload},
util::Deletable,
};
#[derive(Clone)]
pub struct HalfEdgeImpl<T: HalfEdgeImplMeshType> {
id: T::E,
next: T::E,
twin: T::E,
prev: T::E,
origin_id: T::V,
face: T::F,
payload: T::EP,
}
impl<T: HalfEdgeImplMeshType> Edge for HalfEdgeImpl<T> {
type T = T;
}
impl<T: HalfEdgeImplMeshType> std::fmt::Debug for HalfEdgeImpl<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let payload = if self.payload.is_empty() {
"".to_string()
} else {
format!(", payload: {:?}", self.payload)
};
write!(
f,
"{} --{}--> ; twin: {}, face: {} [{}] {} {}",
self.origin_id.index(),
self.id().index(),
self.twin.index(),
self.prev.index(),
if self.face == IndexType::max() {
"none".to_string()
} else {
self.face.index().to_string()
},
self.next.index(),
payload
)?;
if !self.payload.is_empty() {
write!(f, ", payload: {:?}", self.payload)?;
}
Ok(())
}
}
impl<T: HalfEdgeImplMeshType> Deletable<T::E> for HalfEdgeImpl<T> {
fn delete(&mut self) {
assert!(self.id != IndexType::max());
self.id = IndexType::max();
}
fn is_deleted(&self) -> bool {
self.id == IndexType::max()
}
fn set_id(&mut self, id: T::E) {
assert!(self.id == IndexType::max());
assert!(id != IndexType::max());
assert!(self.next != id);
assert!(self.prev != id);
self.id = id;
}
fn allocate() -> Self {
Self {
id: IndexType::max(),
next: IndexType::max(),
twin: IndexType::max(),
prev: IndexType::max(),
origin_id: IndexType::max(),
face: IndexType::max(),
payload: T::EP::allocate(),
}
}
}
impl<T: HalfEdgeImplMeshType> Default for HalfEdgeImpl<T>
where
T::EP: DefaultEdgePayload,
{
fn default() -> Self {
Self {
id: IndexType::max(),
next: IndexType::max(),
twin: IndexType::max(),
prev: IndexType::max(),
origin_id: IndexType::max(),
face: IndexType::max(),
payload: T::EP::default(),
}
}
}