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