1use hashbrown::HashSet;
2
3use crate::{FaceId, HalfedgeId, MeshGraph, VertexId};
4
5impl MeshGraph {
6 pub fn delete_face(&mut self, face_id: FaceId) -> (Vec<VertexId>, Vec<HalfedgeId>) {
13 let face = self.faces[face_id];
14
15 let vertices = face.vertices(self);
16 let halfedges = face.halfedges(self);
17
18 let mut deleted_halfedges = HashSet::with_capacity(4);
19
20 for he_id in halfedges {
21 let twin_id = self.halfedges[he_id].twin();
22
23 if self.halfedges[twin_id].is_boundary() {
24 deleted_halfedges.insert(he_id);
25 deleted_halfedges.insert(twin_id);
26 } else {
27 self.halfedges[he_id].face = None;
28 self.halfedges[he_id].next = None;
29 }
30 }
31
32 #[cfg(feature = "rerun")]
33 self.log_hes_rerun(
34 "deleted_by_face_deletion",
35 &deleted_halfedges.iter().copied().collect::<Vec<_>>(),
36 );
37
38 let mut deleted_vertices = Vec::with_capacity(3);
39
40 for &vertex_id in &vertices {
41 let mut all_deleted = true;
42 for he_id in self.vertices[vertex_id].outgoing_halfedges(self) {
43 if !deleted_halfedges.contains(&he_id) {
44 all_deleted = false;
45 break;
46 }
47 }
48
49 if all_deleted {
50 self.positions.remove(vertex_id);
51 if let Some(normals) = &mut self.vertex_normals {
52 normals.remove(vertex_id);
53 }
54 self.vertices.remove(vertex_id);
55
56 deleted_vertices.push(vertex_id);
57 }
58 }
59
60 for &he_id in &deleted_halfedges {
62 let start_v_id = self.halfedges[he_id].start_vertex(self);
63 if let Some(v) = self.vertices.get(start_v_id) {
64 self.vertices[start_v_id].outgoing_halfedge = v
65 .outgoing_halfedges(self)
66 .into_iter()
67 .find(|id| !deleted_halfedges.contains(id));
68 }
69 }
70
71 for &he_id in &deleted_halfedges {
72 self.halfedges.remove(he_id);
73 }
74
75 self.qbvh.remove(self.faces[face_id]);
76 self.faces.remove(face_id);
77
78 (deleted_vertices, Vec::from_iter(deleted_halfedges))
79 }
80}