use std::collections::HashSet;
use std::ops::Mul;
use crate::data_container::StorageBuffer;
use crate::prelude::{
edge_handle::EdgeHandle,
face_handle::FaceHandle,
vert_handle::VertHandle,
};
use crate::{
ArcId,
EdgeId,
EndpointList,
FaceId,
HalfEdgeId,
MeshData,
MeshStorage,
TopoEdge,
TopoFace,
TopoHalfEdge,
TopoVert,
VertData,
VertId,
};
pub struct HalfEdgeHandle<C: MeshStorage, const MANIFOLD: bool>
{
pub(crate) mesh_data: *mut MeshData<C, MANIFOLD>,
pub(crate) id: HalfEdgeId,
}
impl<C: MeshStorage, const MANIFOLD: bool> HalfEdgeHandle<C, MANIFOLD>
{
pub fn replicate(&self) -> Self
{
HalfEdgeHandle {
mesh_data: self.mesh_data,
id: self.id,
}
}
pub fn id(&self) -> HalfEdgeId { self.id }
pub fn source(&self) -> VertHandle<C, MANIFOLD>
{
unsafe {
let vert_id = (*self.mesh_data).half_edge_ref(self.id).source;
VertHandle {
mesh_data: self.mesh_data,
id: vert_id,
}
}
}
pub fn dest(&self) -> VertHandle<C, MANIFOLD> { self.face_next().source() }
pub fn face_next(&self) -> HalfEdgeHandle<C, MANIFOLD>
{
unsafe {
let half_edge_id = (*self.mesh_data).half_edge_ref(self.id).face_next;
HalfEdgeHandle {
mesh_data: self.mesh_data,
id: half_edge_id,
}
}
}
pub fn face_prev(&self) -> HalfEdgeHandle<C, MANIFOLD>
{
unsafe {
let half_edge_id = (*self.mesh_data).half_edge_ref(self.id).face_prev;
HalfEdgeHandle {
mesh_data: self.mesh_data,
id: half_edge_id,
}
}
}
pub fn orbit_next(&self) -> HalfEdgeHandle<C, MANIFOLD>
{
unsafe {
let half_edge_id = (*self.mesh_data).half_edge_ref(self.id).orbit_next;
HalfEdgeHandle {
mesh_data: self.mesh_data,
id: half_edge_id,
}
}
}
pub fn edge(&self) -> EdgeHandle<C, MANIFOLD>
{
assert!(!MANIFOLD);
unsafe {
let edge_id = (*self.mesh_data).half_edge_ref(self.id).edge;
EdgeHandle {
mesh_data: self.mesh_data,
id: edge_id,
}
}
}
pub fn face(&self) -> FaceHandle<C, MANIFOLD>
{
unsafe {
let face_id = (*self.mesh_data).half_edge_ref(self.id).face;
FaceHandle {
mesh_data: self.mesh_data,
id: face_id,
}
}
}
pub fn iter_orbit(&self) -> OrbitHalfEdgeIterator<C, MANIFOLD>
{
OrbitHalfEdgeIterator::new(self.replicate())
}
pub fn iter_face(&self) -> InFaceHalfEdgeIterator<C, MANIFOLD>
{
InFaceHalfEdgeIterator::new(self.replicate())
}
pub fn is_in_boundary(&self) -> bool
{
for h in self.iter_orbit()
{
if h.face().id().is_void()
{
return true;
}
}
false
}
pub fn edge_index(&self) -> usize
{
if MANIFOLD
{
self.id().to_index() / 2
}
else
{
self.edge().id().to_index()
}
}
pub fn vertices(&self) -> [VertData<C>; 2]
{
[
self.source().read_data().clone(),
self.face_next().source().read_data().clone(),
]
}
pub fn dir<S>(&self) -> VertData<C>
where
VertData<C>: linear_isomorphic::InnerSpace<S>,
S: linear_isomorphic::RealField,
{
self.dest().read_data().clone() - self.source().read_data().clone()
}
pub fn can_collapse(&self) -> bool
{
let v1 = self.source();
let v2 = self.dest();
let v1_verts: Vec<VertId> = v1.iter_neighbours().map(|v| v.id()).collect();
let count = v2
.iter_neighbours()
.filter(|v| v1_verts.contains(&v.id()))
.count();
if count > 2
{
return false;
}
let both_endpoints_are_in_boundary = v1.is_in_boundary() && v2.is_in_boundary();
self.is_in_boundary() || !both_endpoints_are_in_boundary
}
pub fn can_flip(&self) -> bool
{
let [v1, v2] = self.opposite_verts();
let v1_set: HashSet<VertId> =
HashSet::from_iter(v1.iter_neighbours().map(|v| v.id()));
let v2_set: HashSet<VertId> =
HashSet::from_iter(v2.iter_neighbours().map(|v| v.id()));
!v1_set.contains(&v2.id()) && !v2_set.contains(&v1.id())
}
pub fn opposite_verts(&self) -> [VertHandle<C, MANIFOLD>; 2]
{
[
self.face_prev().source(),
self.orbit_next().face_prev().source(),
]
}
pub fn flip(&self)
{
let edge_id = if !MANIFOLD
{
self.edge().id()
}
else
{
EdgeId::default()
};
let hedge1 = self.id();
let hedge2 = self.face_next().id();
let hedge3 = self.face_prev().id();
let hedge4 = self.orbit_next().id();
let hedge5 = self.orbit_next().face_prev().id();
let hedge6 = self.orbit_next().face_next().id();
let vert1 = self.source().id();
let vert2 = self.face_next().source().id();
let trans1 = self.face_prev().source().id();
let trans2 = self.orbit_next().face_prev().source().id();
let face1 = self.face().id();
let face2 = self.orbit_next().face().id();
let vert1_safe_edge = self.source().find_distinct_edge(self.id()).unwrap().id();
let vert2_safe_edge = self.dest().find_distinct_edge(self.id()).unwrap().id();
let (trans1_edge, trans2_edge) = if !MANIFOLD
{
let trans1_edge =
unsafe { (*self.mesh_data).vert_ref(trans1).arc.to_edge_id() };
let trans2_edge =
unsafe { (*self.mesh_data).vert_ref(trans2).arc.to_edge_id() };
(trans1_edge, trans2_edge)
}
else
{
(EdgeId::default(), EdgeId::default())
};
if !MANIFOLD
{
self.edge().remove_from_cycles();
}
unsafe {
(*self.mesh_data).half_edge_mut(hedge1).source = trans1;
(*self.mesh_data).half_edge_mut(hedge4).source = trans2;
}
let topology_data = unsafe { &mut (*self.mesh_data).topology_data };
crate::attach_face(topology_data, &[hedge1, hedge5, hedge2], face1);
crate::attach_face(topology_data, &[hedge4, hedge3, hedge6], face2);
if MANIFOLD
{
unsafe {
let topo_verts = &mut (*self.mesh_data).topology_data.topo_verts;
topo_verts[vert1.to_index()].arc = ArcId::HalfEdge(vert1_safe_edge);
topo_verts[vert2.to_index()].arc = ArcId::HalfEdge(vert2_safe_edge);
}
}
else
{
unsafe {
let edge1 = (*self.mesh_data).half_edge_ref(vert1_safe_edge).edge;
let edge2 = (*self.mesh_data).half_edge_ref(vert2_safe_edge).edge;
(*self.mesh_data).vert_mut(vert1).arc = ArcId::Edge(edge1);
(*self.mesh_data).vert_mut(vert2).arc = ArcId::Edge(edge2);
(*self.mesh_data).edge_mut(edge_id).endpoints = [trans1, trans2];
}
}
if !MANIFOLD
{
unsafe {
crate::EndpointList::join_at(
&mut (*self.mesh_data).topology_data.topo_edges,
trans1_edge,
edge_id,
trans1,
);
crate::EndpointList::join_at(
&mut (*self.mesh_data).topology_data.topo_edges,
trans2_edge,
edge_id,
trans2,
);
(*self.mesh_data).vert_mut(trans1).arc = ArcId::Edge(edge_id);
(*self.mesh_data).vert_mut(trans2).arc = ArcId::Edge(edge_id);
}
}
}
pub fn split<S>(self) -> VertId
where
VertData<C>: linear_isomorphic::InnerSpace<S>,
S: linear_isomorphic::RealField + Mul<VertData<C>, Output = VertData<C>>,
{
let edge_id = if !MANIFOLD
{
self.edge().id()
}
else
{
EdgeId::default()
};
let edge_data = self.edge().read_data().clone();
let mid = (self.source().read_data().clone() + self.dest().read_data().clone())
* S::from(0.5).unwrap();
let vn = unsafe { (*self.mesh_data).add_vert(mid) };
let v2 = self.dest().id();
let vert2_safe_edge = self
.dest()
.find_distinct_edge(self.id())
.map(|h| h.edge().id())
.unwrap_or_default();
if !MANIFOLD
{
unsafe {
let edges = &mut (*self.mesh_data).topology_data.topo_edges;
EndpointList::remove_edge(edges, edge_id, v2);
(*self.mesh_data).vert_mut(vn).arc = ArcId::Edge(edge_id);
(*self.mesh_data).vert_mut(v2).arc = ArcId::Edge(vert2_safe_edge);
let edge = (*self.mesh_data).edge_mut(edge_id);
if edge.endpoints[0] == v2
{
edge.endpoints[0] = vn;
}
else
{
edge.endpoints[1] = vn;
}
}
}
let new_h1 = unsafe { (*self.mesh_data).add_edge(vn, v2, edge_data.clone()) };
let new_h2 = unsafe { (*self.mesh_data).half_edge_ref(new_h1).orbit_next };
unsafe {
if MANIFOLD
{
(*self.mesh_data).vert_mut(v2).arc = ArcId::HalfEdge(new_h2);
}
else
{
let eid = (*self.mesh_data).half_edge_ref(new_h2).edge;
(*self.mesh_data).vert_mut(v2).arc = ArcId::Edge(eid);
}
}
let mut hedge_queue = vec![new_h2, new_h1];
for h in self.iter_orbit()
{
let transversal = h.face_prev().source().id();
let next_hedge = h.face_next().id();
let prev_hedge = h.face_prev().id();
let trans_hedge1 =
unsafe { (*self.mesh_data).add_edge(vn, transversal, edge_data.clone()) };
let trans_hedge2 =
unsafe { (*self.mesh_data).half_edge_ref(trans_hedge1).orbit_next };
let crossing_hedge = hedge_queue.pop().unwrap();
let hid = h.id();
let [cycle1, cycle2] = if h.source().id() == v2
{
unsafe {
(*self.mesh_data).half_edge_mut(h.id()).source = vn;
}
let f1 = [hid, next_hedge, trans_hedge2];
let f2 = [crossing_hedge, trans_hedge1, prev_hedge];
[f1, f2]
}
else
{
let f1 = [hid, trans_hedge1, prev_hedge];
let f2 = [crossing_hedge, next_hedge, trans_hedge2];
[f1, f2]
};
let mut face_id = FaceId::default();
for i in 0..3
{
let h1 = cycle1[i];
let h2 = cycle1[(i + 1) % 3];
let h3 = cycle2[i];
let h4 = cycle2[(i + 1) % 3];
unsafe {
let h1 = (*self.mesh_data).half_edge_mut(h1);
let h2 = (*self.mesh_data).half_edge_mut(h2);
h1.attach_next_in_face(h2);
let f = if h1.face.is_void() { h2.face } else { h1.face };
h1.face = f;
h2.face = f;
(*self.mesh_data).face_mut(f).half_edge = h1.id;
face_id = f;
let h3 = (*self.mesh_data).half_edge_mut(h3);
let h4 = (*self.mesh_data).half_edge_mut(h4);
h3.attach_next_in_face(h4);
h3.face = FaceId::default();
}
}
unsafe {
let data = (*self.mesh_data)
.geometry_data
.face_data
.read(face_id.to_index() as u64)
.clone();
(*self.mesh_data).geometry_data.face_data.append(data);
let fid = if let Some(fid) =
(*self.mesh_data).topology_data.available_face_ids.pop()
{
(*self.mesh_data).face_mut(fid).id = fid;
fid
}
else
{
let fid =
FaceId::new((*self.mesh_data).topology_data.topo_faces.len());
(*self.mesh_data).topology_data.topo_faces.push(TopoFace {
id: fid,
..Default::default()
});
fid
};
for i in 0..3
{
let h = (*self.mesh_data).half_edge_mut(cycle2[i]);
h.face = fid;
}
(*self.mesh_data).face_mut(fid).half_edge = cycle2[0];
};
}
vn
}
pub fn iterate_butterfly(&self) -> impl Iterator<Item = HalfEdgeHandle<C, MANIFOLD>>
{
self.iter_face().chain(self.orbit_next().iter_face())
}
pub fn collapse_to_mid<S>(self) -> VertId
where
VertData<C>: linear_isomorphic::InnerSpace<S>,
S: linear_isomorphic::RealField + Mul<VertData<C>, Output = VertData<C>>,
{
let mid = (self.source().read_data().clone() + self.dest().read_data().clone())
* S::from(0.5).unwrap();
let mesh_data = self.mesh_data;
let vid = self.collapse();
unsafe {
(*mesh_data)
.geometry_data
.vert_data
.update(vid.to_index() as u64, move |v| *v = mid.clone());
}
vid
}
pub fn collapse(self) -> VertId
{
let to_fix = self.iter_orbit().map(|h| h.face().id()).collect::<Vec<_>>();
let vid = self.collapse_without_fixing();
for f in to_fix
{
let f_handle = FaceHandle {
id: f,
mesh_data: self.mesh_data.clone(),
};
let hedge = f_handle
.half_edge()
.iter_face()
.find(|h| h.source().id() == vid)
.unwrap();
let v1 = hedge.source().id();
let v2 = hedge.dest().id();
let to_delete = hedge.face_next();
let pair = to_delete.orbit_next();
let pp = pair.face_prev();
let pn = pair.face_next();
let face = pair.face();
unsafe {
let face_ref = (*self.mesh_data).face_mut(face.id());
face_ref.half_edge = hedge.id();
let h = (*self.mesh_data).half_edge_mut(hedge.id());
let hp = (*self.mesh_data).half_edge_mut(pp.id());
let hn = (*self.mesh_data).half_edge_mut(pn.id());
h.face = face.id();
h.attach_next_in_face(hn);
hp.attach_next_in_face(h);
if MANIFOLD
{
(*self.mesh_data).vert_mut(h.source).arc = ArcId::HalfEdge(h.id);
}
else
{
(*self.mesh_data).vert_mut(h.source).arc = ArcId::Edge(h.edge);
}
if MANIFOLD
{
let safe_v1 = pair.source().find_distinct_edge(pair.id()).unwrap();
let safe_v2 = pair
.dest()
.find_distinct_edge(pair.orbit_next().id())
.unwrap();
(*self.mesh_data).vert_mut(v1).arc = ArcId::HalfEdge(safe_v1.id());
(*self.mesh_data).vert_mut(v2).arc = ArcId::HalfEdge(safe_v2.id());
}
else
{
let safe_v1 = pair.source().find_distinct_edge(pair.id()).unwrap();
let safe_v2 = pair
.dest()
.find_distinct_edge(pair.orbit_next().id())
.unwrap();
(*self.mesh_data).vert_mut(v1).arc = ArcId::Edge(safe_v1.edge().id());
(*self.mesh_data).vert_mut(v2).arc = ArcId::Edge(safe_v2.edge().id());
}
if !MANIFOLD
{
let eid = pair.edge().id();
let edges = &mut (*self.mesh_data).topology_data.topo_edges;
EndpointList::remove_edge(edges, eid, v1);
EndpointList::remove_edge(edges, eid, v2);
(*self.mesh_data).topology_data.available_edge_ids.push(eid);
(&mut (*self.mesh_data).topology_data.topo_edges)[eid.to_index()] =
TopoEdge::default();
}
(*self.mesh_data)
.topology_data
.available_half_edge_ids
.push(to_delete.id());
(*self.mesh_data)
.topology_data
.available_half_edge_ids
.push(pair.id());
(*self.mesh_data).topology_data.available_face_ids.push(f);
(&mut (*self.mesh_data).topology_data.topo_half_edges)
[to_delete.id().to_index()] = TopoHalfEdge::default();
(&mut (*self.mesh_data).topology_data.topo_half_edges)
[pair.id().to_index()] = TopoHalfEdge::default();
(&mut (*self.mesh_data).topology_data.topo_faces)[f.to_index()] =
TopoFace::default();
}
}
vid
}
pub fn collapse_without_fixing(&self) -> VertId
{
let edge_id = if !MANIFOLD
{
self.edge().id()
}
else
{
EdgeId::default()
};
let v1 = self.source().id();
let v2 = self.dest().id();
let to_update = self
.dest()
.iter_star_half_edges()
.filter(|h| h.id() != self.id())
.map(|h| h.id())
.collect::<Vec<_>>();
if MANIFOLD
{
let safe_v1 = self.source().find_distinct_edge(self.id()).unwrap();
let safe_v2 = self
.dest()
.find_distinct_edge(self.orbit_next().id())
.unwrap();
unsafe {
(*self.mesh_data).vert_mut(v1).arc = ArcId::HalfEdge(safe_v1.id());
(*self.mesh_data).vert_mut(v2).arc = ArcId::HalfEdge(safe_v2.id());
}
}
else
{
let safe_v1 = self.source().find_distinct_edge(self.id()).unwrap();
let safe_v2 = self
.dest()
.find_distinct_edge(self.orbit_next().id())
.unwrap();
unsafe {
(*self.mesh_data).vert_mut(v1).arc = ArcId::Edge(safe_v1.edge().id());
(*self.mesh_data).vert_mut(v2).arc = ArcId::Edge(safe_v2.edge().id());
}
}
if !MANIFOLD
{
unsafe {
let safe = self
.source()
.find_distinct_edge(self.id())
.unwrap()
.edge()
.id();
(*self.mesh_data).vert_mut(v1).arc = ArcId::Edge(safe);
let edges = &mut (*self.mesh_data).topology_data.topo_edges;
EndpointList::remove_edge(edges, edge_id, v1);
EndpointList::remove_edge(edges, edge_id, v2);
(*self.mesh_data)
.topology_data
.available_edge_ids
.push(edge_id);
*(*self.mesh_data).edge_mut(edge_id) = TopoEdge::default();
}
}
else
{
unsafe {
let safe = self.source().find_distinct_edge(self.id()).unwrap().id();
(*self.mesh_data).vert_mut(v1).arc = ArcId::HalfEdge(safe);
}
}
let mut to_remove = Vec::new();
for h in self.iter_orbit()
{
to_remove.push(h.id());
let prev = h.face_prev();
let next = h.face_next();
if prev.source().id() == v2
{
unsafe {
(*self.mesh_data).half_edge_mut(prev.id()).source = v1;
}
}
if next.source().id() == v2
{
unsafe {
(*self.mesh_data).half_edge_mut(next.id()).source = v1;
}
}
unsafe {
let h1 = (*self.mesh_data).half_edge_mut(prev.id());
let h2 = (*self.mesh_data).half_edge_mut(next.id());
h1.attach_next_in_face(h2);
let fid = h1.face;
let face = (*self.mesh_data).face_mut(fid);
face.half_edge = h1.id;
}
}
for id in to_remove
{
unsafe {
(*self.mesh_data)
.topology_data
.available_half_edge_ids
.push(id);
*(*self.mesh_data).half_edge_mut(id) = TopoHalfEdge::default();
};
}
unsafe {
(*self.mesh_data).topology_data.available_vert_ids.push(v2);
*(*self.mesh_data).vert_mut(v2) = TopoVert::default();
};
let mut valid_updated_hedge = to_update[0];
for hid in to_update
{
unsafe {
let h = (*self.mesh_data).half_edge_mut(hid);
if h.id.is_void()
{
continue;
}
h.source = v1;
valid_updated_hedge = h.id;
let edge = (*self.mesh_data).edge_mut(h.edge);
if edge.endpoints[0] == v2
{
edge.endpoints[0] = v1;
}
else if edge.endpoints[1] == v2
{
edge.endpoints[1] = v1;
}
}
}
if !MANIFOLD
{
unsafe {
let other_edge = (*self.mesh_data).vert_ref(v1).arc.to_edge_id();
let current_edge =
(*self.mesh_data).half_edge_ref(valid_updated_hedge).edge;
let edges = &mut (*self.mesh_data).topology_data.topo_edges;
EndpointList::join_at(edges, current_edge, other_edge, v1);
}
}
v1
}
}
pub struct OrbitHalfEdgeIterator<C: MeshStorage, const MANIFOLD: bool>
{
start: HalfEdgeId,
current: HalfEdgeHandle<C, MANIFOLD>,
finished: bool,
}
impl<C: MeshStorage, const MANIFOLD: bool> OrbitHalfEdgeIterator<C, MANIFOLD>
{
pub(crate) fn new(edge: HalfEdgeHandle<C, MANIFOLD>) -> Self
{
Self {
start: edge.id(),
current: edge,
finished: MANIFOLD,
}
}
}
impl<C: MeshStorage, const MANIFOLD: bool> Iterator for OrbitHalfEdgeIterator<C, MANIFOLD>
{
type Item = HalfEdgeHandle<C, MANIFOLD>;
fn next(&mut self) -> Option<Self::Item>
{
if self.finished || self.current.id().is_void()
{
return None;
}
let current_edge = self.current.replicate();
self.current = self.current.orbit_next();
if self.current.id() == self.start
{
self.finished = true;
}
Some(current_edge)
}
}
pub struct InFaceHalfEdgeIterator<C: MeshStorage, const MANIFOLD: bool>
{
start: HalfEdgeId,
current: HalfEdgeHandle<C, MANIFOLD>,
finished: bool,
}
impl<C: MeshStorage, const MANIFOLD: bool> InFaceHalfEdgeIterator<C, MANIFOLD>
{
pub(crate) fn new(edge: HalfEdgeHandle<C, MANIFOLD>) -> Self
{
Self {
start: edge.id(),
current: edge,
finished: MANIFOLD,
}
}
}
impl<C: MeshStorage, const MANIFOLD: bool> Iterator
for InFaceHalfEdgeIterator<C, MANIFOLD>
{
type Item = HalfEdgeHandle<C, MANIFOLD>;
fn next(&mut self) -> Option<Self::Item>
{
if self.finished || self.current.id().is_void()
{
return None;
}
let current_edge = self.current.replicate();
self.current = self.current.face_next();
if self.current.id() == self.start
{
self.finished = true;
}
Some(current_edge)
}
}