fj_core/operations/replace/
curve.rs

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