use crate::{
halfedge::{HalfEdgeFaceImpl, HalfEdgeImplMeshType, HalfEdgeMeshImpl},
math::IndexType,
mesh::{
DefaultEdgePayload, DefaultFacePayload, EdgeBasics, FaceBasics, HalfEdge, HalfEdgeVertex,
MeshBasics, MeshBuilder, MeshHalfEdgeBuilder,
},
};
impl<T: HalfEdgeImplMeshType> MeshBuilder<T> for HalfEdgeMeshImpl<T> {
fn add_vertex_via_vertex_default(&mut self, v: T::V, vp: T::VP) -> (T::V, T::E, T::E)
where
T::EP: DefaultEdgePayload,
{
self.add_vertex_via_vertex(v, vp, T::EP::default(), T::EP::default())
}
fn add_vertex_via_edge_default(
&mut self,
input: T::E,
output: T::E,
vp: T::VP,
) -> (T::V, T::E, T::E)
where
T::EP: DefaultEdgePayload,
{
self.add_vertex_via_edge(input, output, vp, T::EP::default(), T::EP::default())
}
fn remove_face(&mut self, f: T::F) -> T::FP {
let face = self.face(f);
let fp = face.payload().clone();
let edge_ids: Vec<_> = face.edges(self).map(|e| e.id()).collect();
for e in edge_ids {
self.edge_mut(e).delete_face();
}
self.faces.delete_internal(f);
fp
}
fn close_hole(&mut self, e: T::E, fp: T::FP, curved: bool) -> T::F {
let f = self.faces.push(HalfEdgeFaceImpl::new(e, curved, fp));
self.edge(e)
.clone()
.edges_face_mut(self)
.for_each(|e| e.set_face(f));
return f;
}
fn close_face_vertices_default(
&mut self,
prev: T::V,
from: T::V,
to: T::V,
curved: bool,
) -> (T::F, T::E, T::E)
where
T::EP: DefaultEdgePayload,
T::FP: DefaultFacePayload,
{
self.close_face_vertices(
prev,
Default::default(),
from,
Default::default(),
to,
Default::default(),
curved,
)
}
fn insert_vertices_into_edge<I: Iterator<Item = (T::EP, T::EP, T::VP)>>(
&mut self,
e: T::E,
ps: I,
) -> T::E {
let twin_id = self.edge(e).twin_id();
let mut current = self.edge(e).prev_id();
let mut current_twin = self.edge(twin_id).next_id();
let f1 = self.edge(e).face_id();
let f2 = self.edge(twin_id).face_id();
let mut last_v = self.edge(e).origin_id();
let mut first = true;
for (ep1, ep2, vp) in ps {
let (v, e1, e2) =
self.add_vertex_via_edge(current, self.edge(current).twin_id(), vp, ep1, ep2);
current = e1;
current_twin = e2;
last_v = v;
self.edge_mut(current).set_face(f1);
self.edge_mut(current_twin).set_face(f2);
if first {
self.vertex_mut(self.edge(e).origin_id()).set_edge(e1);
first = false;
}
}
self.edge_mut(current).set_next(e);
self.edge_mut(e).set_prev(current);
self.edge_mut(current_twin).set_prev(twin_id);
self.edge_mut(twin_id).set_next(current_twin);
self.edge_mut(e).set_origin(last_v);
return e;
}
fn add_vertex(&mut self, vp: T::VP) -> T::V {
let new = self.vertices.allocate();
self.vertices.set(new, T::Vertex::new(IndexType::max(), vp));
new
}
fn insert_path(&mut self, vp: impl IntoIterator<Item = T::VP>) -> (T::E, T::E)
where
T::EP: DefaultEdgePayload,
{
let mut iter = vp.into_iter();
let p0 = iter.next().expect("Path must have at least one vertex");
let p1 = iter.next().expect("Path must have at least two vertices");
let (v0, v) = self.add_isolated_edge_default(p0, p1);
let first = self.shared_edge(v0, v).unwrap();
let mut input = first.id();
let mut output = first.twin_id();
for pos in iter {
self.add_vertex_via_edge_default(input, output, pos);
let n = self.edge(input).next(self);
input = n.id();
output = n.twin_id();
}
(first.twin_id(), input)
}
fn add_isolated_edge_default(&mut self, a: T::VP, b: T::VP) -> (T::V, T::V)
where
T::EP: DefaultEdgePayload,
{
self.add_isolated_edge(a, T::EP::default(), b, T::EP::default())
}
fn insert_loop(&mut self, vp: impl IntoIterator<Item = T::VP>) -> T::E
where
T::EP: DefaultEdgePayload,
{
let (first, last) = self.insert_path(vp);
self.insert_edge(first, Default::default(), last, Default::default());
return first;
}
}