fj_core/operations/replace/
vertex.rs

1use std::ops::Deref;
2
3use crate::{
4    objects::{
5        Cycle, Face, HalfEdge, IsObject, Region, Shell, Sketch, Solid, Vertex,
6    },
7    operations::{derive::DeriveFrom, insert::Insert, update::UpdateHalfEdge},
8    storage::Handle,
9    Core,
10};
11
12use super::ReplaceOutput;
13
14/// Replace a [`Vertex`] in the referenced object graph
15///
16/// See [module documentation] for more information.
17///
18/// [module documentation]: super
19pub trait ReplaceVertex: IsObject + Sized {
20    /// Replace the vertex
21    #[must_use]
22    fn replace_vertex(
23        &self,
24        original: &Handle<Vertex>,
25        replacement: Handle<Vertex>,
26        core: &mut Core,
27    ) -> ReplaceOutput<Self, Self::BareObject>;
28}
29
30impl ReplaceVertex for HalfEdge {
31    fn replace_vertex(
32        &self,
33        original: &Handle<Vertex>,
34        replacement: Handle<Vertex>,
35        core: &mut Core,
36    ) -> ReplaceOutput<Self, Self::BareObject> {
37        if original.id() == self.start_vertex().id() {
38            ReplaceOutput::Updated(
39                self.update_start_vertex(|_, _| replacement, core),
40            )
41        } else {
42            ReplaceOutput::Original(self.clone())
43        }
44    }
45}
46
47impl ReplaceVertex for Cycle {
48    fn replace_vertex(
49        &self,
50        original: &Handle<Vertex>,
51        replacement: Handle<Vertex>,
52        core: &mut Core,
53    ) -> ReplaceOutput<Self, Self::BareObject> {
54        let mut replacement_happened = false;
55
56        let mut half_edges = Vec::new();
57        for original_half_edge in self.half_edges() {
58            let half_edge = original_half_edge.replace_vertex(
59                original,
60                replacement.clone(),
61                core,
62            );
63            replacement_happened |= half_edge.was_updated();
64            half_edges.push(
65                half_edge
66                    .map_updated(|updated| {
67                        updated
68                            .insert(core)
69                            .derive_from(original_half_edge, core)
70                    })
71                    .into_inner(),
72            );
73        }
74
75        if replacement_happened {
76            ReplaceOutput::Updated(Cycle::new(half_edges))
77        } else {
78            ReplaceOutput::Original(self.clone())
79        }
80    }
81}
82
83impl ReplaceVertex for Region {
84    fn replace_vertex(
85        &self,
86        original: &Handle<Vertex>,
87        replacement: Handle<Vertex>,
88        core: &mut Core,
89    ) -> ReplaceOutput<Self, Self::BareObject> {
90        let mut replacement_happened = false;
91
92        let exterior =
93            self.exterior()
94                .replace_vertex(original, replacement.clone(), core);
95        replacement_happened |= exterior.was_updated();
96
97        let mut interiors = Vec::new();
98        for original_cycle in self.interiors() {
99            let cycle = original_cycle.replace_vertex(
100                original,
101                replacement.clone(),
102                core,
103            );
104            replacement_happened |= cycle.was_updated();
105            interiors.push(
106                cycle
107                    .map_updated(|updated| {
108                        updated.insert(core).derive_from(original_cycle, core)
109                    })
110                    .into_inner(),
111            );
112        }
113
114        if replacement_happened {
115            ReplaceOutput::Updated(Region::new(
116                exterior
117                    .map_updated(|updated| {
118                        updated.insert(core).derive_from(self.exterior(), core)
119                    })
120                    .into_inner(),
121                interiors,
122            ))
123        } else {
124            ReplaceOutput::Original(self.clone())
125        }
126    }
127}
128
129impl ReplaceVertex for Sketch {
130    fn replace_vertex(
131        &self,
132        original: &Handle<Vertex>,
133        replacement: Handle<Vertex>,
134        core: &mut Core,
135    ) -> ReplaceOutput<Self, Self::BareObject> {
136        let mut replacement_happened = false;
137
138        let mut regions = Vec::new();
139        for original_region in self.regions() {
140            let region = original_region.replace_vertex(
141                original,
142                replacement.clone(),
143                core,
144            );
145            replacement_happened |= region.was_updated();
146            regions.push(
147                region
148                    .map_updated(|updated| {
149                        updated.insert(core).derive_from(original_region, core)
150                    })
151                    .into_inner(),
152            );
153        }
154
155        if replacement_happened {
156            ReplaceOutput::Updated(Sketch::new(regions))
157        } else {
158            ReplaceOutput::Original(self.clone())
159        }
160    }
161}
162
163impl ReplaceVertex for Face {
164    fn replace_vertex(
165        &self,
166        original: &Handle<Vertex>,
167        replacement: Handle<Vertex>,
168        core: &mut Core,
169    ) -> ReplaceOutput<Self, Self::BareObject> {
170        let region = self.region().replace_vertex(original, replacement, core);
171
172        if region.was_updated() {
173            ReplaceOutput::Updated(Face::new(
174                self.surface().clone(),
175                region
176                    .map_updated(|updated| {
177                        updated.insert(core).derive_from(self.region(), core)
178                    })
179                    .into_inner(),
180            ))
181        } else {
182            ReplaceOutput::Original(self.clone())
183        }
184    }
185}
186
187impl ReplaceVertex for Shell {
188    fn replace_vertex(
189        &self,
190        original: &Handle<Vertex>,
191        replacement: Handle<Vertex>,
192        core: &mut Core,
193    ) -> ReplaceOutput<Self, Self::BareObject> {
194        let mut replacement_happened = false;
195
196        let mut faces = Vec::new();
197        for original_face in self.faces() {
198            let face = original_face.replace_vertex(
199                original,
200                replacement.clone(),
201                core,
202            );
203            replacement_happened |= face.was_updated();
204            faces.push(
205                face.map_updated(|updated| {
206                    updated.insert(core).derive_from(original_face, core)
207                })
208                .into_inner(),
209            );
210        }
211
212        if replacement_happened {
213            ReplaceOutput::Updated(Shell::new(faces))
214        } else {
215            ReplaceOutput::Original(self.clone())
216        }
217    }
218}
219
220impl ReplaceVertex for Solid {
221    fn replace_vertex(
222        &self,
223        original: &Handle<Vertex>,
224        replacement: Handle<Vertex>,
225        core: &mut Core,
226    ) -> ReplaceOutput<Self, Self::BareObject> {
227        let mut replacement_happened = false;
228
229        let mut shells = Vec::new();
230        for original_shell in self.shells() {
231            let shell = original_shell.replace_vertex(
232                original,
233                replacement.clone(),
234                core,
235            );
236            replacement_happened |= shell.was_updated();
237            shells.push(
238                shell
239                    .map_updated(|updated| {
240                        updated.insert(core).derive_from(original_shell, core)
241                    })
242                    .into_inner(),
243            );
244        }
245
246        if replacement_happened {
247            ReplaceOutput::Updated(Solid::new(shells))
248        } else {
249            ReplaceOutput::Original(self.clone())
250        }
251    }
252}
253
254impl ReplaceVertex for Handle<HalfEdge> {
255    fn replace_vertex(
256        &self,
257        original: &Handle<Vertex>,
258        replacement: Handle<Vertex>,
259        core: &mut Core,
260    ) -> ReplaceOutput<Self, Self::BareObject> {
261        self.deref()
262            .replace_vertex(original, replacement, core)
263            .map_original(|_| self.clone())
264    }
265}
266
267impl ReplaceVertex for Handle<Cycle> {
268    fn replace_vertex(
269        &self,
270        original: &Handle<Vertex>,
271        replacement: Handle<Vertex>,
272        core: &mut Core,
273    ) -> ReplaceOutput<Self, Self::BareObject> {
274        self.deref()
275            .replace_vertex(original, replacement, core)
276            .map_original(|_| self.clone())
277    }
278}
279
280impl ReplaceVertex for Handle<Region> {
281    fn replace_vertex(
282        &self,
283        original: &Handle<Vertex>,
284        replacement: Handle<Vertex>,
285        core: &mut Core,
286    ) -> ReplaceOutput<Self, Self::BareObject> {
287        self.deref()
288            .replace_vertex(original, replacement, core)
289            .map_original(|_| self.clone())
290    }
291}
292
293impl ReplaceVertex for Handle<Sketch> {
294    fn replace_vertex(
295        &self,
296        original: &Handle<Vertex>,
297        replacement: Handle<Vertex>,
298        core: &mut Core,
299    ) -> ReplaceOutput<Self, Self::BareObject> {
300        let mut replacement_happened = false;
301
302        let mut regions = Vec::new();
303        for original_region in self.regions() {
304            let region = original_region.replace_vertex(
305                original,
306                replacement.clone(),
307                core,
308            );
309            replacement_happened |= region.was_updated();
310            regions.push(
311                region
312                    .map_updated(|updated| {
313                        updated.insert(core).derive_from(original_region, core)
314                    })
315                    .into_inner(),
316            );
317        }
318
319        if replacement_happened {
320            ReplaceOutput::Updated(Sketch::new(regions))
321        } else {
322            ReplaceOutput::Original(self.clone())
323        }
324    }
325}
326
327impl ReplaceVertex for Handle<Face> {
328    fn replace_vertex(
329        &self,
330        original: &Handle<Vertex>,
331        replacement: Handle<Vertex>,
332        core: &mut Core,
333    ) -> ReplaceOutput<Self, Self::BareObject> {
334        self.deref()
335            .replace_vertex(original, replacement, core)
336            .map_original(|_| self.clone())
337    }
338}
339
340impl ReplaceVertex for Handle<Shell> {
341    fn replace_vertex(
342        &self,
343        original: &Handle<Vertex>,
344        replacement: Handle<Vertex>,
345        core: &mut Core,
346    ) -> ReplaceOutput<Self, Self::BareObject> {
347        self.deref()
348            .replace_vertex(original, replacement, core)
349            .map_original(|_| self.clone())
350    }
351}
352
353impl ReplaceVertex for Handle<Solid> {
354    fn replace_vertex(
355        &self,
356        original: &Handle<Vertex>,
357        replacement: Handle<Vertex>,
358        core: &mut Core,
359    ) -> ReplaceOutput<Self, Self::BareObject> {
360        self.deref()
361            .replace_vertex(original, replacement, core)
362            .map_original(|_| self.clone())
363    }
364}