Skip to main content

mesh_graph/integrations/
mod.rs

1use std::iter::repeat_n;
2
3use glam::Vec3;
4use hashbrown::HashMap;
5use slotmap::SecondaryMap;
6use tracing::{error, instrument};
7
8use crate::{MeshGraph, VertexId};
9
10#[cfg(feature = "bevy")]
11pub mod bevy;
12#[cfg(feature = "gltf")]
13pub mod gltf;
14#[cfg(feature = "manifold")]
15pub mod manifold;
16
17/// Classical indexed mesh representation
18#[derive(Clone, Debug)]
19pub struct VertexIndexBuffers<T = ()> {
20    /// Vertex positions, one per vertex.
21    pub positions: Vec<Vec3>,
22    /// Vertex normals, one per vertex.
23    pub normals: Vec<Vec3>,
24    /// Indices: 3*N where N is the number of triangles. Indices point to
25    /// elements of `positions` and `normals`.
26    pub indices: Vec<u32>,
27    /// Potential custom vertex attribute(s)
28    pub custom_vertex_attribute: Vec<T>,
29}
30
31impl<T> VertexIndexBuffers<T>
32where
33    T: Clone + Default,
34{
35    pub fn with_attr_from_map(mesh_graph: &MeshGraph, attr: &HashMap<VertexId, T>) -> Self {
36        let (positions, normals, indices, vertex_id_to_index) =
37            Self::attrs_from_mesh_graph(mesh_graph);
38
39        let mut custom_vertex_attribute =
40            repeat_n(T::default(), positions.len()).collect::<Vec<T>>();
41
42        for (vertex_id, value) in attr {
43            if let Some(index) = vertex_id_to_index.get(*vertex_id) {
44                custom_vertex_attribute[*index as usize] = value.clone();
45            }
46        }
47
48        Self {
49            positions,
50            normals,
51            indices,
52            custom_vertex_attribute,
53        }
54    }
55
56    fn attrs_from_mesh_graph(
57        mesh_graph: &MeshGraph,
58    ) -> (Vec<Vec3>, Vec<Vec3>, Vec<u32>, SecondaryMap<VertexId, u32>) {
59        let mut vertex_id_to_index = SecondaryMap::default();
60
61        let mut positions = vec![];
62        let mut normals = vec![];
63        let mut indices = vec![];
64
65        for (vertex_id, pos) in &mesh_graph.positions {
66            vertex_id_to_index.insert(vertex_id, positions.len() as u32);
67            positions.push(*pos);
68
69            if let Some(vertex_normals) = mesh_graph.vertex_normals.as_ref() {
70                normals.push(vertex_normals.get(vertex_id).copied().unwrap_or_else(|| {
71                    error!("Normal not found");
72                    Vec3::ZERO
73                }));
74            }
75        }
76
77        'outer: for face in mesh_graph.faces.values() {
78            let mut face_indices = Vec::with_capacity(3);
79
80            for vertex in face.vertices(mesh_graph) {
81                let Some(&index) = vertex_id_to_index.get(vertex) else {
82                    error!("Vertex {vertex:?} not found in mapped vertices");
83                    continue 'outer;
84                };
85                face_indices.push(index);
86            }
87
88            indices.extend(face_indices);
89        }
90
91        (positions, normals, indices, vertex_id_to_index)
92    }
93}
94
95impl From<&MeshGraph> for VertexIndexBuffers {
96    #[instrument(skip(mesh_graph))]
97    fn from(mesh_graph: &MeshGraph) -> VertexIndexBuffers {
98        let (positions, normals, indices, _) = Self::attrs_from_mesh_graph(mesh_graph);
99
100        VertexIndexBuffers {
101            indices,
102            positions,
103            normals,
104            custom_vertex_attribute: vec![],
105        }
106    }
107}
108
109impl From<MeshGraph> for VertexIndexBuffers {
110    fn from(mesh_graph: MeshGraph) -> Self {
111        Self::from(&mesh_graph)
112    }
113}