runmat_geometry_ops/
lib.rs1pub mod bounds;
4pub mod quality;
5pub mod queries;
6pub mod stats;
7
8pub use bounds::{compute_axis_aligned_bounds, AxisAlignedBounds};
9pub use quality::{evaluate_quality, QualityReport};
10pub use queries::{find_region, QueryError};
11pub use stats::{compute_stats, GeometryStats};
12
13#[cfg(test)]
14mod tests {
15 use runmat_geometry_core::{
16 GeometryAsset, GeometrySource, MeshDescriptor, MeshKind, SourceGeometry,
17 SourceGeometryKind, SurfaceMesh, TessellationProfile, UnitSystem,
18 };
19
20 use crate::{compute_axis_aligned_bounds, compute_stats, evaluate_quality};
21
22 fn sample() -> GeometryAsset {
23 GeometryAsset {
24 geometry_id: "geo".to_string(),
25 source: GeometrySource {
26 path: "/x.stl".to_string(),
27 sha256: "hash".to_string(),
28 importer_version: "stl/v1".to_string(),
29 },
30 source_geometry: SourceGeometry {
31 kind: SourceGeometryKind::Mesh,
32 assembly: None,
33 material_evidence: vec![],
34 },
35 tessellation_profile: TessellationProfile::default(),
36 units: UnitSystem::Meter,
37 revision: 1,
38 meshes: vec![MeshDescriptor {
39 mesh_id: "mesh".to_string(),
40 kind: MeshKind::Surface,
41 vertex_count: 3,
42 element_count: 1,
43 }],
44 surface_meshes: vec![SurfaceMesh::new(
45 "mesh",
46 vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
47 vec![[0, 1, 2]],
48 )],
49 regions: vec![],
50 region_entity_mappings: vec![],
51 diagnostics: vec![],
52 }
53 }
54
55 #[test]
56 fn stats_are_computed() {
57 let stats = compute_stats(&sample());
58 assert_eq!(stats.mesh_count, 1);
59 assert_eq!(stats.total_vertices, 3);
60 assert_eq!(stats.total_elements, 1);
61 }
62
63 #[test]
64 fn bounds_are_deterministic() {
65 let bounds = compute_axis_aligned_bounds(&sample());
66 assert_eq!(bounds.min, [0.0, 0.0, 0.0]);
67 assert_eq!(bounds.max, [1.0, 1.0, 0.0]);
68 }
69
70 #[test]
71 fn quality_reports_units_warning_when_unspecified() {
72 let mut asset = sample();
73 asset.units = UnitSystem::Unspecified;
74 let report = evaluate_quality(&asset);
75 assert!(report
76 .warnings
77 .iter()
78 .any(|message| message.contains("units")));
79 }
80}