Skip to main content

mesh_graph/
utils.rs

1#[cfg(feature = "rerun")]
2use std::borrow::Borrow;
3
4#[cfg(any(test, feature = "rerun"))]
5use glam::Vec3;
6#[cfg(feature = "rerun")]
7use glam::{Quat, Vec2};
8
9#[cfg(feature = "rerun")]
10pub fn vec3_array(v: impl Borrow<Vec3>) -> [f32; 3] {
11    [v.borrow().x, v.borrow().y, v.borrow().z]
12}
13
14#[cfg(feature = "rerun")]
15pub fn vec2_array(v: impl Borrow<Vec2>) -> [f32; 3] {
16    [v.borrow().x, v.borrow().y, 0.0]
17}
18
19#[cfg(feature = "rerun")]
20pub fn quat_array(q: impl Borrow<Quat>) -> [f32; 4] {
21    [q.borrow().x, q.borrow().y, q.borrow().z, q.borrow().w]
22}
23
24#[macro_export]
25macro_rules! error_none {
26    ($msg:literal $(, $args:expr)*) => {
27        || {
28            tracing::error!($msg $(, $args)*);
29            None
30        }
31    };
32}
33
34macro_rules! unwrap_or_return {
35    ($code:expr, $error:expr, $ret:expr) => {
36        match $code {
37            Some(value) => value,
38            None => {
39                tracing::error!($error);
40                return $ret;
41            }
42        }
43    };
44    ($code:expr, $error:expr) => {
45        match $code {
46            Some(value) => value,
47            None => {
48                tracing::error!($error);
49                return;
50            }
51        }
52    };
53}
54
55#[cfg(test)]
56pub(crate) fn get_tracing_subscriber() {
57    if let Err(e) = tracing_subscriber::fmt()
58        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
59        .with_line_number(true)
60        .pretty()
61        .try_init()
62    {
63        tracing::warn!("Tracing subscriber already initialized: {}", e);
64    }
65}
66
67pub(crate) use unwrap_or_return;
68
69#[cfg(test)]
70fn extend_outer_corners(
71    meshgraph: &mut crate::MeshGraph,
72    new_vertex_ids: &mut Vec<crate::VertexId>,
73    outer_vertex_ids: &[crate::VertexId],
74    scalar: f32,
75    steps: usize,
76) {
77    if steps == 0 {
78        return;
79    }
80
81    let mut corner_vertex_ids = Vec::with_capacity(outer_vertex_ids.len());
82
83    // mesh star corners to make the mesh larger
84    for i in 0..outer_vertex_ids.len() {
85        let point_1 = meshgraph.positions.get(outer_vertex_ids[i]).unwrap();
86        let point_2 = meshgraph
87            .positions
88            .get(outer_vertex_ids[(i + 1) % outer_vertex_ids.len()])
89            .unwrap();
90
91        let mut point_3 = point_1
92            + ((point_2 - point_1) * 0.5)
93            + (point_1 + point_2).normalize() * scalar / steps as f32;
94
95        point_3.z = 0.0; // allow expansion only in x-y-plane
96
97        let vertex_id = meshgraph.add_vertex(point_3);
98        corner_vertex_ids.push(vertex_id);
99    }
100
101    for cv_i in 0..corner_vertex_ids.len() {
102        let corner_vertex_id = corner_vertex_ids[cv_i];
103        let vertex_id = outer_vertex_ids[cv_i];
104        let next_vertext_id = outer_vertex_ids[(cv_i + 1) % outer_vertex_ids.len()];
105        let halfedge_vertex_to_corner_id = meshgraph
106            .add_or_get_edge(vertex_id, corner_vertex_id)
107            .unwrap()
108            .start_to_end_he_id;
109        let halfedge_vertex_to_next_vertex_id = meshgraph
110            .add_or_get_edge(vertex_id, next_vertext_id)
111            .unwrap()
112            .start_to_end_he_id;
113
114        meshgraph
115            .add_face_from_halfedges(
116                halfedge_vertex_to_corner_id,
117                halfedge_vertex_to_next_vertex_id,
118            )
119            .unwrap();
120
121        let halfedge_corner_to_next_vertex_id = meshgraph
122            .add_or_get_edge(corner_vertex_id, next_vertext_id)
123            .unwrap()
124            .start_to_end_he_id;
125
126        let halfedge_next_vertex_to_next_corner_vertex_id = meshgraph
127            .add_or_get_edge(
128                next_vertext_id,
129                corner_vertex_ids[(cv_i + 1) % corner_vertex_ids.len()],
130            )
131            .unwrap()
132            .start_to_end_he_id;
133
134        meshgraph
135            .add_face_from_halfedges(
136                halfedge_corner_to_next_vertex_id,
137                halfedge_next_vertex_to_next_corner_vertex_id,
138            )
139            .unwrap();
140    }
141
142    extend_outer_corners(
143        meshgraph,
144        new_vertex_ids,
145        &corner_vertex_ids,
146        scalar,
147        steps - 1,
148    );
149
150    new_vertex_ids.extend(corner_vertex_ids);
151}
152
153/// Extend a mesh graph with new points.
154/// Expects the first point to be the geometrical center of the new vertices.
155/// Mesh then extends further by `steps` iterations from the center outward.
156#[cfg(test)]
157pub(crate) fn extend_with(
158    meshgraph: &mut crate::MeshGraph,
159    center_and_points: &[Vec3],
160    matrix: glam::Mat4,
161    scalar: f32,
162    steps: usize,
163) -> Vec<crate::VertexId> {
164    let (center, points) = center_and_points.split_first().unwrap();
165    let center_id = meshgraph.add_vertex(*center);
166
167    let mut vertex_ids = Vec::new();
168    let mut halfedge_ids = Vec::new();
169
170    for point in points {
171        let vertex_id = meshgraph.add_vertex(*point);
172        let halfedge_id = meshgraph
173            .add_or_get_edge(center_id, vertex_id)
174            .unwrap()
175            .start_to_end_he_id;
176
177        vertex_ids.push(vertex_id);
178        halfedge_ids.push(halfedge_id);
179    }
180
181    for i in 0..points.len() {
182        meshgraph
183            .add_face_from_halfedges(halfedge_ids[i], halfedge_ids[(i + 1) % points.len()])
184            .unwrap();
185    }
186
187    let mut new_vertex_ids = vec![center_id];
188    new_vertex_ids.extend(vertex_ids.clone());
189    extend_outer_corners(meshgraph, &mut new_vertex_ids, &vertex_ids, scalar, steps);
190
191    for new_vertex_id in new_vertex_ids.iter() {
192        if let Some(pos) = meshgraph.positions.get_mut(*new_vertex_id) {
193            *pos = matrix.transform_point3(*pos);
194        };
195    }
196
197    new_vertex_ids
198}