mesh_graph/ops/
subdivide.rs1use hashbrown::HashSet;
2use tracing::instrument;
3
4use crate::{
5 HalfedgeId, MeshGraph, Selection, SelectionOps, VertexId, error_none, utils::unwrap_or_return,
6};
7
8#[cfg(feature = "rerun")]
9use crate::utils::vec3_array;
10
11impl MeshGraph {
12 #[instrument(skip(self))]
18 pub fn subdivide_until_edges_below_max_length(
19 &mut self,
20 max_length_squared: f32,
21 marked_halfedge_ids: &mut HashSet<HalfedgeId>,
22 marked_vertex_ids: &mut HashSet<VertexId>,
23 ) {
24 let mut halfedges_to_subdivide = self.halfedges_map(|len_sqr| len_sqr > max_length_squared);
25
26 while !halfedges_to_subdivide.is_empty() {
27 let mut max_len = 0.0;
28 let mut max_he_id = HalfedgeId::default();
29
30 #[cfg(feature = "rerun")]
31 self.log_hes_rerun(
32 "subdivide/selection",
33 &halfedges_to_subdivide
34 .iter()
35 .map(|(he, _)| *he)
36 .collect::<Vec<_>>(),
37 );
38
39 for (&he, &len) in &halfedges_to_subdivide {
40 if len > max_len {
41 max_len = len;
42 max_he_id = he;
43 }
44 }
45
46 halfedges_to_subdivide.remove(&max_he_id);
47
48 let mut affected_faces = Selection::default();
49
50 let max_he = self.halfedges[max_he_id];
52 if let Some(face_id) = max_he.face {
53 affected_faces.insert(face_id);
54 }
55
56 if let Some(twin_id) = max_he.twin.or_else(error_none!("Twin missing"))
57 && let Some(twin_he) = self
58 .halfedges
59 .get(twin_id)
60 .or_else(error_none!("Halfedge not found"))
61 && let Some(twin_face_id) = twin_he.face
62 {
63 affected_faces.insert(twin_face_id);
64 }
65
66 let subdivide_edge_result =
67 unwrap_or_return!(self.subdivide_edge(max_he_id), "Couldn't subdivide edge");
68
69 if marked_halfedge_ids.contains(&max_he_id) {
70 marked_halfedge_ids.extend(subdivide_edge_result.added_halfedges.iter().copied());
71 marked_vertex_ids.insert(subdivide_edge_result.added_vertex);
72 }
73
74 for new_he_id in subdivide_edge_result.added_halfedges {
89 let new_he = self.halfedges[new_he_id];
91
92 if let Some(face_id) = new_he.face {
93 affected_faces.insert(face_id);
94 }
95
96 let new_twin_id = unwrap_or_return!(new_he.twin, "New twin missing");
97 let new_twin =
98 unwrap_or_return!(self.halfedges.get(new_twin_id), "New twin not found");
99
100 if let Some(face_id) = new_twin.face {
101 affected_faces.insert(face_id);
102 #[cfg(feature = "rerun")]
103 self.log_face_rerun("subdivide/selected_new", face_id);
104 }
105 }
106
107 let mut new_hes_to_check = HashSet::new();
108
109 for he_id in affected_faces.resolve_to_halfedges(self) {
110 let he = unwrap_or_return!(self.halfedges.get(he_id), "Halfedge not found");
111 let twin_id = unwrap_or_return!(he.twin, "Twin missing");
112
113 new_hes_to_check.insert(he_id.min(twin_id));
114 }
115
116 for he_id in new_hes_to_check {
117 let he = self.halfedges[he_id]; let len_sqr = he.length_squared(self);
120
121 if len_sqr > max_length_squared {
122 #[cfg(feature = "rerun")]
123 self.log_he_rerun("/subdivide/new_edge", he_id);
124
125 halfedges_to_subdivide.insert(he_id, len_sqr);
126 }
127 }
128 }
129
130 #[cfg(feature = "rerun")]
131 self.log_rerun();
132 }
133
134 #[instrument(skip(self))]
144 pub fn subdivide_edge(&mut self, halfedge_id: HalfedgeId) -> Option<SubdivideEdge> {
145 let mut added_halfedges = Vec::with_capacity(3);
146
147 let he = self
148 .halfedges
149 .get(halfedge_id)
150 .or_else(error_none!("Halfedge not found"))?;
151 let twin_id = he.twin.or_else(error_none!("Twin halfedge not found"))?;
152
153 let start_v = he
154 .start_vertex(self)
155 .or_else(error_none!("Start vertex not found"))?;
156 let end_v = he.end_vertex;
157
158 let start_pos = self.positions[start_v];
159 let end_pos = self.positions[end_v];
160
161 let center_pos = (start_pos + end_pos) * 0.5;
162
163 #[cfg(feature = "rerun")]
164 {
165 crate::RR
166 .log(
167 "meshgraph/subdivide/edge",
168 &rerun::Arrows3D::from_vectors([vec3_array(end_pos - start_pos)])
169 .with_origins([vec3_array(start_pos)]),
170 )
171 .unwrap();
172
173 crate::RR
174 .log(
175 "meshgraph/subdivide/center",
176 &rerun::Points3D::new([vec3_array(center_pos)]),
177 )
178 .unwrap();
179 }
180
181 let center_v = self.add_vertex(center_pos);
182 if let Some(normals) = &mut self.vertex_normals {
183 let start_normal = normals
184 .get(start_v)
185 .or_else(error_none!("Start normal not found"))?;
186 let end_normal = normals
187 .get(end_v)
188 .or_else(error_none!("End normal not found"))?;
189 normals.insert(center_v, (start_normal + end_normal).normalize());
190 }
191
192 let new_he = self.add_halfedge(center_v, end_v);
193 self.vertices[center_v].outgoing_halfedge = Some(new_he);
195
196 added_halfedges.push(new_he);
197
198 if let Some(new_face_he) = self.subdivide_face(halfedge_id, new_he, center_v) {
199 added_halfedges.push(new_face_he);
200 }
201
202 let new_twin = self.add_halfedge(center_v, start_v);
203
204 if let Some(new_face_he) = self.subdivide_face(twin_id, new_twin, center_v) {
205 added_halfedges.push(new_face_he);
206 }
207
208 self.halfedges[new_he].twin = Some(twin_id);
210 self.halfedges
211 .get_mut(twin_id)
212 .or_else(error_none!("Twin halfedge not found"))?
213 .twin = Some(new_he);
214
215 self.halfedges[halfedge_id].twin = Some(new_twin);
217 self.halfedges[new_twin].twin = Some(halfedge_id);
219
220 Some(SubdivideEdge {
224 added_halfedges,
225 added_vertex: center_v,
226 })
227 }
228
229 #[instrument(skip(self))]
231 fn subdivide_face(
232 &mut self,
233 existing_halfedge_id: HalfedgeId,
234 new_halfedge_id: HalfedgeId,
235 center_v: VertexId,
236 ) -> Option<HalfedgeId> {
237 let he = self
238 .halfedges
239 .get(existing_halfedge_id)
240 .or_else(error_none!("Halfedge not found"))?;
241
242 let face_id = he.face?;
243 self.faces
244 .get_mut(face_id)
245 .or_else(error_none!("Facee not found"))?
246 .halfedge = existing_halfedge_id;
247
248 let next_he = self.halfedges[existing_halfedge_id]
250 .next
251 .or_else(error_none!("Next halfedge missing"))?;
252 let last_he = self
253 .halfedges
254 .get(next_he)
255 .or_else(error_none!("Next halfedge not found"))?
256 .next
257 .or_else(error_none!("Last halfedge not found"))?;
258
259 let new_he = self.add_halfedge(center_v, self.halfedges[next_he].end_vertex);
261
262 self.halfedges[existing_halfedge_id].next = Some(new_he);
263 self.halfedges[new_he].next = Some(last_he);
264 self.halfedges[new_he].face = Some(face_id);
265
266 let new_twin = self.add_halfedge(self.halfedges[next_he].end_vertex, center_v);
267
268 let new_face_id = self.add_face(new_halfedge_id, next_he, new_twin);
270
271 self.halfedges[new_twin].twin = Some(new_he);
272 self.halfedges[new_he].twin = Some(new_twin);
273
274 self.halfedges[existing_halfedge_id].end_vertex = center_v;
275
276 let face = self.faces[face_id];
278 let new_face = self.faces[new_face_id];
280 self.bvh
281 .insert_or_update_partially(face.aabb(self), face.index, 0.0);
282 self.bvh
283 .insert_or_update_partially(new_face.aabb(self), new_face.index, 0.0);
284
285 #[cfg(feature = "rerun")]
286 {
287 self.log_he_rerun("subdivide/new_he", new_he);
288 self.log_he_rerun("subdivide/new_twin", new_twin);
289 }
290
291 Some(new_he)
292 }
293}
294
295pub struct SubdivideEdge {
296 added_halfedges: Vec<HalfedgeId>,
298 added_vertex: VertexId,
300}
301
302#[cfg(test)]
303mod tests {}