mesh_graph/integrations/
mod.rs1use 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#[derive(Clone, Debug)]
19pub struct VertexIndexBuffers<T = ()> {
20 pub positions: Vec<Vec3>,
22 pub normals: Vec<Vec3>,
24 pub indices: Vec<u32>,
27 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}