axiolid_mesh/
view.rs

1//! Borrowed mesh interoperability seam.
2
3use axiolid_core::Point3;
4
5use crate::TriMesh;
6
7/// Read-only triangle mesh view.
8///
9/// A foreign kernel can implement this for its native mesh and call algorithms
10/// without first adopting Axiolid's owned container.
11pub trait MeshView {
12    /// Position buffer.
13    fn positions(&self) -> &[Point3];
14    /// Triangle corner index buffer.
15    fn indices(&self) -> &[u32];
16}
17
18impl MeshView for TriMesh {
19    fn positions(&self) -> &[Point3] {
20        &self.positions
21    }
22
23    fn indices(&self) -> &[u32] {
24        &self.indices
25    }
26}
27
28/// Read-only triangle mesh with arbitrary caller index storage.
29///
30/// This is the validation seam for foreign meshes. Implementations must return
31/// a finite, stable position for every `index < position_count()`; triangle
32/// indices may be invalid and are reported by validation rather than trusted.
33pub trait TriangleMeshView {
34    /// Number of addressable positions.
35    fn position_count(&self) -> usize;
36    /// Position at a valid index.
37    fn position(&self, index: usize) -> Point3;
38    /// Number of complete triangle records.
39    fn triangle_count(&self) -> usize;
40    /// Three caller-provided position indices for one triangle.
41    fn triangle(&self, index: usize) -> [u64; 3];
42}
43
44impl TriangleMeshView for TriMesh {
45    fn position_count(&self) -> usize {
46        self.positions.len()
47    }
48
49    fn position(&self, index: usize) -> Point3 {
50        self.positions[index]
51    }
52
53    fn triangle_count(&self) -> usize {
54        self.triangle_count()
55    }
56
57    fn triangle(&self, index: usize) -> [u64; 3] {
58        let triangle: [u32; 3] = self.indices[index * 3..index * 3 + 3]
59            .try_into()
60            .expect("triangle_count only exposes complete triples");
61        triangle.map(u64::from)
62    }
63}