Skip to main content

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//! [`HalfedgeMesh`] is the editable surface mesh with O(1) adjacency for
8//! algorithms that rewrite connectivity in place.
9
10pub mod adjacency;
11pub mod attribute;
12pub mod audit;
13pub mod component;
14pub mod error;
15pub mod halfedge;
16pub mod polygon;
17mod split;
18pub mod triangle;
19pub mod view;
20
21pub use adjacency::{EdgeAdjacency, EdgeKey, EdgeUse};
22pub use attribute::{AttributeChannel, AttributeFate, Blend, DropReason};
23pub use audit::{
24    audit_mesh, audit_mesh_cycle, audit_mesh_scratch_bytes, try_audit_mesh, try_audit_mesh_cycle,
25    MeshAuditError, MeshCycleHealth, MeshHealth,
26};
27pub use component::{component_count, compose, decompose};
28pub use error::MeshValidationError;
29pub use halfedge::{
30    EdgeId, FaceId, HalfedgeBuildError, HalfedgeEditError, HalfedgeId, HalfedgeInvariantError,
31    HalfedgeMesh, HalfedgeRemap, VertexId,
32};
33pub use polygon::{PolygonFace, PolygonMesh};
34pub use split::split_triangle_at_side_corners;
35pub use triangle::{NormalAttribute, TriMesh};
36pub use view::{MeshView, TriangleMeshView};
37
38#[cfg(test)]
39mod tests {
40    use axiolid_core::Vec3;
41
42    use super::*;
43
44    #[test]
45    fn triangle_iteration_preserves_index_order() {
46        let mesh = TriMesh::new(
47            vec![Vec3::ZERO, Vec3::X, Vec3::Y, Vec3::Z],
48            vec![0, 1, 2, 0, 2, 3],
49        );
50        assert_eq!(mesh.triangles().collect::<Vec<_>>(), [[0, 1, 2], [0, 2, 3]]);
51        assert!(mesh.validate_structure().is_ok());
52    }
53
54    #[test]
55    fn invalid_index_is_a_structured_error() {
56        let mesh = TriMesh::new(vec![Vec3::ZERO], vec![0, 1, 2]);
57        assert!(matches!(
58            mesh.validate_structure(),
59            Err(MeshValidationError::PositionIndexOutOfRange { index: 1, .. })
60        ));
61    }
62}