use std::collections::HashMap;
use super::{HalfEdgeImplMeshType, HalfEdgeMeshImpl};
use crate::{
math::IndexType,
mesh::{
EdgeBasics, FaceBasics, HalfEdge, MeshBasics, Triangulation, VertexBasics, VertexPayload,
},
util::Deletable,
};
impl<T: HalfEdgeImplMeshType> MeshBasics<T> for HalfEdgeMeshImpl<T> {
fn has_vertex(&self, index: T::V) -> bool {
self.vertices.has(index)
}
fn vertex(&self, index: T::V) -> &T::Vertex {
self.vertices.get(index)
}
fn edge(&self, index: T::E) -> &T::Edge {
self.halfedges.get(index)
}
fn face(&self, index: T::F) -> &T::Face {
let f = &self.faces.get(index);
assert!(!f.is_deleted());
f
}
fn vertex_mut(&mut self, index: T::V) -> &mut T::Vertex {
self.vertices.get_mut(index)
}
fn edge_mut<'a>(&'a mut self, index: T::E) -> &'a mut T::Edge {
self.halfedges.get_mut(index)
}
fn face_mut(&mut self, index: T::F) -> &mut T::Face {
self.faces.get_mut(index)
}
fn is_open(&self) -> bool {
self.halfedges.iter().any(|e| e.is_boundary_self())
}
fn max_vertex_index(&self) -> usize {
self.vertices.capacity()
}
fn num_vertices(&self) -> usize {
self.vertices.len()
}
fn num_edges(&self) -> usize {
self.halfedges.len()
}
fn num_faces(&self) -> usize {
self.faces.len()
}
fn clear(&mut self) -> &mut Self {
self.vertices.clear();
self.halfedges.clear();
self.faces.clear();
self
}
fn payload(&self) -> &T::MP {
&self.payload
}
fn payload_mut(&mut self) -> &mut T::MP {
&mut self.payload
}
fn set_payload(&mut self, payload: T::MP) -> &mut Self {
self.payload = payload;
self
}
fn vertices<'a>(&'a self) -> impl Iterator<Item = &'a T::Vertex>
where
T::Vertex: 'a,
{
self.vertices.iter()
}
fn vertices_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T::Vertex>
where
T::Vertex: 'a,
{
self.vertices.iter_mut()
}
fn faces<'a>(&'a self) -> impl Iterator<Item = &'a T::Face>
where
T::Face: 'a,
{
self.faces.iter()
}
fn faces_mut<'a>(
&'a mut self,
) -> impl Iterator<Item = &'a mut <T as crate::prelude::MeshType>::Face>
where
T: 'a,
{
self.faces.iter_mut()
}
fn edges<'a>(&'a self) -> impl Iterator<Item = &'a T::Edge>
where
T::Edge: 'a,
{
self.halfedges.iter()
}
fn edges_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T::Edge>
where
T::Edge: 'a,
{
self.halfedges.iter_mut()
}
fn dense_vertices(&self, indices: &mut Vec<T::V>) -> Vec<T::VP> {
let mut vertices = Vec::with_capacity(self.num_vertices());
if self.vertices.len() == self.vertices.capacity() {
for _ in 0..self.vertices.capacity() {
vertices.push(T::VP::allocate());
}
for v in self.vertices() {
vertices[v.id().index()] = v.payload().clone();
}
} else {
let mut id_map = HashMap::new();
for v in self.vertices() {
id_map.insert(v.id(), T::V::new(vertices.len()));
vertices.push(v.payload().clone());
}
Triangulation::new(indices).map_indices(&id_map);
}
vertices
}
fn shared_edge(&self, v: T::V, w: T::V) -> Option<T::Edge> {
self.vertex(v).edges_out(self).find_map(|e| {
if e.target_id(self) == w {
Some(e)
} else {
None
}
})
}
fn shared_edge_id(&self, v: T::V, w: T::V) -> Option<T::E> {
self.shared_edge(v, w).map(|e| e.id())
}
fn shared_face(&self, v0: T::V, v1: T::V) -> Option<T::F> {
let w0 = self.vertex(v0);
let w1 = self.vertex(v1);
w0.faces(self).find_map(|f0| {
w1.faces(self).find_map(|f1: T::Face| {
if f0.id() == f1.id() {
Some(f0.id())
} else {
None
}
})
})
}
}