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