1use maplike::{Get, Insert, StableRemove};
6
7use crate::{
8 Dcel, EdgeId, Face, FaceId, HalfEdge, HalfEdgeId, Vertex, VertexId,
9 track::{HalfEdgesCounter, VertexesCounter},
10};
11
12impl<
13 VW: Clone,
14 HEW: Clone,
15 FW: Clone,
16 VC: Get<usize, Value = Vertex<VW>> + Insert<usize> + StableRemove<usize>,
17 HEC: Get<usize, Value = HalfEdge<HEW>> + Insert<usize> + StableRemove<usize>,
18 FC: Get<usize, Value = Face<FW>> + Insert<usize> + StableRemove<usize>,
19> Dcel<VW, HEW, FW, VC, HEC, FC>
20{
21 pub fn smoothen_vertex(&mut self, vertex: VertexId) {
30 let representative = self.vertex_representative(vertex);
31
32 self.link_subsequent_half_edges(self.prev(representative), self.next(representative));
33 self.link_subsequent_half_edges(
34 self.prev(self.twin(representative)),
35 self.next(self.twin(representative)),
36 );
37
38 self.remove_orphaned_edges([self.full_edge(representative)]);
39 self.remove_orphaned_vertices([vertex]);
40 }
41
42 pub fn merge_faces_around_vertex(&mut self, inner_vertex: VertexId) {
49 let absorbing_face = self.incident_face(self.vertex_representative(inner_vertex));
50 self.absorb_faces_around_vertex(absorbing_face, inner_vertex);
51 }
52
53 pub fn absorb_faces_around_vertex(&mut self, absorbing_face: FaceId, inner_vertex: VertexId) {
60 let initial_half_edge = self.vertex_representative(inner_vertex);
61
62 let inner_edges: Vec<EdgeId> = self.spokes(initial_half_edge).collect();
63 let perimeter_half_edges: Vec<HalfEdgeId> = self
64 .vertex_rim_half_edges(inner_vertex)
65 .collect::<Vec<HalfEdgeId>>();
66
67 self.absorb_faces_over_edges_and_vertices_in_perimeter(
68 absorbing_face,
69 self.interspokes(initial_half_edge)
70 .filter(|face| face.id() != absorbing_face.id())
71 .collect::<Vec<FaceId>>(),
72 inner_edges,
73 [inner_vertex],
74 &perimeter_half_edges,
75 );
76 }
77
78 pub(crate) fn merge_faces_over_edges_and_vertices(
85 &mut self,
86 faces: impl IntoIterator<Item = FaceId>,
87 edges: impl IntoIterator<Item = EdgeId>,
88 vertices: impl IntoIterator<Item = VertexId>,
89 ) {
90 let mut faces = faces.into_iter();
91 let absorbing_face = faces.next().unwrap();
92
93 self.absorb_faces_over_edges_and_vertices(
94 absorbing_face,
95 faces.filter(|face| face.id() != absorbing_face.id()),
96 edges,
97 vertices,
98 );
99 }
100
101 pub(crate) fn absorb_faces_over_edges_and_vertices(
108 &mut self,
109 absorbing_face: FaceId,
110 faces: impl IntoIterator<Item = FaceId>,
111 edges: impl IntoIterator<Item = EdgeId>,
112 vertices: impl IntoIterator<Item = VertexId>,
113 ) {
114 let edges: Vec<EdgeId> = edges.into_iter().collect();
115 let excluded_half_edges: Vec<HalfEdgeId> = edges
116 .iter()
117 .flat_map(|edge| [edge.lesser(), edge.greater()])
118 .collect();
119
120 let initial_half_edge = self
125 .face_half_edges(absorbing_face)
126 .find(|half_edge| !excluded_half_edges.contains(half_edge))
127 .unwrap_or_else(|| {
130 self.face_rim_half_edges(absorbing_face)
131 .find(|half_edge| !excluded_half_edges.contains(half_edge))
132 .unwrap()
133 });
134
135 let perimeter_half_edges: Vec<HalfEdgeId> = self
136 .circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges.clone())
137 .collect();
138
139 self.absorb_faces_over_edges_and_vertices_in_perimeter(
140 absorbing_face,
141 faces,
142 edges,
143 vertices,
144 &perimeter_half_edges,
145 );
146 }
147
148 pub fn merge_faces(&mut self, faces: impl IntoIterator<Item = FaceId>) {
159 let mut faces = faces.into_iter();
160 let absorbing_face = faces.next().unwrap();
161
162 self.absorb_faces(
163 absorbing_face,
164 faces.filter(|face| face.id() != absorbing_face.id()),
165 );
166 }
167
168 pub fn absorb_faces(
178 &mut self,
179 absorbing_face: FaceId,
180 faces: impl IntoIterator<Item = FaceId>,
181 ) {
182 let mut half_edges_counter = HalfEdgesCounter::new();
183 let mut vertex_weights_counter = VertexesCounter::new();
184 let faces: Vec<FaceId> = faces.into_iter().collect();
185
186 half_edges_counter.visit_face_half_edges(self, absorbing_face);
189 vertex_weights_counter.visit_face_vertices(self, absorbing_face);
190
191 for &face in &faces {
192 half_edges_counter.visit_face_half_edges(self, face);
193 vertex_weights_counter.visit_face_vertices(self, face);
194 }
195
196 self.absorb_faces_over_edges_and_vertices_in_perimeter(
197 absorbing_face,
198 faces,
199 half_edges_counter
200 .inner_edges(self)
201 .collect::<Vec<EdgeId>>(),
202 vertex_weights_counter
203 .visited_vertices()
204 .filter(|&vertex| {
205 self.spokes_reverse(self.vertex_representative(vertex))
206 .all(|edge| half_edges_counter.is_inner_edge(edge))
207 })
208 .collect::<Vec<VertexId>>(),
210 &half_edges_counter
211 .outer_edges(self)
212 .map(|(half_edge, _)| half_edge)
213 .collect::<Vec<HalfEdgeId>>(),
214 );
215 }
216
217 pub(crate) fn absorb_faces_over_edges_and_vertices_in_perimeter(
224 &mut self,
225 absorbing_face: FaceId,
226 faces_to_absorb: impl IntoIterator<Item = FaceId>,
227 edges_to_remove: impl IntoIterator<Item = EdgeId>,
228 vertices_to_remove: impl IntoIterator<Item = VertexId>,
229 perimeter_half_edges: &[HalfEdgeId],
230 ) {
231 self.remove_orphaned_faces(faces_to_absorb);
232 self.remove_orphaned_edges(edges_to_remove);
233 self.remove_orphaned_vertices(vertices_to_remove);
234
235 self.wire_inner_half_edge_chain(absorbing_face, perimeter_half_edges);
236 }
237}
238
239#[cfg(all(test, feature = "stable-vec"))]
240mod test {
241 use crate::{
242 EdgeId, FaceId, HalfEdgeId, StableDcel, VertexId, assert_face_boundary,
243 init_dcel_with_3x3_hex_mesh,
244 };
245
246 #[test]
247 fn test_merge_faces_around_vertex() {
248 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
249 dcel.merge_faces_around_vertex(VertexId::new(8));
250
251 assert_eq!(dcel.vertices().num_elements(), 29);
253 assert_eq!(dcel.half_edges().num_elements(), 70);
254 assert_eq!(dcel.faces().num_elements(), 8);
255
256 assert_face_boundary!(&dcel, 0, 0);
259 assert_face_boundary!(&dcel, 1, 6);
260 assert_face_boundary!(&dcel, 3, 6);
262 assert_face_boundary!(&dcel, 5, 12);
264 assert_face_boundary!(&dcel, 6, 6);
265 assert_face_boundary!(&dcel, 7, 6);
266 assert_face_boundary!(&dcel, 8, 6);
267 assert_face_boundary!(&dcel, 9, 6);
268 }
269
270 #[test]
271 fn test_absorb_faces_around_vertex() {
272 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
273 dcel.absorb_faces_around_vertex(FaceId::new(2), VertexId::new(8));
274
275 assert_eq!(dcel.vertices().num_elements(), 29);
277 assert_eq!(dcel.half_edges().num_elements(), 70);
278 assert_eq!(dcel.faces().num_elements(), 8);
279
280 assert_face_boundary!(&dcel, 0, 0);
283 assert_face_boundary!(&dcel, 1, 6);
284 assert_face_boundary!(&dcel, 2, 12);
285 assert_face_boundary!(&dcel, 3, 6);
286 assert_face_boundary!(&dcel, 6, 6);
289 assert_face_boundary!(&dcel, 7, 6);
290 assert_face_boundary!(&dcel, 8, 6);
291 assert_face_boundary!(&dcel, 9, 6);
292 }
293
294 #[test]
295 fn test_merge_faces_over_edge() {
296 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
297 dcel.merge_faces_over_edges_and_vertices(
298 [FaceId::new(5), FaceId::new(6)],
299 [EdgeId::new(HalfEdgeId::new(44), HalfEdgeId::new(45))],
300 [],
301 );
302
303 assert_eq!(dcel.vertices().num_elements(), 30);
304 assert_eq!(dcel.half_edges().num_elements(), 74);
305 assert_eq!(dcel.faces().num_elements(), 9);
306
307 assert_face_boundary!(&dcel, 0, 0);
308 assert_face_boundary!(&dcel, 1, 6);
309 assert_face_boundary!(&dcel, 2, 6);
310 assert_face_boundary!(&dcel, 3, 6);
311 assert_face_boundary!(&dcel, 4, 6);
312 assert_face_boundary!(&dcel, 5, 10);
313 assert_face_boundary!(&dcel, 7, 6);
315 assert_face_boundary!(&dcel, 8, 6);
316 assert_face_boundary!(&dcel, 9, 6);
317 }
318
319 #[test]
320 fn test_absorb_face_into_face_over_edge() {
321 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
322 dcel.absorb_faces_over_edges_and_vertices(
323 FaceId::new(6),
324 [FaceId::new(5)],
325 [EdgeId::new(HalfEdgeId::new(44), HalfEdgeId::new(45))],
326 [],
327 );
328
329 assert_eq!(dcel.vertices().num_elements(), 30);
330 assert_eq!(dcel.half_edges().num_elements(), 74);
331 assert_eq!(dcel.faces().num_elements(), 9);
332
333 assert_face_boundary!(&dcel, 0, 0);
334 assert_face_boundary!(&dcel, 1, 6);
335 assert_face_boundary!(&dcel, 2, 6);
336 assert_face_boundary!(&dcel, 3, 6);
337 assert_face_boundary!(&dcel, 4, 6);
338 assert_face_boundary!(&dcel, 6, 10);
340 assert_face_boundary!(&dcel, 7, 6);
341 assert_face_boundary!(&dcel, 8, 6);
342 assert_face_boundary!(&dcel, 9, 6);
343 }
344
345 #[test]
346 fn merge_two_faces() {
347 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
348 dcel.merge_faces([FaceId::new(7), FaceId::new(8)]);
349
350 assert_eq!(dcel.vertices().num_elements(), 30);
351 assert_eq!(dcel.half_edges().num_elements(), 74);
352 assert_eq!(dcel.faces().num_elements(), 9);
353
354 assert_face_boundary!(&dcel, 0, 0);
355 assert_face_boundary!(&dcel, 1, 6);
356 assert_face_boundary!(&dcel, 2, 6);
357 assert_face_boundary!(&dcel, 3, 6);
358 assert_face_boundary!(&dcel, 4, 6);
359 assert_face_boundary!(&dcel, 5, 6);
360 assert_face_boundary!(&dcel, 6, 6);
361 assert_face_boundary!(&dcel, 7, 10);
362 assert_face_boundary!(&dcel, 9, 6);
364 }
365
366 #[test]
367 fn absorb_face_into_face() {
368 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
369 dcel.absorb_faces(FaceId::new(8), [FaceId::new(7)]);
370
371 assert_eq!(dcel.vertices().num_elements(), 30);
372 assert_eq!(dcel.half_edges().num_elements(), 74);
373 assert_eq!(dcel.faces().num_elements(), 9);
374
375 assert_face_boundary!(&dcel, 0, 0);
376 assert_face_boundary!(&dcel, 1, 6);
377 assert_face_boundary!(&dcel, 2, 6);
378 assert_face_boundary!(&dcel, 3, 6);
379 assert_face_boundary!(&dcel, 4, 6);
380 assert_face_boundary!(&dcel, 5, 6);
381 assert_face_boundary!(&dcel, 6, 6);
382 assert_face_boundary!(&dcel, 8, 10);
384 assert_face_boundary!(&dcel, 9, 6);
385 }
386}