Skip to main content

oxiphysics_geometry/geodesic/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6/// A single geodesic isoline segment on the mesh.
7#[derive(Debug, Clone)]
8pub struct IsolineSegment {
9    /// Start point of the segment.
10    pub start: [f64; 3],
11    /// End point of the segment.
12    pub end: [f64; 3],
13}
14/// A geodesic Voronoi cell: the set of mesh vertices closest to a given source.
15#[derive(Debug, Clone)]
16pub struct GeoVoronoiCell {
17    /// Index into the sources array.
18    pub source_idx: usize,
19    /// Original source vertex index.
20    pub source_vertex: usize,
21    /// Vertex indices assigned to this cell.
22    pub vertices: Vec<usize>,
23    /// Total surface area of this cell (sum of proportional triangle areas).
24    pub area: f64,
25}
26/// Result of intrinsic Delaunay triangulation.
27#[derive(Debug, Clone)]
28pub struct IntrinsicDelaunay {
29    /// Edge lengths for each face edge: `edge_lengths[fi][k]` is the length of
30    /// edge opposite to local vertex `k` in face `fi`.
31    pub edge_lengths: Vec<[f64; 3]>,
32    /// Face connectivity (same as input but potentially with flipped edges).
33    pub faces: Vec<[usize; 3]>,
34    /// Vertex positions (unchanged from input).
35    pub vertices: Vec<[f64; 3]>,
36}
37/// A simple triangle mesh for geodesic computation.
38#[derive(Debug, Clone)]
39pub struct GeoMesh {
40    /// Vertex positions.
41    pub vertices: Vec<[f64; 3]>,
42    /// Triangle face indices (each entry is \[v0, v1, v2\]).
43    pub faces: Vec<[usize; 3]>,
44}
45impl GeoMesh {
46    /// Create a new geodesic mesh.
47    pub fn new(vertices: Vec<[f64; 3]>, faces: Vec<[usize; 3]>) -> Self {
48        Self { vertices, faces }
49    }
50    /// Number of vertices.
51    pub fn n_vertices(&self) -> usize {
52        self.vertices.len()
53    }
54    /// Number of faces.
55    pub fn n_faces(&self) -> usize {
56        self.faces.len()
57    }
58    /// Build an adjacency list: for each vertex, list all neighbouring vertex
59    /// indices along with the edge length.
60    pub fn build_adjacency(&self) -> Vec<Vec<(usize, f64)>> {
61        let n = self.vertices.len();
62        let mut adj: Vec<Vec<(usize, f64)>> = vec![Vec::new(); n];
63        for face in &self.faces {
64            let [a, b, c] = *face;
65            let lab = dist3(self.vertices[a], self.vertices[b]);
66            let lbc = dist3(self.vertices[b], self.vertices[c]);
67            let lca = dist3(self.vertices[c], self.vertices[a]);
68            adj[a].push((b, lab));
69            adj[b].push((a, lab));
70            adj[b].push((c, lbc));
71            adj[c].push((b, lbc));
72            adj[c].push((a, lca));
73            adj[a].push((c, lca));
74        }
75        adj
76    }
77    /// Compute the area of a triangular face.
78    pub fn face_area(&self, face_idx: usize) -> f64 {
79        let [a, b, c] = self.faces[face_idx];
80        let va = self.vertices[a];
81        let vb = self.vertices[b];
82        let vc = self.vertices[c];
83        let ab = sub3(vb, va);
84        let ac = sub3(vc, va);
85        len3(cross3(ab, ac)) * 0.5
86    }
87    /// Compute the normal of a triangular face (not normalised).
88    pub fn face_normal_raw(&self, face_idx: usize) -> [f64; 3] {
89        let [a, b, c] = self.faces[face_idx];
90        let ab = sub3(self.vertices[b], self.vertices[a]);
91        let ac = sub3(self.vertices[c], self.vertices[a]);
92        cross3(ab, ac)
93    }
94}
95/// Result of the heat method geodesic computation.
96pub struct HeatGeodesicResult {
97    /// Geodesic distances from the source vertex to all vertices.
98    pub distances: Vec<f64>,
99    /// Normalised heat gradient (per face, not per vertex) for debugging.
100    pub gradient: Vec<[f64; 3]>,
101}
102/// Entry for the Dijkstra priority queue.
103#[derive(PartialEq)]
104pub(super) struct DijkEntry {
105    pub(super) dist: f64,
106    pub(super) vertex: usize,
107}