1mod iter;
6mod triangulate;
7
8pub use iter::{
9 CcwEdgesIter, CcwEdgesWalker, CcwHalfEdgesIter, CcwHalfEdgesWalker, CwEdgesIter, CwEdgesWalker,
10 CwHalfEdgesIter, CwHalfEdgesWalker, FaceEdgesIter, FaceEdgesWalker, FaceHalfEdgesIter,
11 FaceHalfEdgesWalker,
12};
13use maplike::{Get, Insert, Push, Remove};
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub struct VertexId(usize);
17
18impl VertexId {
19 #[inline]
20 pub fn id(self) -> usize {
21 self.0
22 }
23}
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26pub struct HalfEdgeId(usize);
27
28impl HalfEdgeId {
29 #[inline]
30 pub fn id(self) -> usize {
31 self.0
32 }
33}
34
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub struct EdgeId(HalfEdgeId, HalfEdgeId);
37
38impl EdgeId {
39 #[inline]
40 pub fn forward(self) -> HalfEdgeId {
41 self.0
42 }
43
44 #[inline]
45 pub fn backward(self) -> HalfEdgeId {
46 self.1
47 }
48}
49
50#[derive(Clone, Copy, Debug, Eq, PartialEq)]
51pub struct FaceId(usize);
52
53impl FaceId {
54 #[inline]
55 pub fn id(self) -> usize {
56 self.0
57 }
58}
59
60#[derive(Clone, Debug)]
61pub struct Vertex<VW> {
62 outgoing_next_half_edge: HalfEdgeId,
63 weight: VW,
64}
65
66#[derive(Clone, Debug)]
67pub struct HalfEdge<HEW> {
68 origin: VertexId,
69 twin: HalfEdgeId,
70 prev: HalfEdgeId,
71 next: HalfEdgeId,
72 face: FaceId,
73 weight: HEW,
74}
75
76#[derive(Clone, Debug)]
77pub struct Face<FW> {
78 incident_half_edge: Option<HalfEdgeId>,
79 weight: FW,
80}
81
82#[derive(Clone, Debug)]
83pub struct Dcel<
84 VW,
85 HEW = (),
86 FW = (),
87 VC = Vec<Vertex<VW>>,
88 HEC = Vec<HalfEdge<HEW>>,
89 FC = Vec<Face<FW>>,
90> {
91 vertexes: VC,
92 half_edges: HEC,
93 faces: FC,
94 vertex_weight_marker: std::marker::PhantomData<VW>,
95 half_edge_weight_marker: std::marker::PhantomData<HEW>,
96 face_weight_marker: std::marker::PhantomData<FW>,
97}
98
99impl<VW, HEW, FW: Default, VC: Default, HEC: Default, FC: Default + Push<usize, Item = FW>>
100 Dcel<VW, HEW, FW, VC, HEC, FC>
101{
102 #[inline]
103 pub fn new() -> Self {
104 let mut faces = FC::default();
105
106 faces.push(FW::default());
108
109 Self {
110 vertexes: VC::default(),
111 half_edges: HEC::default(),
112 faces,
113 vertex_weight_marker: std::marker::PhantomData,
114 half_edge_weight_marker: std::marker::PhantomData,
115 face_weight_marker: std::marker::PhantomData,
116 }
117 }
118}
119
120impl<VW, HEW, FW: Default, VC: Default, HEC: Default, FC: Default + Push<usize, Item = FW>> Default
121 for Dcel<VW, HEW, FW, VC, HEC, FC>
122{
123 #[inline]
124 fn default() -> Self {
125 Self::new()
126 }
127}
128
129impl<VW, HEW, FW, VC, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
130 #[inline]
131 pub fn from_parts(vertexes: VC, half_edges: HEC, faces: FC) -> Self {
132 Self {
133 vertexes,
134 half_edges,
135 faces,
136 vertex_weight_marker: std::marker::PhantomData,
137 half_edge_weight_marker: std::marker::PhantomData,
138 face_weight_marker: std::marker::PhantomData,
139 }
140 }
141}
142
143impl<VW, HEW, FW, VC, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
144 #[inline]
145 pub fn vertexes(&self) -> &VC {
146 &self.vertexes
147 }
148
149 #[inline]
150 pub fn half_edges(&self) -> &HEC {
151 &self.half_edges
152 }
153
154 #[inline]
155 pub fn faces(&self) -> &FC {
156 &self.faces
157 }
158
159 #[inline]
160 pub fn dissolve(self) -> (VC, HEC, FC) {
161 (self.vertexes, self.half_edges, self.faces)
162 }
163}
164
165impl<
166 VW: Clone,
167 HEW: Clone + Default,
168 FW: Clone + Default,
169 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
170 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
171 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
172> Dcel<VW, HEW, FW, VC, HEC, FC>
173{
174 pub fn insert_polygon(&mut self, vertex_weights: impl IntoIterator<Item = VW>) {
175 self.insert_polygon_in_face(self.unbounded_face(), vertex_weights);
176 }
177
178 pub fn insert_polygon_in_face(
179 &mut self,
180 target_face: FaceId,
181 vertex_weights: impl IntoIterator<Item = VW>,
182 ) {
183 self.insert_polygon_in_face_with_all_weights(
184 target_face,
185 vertex_weights,
186 std::iter::repeat((HEW::default(), HEW::default())),
187 FW::default(),
188 );
189 }
190}
191
192impl<
193 VW: Clone,
194 HEW: Clone,
195 FW: Clone,
196 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
197 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
198 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
199> Dcel<VW, HEW, FW, VC, HEC, FC>
200{
201 pub fn insert_polygon_with_all_weights(
202 &mut self,
203 vertex_weights: impl IntoIterator<Item = VW>,
204 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
205 face_weight: FW,
206 ) {
207 self.insert_polygon_in_face_with_all_weights(
208 self.unbounded_face(),
209 vertex_weights,
210 edge_weights,
211 face_weight,
212 );
213 }
214
215 pub fn insert_polygon_in_face_with_all_weights(
216 &mut self,
217 outer_face: FaceId,
218 vertex_weights: impl IntoIterator<Item = VW>,
219 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
220 face_weight: FW,
221 ) {
222 let new_face = self.add_unwired_face(face_weight);
223 let vertexes = self.add_unwired_polygon_vertexes(vertex_weights);
224 let edges = self.add_unwired_polygon_edges(&vertexes, new_face, outer_face, edge_weights);
225
226 self.wire_face_edges_vertexes(new_face, &edges);
227 }
228
229 fn add_unwired_polygon_vertexes(
230 &mut self,
231 vertex_weights: impl IntoIterator<Item = VW>,
232 ) -> Vec<VertexId> {
233 let vertexes: Vec<VertexId> = vertex_weights
234 .into_iter()
235 .map(|vertex_weight| self.add_unwired_vertex(vertex_weight))
236 .collect();
237
238 vertexes
239 }
240
241 fn add_unwired_polygon_edges(
242 &mut self,
243 vertexes: &[VertexId],
244 new_face: FaceId,
245 target_face: FaceId,
246 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
247 ) -> Vec<EdgeId> {
248 let vertexes_circular_pair_windows = vertexes
249 .iter()
250 .zip(vertexes.iter().skip(1).chain(vertexes.iter().take(1)));
251
252 let mut edges = vec![];
253 let edge_weights: Vec<(HEW, HEW)> = edge_weights.into_iter().collect();
254
255 for ((from_vertex, to_vertex), (forward_half_edge_weight, backward_half_edge_weight)) in
256 vertexes_circular_pair_windows.zip(edge_weights.clone().into_iter())
257 {
258 let edge = self.add_unwired_edge(
259 *from_vertex,
260 *to_vertex,
261 new_face,
262 target_face,
263 forward_half_edge_weight,
264 backward_half_edge_weight,
265 );
266 edges.push(edge);
267 }
268
269 edges
270 }
271}
272
273impl<
274 VW: Clone,
275 HEW: Clone,
276 FW: Clone,
277 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Remove<usize>,
278 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Remove<usize>,
279 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Remove<usize>,
280> Dcel<VW, HEW, FW, VC, HEC, FC>
281{
282 pub fn merge_faces_around_vertex(&mut self, inner_vertex: VertexId) {
283 let absorbing_face = self.face_in_front(
284 self.vertexes
285 .get(&inner_vertex.id())
286 .unwrap()
287 .outgoing_next_half_edge,
288 );
289 self.absorb_faces_around_vertex(absorbing_face, inner_vertex);
290 }
291
292 pub fn absorb_faces_around_vertex(&mut self, absorbing_face: FaceId, inner_vertex: VertexId) {
293 let initial_half_edge = self
294 .vertexes
295 .get(&inner_vertex.id())
296 .unwrap()
297 .outgoing_next_half_edge;
298 let initial_edge = self.full_edge(
299 self.vertexes
300 .get(&inner_vertex.id())
301 .unwrap()
302 .outgoing_next_half_edge,
303 );
304 let inner_edges: Vec<EdgeId> = self.cw_edges(initial_edge).collect();
305 let perimeter_edges: Vec<EdgeId> = self
306 .edges_with_excludes(initial_edge, inner_edges.clone())
307 .collect();
308
309 self.remove_faces(
310 self.cw_faces(self.face_in_front(initial_half_edge))
311 .collect::<Vec<FaceId>>(),
312 );
313 self.remove_edges(inner_edges);
314 self.remove_vertex(inner_vertex);
315
316 self.wire_face_edges_vertexes(absorbing_face, &perimeter_edges);
317 }
318}
319
320impl<
321 VW: Clone,
322 HEW: Clone,
323 FW: Clone,
324 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Remove<usize>,
325 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Remove<usize>,
326 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Remove<usize>,
327> Dcel<VW, HEW, FW, VC, HEC, FC>
328{
329 pub fn merge_faces_over_edges_and_vertexes(
330 &mut self,
331 faces: impl IntoIterator<Item = FaceId>,
332 edges: impl IntoIterator<Item = EdgeId>,
333 vertexes: impl IntoIterator<Item = VertexId>,
334 ) {
335 let mut faces = faces.into_iter();
336 let absorbing_face = faces.next().unwrap();
337
338 self.absorb_faces_over_edges_and_vertexes(absorbing_face, faces, edges, vertexes)
339 }
340
341 pub fn absorb_faces_over_edges_and_vertexes(
342 &mut self,
343 absorbing_face: FaceId,
344 faces: impl IntoIterator<Item = FaceId>,
345 edges: impl IntoIterator<Item = EdgeId>,
346 vertexes: impl IntoIterator<Item = VertexId>,
347 ) {
348 let edges: Vec<EdgeId> = edges.into_iter().collect();
349 let perimeter_edges: Vec<EdgeId> = self
350 .edges_with_excludes(
351 self.full_edge(
352 self.faces
353 .get(&absorbing_face.id())
354 .unwrap()
355 .incident_half_edge
356 .unwrap(),
357 ),
358 edges.clone(),
359 )
360 .collect();
361
362 self.remove_faces(faces);
363 self.remove_edges(edges);
364 self.remove_vertexes(vertexes);
365
366 self.wire_face_edges_vertexes(absorbing_face, &perimeter_edges);
367 }
368}
369
370impl<
371 VW: Clone,
372 HEW: Clone,
373 FW: Clone,
374 VC: Get<usize, Item = Vertex<VW>> + Insert<usize>,
375 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize>,
376 FC: Get<usize, Item = Face<FW>> + Insert<usize>,
377> Dcel<VW, HEW, FW, VC, HEC, FC>
378{
379 fn wire_edge_chain(&mut self, face: FaceId, edges: &[EdgeId]) {
380 self.wire_face(face, edges[0].forward());
381
382 let edges_circular_pair_windows = edges
383 .iter()
384 .zip(edges.iter().skip(1).chain(edges.iter().take(1)));
385
386 for (edge, next_edge) in edges_circular_pair_windows {
387 self.wire_edge(*edge, *next_edge);
388 self.wire_vertex(self.origin(edge.forward()), edge.forward());
389 }
390 }
391
392 fn wire_face_edges_vertexes(&mut self, face: FaceId, edges: &[EdgeId]) {
393 self.wire_face(face, edges[0].forward());
394
395 let edges_circular_pair_windows = edges
396 .iter()
397 .zip(edges.iter().skip(1).chain(edges.iter().take(1)));
398
399 for (edge, next_edge) in edges_circular_pair_windows {
400 self.wire_edge(*edge, *next_edge);
401 self.wire_vertex(self.origin(edge.forward()), edge.forward());
402 }
403 }
404}
405
406impl<VW, HEW, FW, VC: Push<usize, Item = Vertex<VW>>, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
407 fn add_unwired_vertex(&mut self, weight: VW) -> VertexId {
408 VertexId(self.vertexes.push(Vertex {
409 outgoing_next_half_edge: HalfEdgeId(0),
414 weight,
415 }))
416 }
417}
418
419impl<VW, HEW, FW, VC: Remove<usize, Item = Vertex<VW>>, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
420 fn remove_vertexes(&mut self, vertexes: impl IntoIterator<Item = VertexId>) {
421 for vertex in vertexes.into_iter() {
422 self.remove_vertex(vertex);
423 }
424 }
425
426 fn remove_vertex(&mut self, vertex: VertexId) {
427 self.vertexes.remove(&vertex.id());
428 }
429}
430
431impl<VW: Clone, HEW, FW, VC: Get<usize, Item = Vertex<VW>> + Insert<usize>, HEC, FC>
432 Dcel<VW, HEW, FW, VC, HEC, FC>
433{
434 fn wire_vertex(&mut self, vertex: VertexId, outgoing_half_edge: HalfEdgeId) {
435 self.vertexes.insert(
436 vertex.id(),
437 Vertex {
438 outgoing_next_half_edge: outgoing_half_edge,
439 weight: self.vertexes.get(&vertex.id()).unwrap().weight.clone(),
440 },
441 )
442 }
443}
444
445impl<
446 VW: Clone,
447 HEW: Clone + Default,
448 FW: Clone + Default,
449 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
450 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
451 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
452> Dcel<VW, HEW, FW, VC, HEC, FC>
453{
454 pub fn split_face_by_edge_chain(
455 &mut self,
456 from: VertexId,
457 to: VertexId,
458 vertex_weights: impl IntoIterator<Item = VW>,
459 split_face: FaceId,
460 ) {
461 self.split_face_by_edge_chain_with_all_weights(
462 from,
463 to,
464 vertex_weights,
465 std::iter::repeat((HEW::default(), HEW::default())),
466 split_face,
467 FW::default(),
468 )
469 }
470}
471
472impl<
473 VW: Clone,
474 HEW: Clone,
475 FW: Clone,
476 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
477 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
478 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
479> Dcel<VW, HEW, FW, VC, HEC, FC>
480{
481 pub fn split_face_by_edge_chain_with_all_weights(
482 &mut self,
483 from: VertexId,
484 to: VertexId,
485 vertex_weights: impl IntoIterator<Item = VW>,
486 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
487 split_face: FaceId,
488 new_face_weight: FW,
489 ) {
490 let new_face = self.add_unwired_face(new_face_weight);
491 let (new_edges, last_vertex, last_edge_weight) = self.add_unwired_dangling_edge_chain(
492 from,
493 vertex_weights,
494 edge_weights,
495 split_face,
496 new_face,
497 );
498 self.add_unwired_edge(
499 last_vertex,
500 to,
501 split_face,
502 new_face,
503 last_edge_weight.0,
504 last_edge_weight.1,
505 );
506
507 let mut edges = vec![];
508 edges.push(self.vertex_prev_edge(from));
509 edges.extend(new_edges);
510 edges.push(self.vertex_next_edge(to));
511
512 self.wire_edge_chain(new_face, &edges);
513 }
514
515 fn add_unwired_dangling_edge_chain(
516 &mut self,
517 from: VertexId,
518 dangling_vertex_weights: impl IntoIterator<Item = VW>,
519 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
520 face: FaceId,
521 twin_face: FaceId,
522 ) -> (Vec<EdgeId>, VertexId, (HEW, HEW)) {
523 let mut edge_weights = edge_weights.into_iter();
524 let mut edges = vec![];
525 let mut last_vertex = from;
526
527 for (vertex_weight, edge_weight) in dangling_vertex_weights
528 .into_iter()
529 .zip(edge_weights.by_ref())
530 {
531 let (new_edge, new_vertex) = self.add_unwired_dangling_edge(
532 last_vertex,
533 vertex_weight,
534 edge_weight,
535 face,
536 twin_face,
537 );
538
539 edges.push(new_edge);
540 last_vertex = new_vertex;
541 }
542
543 (edges, last_vertex, edge_weights.next().unwrap())
544 }
545
546 fn add_unwired_dangling_edge(
547 &mut self,
548 from: VertexId,
549 dangling_vertex_weight: VW,
550 edge_weight: (HEW, HEW),
551 face: FaceId,
552 twin_face: FaceId,
553 ) -> (EdgeId, VertexId) {
554 let dangling_vertex = self.add_unwired_vertex(dangling_vertex_weight);
555 let dangling_edge = self.add_unwired_edge(
556 from,
557 dangling_vertex,
558 face,
559 twin_face,
560 edge_weight.0,
561 edge_weight.1,
562 );
563
564 (dangling_edge, dangling_vertex)
565 }
566}
567
568impl<VW, HEW: Clone, FW, VC, HEC: Insert<usize, Item = HalfEdge<HEW>> + Push<usize>, FC>
569 Dcel<VW, HEW, FW, VC, HEC, FC>
570{
571 fn add_unwired_edge(
572 &mut self,
573 origin: VertexId,
574 twin_origin: VertexId,
575 face: FaceId,
576 twin_face: FaceId,
577 weight: HEW,
578 twin_weight: HEW,
579 ) -> EdgeId {
580 let forward_half_edge = HalfEdgeId(self.half_edges.push(HalfEdge {
581 origin,
582 twin: HalfEdgeId(0),
584 prev: HalfEdgeId(0),
587 next: HalfEdgeId(0),
588 face,
589 weight: weight.clone(),
590 }));
591
592 let backward_half_edge = HalfEdgeId(self.half_edges.push(HalfEdge {
593 origin: twin_origin,
594 twin: forward_half_edge,
595 prev: HalfEdgeId(0),
598 next: HalfEdgeId(0),
599 face: twin_face,
600 weight: twin_weight,
601 }));
602
603 self.half_edges.insert(
607 forward_half_edge.id(),
608 HalfEdge {
609 origin,
610 twin: backward_half_edge,
612 prev: HalfEdgeId(0),
615 next: HalfEdgeId(0),
616 face,
617 weight,
618 },
619 );
620
621 EdgeId(forward_half_edge, backward_half_edge)
622 }
623}
624
625impl<VW, HEW, FW, VC, HEC: Remove<usize, Item = HalfEdge<HEW>>, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
626 fn remove_edges(&mut self, edges: impl IntoIterator<Item = EdgeId>) {
627 for edge in edges.into_iter() {
628 self.remove_edge(edge);
629 }
630 }
631
632 fn remove_edge(&mut self, edge: EdgeId) {
633 self.half_edges.remove(&edge.forward().id());
634 self.half_edges.remove(&edge.backward().id());
635 }
636}
637
638impl<VW, HEW: Clone, FW, VC, HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize>, FC>
639 Dcel<VW, HEW, FW, VC, HEC, FC>
640{
641 fn wire_edge(&mut self, edge: EdgeId, next_edge: EdgeId) {
642 self.half_edges.insert(
643 edge.forward().id(),
644 HalfEdge {
645 next: next_edge.forward(),
646 ..self.half_edges.get(&edge.forward().id()).unwrap().clone()
647 },
648 );
649 self.half_edges.insert(
650 next_edge.backward().id(),
651 HalfEdge {
652 next: edge.backward(),
653 ..self.half_edges.get(&edge.forward().id()).unwrap().clone()
654 },
655 );
656 }
657}
658
659impl<VW, HEW, FW, VC, HEC, FC: Push<usize, Item = Face<FW>>> Dcel<VW, HEW, FW, VC, HEC, FC> {
660 fn add_unwired_face(&mut self, weight: FW) -> FaceId {
661 FaceId(self.faces.push(Face {
662 incident_half_edge: None,
663 weight,
664 }))
665 }
666}
667
668impl<VW, HEW, FW, VC, HEC, FC: Remove<usize>> Dcel<VW, HEW, FW, VC, HEC, FC> {
669 fn remove_faces(&mut self, faces: impl IntoIterator<Item = FaceId>) {
670 for face in faces.into_iter() {
671 self.remove_face(face);
672 }
673 }
674
675 fn remove_face(&mut self, face: FaceId) {
676 self.faces.remove(&face.id());
677 }
678}
679
680impl<VW, HEW, FW: Clone, VC, HEC, FC: Get<usize, Item = Face<FW>> + Insert<usize>>
681 Dcel<VW, HEW, FW, VC, HEC, FC>
682{
683 fn wire_face(&mut self, face: FaceId, incident_half_edge: HalfEdgeId) {
684 self.faces.insert(
685 face.id(),
686 Face {
687 incident_half_edge: Some(incident_half_edge),
688 weight: self.faces.get(&face.id()).unwrap().weight.clone(),
689 },
690 );
691 }
692}
693
694impl<VW, HEW, FW, VC: Get<usize, Item = Vertex<VW>>, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
695 #[inline]
696 fn outgoing_next_half_edge(&self, vertex: VertexId) -> HalfEdgeId {
697 self.vertexes
698 .get(&vertex.id())
699 .unwrap()
700 .outgoing_next_half_edge
701 }
702}
703
704impl<VW, HEW, FW, VC: Get<usize, Item = Vertex<VW>>, HEC: Get<usize, Item = HalfEdge<HEW>>, FC>
705 Dcel<VW, HEW, FW, VC, HEC, FC>
706{
707 #[inline]
708 fn incoming_next_half_edge(&self, vertex: VertexId) -> HalfEdgeId {
709 self.twin(self.outgoing_next_half_edge(vertex))
710 }
711
712 #[inline]
713 fn vertex_next_edge(&self, vertex: VertexId) -> EdgeId {
714 EdgeId(
715 self.outgoing_next_half_edge(vertex),
716 self.incoming_next_half_edge(vertex),
717 )
718 }
719
720 #[inline]
721 fn incoming_prev_half_edge(&self, vertex: VertexId) -> HalfEdgeId {
722 self.prev_half_edge(self.outgoing_next_half_edge(vertex))
723 }
724
725 #[inline]
726 fn outgoing_prev_half_edge(&self, vertex: VertexId) -> HalfEdgeId {
727 self.twin(self.incoming_prev_half_edge(vertex))
728 }
729
730 #[inline]
731 fn vertex_prev_edge(&self, vertex: VertexId) -> EdgeId {
732 EdgeId(
733 self.incoming_prev_half_edge(vertex),
734 self.outgoing_prev_half_edge(vertex),
735 )
736 }
737}
738
739impl<VW, HEW, FW, VC: Get<usize, Item = Vertex<VW>>, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
740 #[inline]
741 fn vertex_weight(&self, vertex: VertexId) -> &VW {
742 &self.vertexes.get(&vertex.id()).unwrap().weight
743 }
744}
745
746impl<VW, HEW, FW, VC: Get<usize, Item = Vertex<VW>>, HEC: Get<usize, Item = HalfEdge<HEW>>, FC>
747 Dcel<VW, HEW, FW, VC, HEC, FC>
748{
749 #[inline]
750 fn prev_vertex(&self, vertex: VertexId) -> VertexId {
751 self.origin(self.prev_half_edge(self.outgoing_next_half_edge(vertex)))
752 }
753
754 #[inline]
755 fn next_vertex(&self, vertex: VertexId) -> VertexId {
756 self.origin(self.next_half_edge(self.outgoing_next_half_edge(vertex)))
757 }
758}
759
760impl<VW, HEW, FW, VC, HEC: Get<usize, Item = HalfEdge<HEW>>, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
761 #[inline]
762 pub fn origin(&self, half_edge: HalfEdgeId) -> VertexId {
763 self.half_edges.get(&half_edge.id()).unwrap().origin
764 }
765
766 #[inline]
767 pub fn endpoints(&self, edge: EdgeId) -> (VertexId, VertexId) {
768 (self.origin(edge.forward()), self.origin(edge.backward()))
769 }
770
771 #[inline]
772 pub fn twin(&self, half_edge: HalfEdgeId) -> HalfEdgeId {
773 self.half_edges.get(&half_edge.id()).unwrap().twin
774 }
775
776 #[inline]
777 pub fn full_edge(&self, half_edge: HalfEdgeId) -> EdgeId {
778 EdgeId(half_edge, self.twin(half_edge))
779 }
780
781 #[inline]
782 pub fn face_in_front(&self, half_edge: HalfEdgeId) -> FaceId {
783 self.half_edges.get(&half_edge.id()).unwrap().face
784 }
785
786 #[inline]
787 pub fn face_behind(&self, half_edge: HalfEdgeId) -> FaceId {
788 self.face_in_front(self.twin(half_edge))
789 }
790
791 #[inline]
792 pub fn edge_faces(&self, edge: EdgeId) -> (FaceId, FaceId) {
793 (
794 self.face_in_front(edge.forward()),
795 self.face_behind(edge.backward()),
796 )
797 }
798
799 #[inline]
800 pub fn prev_half_edge(&self, half_edge: HalfEdgeId) -> HalfEdgeId {
801 self.half_edges.get(&half_edge.id()).unwrap().prev
802 }
803
804 #[inline]
805 pub fn next_half_edge(&self, half_edge: HalfEdgeId) -> HalfEdgeId {
806 self.half_edges.get(&half_edge.id()).unwrap().next
807 }
808
809 #[inline]
810 pub fn prev_edge(&self, edge: EdgeId) -> EdgeId {
811 let next_forward_half_edge = self.half_edges.get(&edge.forward().id()).unwrap().prev;
812 let next_backward_half_edge = self
813 .half_edges
814 .get(&next_forward_half_edge.id())
815 .unwrap()
816 .twin;
817
818 EdgeId(next_forward_half_edge, next_backward_half_edge)
819 }
820
821 #[inline]
822 pub fn next_edge(&self, edge: EdgeId) -> EdgeId {
823 let next_forward_half_edge = self.half_edges.get(&edge.forward().id()).unwrap().next;
824 let next_backward_half_edge = self
825 .half_edges
826 .get(&next_forward_half_edge.id())
827 .unwrap()
828 .twin;
829
830 EdgeId(next_forward_half_edge, next_backward_half_edge)
831 }
832
833 #[inline]
834 pub fn cw_half_edge(&self, half_edge: HalfEdgeId) -> HalfEdgeId {
835 self.twin(self.prev_half_edge(half_edge))
836 }
837
838 #[inline]
839 pub fn ccw_half_edge(&self, half_edge: HalfEdgeId) -> HalfEdgeId {
840 self.next_half_edge(self.twin(half_edge))
841 }
842
843 #[inline]
844 pub fn cw_edge(&self, edge: EdgeId) -> EdgeId {
845 self.full_edge(self.cw_half_edge(edge.forward()))
846 }
847
848 #[inline]
849 pub fn ccw_edge(&self, edge: EdgeId) -> EdgeId {
850 self.full_edge(self.ccw_half_edge(edge.forward()))
851 }
852
853 #[inline]
854 pub fn half_edge_weight(&self, half_edge: HalfEdgeId) -> &HEW {
855 &self.half_edges.get(&half_edge.id()).unwrap().weight
856 }
857
858 #[inline]
859 pub fn edge_weights(&self, edge: EdgeId) -> (&HEW, &HEW) {
860 (
861 self.half_edge_weight(edge.forward()),
862 self.half_edge_weight(edge.backward()),
863 )
864 }
865}
866
867impl<VW, HEW, FW, VC, HEC, FC: Get<usize, Item = Face<FW>>> Dcel<VW, HEW, FW, VC, HEC, FC> {
868 #[inline]
869 pub fn incident_half_edge(&self, face: FaceId) -> Option<HalfEdgeId> {
870 self.faces.get(&face.id()).unwrap().incident_half_edge
871 }
872
873 #[inline]
874 pub fn face_weight(&self, face: FaceId) -> &FW {
875 &self.faces.get(&face.id()).unwrap().weight
876 }
877}
878
879impl<VW, HEW, FW, VC, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
880 #[inline]
884 pub fn unbounded_face(&self) -> FaceId {
885 FaceId(0)
886 }
887}