1use maplike::{Get, Insert, Push};
6
7use crate::{Dcel, EdgeId, Face, FaceId, HalfEdge, HalfEdgeId, Vertex, VertexId};
8
9impl<
10 VW: Clone,
11 HEW: Clone + Default,
12 FW: Clone + Default,
13 VC: Get<usize, Value = Vertex<VW>> + Insert<usize> + Push<usize>,
14 HEC: Get<usize, Value = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
15 FC: Get<usize, Value = Face<FW>> + Insert<usize> + Push<usize>,
16> Dcel<VW, HEW, FW, VC, HEC, FC>
17{
18 pub fn split_edge_by_vertex(
19 &mut self,
20 edge_to_split: EdgeId,
21 vertex: VW,
22 ) -> (VertexId, EdgeId) {
23 let (source, _) = self.edge_endpoints(edge_to_split);
24 let forward = edge_to_split.lesser();
25 let backward = edge_to_split.greater();
26 let face = self.incident_face(forward);
27 let twin_face = self.incident_face(backward);
28 let (forward_weight, backward_weight) = self.edge_weights(edge_to_split);
29 let (forward_weight, backward_weight) = (forward_weight.clone(), backward_weight.clone());
30
31 let new_vertex = self.add_unwired_vertex(vertex);
32 let (new_forward, _) = self.add_unwired_edge(
33 source,
34 new_vertex,
35 face,
36 twin_face,
37 forward_weight.clone(),
38 backward_weight.clone(),
39 );
40 let new_edge = self.full_edge(new_forward);
41
42 self.half_edges.insert(
44 forward.id(),
45 HalfEdge {
46 source: new_vertex,
47 ..self.half_edges.get(&forward.id()).unwrap().clone()
48 },
49 );
50
51 let forward_prev = self.prev(forward);
52 let backward_next = self.next(backward);
53
54 self.link_subsequent_half_edges(forward_prev, new_edge.lesser());
56 self.link_subsequent_half_edges(new_edge.lesser(), forward);
57
58 self.link_subsequent_half_edges(backward, new_edge.greater());
60 self.link_subsequent_half_edges(new_edge.greater(), backward_next);
61
62 self.link_vertex_with_half_edge(new_vertex, forward);
65 if self.vertex_representative(source) == forward {
66 self.link_vertex_with_half_edge(source, new_edge.lesser());
67 }
68
69 (new_vertex, new_edge)
70 }
71
72 pub fn split_face_by_edge(
73 &mut self,
74 from: VertexId,
75 to: VertexId,
76 face_to_split: FaceId,
77 ) -> ((HalfEdgeId, HalfEdgeId), FaceId) {
78 let (mut new_edges, new_face) = self.split_face_by_edge_chain(from, to, [], face_to_split);
79 let new_edge = new_edges
80 .pop()
81 .expect("split_face_by_edge should create exactly one edge");
82
83 (new_edge, new_face)
84 }
85
86 pub fn split_face_by_edge_chain(
87 &mut self,
88 from: VertexId,
89 to: VertexId,
90 vertex_weights: impl IntoIterator<Item = VW>,
91 face_to_split: FaceId,
92 ) -> (Vec<(HalfEdgeId, HalfEdgeId)>, FaceId) {
93 self.split_face_by_edge_chain_with_all_weights(
94 from,
95 to,
96 vertex_weights,
97 std::iter::repeat((HEW::default(), HEW::default())),
98 face_to_split,
99 FW::default(),
100 )
101 }
102}
103
104impl<
105 VW: Clone,
106 HEW: Clone,
107 FW: Clone,
108 VC: Get<usize, Value = Vertex<VW>> + Insert<usize> + Push<usize>,
109 HEC: Get<usize, Value = HalfEdge<HEW>> + Insert<usize> + Push<usize>,
110 FC: Get<usize, Value = Face<FW>> + Insert<usize> + Push<usize>,
111> Dcel<VW, HEW, FW, VC, HEC, FC>
112{
113 pub fn split_face_by_edge_chain_with_all_weights(
114 &mut self,
115 from: VertexId,
116 to: VertexId,
117 vertex_weights: impl IntoIterator<Item = VW>,
118 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
119 face_to_split: FaceId,
120 new_face_weight: FW,
121 ) -> (Vec<(HalfEdgeId, HalfEdgeId)>, FaceId) {
122 let from_incoming = self.find_prev_incident_half_spoke(from, face_to_split);
123 let from_outgoing = self.find_incident_half_spoke(from, face_to_split);
124 let to_incoming = self.find_prev_incident_half_spoke(to, face_to_split);
125 let to_outgoing = self.find_incident_half_spoke(to, face_to_split);
126
127 let new_face = self.add_unwired_face(new_face_weight);
128 let (mut new_edges, last_vertex, last_edge_weight) = self.add_unwired_dangling_edge_chain(
129 from,
130 vertex_weights,
131 edge_weights,
132 face_to_split,
133 new_face,
134 );
135 let (forward, backward) = self.add_unwired_edge(
136 last_vertex,
137 to,
138 face_to_split,
139 new_face,
140 last_edge_weight.0,
141 last_edge_weight.1,
142 );
143 new_edges.push((forward, backward));
144
145 let mut face_to_split_directed_edges: Vec<(HalfEdgeId, HalfEdgeId)> = vec![];
146 face_to_split_directed_edges.push((from_incoming, self.twin(from_incoming)));
147 face_to_split_directed_edges.extend(new_edges.iter().copied());
148 face_to_split_directed_edges.push((to_outgoing, self.twin(to_outgoing)));
149
150 let mut curr_half_edge = self.next(to_outgoing);
152 while curr_half_edge != from_incoming {
153 face_to_split_directed_edges.push((curr_half_edge, self.twin(curr_half_edge)));
154 curr_half_edge = self.next(curr_half_edge);
155 }
156
157 let mut new_face_directed_edges: Vec<(HalfEdgeId, HalfEdgeId)> = vec![];
158 new_face_directed_edges.push((to_incoming, self.twin(to_incoming)));
159 new_face_directed_edges.extend(
160 new_edges
161 .iter()
162 .rev()
163 .map(|(forward, backward)| (*backward, *forward)),
164 );
165 new_face_directed_edges.push((from_outgoing, self.twin(from_outgoing)));
166
167 let mut curr_half_edge = self.next(from_outgoing);
169 while curr_half_edge != to_incoming {
170 new_face_directed_edges.push((curr_half_edge, self.twin(curr_half_edge)));
171 curr_half_edge = self.next(curr_half_edge);
172 }
173
174 self.wire_inner_half_edge_chain(
175 face_to_split,
176 &face_to_split_directed_edges
177 .iter()
178 .map(|(forward, _)| *forward)
179 .collect::<Vec<HalfEdgeId>>(),
180 );
181 self.wire_inner_half_edge_chain(
182 new_face,
183 &new_face_directed_edges
184 .iter()
185 .map(|(forward, _)| *forward)
186 .collect::<Vec<HalfEdgeId>>(),
187 );
188
189 (new_edges, new_face)
190 }
191
192 fn add_unwired_dangling_edge_chain(
193 &mut self,
194 from: VertexId,
195 dangling_vertex_weights: impl IntoIterator<Item = VW>,
196 edge_weights: impl IntoIterator<Item = (HEW, HEW)>,
197 face: FaceId,
198 twin_face: FaceId,
199 ) -> (Vec<(HalfEdgeId, HalfEdgeId)>, VertexId, (HEW, HEW)) {
200 let mut edge_weights = edge_weights.into_iter();
201 let mut edges = vec![];
202 let mut last_vertex = from;
203
204 for (vertex_weight, edge_weight) in dangling_vertex_weights
205 .into_iter()
206 .zip(edge_weights.by_ref())
207 {
208 let (new_edge, new_vertex) = self.add_unwired_dangling_edge(
209 last_vertex,
210 vertex_weight,
211 edge_weight,
212 face,
213 twin_face,
214 );
215
216 edges.push(new_edge);
217 last_vertex = new_vertex;
218 }
219
220 (edges, last_vertex, edge_weights.next().unwrap())
221 }
222
223 fn add_unwired_dangling_edge(
224 &mut self,
225 from: VertexId,
226 dangling_vertex_weight: VW,
227 edge_weights: (HEW, HEW),
228 face: FaceId,
229 twin_face: FaceId,
230 ) -> ((HalfEdgeId, HalfEdgeId), VertexId) {
231 let dangling_vertex = self.add_unwired_vertex(dangling_vertex_weight);
232 let (forward, backward) = self.add_unwired_edge(
233 from,
234 dangling_vertex,
235 face,
236 twin_face,
237 edge_weights.0,
238 edge_weights.1,
239 );
240 let dangling_edge = (forward, backward);
241
242 (dangling_edge, dangling_vertex)
243 }
244}
245
246#[cfg(all(test, feature = "stable-vec"))]
247mod test {
248 use crate::{
249 EdgeId, FaceId, HalfEdgeId, StableDcel, VertexId, assert_face_boundary,
250 init_dcel_with_3x3_hex_mesh,
251 };
252
253 #[test]
254 fn test_split_edge_by_vertex() {
255 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
256 let face = FaceId::new(5);
257 let edge = EdgeId::new(HalfEdgeId::new(38), HalfEdgeId::new(39));
258 let old_source = dcel.source(edge.lesser());
259
260 let (_new_vertex, new_edge) = dcel.split_edge_by_vertex(edge, (259, 150));
261
262 assert_eq!(dcel.vertices().num_elements(), 31);
263 assert_eq!(dcel.half_edges().num_elements(), 78);
264 assert_eq!(dcel.faces().num_elements(), 10);
265
266 assert_face_boundary!(&dcel, 0, 0);
267 assert_face_boundary!(&dcel, 1, 6);
268 assert_face_boundary!(&dcel, 2, 6);
269 assert_face_boundary!(&dcel, 3, 6);
270 assert_face_boundary!(&dcel, 4, 7);
271 assert_face_boundary!(&dcel, 5, 7);
272 assert_face_boundary!(&dcel, 6, 6);
273 assert_face_boundary!(&dcel, 7, 6);
274 assert_face_boundary!(&dcel, 8, 6);
275 assert_face_boundary!(&dcel, 9, 6);
276 }
277
278 #[test]
279 fn test_split_face_by_edge() {
280 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
281 let face_to_split = FaceId::new(5);
282 let face_to_split_vertices: Vec<VertexId> = dcel.face_vertices(face_to_split).collect();
283
284 let (_new_edge, _new_face) = dcel.split_face_by_edge(
286 face_to_split_vertices[0],
287 face_to_split_vertices[3],
288 face_to_split,
289 );
290
291 assert_eq!(dcel.vertices().num_elements(), 30);
293 assert_eq!(dcel.half_edges().num_elements(), 78);
294 assert_eq!(dcel.faces().num_elements(), 11);
295
296 assert_face_boundary!(&dcel, 0, 0);
298 assert_face_boundary!(&dcel, 1, 6);
299 assert_face_boundary!(&dcel, 2, 6);
300 assert_face_boundary!(&dcel, 3, 6);
301 assert_face_boundary!(&dcel, 4, 6);
302 assert_face_boundary!(&dcel, 5, 4);
304 assert_face_boundary!(&dcel, 6, 6);
305 assert_face_boundary!(&dcel, 7, 6);
306 assert_face_boundary!(&dcel, 8, 6);
307 assert_face_boundary!(&dcel, 9, 6);
308 assert_face_boundary!(&dcel, 10, 4);
310 }
311
312 #[test]
313 fn test_split_face_by_chain_of_two_edges() {
314 let mut dcel = init_dcel_with_3x3_hex_mesh!(StableDcel<(i32, i32)>);
315 let face_to_split = FaceId::new(5);
316 let face_to_split_vertices: Vec<VertexId> = dcel.face_vertices(face_to_split).collect();
317
318 let (_new_edges, _new_face) = dcel.split_face_by_edge_chain(
321 face_to_split_vertices[0],
322 face_to_split_vertices[3],
323 [(259, 150)],
324 face_to_split,
325 );
326
327 assert_eq!(dcel.vertices().num_elements(), 31);
329 assert_eq!(dcel.half_edges().num_elements(), 80);
330 assert_eq!(dcel.faces().num_elements(), 11);
331
332 assert_face_boundary!(&dcel, 0, 0);
335 assert_face_boundary!(&dcel, 1, 6);
336 assert_face_boundary!(&dcel, 2, 6);
337 assert_face_boundary!(&dcel, 3, 6);
338 assert_face_boundary!(&dcel, 4, 6);
339 assert_face_boundary!(&dcel, 5, 5);
341 assert_face_boundary!(&dcel, 6, 6);
342 assert_face_boundary!(&dcel, 7, 6);
343 assert_face_boundary!(&dcel, 8, 6);
344 assert_face_boundary!(&dcel, 9, 6);
345 assert_face_boundary!(&dcel, 10, 5);
347 }
348}