axiolid_mesh/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Mesh representations and zero-copy interoperability views.
4//!
5//! N-gons remain [`PolygonMesh`] until explicit triangulation. [`TriMesh`] is
6//! the compact exchange type for render, spatial, and mesh-kernel algorithms.
7
8pub mod adjacency;
9pub mod attribute;
10pub mod audit;
11pub mod component;
12pub mod error;
13pub mod polygon;
14pub mod triangle;
15pub mod view;
16
17pub use adjacency::{EdgeAdjacency, EdgeKey, EdgeUse};
18pub use attribute::{AttributeChannel, AttributeFate, Blend, DropReason};
19pub use audit::{audit_mesh, audit_mesh_scratch_bytes, try_audit_mesh, MeshAuditError, MeshHealth};
20pub use component::{component_count, compose, decompose};
21pub use error::MeshValidationError;
22pub use polygon::{PolygonFace, PolygonMesh};
23pub use triangle::{NormalAttribute, TriMesh};
24pub use view::{MeshView, TriangleMeshView};
25
26#[cfg(test)]
27mod tests {
28    use axiolid_core::Vec3;
29
30    use super::*;
31
32    #[test]
33    fn triangle_iteration_preserves_index_order() {
34        let mesh = TriMesh::new(
35            vec![Vec3::ZERO, Vec3::X, Vec3::Y, Vec3::Z],
36            vec![0, 1, 2, 0, 2, 3],
37        );
38        assert_eq!(mesh.triangles().collect::<Vec<_>>(), [[0, 1, 2], [0, 2, 3]]);
39        assert!(mesh.validate_structure().is_ok());
40    }
41
42    #[test]
43    fn invalid_index_is_a_structured_error() {
44        let mesh = TriMesh::new(vec![Vec3::ZERO], vec![0, 1, 2]);
45        assert!(matches!(
46            mesh.validate_structure(),
47            Err(MeshValidationError::PositionIndexOutOfRange { index: 1, .. })
48        ));
49    }
50}