polyhedron 0.1.0

A half edge and radial edge implementation.
Documentation
use crate::data_container::StorageBuffer;
use crate::prelude::{half_edge_handle::HalfEdgeHandle, vert_handle::VertHandle};
use crate::EdgeData;
use crate::{ArcId, EdgeId, EndpointList, MeshData, MeshStorage, VertId};

/// Topological handle to an edge (non-manifold only).
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>
{
    /// Id of the handle.
    pub fn id(&self) -> EdgeId { self.id }

    /// Whether there are any half edges orbitting this eedge.
    pub fn is_thin(&self) -> bool
    {
        unsafe { (*self.mesh_data).edge_ref(self.id).half_edge.is_void() }
    }

    /// Handle to a random half edge orbitting this edge.
    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,
            }
        }
    }

    /// Ids of both endpoints of the edge in o particular order.
    pub fn endpoints(&self) -> [VertId; 2]
    {
        unsafe { (*self.mesh_data).edge_ref(self.id).endpoints }
    }

    /// Handles to both endpoints of the edge in o particular order.
    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),
        ]
    }

    /// Next edge in the radial cycle of the given endpoint (will crash
    /// if the specified vertex id is not in the edge).
    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,
            }
        }
    }

    /// Previous edge in the radial cycle of the given endpoint (will crash
    /// if the specified vertex id is not in the edge).
    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,
            }
        }
    }

    /// Make a shallow copy of the handle.
    pub fn replicate(&self) -> Self
    {
        EdgeHandle {
            mesh_data: self.mesh_data,
            id: self.id,
        }
    }

    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());
        }
    }

    /// Read the stored data for this edge.
    pub fn read_data(&self) -> &EdgeData<C>
    {
        unsafe {
            (*self.mesh_data)
                .geometry_data
                .edge_data
                .read(self.id.to_index() as u64)
        }
    }

    /// Update the stored data for this edge.
    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)
        }
    }
}