1use glam::Vec3;
2use tracing::{error, instrument};
3
4use crate::{Face, FaceId, HalfedgeId, MeshGraph, VertexId, error_none};
5
6impl MeshGraph {
7 #[instrument(skip(self))]
8 pub fn add_face_from_positions(&mut self, a: Vec3, b: Vec3, c: Vec3) -> AddFace {
9 let a_id = self.add_vertex(a);
10 let b_id = self.add_vertex(b);
11 let c_id = self.add_vertex(c);
12
13 let inserted_a = self.add_or_get_edge(a_id, b_id).unwrap();
15 let inserted_b = self.add_or_get_edge(b_id, c_id).unwrap();
16 let inserted_c = self.add_or_get_edge(c_id, a_id).unwrap();
17
18 let face_id = self.add_face(
19 inserted_a.start_to_end_he_id,
20 inserted_b.start_to_end_he_id,
21 inserted_c.start_to_end_he_id,
22 );
23
24 let mut halfedge_ids = inserted_a.created_he_ids();
25 halfedge_ids.extend(inserted_b.created_he_ids());
26 halfedge_ids.extend(inserted_c.created_he_ids());
27
28 AddFace {
29 face_id,
30 halfedge_ids,
31 vertex_ids: vec![a_id, b_id, c_id],
32 }
33 }
34
35 #[instrument(skip(self))]
37 pub fn add_face_from_halfedge_and_position(
38 &mut self,
39 he_id: HalfedgeId,
40 opposite_vertex_pos: Vec3,
41 ) -> Option<AddFace> {
42 let vertex_id = self.add_vertex(opposite_vertex_pos);
43 self.add_face_from_halfedge_and_vertex(he_id, vertex_id)
44 }
45
46 #[instrument(skip(self))]
48 pub fn add_face_from_halfedge_and_vertex(
49 &mut self,
50 he_id: HalfedgeId,
51 vertex_id: VertexId,
52 ) -> Option<AddFace> {
53 let he_a_id = self.boundary_he(he_id)?;
54
55 let he_a = self.halfedges[he_a_id];
56 let start_vertex_id_he_a = he_a.start_vertex(self)?;
57 let end_vertex_id_he_a = he_a.end_vertex;
58
59 let inserted_b = self.add_or_get_edge(end_vertex_id_he_a, vertex_id)?;
60 let inserted_c = self.add_or_get_edge(vertex_id, start_vertex_id_he_a)?;
61
62 let face_id = self.add_face(
63 he_a_id,
64 inserted_b.start_to_end_he_id,
65 inserted_c.start_to_end_he_id,
66 );
67
68 let mut halfedge_ids = inserted_b.created_he_ids();
69 halfedge_ids.extend(inserted_c.created_he_ids());
70
71 Some(AddFace {
72 face_id,
73 halfedge_ids,
74 vertex_ids: vec![],
75 })
76 }
77
78 #[instrument(skip(self))]
80 pub fn add_face_from_vertices(
81 &mut self,
82 v_id1: VertexId,
83 v_id2: VertexId,
84 v_id3: VertexId,
85 ) -> Option<AddFace> {
86 let inserted_a = self.add_or_get_edge(v_id1, v_id2)?;
87 let inserted_b = self.add_or_get_edge(v_id2, v_id3)?;
88 let inserted_c = self.add_or_get_edge(v_id3, v_id1)?;
89
90 let face_id = self.add_face(
91 inserted_a.start_to_end_he_id,
92 inserted_b.start_to_end_he_id,
93 inserted_c.start_to_end_he_id,
94 );
95
96 let mut halfedge_ids = inserted_a.created_he_ids();
97 halfedge_ids.extend(inserted_b.created_he_ids());
98 halfedge_ids.extend(inserted_c.created_he_ids());
99
100 Some(AddFace {
101 face_id,
102 halfedge_ids,
103 vertex_ids: vec![],
104 })
105 }
106
107 #[instrument(skip(self))]
109 pub fn add_face_from_halfedges(
110 &mut self,
111 he_id1: HalfedgeId,
112 he_id2: HalfedgeId,
113 ) -> Option<AddFace> {
114 let he_id1 = self
115 .boundary_he(he_id1)
116 .or_else(error_none!("Boundary Halfedge 1 {he_id1:?} not found"))?;
117 let he_id2 = self
118 .boundary_he(he_id2)
119 .or_else(error_none!("Boundary Halfedge 2 {he_id2:?} not found"))?;
120
121 let he1 = *self
122 .halfedges
123 .get(he_id1)
124 .or_else(error_none!("Halfedge 1 not found"))?;
125 let he2 = *self
126 .halfedges
127 .get(he_id2)
128 .or_else(error_none!("Halfedge 2 not found"))?;
129
130 let he1_start_vertex = he1
131 .start_vertex(self)
132 .or_else(error_none!("Start vertex should be available"))?;
133
134 let he2_start_vertex = he2
135 .start_vertex(self)
136 .or_else(error_none!("Start vertex should be available"))?;
137
138 if he1_start_vertex == he2.end_vertex {
139 let inserted = self.add_or_get_boundary_edge(he1.end_vertex, he2_start_vertex)?;
140
141 let face_id = self.add_face(inserted.start_to_end_he_id, he_id2, he_id1);
142
143 Some(AddFace {
144 face_id,
145 halfedge_ids: inserted.created_he_ids(),
146 vertex_ids: vec![],
147 })
148 } else if he1_start_vertex == he2_start_vertex {
149 let inserted = self.add_or_get_boundary_edge(he1.end_vertex, he2.end_vertex)?;
150
151 let face_id = self.add_face(
152 inserted.start_to_end_he_id,
153 he2.twin.or_else(error_none!("Twin not set"))?,
154 he_id1,
155 );
156
157 Some(AddFace {
158 face_id,
159 halfedge_ids: inserted.created_he_ids(),
160 vertex_ids: vec![],
161 })
162 } else if he1.end_vertex == he2.end_vertex {
163 let inserted = self.add_or_get_boundary_edge(he2_start_vertex, he1_start_vertex)?;
164
165 let face_id = self.add_face(
166 inserted.start_to_end_he_id,
167 he_id1,
168 he2.twin.or_else(error_none!("Twin not set"))?,
169 );
170
171 Some(AddFace {
172 face_id,
173 halfedge_ids: inserted.created_he_ids(),
174 vertex_ids: vec![],
175 })
176 } else {
177 let inserted = self.add_or_get_boundary_edge(he2.end_vertex, he1_start_vertex)?;
178
179 let face_id = self.add_face(inserted.start_to_end_he_id, he_id1, he_id2);
180
181 Some(AddFace {
182 face_id,
183 halfedge_ids: inserted.created_he_ids(),
184 vertex_ids: vec![],
185 })
186 }
187 }
188
189 #[instrument(skip(self))]
192 pub fn add_face(
193 &mut self,
194 he1_id: HalfedgeId,
195 he2_id: HalfedgeId,
196 he3_id: HalfedgeId,
197 ) -> FaceId {
198 let face_id = self.faces.insert_with_key(|id| Face {
199 halfedge: he1_id,
200 index: self.next_index,
201 id,
202 });
203
204 self.index_to_face_id.insert(self.next_index, face_id);
205
206 self.next_index += 1;
207
208 for (he_id, next_he_id) in [(he1_id, he2_id), (he2_id, he3_id), (he3_id, he1_id)] {
209 if let Some(halfedge) = self.halfedges.get_mut(he_id) {
210 halfedge.face = Some(face_id);
211 halfedge.next = Some(next_he_id);
212 } else {
213 error!("Halfedge not found");
214 }
215 }
216
217 let face = self.faces[face_id]; self.bvh
219 .insert_or_update_partially(face.aabb(self), face.index, 0.0);
220
221 face_id
222 }
223}
224
225pub struct AddFace {
227 pub face_id: FaceId,
229 pub halfedge_ids: Vec<HalfedgeId>,
231 pub vertex_ids: Vec<VertexId>,
233}
234
235#[cfg(test)]
236mod test {
237 use super::*;
238
239 fn add_face(mesh_graph: &mut MeshGraph) -> FaceId {
240 mesh_graph
241 .add_face_from_positions(
242 Vec3::new(0.0, 0.0, 0.0),
243 Vec3::new(1.0, 0.0, 0.0),
244 Vec3::new(0.0, 1.0, 0.0),
245 )
246 .face_id
247 }
248
249 fn add_face_to_edge(
250 mesh_graph: &mut MeshGraph,
251 face_id: FaceId,
252 pos: Vec3,
253 use_twin: bool,
254 ) -> Option<FaceId> {
255 let mut associated_he_id = mesh_graph.faces[face_id]
256 .halfedges(mesh_graph)
257 .nth(1)
258 .unwrap();
259
260 if use_twin {
261 associated_he_id = mesh_graph.halfedges[associated_he_id].twin.unwrap();
262 }
263
264 mesh_graph
265 .add_face_from_halfedge_and_position(associated_he_id, pos)
266 .map(|f| f.face_id)
267 }
268
269 fn fill_face(
270 mesh_graph: &mut MeshGraph,
271 face_id_1: FaceId,
272 face_id_2: FaceId,
273 use_twin: bool,
274 ) -> Option<FaceId> {
275 let mut he_id_1 = mesh_graph.faces[face_id_1]
276 .halfedges(mesh_graph)
277 .next()
278 .unwrap();
279
280 let mut he_id_2 = mesh_graph.faces[face_id_2]
281 .halfedges(mesh_graph)
282 .nth(1)
283 .unwrap();
284
285 if use_twin {
286 he_id_1 = mesh_graph.halfedges[he_id_1].twin.unwrap();
287 he_id_2 = mesh_graph.halfedges[he_id_2].twin.unwrap();
288 }
289
290 mesh_graph
291 .add_face_from_halfedges(he_id_1, he_id_2)
292 .map(|f| f.face_id)
293 }
294
295 macro_rules! init_fill_face {
296 ($f1:ident, $f2:ident, $f3:ident, $mg:ident) => {
297 let $f1 = add_face(&mut $mg);
298
299 let $f2 = add_face_to_edge(&mut $mg, $f1, Vec3::new(1.0, 1.0, 0.0), false);
300 let $f3 = add_face_to_edge(&mut $mg, $f2.unwrap(), Vec3::new(0.5, 0.5, 1.0), false);
301 };
302 }
303
304 macro_rules! log_faces_rerun {
305 ($mg:ident, $($face:expr),*) => {
306 #[cfg(feature = "rerun")]
307 {
308 $(
309 $mg.log_face_rerun(&format!("{:?}", $face), $face);
310 )*
311 }
312 };
313 }
314
315 fn test_vertices(mesh_graph: &MeshGraph, face: FaceId) {
316 let mut vertices = mesh_graph.faces[face].vertices(mesh_graph);
317
318 let vertex = vertices.next();
319 assert!(vertex.is_some());
320 assert!(
321 mesh_graph.vertices[vertex.unwrap()]
322 .outgoing_halfedge
323 .is_some()
324 );
325
326 let vertex = vertices.next();
327 assert!(vertex.is_some());
328 assert!(
329 mesh_graph.vertices[vertex.unwrap()]
330 .outgoing_halfedge
331 .is_some()
332 );
333
334 let vertex = vertices.next();
335 assert!(vertex.is_some());
336 assert!(
337 mesh_graph.vertices[vertex.unwrap()]
338 .outgoing_halfedge
339 .is_some()
340 );
341
342 assert!(vertices.next().is_none());
343 }
344
345 fn test_halfedges(mesh_graph: &MeshGraph, face: FaceId) {
346 let mut halfedges = mesh_graph.faces[face].halfedges(mesh_graph);
347
348 assert!(halfedges.next().is_some());
349 assert!(halfedges.next().is_some());
350 assert!(halfedges.next().is_some());
351 assert!(halfedges.next().is_none());
352 }
353
354 #[test]
355 fn test_create_face() {
356 let mut mesh_graph = MeshGraph::new();
357 let face1 = add_face(&mut mesh_graph);
358
359 assert_eq!(mesh_graph.vertices.len(), 3);
360 assert_eq!(mesh_graph.positions.len(), 3);
361 assert_eq!(mesh_graph.halfedges.len(), 6);
362 assert_eq!(mesh_graph.faces.len(), 1);
363
364 test_vertices(&mesh_graph, face1);
365 test_halfedges(&mesh_graph, face1);
366
367 log_faces_rerun!(mesh_graph, face1);
368 }
369
370 #[test]
371 fn test_add_face_to_edge() {
372 let mut mesh_graph = MeshGraph::new();
373 let face1 = add_face(&mut mesh_graph);
374
375 let face2 = add_face_to_edge(&mut mesh_graph, face1, Vec3::new(1.0, 1.0, 0.0), false);
376
377 assert!(face2.is_some());
378 assert_eq!(mesh_graph.vertices.len(), 4);
379 assert_eq!(mesh_graph.positions.len(), 4);
380 assert_eq!(mesh_graph.halfedges.len(), 10);
381 assert_eq!(mesh_graph.faces.len(), 2);
382
383 test_vertices(&mesh_graph, face2.unwrap());
384 test_halfedges(&mesh_graph, face2.unwrap());
385
386 log_faces_rerun!(mesh_graph, face1, face2.unwrap());
387 }
388
389 #[test]
390 fn test_add_face_to_twin_edge() {
391 let mut mesh_graph = MeshGraph::new();
392 let face1 = add_face(&mut mesh_graph);
393
394 let face2 = add_face_to_edge(&mut mesh_graph, face1, Vec3::new(1.0, 1.0, 0.0), true);
395
396 assert!(face2.is_some());
397 assert_eq!(mesh_graph.vertices.len(), 4);
398 assert_eq!(mesh_graph.positions.len(), 4);
399 assert_eq!(mesh_graph.halfedges.len(), 10);
400 assert_eq!(mesh_graph.faces.len(), 2);
401
402 test_vertices(&mesh_graph, face2.unwrap());
403 test_halfedges(&mesh_graph, face2.unwrap());
404
405 log_faces_rerun!(mesh_graph, face1, face2.unwrap());
406 }
407
408 #[test]
409 fn test_fill_face() {
410 let mut mesh_graph = MeshGraph::new();
411 init_fill_face!(face1, face2, face3, mesh_graph);
412
413 let face4 = fill_face(&mut mesh_graph, face1, face3.unwrap(), false);
414
415 assert!(face4.is_some());
416 assert_eq!(mesh_graph.vertices.len(), 5);
417 assert_eq!(mesh_graph.positions.len(), 5);
418 assert_eq!(mesh_graph.halfedges.len(), 16);
419 assert_eq!(mesh_graph.faces.len(), 4);
420
421 test_vertices(&mesh_graph, face4.unwrap());
422 test_halfedges(&mesh_graph, face4.unwrap());
423
424 log_faces_rerun!(
425 mesh_graph,
426 face1,
427 face2.unwrap(),
428 face3.unwrap(),
429 face4.unwrap()
430 );
431 }
432
433 #[test]
434 fn test_fill_face_from_twin_edges() {
435 let mut mesh_graph = MeshGraph::new();
436 init_fill_face!(face1, face2, face3, mesh_graph);
437
438 let face4 = fill_face(&mut mesh_graph, face1, face3.unwrap(), true);
439
440 assert!(face4.is_some());
441 assert_eq!(mesh_graph.vertices.len(), 5);
442 assert_eq!(mesh_graph.positions.len(), 5);
443 assert_eq!(mesh_graph.halfedges.len(), 16);
444 assert_eq!(mesh_graph.faces.len(), 4);
445
446 test_vertices(&mesh_graph, face4.unwrap());
447 test_halfedges(&mesh_graph, face4.unwrap());
448
449 log_faces_rerun!(
450 mesh_graph,
451 face1,
452 face2.unwrap(),
453 face3.unwrap(),
454 face4.unwrap()
455 );
456 }
457}