use crate::data_container::StorageBuffer;
use crate::prelude::{half_edge_handle::HalfEdgeHandle, vert_handle::VertHandle};
use crate::{ArcId, EdgeId, EndpointList, MeshData, MeshStorage, VertId};
use crate::{EdgeData, TopoEdge};
pub struct EdgeHandle<C: MeshStorage, const MANIFOLD: bool>
{
pub(crate) mesh_data: *mut MeshData<C, MANIFOLD>,
pub(crate) id: EdgeId,
}
impl<C: MeshStorage, const MANIFOLD: bool> EdgeHandle<C, MANIFOLD>
{
pub fn id(&self) -> EdgeId { self.id }
pub fn is_thin(&self) -> bool
{
unsafe { (*self.mesh_data).edge_ref(self.id).half_edge.is_void() }
}
pub fn half_edge(&self) -> HalfEdgeHandle<C, MANIFOLD>
{
unsafe {
let half_edge_id = (*self.mesh_data).edge_ref(self.id).half_edge;
HalfEdgeHandle {
mesh_data: self.mesh_data,
id: half_edge_id,
}
}
}
pub fn endpoints(&self) -> [VertId; 2]
{
unsafe { (*self.mesh_data).edge_ref(self.id).endpoints }
}
pub fn endpoint_handles(&self) -> [VertHandle<C, MANIFOLD>; 2]
{
let [v1, v2] = self.endpoints();
[
VertHandle::new(self.mesh_data, v1),
VertHandle::new(self.mesh_data, v2),
]
}
pub fn next_at(&self, v: VertId) -> Self
{
unsafe {
let next_id = (*self.mesh_data)
.edge_ref(self.id)
.cycle_at(v)
.unwrap()
.next;
EdgeHandle {
mesh_data: self.mesh_data,
id: next_id,
}
}
}
pub fn prev_at(&self, v: VertId) -> Self
{
unsafe {
let prev_id = (*self.mesh_data)
.edge_ref(self.id)
.cycle_at(v)
.unwrap()
.prev;
EdgeHandle {
mesh_data: self.mesh_data,
id: prev_id,
}
}
}
pub fn replicate(&self) -> Self
{
EdgeHandle {
mesh_data: self.mesh_data,
id: self.id,
}
}
pub fn unclean_delete(self)
{
unsafe {
let handle = EdgeHandle {
mesh_data: self.mesh_data,
id: self.id,
};
let half_edges: Vec<_> =
handle.half_edge().iter_orbit().map(|h| h.id()).collect();
for h in half_edges
{
let hedge_ref = (*self.mesh_data).half_edge_ref(h);
if hedge_ref.id.is_void()
{
continue;
}
let handle = HalfEdgeHandle {
mesh_data: self.mesh_data,
id: h,
};
handle.unclean_delete();
}
self.remove_from_cycles();
(*self.mesh_data)
.topology_data
.available_edge_ids
.push(self.id);
*(*self.mesh_data).edge_mut(self.id) = TopoEdge::default();
}
}
pub fn delete(self)
{
let [v1, v2] = self.endpoints();
let mesh_data = self.mesh_data;
self.unclean_delete();
let vert1 = VertHandle { mesh_data, id: v1 };
let should_delete_v1 = vert1.iter_star_edges().count() == 0;
if should_delete_v1
{
vert1.delete();
}
let vert2 = VertHandle { mesh_data, id: v2 };
let should_delete_2 = vert2.iter_star_edges().count() == 0;
if should_delete_2
{
vert2.delete();
}
}
pub(crate) fn remove_from_cycles(&self)
{
assert!(!MANIFOLD);
let [v1, v2] = self.endpoint_handles();
if let Some(h) = v1.find_distinct_edge(self.half_edge().id())
{
unsafe {
(*self.mesh_data).vert_mut(v1.id()).arc = ArcId::Edge(h.edge().id())
};
}
else
{
unsafe {
(*self.mesh_data).vert_mut(v1.id()).arc = ArcId::Edge(EdgeId::default());
};
};
if let Some(h) = v2.find_distinct_edge(self.half_edge().id())
{
unsafe {
(*self.mesh_data).vert_mut(v2.id()).arc = ArcId::Edge(h.edge().id());
};
}
else
{
unsafe {
(*self.mesh_data).vert_mut(v2.id()).arc = ArcId::Edge(EdgeId::default());
};
};
unsafe {
let edges = &mut (*self.mesh_data).topology_data.topo_edges;
EndpointList::remove_edge(edges, self.id(), v1.id());
EndpointList::remove_edge(edges, self.id(), v2.id());
}
}
pub fn read_data(&self) -> &EdgeData<C>
{
unsafe {
(*self.mesh_data)
.geometry_data
.edge_data
.read(self.id.to_index() as u64)
}
}
pub fn update_data<F: FnMut(&mut EdgeData<C>)>(&mut self, update: F)
{
unsafe {
(*self.mesh_data)
.geometry_data
.edge_data
.update(self.id.to_index() as u64, update)
}
}
}