mesh_graph/ops/
delete.rs

1use hashbrown::HashSet;
2
3use crate::{FaceId, HalfedgeId, MeshGraph, VertexId};
4
5impl MeshGraph {
6    /// Deletes a face from the mesh graph.
7    ///
8    /// It also deletes the vertices and halfedges that are no
9    /// longer connected to any other faces.
10    ///
11    /// Returns the ids of the removed vertices and halfedges.
12    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        // Update connections from vertices to deleted halfedges
61        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}