Skip to main content

runmat_geometry_core/
lib.rs

1//! Canonical geometry domain model for RunMat.
2
3pub mod diagnostics;
4pub mod model;
5pub mod selection;
6
7pub use diagnostics::{Diagnostic, DiagnosticSeverity};
8pub use model::{
9    AssemblyNode, CadColorEvidence, CadLabelRef, CadPhysicalMaterialEvidence, CadRegionOwnership,
10    CadSemanticKind, EntityIdRange, GeometryAsset, GeometrySource, MaterialEvidence,
11    MaterialEvidenceConfidence, MeshDescriptor, MeshKind, Region, RegionEntityMapping,
12    SourceGeometry, SourceGeometryKind, SurfaceMesh, TessellationProfile, UnitSystem,
13};
14pub use selection::{EntityKind, EntityRef};
15
16#[cfg(test)]
17mod tests {
18    use super::*;
19
20    fn sample_asset() -> GeometryAsset {
21        GeometryAsset {
22            geometry_id: "geo_test".to_string(),
23            source: GeometrySource {
24                path: "/models/part.stl".to_string(),
25                sha256: "abc123".to_string(),
26                importer_version: "stl/v1".to_string(),
27            },
28            source_geometry: SourceGeometry {
29                kind: SourceGeometryKind::Mesh,
30                assembly: None,
31                material_evidence: vec![],
32            },
33            tessellation_profile: TessellationProfile::default(),
34            units: UnitSystem::Meter,
35            revision: 1,
36            meshes: vec![MeshDescriptor {
37                mesh_id: "mesh_1".to_string(),
38                kind: MeshKind::Surface,
39                vertex_count: 3,
40                element_count: 1,
41            }],
42            surface_meshes: vec![SurfaceMesh::new(
43                "mesh_1",
44                vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
45                vec![[0, 1, 2]],
46            )],
47            regions: vec![Region {
48                region_id: "region_a".to_string(),
49                name: "body".to_string(),
50                tag: None,
51                cad_ownership: None,
52            }],
53            region_entity_mappings: vec![RegionEntityMapping::all_faces("region_a", "mesh_1", 1)],
54            diagnostics: vec![],
55        }
56    }
57
58    #[test]
59    fn entity_identity_stable_within_revision() {
60        let first = EntityRef {
61            geometry_id: "geo_test".to_string(),
62            geometry_revision: 1,
63            mesh_id: "mesh_1".to_string(),
64            entity_kind: EntityKind::Face,
65            entity_id: 42,
66        };
67        let second = EntityRef { ..first.clone() };
68        assert_eq!(first, second);
69    }
70
71    #[test]
72    fn geometry_asset_round_trips_via_json() {
73        let asset = sample_asset();
74        let json = serde_json::to_string(&asset).expect("serialize");
75        let decoded: GeometryAsset = serde_json::from_str(&json).expect("deserialize");
76        assert_eq!(decoded, asset);
77    }
78
79    #[test]
80    fn unit_metadata_must_be_present() {
81        let mut asset = sample_asset();
82        asset.units = UnitSystem::Unspecified;
83        let error = asset
84            .validate()
85            .expect_err("expected unspecified units to fail");
86        assert_eq!(error, "geometry units must be specified");
87    }
88}