polyhedron 0.1.0

A half edge and radial edge implementation.
Documentation
use std::fmt::Debug;

/// Abstract storage interface.
pub trait StorageBuffer: Clone + Debug + Default
{
    /// Underlying element stored in this collection.
    type Element: Clone + Debug + Default;

    /// Read the element at the specified index.
    fn read(&self, idx: u64) -> &Self::Element;
    /// Update the element at the specified index.
    fn update<F: FnMut(&mut Self::Element)>(&mut self, idx: u64, update: F);

    /// Add an element to the collection.
    fn append(&mut self, value: Self::Element);
    /// Remove the element at the specified index from the collection.
    fn discard(&mut self, idx: u64) -> Self::Element;
    /// Remove elements fpr which `keep` returns false.
    fn filter<F: FnMut(&Self::Element) -> bool>(&mut self, keep: F);
    /// cardinality of the collection.
    fn len(&self) -> usize;
    /// Iterate over the collection.
    fn iter_ref(&self) -> impl Iterator<Item = &Self::Element>;
}

impl<T: Default + Clone + Debug> StorageBuffer for Vec<T>
{
    type Element = T;

    fn read(&self, idx: u64) -> &Self::Element { &self[idx as usize] }

    fn update<F: FnMut(&mut Self::Element)>(&mut self, idx: u64, mut update: F)
    {
        update(&mut self[idx as usize])
    }

    fn append(&mut self, value: Self::Element) { self.push(value) }

    fn discard(&mut self, idx: u64) -> Self::Element { self.remove(idx as usize) }

    fn filter<F: FnMut(&Self::Element) -> bool>(&mut self, keep: F) { self.retain(keep) }

    fn len(&self) -> usize { self.len() }

    fn iter_ref(&self) -> impl Iterator<Item = &Self::Element> { self.iter() }
}

impl StorageBuffer for ()
{
    type Element = ();

    fn read(&self, _idx: u64) -> &Self::Element { self }

    fn update<F: FnMut(&mut Self::Element)>(&mut self, _idx: u64, mut _update: F) {}

    fn append(&mut self, _value: Self::Element) {}

    fn discard(&mut self, _idx: u64) -> Self::Element {}

    fn filter<F: FnMut(&Self::Element) -> bool>(&mut self, _f: F) {}

    fn iter_ref(&self) -> impl Iterator<Item = &Self::Element> { std::iter::empty() }

    fn len(&self) -> usize { 0 }
}

/// Defines container layout for mesh elements.
pub trait MeshStorage
{
    /// Sorage for vertex data.
    type VertStorage: StorageBuffer;
    /// Sorage for edge data.
    type EdgeStorage: StorageBuffer;
    /// Sorage for face data.
    type FaceStorage: StorageBuffer;
}

/// Helper type accessor for vertex data.
pub type VertData<M> = <<M as MeshStorage>::VertStorage as StorageBuffer>::Element;
/// Helper type accessor for edge data.
pub type EdgeData<M> = <<M as MeshStorage>::EdgeStorage as StorageBuffer>::Element;
/// Helper type accessor for face data.
pub type FaceData<M> = <<M as MeshStorage>::FaceStorage as StorageBuffer>::Element;

impl<V, E, F> MeshStorage for (V, E, F)
where
    V: StorageBuffer,
    E: StorageBuffer,
    F: StorageBuffer,
{
    type EdgeStorage = E;
    type FaceStorage = F;
    type VertStorage = V;
}