1#![forbid(unsafe_code)]
2
3pub 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}