1use maplike::{Get, Insert, Push};
6
7use crate::{Dcel, EdgeId, Face, FaceId, HalfEdge, Vertex, VertexId};
8
9impl<
10 VW: Clone,
11 HEW: Clone + Default,
12 FW: Clone + Default,
13 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
14 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
15 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
16> Dcel<VW, HEW, FW, VC, HEC, FC>
17{
18 pub fn triangulate_around_vertex(&mut self, perimeter_face: FaceId, inner_vertex_weight: VW) {
27 let perimeter_vertex_count = self.face_vertexes(perimeter_face).count();
28
29 self.triangulate_around_vertex_with_all_weights(
30 perimeter_face,
31 inner_vertex_weight,
32 std::iter::repeat_n(Default::default(), perimeter_vertex_count),
33 std::iter::repeat_n(Default::default(), perimeter_vertex_count),
34 )
35 }
36
37 pub fn fan_triangulate(&mut self, perimeter_face: FaceId, apex: VertexId) {
38 let fan_vertexes_count = self.face_vertexes(perimeter_face).count() - 1;
39
40 self.fan_triangulate_with_all_weights(
41 perimeter_face,
42 apex,
43 std::iter::repeat_n(Default::default(), fan_vertexes_count),
44 std::iter::repeat_n(Default::default(), fan_vertexes_count),
45 )
46 }
47}
48
49impl<
50 VW: Clone,
51 HEW: Clone,
52 FW: Clone,
53 VC: Get<usize, Item = Vertex<VW>> + Insert<usize> + Push<usize>,
54 HEC: Get<usize, Item = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
55 FC: Get<usize, Item = Face<FW>> + Insert<usize> + Push<usize>,
56> Dcel<VW, HEW, FW, VC, HEC, FC>
57{
58 pub fn triangulate_around_vertex_with_all_weights(
59 &mut self,
60 perimeter_face: FaceId,
61 inner_vertex_weight: VW,
62 inner_edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
63 triangle_face_weights: impl IntoIterator<Item = FW>,
64 ) {
65 let inner_vertex = self.add_unwired_vertex(inner_vertex_weight);
66 self.fan_triangulate_with_all_weights(
67 perimeter_face,
68 inner_vertex,
69 inner_edge_weights,
70 triangle_face_weights,
71 );
72 }
73
74 pub fn fan_triangulate_with_all_weights(
75 &mut self,
76 perimeter_face: FaceId,
77 apex: VertexId,
78 inner_edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
79 triangle_face_weights: impl IntoIterator<Item = FW>,
80 ) {
81 let triangle_faces =
82 self.add_unwired_triangulation_faces(perimeter_face, triangle_face_weights);
83 let inner_edges = self.add_unwired_triangulation_edges(
84 perimeter_face,
85 apex,
86 &triangle_faces,
87 inner_edge_weights,
88 );
89 self.wire_triangulation_faces_edges_vertexes(perimeter_face, &inner_edges);
90 }
91
92 fn add_unwired_triangulation_faces(
93 &mut self,
94 first_face: FaceId,
95 triangle_face_weights: impl IntoIterator<Item = FW>,
96 ) -> Vec<FaceId> {
97 let mut triangle_faces = vec![];
98
99 let mut face_weights_iter = triangle_face_weights.into_iter();
100 self.faces.insert(
101 first_face.id(),
102 Face {
103 incident_half_edge: self.faces.get(&first_face.id()).unwrap().incident_half_edge,
104 weight: face_weights_iter.next().unwrap(),
105 },
106 );
107 triangle_faces.push(first_face);
108
109 for face_weight in face_weights_iter {
110 triangle_faces.push(self.add_unwired_face(face_weight));
111 }
112
113 triangle_faces
114 }
115
116 fn add_unwired_triangulation_edges(
117 &mut self,
118 perimeter_face: FaceId,
119 inner_vertex: VertexId,
120 triangle_faces: &[FaceId],
121 inner_edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
122 ) -> Vec<EdgeId> {
123 let mut inner_edge_weights = inner_edge_weights.into_iter();
124 let mut face_vertexes_walker = self.face_vertexes(perimeter_face).walker();
125 let mut edges = vec![];
126
127 let mut i: usize = 0;
128
129 while let Some(perimeter_vertex) = face_vertexes_walker.next(self) {
130 let (weight, twin_weight) = inner_edge_weights.next().unwrap();
131
132 let prev_face = if i == 0 {
133 triangle_faces[triangle_faces.len() - 1]
135 } else {
136 triangle_faces[i - 1]
137 };
138
139 edges.push(self.add_unwired_edge(
140 perimeter_vertex,
141 inner_vertex,
142 prev_face,
143 triangle_faces[i],
144 weight,
145 twin_weight,
146 ));
147
148 i += 1;
149 }
150
151 edges
152 }
153
154 fn wire_triangulation_faces_edges_vertexes(
155 &mut self,
156 perimeter_face: FaceId,
157 inner_edges: &[EdgeId],
158 ) {
159 let inner_edges_circular_tuple_windows = inner_edges
160 .iter()
161 .zip(inner_edges.iter().skip(1).chain(inner_edges.iter().take(1)));
162 let mut perimeter_half_edges_walker = self.face_half_edges(perimeter_face).walker();
163
164 for (inner_edge, next_inner_edge) in inner_edges_circular_tuple_windows {
165 let perimeter_half_edge = perimeter_half_edges_walker.next(self).unwrap();
166 let triangle_face = self.face_in_front(inner_edge.backward());
167
168 self.wire_inner_half_edge_chain(
169 triangle_face,
170 &[
171 self.full_edge(perimeter_half_edge),
172 self.full_edge(next_inner_edge.forward()),
173 self.full_edge(inner_edge.backward()),
174 ],
175 );
176 }
177 }
178}