Skip to main content

mesh_graph/ops/add/
face.rs

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