mesh_graph/ops/
cleanup.rs

1use tracing::instrument;
2
3use crate::{FaceId, HalfedgeId, MeshGraph, VertexId, error_none};
4
5impl MeshGraph {
6    /// Test if two faces have at least one halfedge in common.
7    #[inline]
8    #[instrument(skip(self))]
9    pub fn faces_share_edge(&self, face_id1: FaceId, face_id2: FaceId) -> bool {
10        self.faces_share_edge_inner(face_id1, face_id2).is_some()
11    }
12
13    fn faces_share_edge_inner(&self, face_id1: FaceId, face_id2: FaceId) -> Option<()> {
14        let face1 = self
15            .faces
16            .get(face_id1)
17            .or_else(error_none!("Face 1 not found"))?;
18        let face2 = self
19            .faces
20            .get(face_id2)
21            .or_else(error_none!("Face 2 not found"))?;
22
23        for edge_id1 in face1.halfedges(self) {
24            let edge1 = self
25                .halfedges
26                .get(edge_id1)
27                .or_else(error_none!("Halfedge 1 not found"))?;
28
29            let start_pos1 = self
30                .positions
31                .get(edge1.start_vertex(self)?)
32                .or_else(error_none!("Position of start vertex 1 not found"))?;
33            let end_pos1 = self
34                .positions
35                .get(edge1.end_vertex)
36                .or_else(error_none!("Position of end vertex 1 not found"))?;
37
38            for edge_id2 in face2.halfedges(self) {
39                let edge2 = self
40                    .halfedges
41                    .get(edge_id2)
42                    .or_else(error_none!("Halfedge 2 not found"))?;
43
44                let start_pos2 = self
45                    .positions
46                    .get(edge2.start_vertex(self)?)
47                    .or_else(error_none!("Position of start vertex 2 not found"))?;
48                let end_pos2 = self
49                    .positions
50                    .get(edge2.end_vertex)
51                    .or_else(error_none!("Position of end vertex 2 not found"))?;
52
53                if start_pos1 == start_pos2 && end_pos1 == end_pos2 {
54                    return Some(());
55                }
56            }
57        }
58
59        None
60    }
61
62    /// Test if two faces share all vertices.
63    #[inline]
64    #[instrument(skip(self))]
65    pub fn faces_share_all_vertices(&self, face_id1: FaceId, face_id2: FaceId) -> bool {
66        self.faces_share_all_vertices_inner(face_id1, face_id2)
67            .is_some()
68    }
69
70    fn faces_share_all_vertices_inner(&self, face_id1: FaceId, face_id2: FaceId) -> Option<()> {
71        let face1 = self
72            .faces
73            .get(face_id1)
74            .or_else(error_none!("Face 1 not found"))?;
75        let face2 = self
76            .faces
77            .get(face_id2)
78            .or_else(error_none!("Face 2 not found"))?;
79
80        'outer: for vertex_id1 in face1.vertices(self) {
81            let pos1 = self
82                .positions
83                .get(vertex_id1)
84                .or_else(error_none!("Position of vertex 1 not found"))?;
85
86            for vertex_id2 in face2.vertices(self) {
87                let pos2 = self
88                    .positions
89                    .get(vertex_id2)
90                    .or_else(error_none!("Position of vertex 2 not found"))?;
91
92                if pos1 == pos2 {
93                    continue 'outer;
94                }
95            }
96
97            return None;
98        }
99
100        Some(())
101    }
102
103    /// Test if two halfedges share all vertices.
104    #[inline]
105    #[instrument(skip(self))]
106    pub fn halfedges_share_all_vertices(
107        &self,
108        halfedge_id1: HalfedgeId,
109        halfedge_id2: HalfedgeId,
110    ) -> bool {
111        self.halfedges_share_all_vertices_inner(halfedge_id1, halfedge_id2)
112            .is_some()
113    }
114
115    fn halfedges_share_all_vertices_inner(
116        &self,
117        halfedge_id1: HalfedgeId,
118        halfedge_id2: HalfedgeId,
119    ) -> Option<()> {
120        let edge1 = self
121            .halfedges
122            .get(halfedge_id1)
123            .or_else(error_none!("Halfedge 1 not found"))?;
124        let edge2 = self
125            .halfedges
126            .get(halfedge_id2)
127            .or_else(error_none!("Halfedge 2 not found"))?;
128
129        let start1 = self
130            .positions
131            .get(edge1.start_vertex(self)?)
132            .or_else(error_none!("Position of start vertex 1 not found"))?;
133        let end1 = self
134            .positions
135            .get(edge1.end_vertex)
136            .or_else(error_none!("Position of end vertex 1 not found"))?;
137
138        let start2 = self
139            .positions
140            .get(edge2.start_vertex(self)?)
141            .or_else(error_none!("Position of start vertex 2 not found"))?;
142        let end2 = self
143            .positions
144            .get(edge2.end_vertex)
145            .or_else(error_none!("Position of end vertex 2 not found"))?;
146
147        (start1 == start2 && end1 == end2).then_some(())
148    }
149
150    /// Test if two vertices have the exact same position.
151    #[inline]
152    #[instrument(skip(self))]
153    pub fn vertices_share_position(&self, vertex_id1: VertexId, vertex_id2: VertexId) -> bool {
154        self.vertices_share_position_inner(vertex_id1, vertex_id2)
155            .is_some()
156    }
157
158    fn vertices_share_position_inner(
159        &self,
160        vertex_id1: VertexId,
161        vertex_id2: VertexId,
162    ) -> Option<()> {
163        (self
164            .positions
165            .get(vertex_id1)
166            .or_else(error_none!("Position of vertex 1 not found"))?
167            == self
168                .positions
169                .get(vertex_id2)
170                .or_else(error_none!("Position of vertex 2 not found"))?)
171        .then_some(())
172    }
173
174    pub fn make_outgoing_halfedge_boundary_if_possible(&mut self, _vertex_id: VertexId) {
175        todo!()
176    }
177}