grana-object 0.1.1

Next-generation microscopy image visualization and analysis platform
Documentation
use bytemuck::{Pod, Zeroable};

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct MeshVertex {
    position: [f32; 3],
    normal: [f32; 3],
    object: u32,
}

impl MeshVertex {
    pub fn new(position: [f32; 3], normal: [f32; 3], object: u32) -> Self {
        assert!(
            position
                .iter()
                .chain(normal.iter())
                .all(|value| value.is_finite()),
            "a mesh vertex is finite"
        );
        let length_squared = normal.iter().map(|value| value * value).sum::<f32>();
        assert!(
            (length_squared - 1.0).abs() < 1.0e-3,
            "a mesh normal has unit length"
        );
        Self {
            position,
            normal,
            object,
        }
    }

    pub fn position(self) -> [f32; 3] {
        self.position
    }

    pub fn normal(self) -> [f32; 3] {
        self.normal
    }

    pub fn object(self) -> u32 {
        self.object
    }
}

const _: () = assert!(size_of::<MeshVertex>() == 28);

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Mesh {
    vertices: Vec<MeshVertex>,
    indices: Vec<u32>,
}

impl Mesh {
    pub fn new(vertices: Vec<MeshVertex>, indices: Vec<u32>) -> Self {
        assert!(
            indices.len().is_multiple_of(3),
            "a mesh holds whole triangles"
        );
        assert!(
            indices
                .iter()
                .all(|index| (*index as usize) < vertices.len()),
            "every mesh index addresses a vertex"
        );
        Self { vertices, indices }
    }

    pub fn vertices(&self) -> &[MeshVertex] {
        &self.vertices
    }

    pub fn indices(&self) -> &[u32] {
        &self.indices
    }

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

    pub fn triangle_count(&self) -> usize {
        self.indices.len() / 3
    }

    pub fn is_empty(&self) -> bool {
        self.indices.is_empty()
    }

    pub fn triangle(&self, index: usize) -> [MeshVertex; 3] {
        [0, 1, 2].map(|corner| self.vertices[self.indices[index * 3 + corner] as usize])
    }
}