use crate::KernelError;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Mesh {
pub vertex_count: u32,
pub face_vertex_counts: Vec<u32>,
pub face_vertex_indices: Vec<u32>,
pub edge_vertices: Vec<[u32; 2]>,
pub edge_creases: Vec<f32>,
pub vertex_corners: Vec<f32>,
}
impl Mesh {
pub fn validate(&self) -> Result<(), KernelError> {
let corner_count: usize = self.face_vertex_counts.iter().map(|v| *v as usize).sum();
(corner_count == self.face_vertex_indices.len())
.then_some(())
.ok_or(KernelError::InvalidTopology(
"face corner count does not match index buffer length",
))?;
(self.edge_creases.len() == self.edge_vertices.len())
.then_some(())
.ok_or(KernelError::InvalidTopology(
"edge crease count does not match edge buffer length",
))?;
(self.vertex_corners.len() == self.vertex_count as usize)
.then_some(())
.ok_or(KernelError::InvalidTopology(
"vertex corner count does not match vertex count",
))?;
self.face_vertex_indices
.iter()
.all(|&idx| idx < self.vertex_count)
.then_some(())
.ok_or(KernelError::InvalidTopology("face index out of bounds"))?;
self.edge_vertices
.iter()
.flat_map(|e| e.iter())
.all(|&idx| idx < self.vertex_count)
.then_some(())
.ok_or(KernelError::InvalidTopology("edge endpoint out of bounds"))
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct Adjacency {
pub face_edges: Vec<u32>,
pub edge_faces: Vec<[u32; 2]>,
pub vertex_edge_offsets: Vec<u32>,
pub vertex_edges: Vec<u32>,
pub vertex_face_offsets: Vec<u32>,
pub vertex_faces: Vec<u32>,
pub edge_is_boundary: Vec<bool>,
pub vertex_is_boundary: Vec<bool>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FaceVaryingChannel {
pub indices: Vec<u32>,
pub value_count: u32,
}