1use honeycomb_core::{
2 cmap::{CMap2, DartIdType, EdgeIdType, SewError},
3 geometry::{CoordsFloat, Vertex2},
4 stm::{Transaction, TransactionClosureResult, retry, try_or_coerce},
5};
6
7use crate::utils::{EdgeAnchor, FaceAnchor, VertexAnchor};
8
9#[inline]
49pub fn cut_outer_edge<T: CoordsFloat>(
50 t: &mut Transaction,
51 map: &CMap2<T>,
52 e: EdgeIdType,
53 [nd1, nd2, nd3]: [DartIdType; 3],
54) -> TransactionClosureResult<(), SewError> {
55 try_or_coerce!(map.link::<2>(t, nd1, nd2), SewError);
57 try_or_coerce!(map.link::<1>(t, nd2, nd3), SewError);
58
59 let f_anchor = if map.contains_attribute::<FaceAnchor>() {
60 let fid = map.face_id_tx(t, e)?;
61 map.remove_attribute::<FaceAnchor>(t, fid)?
62 } else {
63 None
64 };
65 let e_anchor = if map.contains_attribute::<EdgeAnchor>() {
66 map.read_attribute::<EdgeAnchor>(t, e)?
67 } else {
68 None
69 };
70
71 let ld = e as DartIdType;
72 let (b0ld, b1ld) = (map.beta_tx::<0>(t, ld)?, map.beta_tx::<1>(t, ld)?);
73
74 let (vid1, vid2) = (map.vertex_id_tx(t, ld)?, map.vertex_id_tx(t, b1ld)?);
75 let new_v = match (map.read_vertex(t, vid1)?, map.read_vertex(t, vid2)?) {
76 (Some(v1), Some(v2)) => Vertex2::average(&v1, &v2),
77 _ => retry()?,
78 };
79 map.write_vertex(t, nd1, new_v)?;
80
81 map.unsew::<1>(t, ld)?;
82 map.unsew::<1>(t, b1ld)?;
83
84 map.sew::<1>(t, ld, nd1)?;
85 map.sew::<1>(t, nd1, b0ld)?;
86 map.sew::<1>(t, nd3, b1ld)?;
87 map.sew::<1>(t, b1ld, nd2)?;
88
89 if let Some(a) = f_anchor {
91 let fid1 = map.face_id_tx(t, nd1)?;
92 let fid2 = map.face_id_tx(t, nd2)?;
93 map.write_attribute(t, fid1, a)?;
94 map.write_attribute(t, fid2, a)?;
95 if map.contains_attribute::<EdgeAnchor>() {
96 let eid = map.edge_id_tx(t, nd1)?;
97 map.write_attribute(t, eid, EdgeAnchor::from(a))?;
98 }
99 }
100 if let Some(a) = e_anchor {
101 let vid = map.vertex_id_tx(t, nd1)?;
102 map.write_attribute(t, vid, VertexAnchor::from(a))?;
103 map.write_attribute(t, nd3 as EdgeIdType, a)?;
104 }
105
106 Ok(())
107}
108
109#[inline]
154pub fn cut_inner_edge<T: CoordsFloat>(
155 t: &mut Transaction,
156 map: &CMap2<T>,
157 e: EdgeIdType,
158 [nd1, nd2, nd3, nd4, nd5, nd6]: [DartIdType; 6],
159) -> TransactionClosureResult<(), SewError> {
160 try_or_coerce!(map.link::<2>(t, nd1, nd2), SewError);
162 try_or_coerce!(map.link::<1>(t, nd2, nd3), SewError);
163 try_or_coerce!(map.link::<2>(t, nd4, nd5), SewError);
164 try_or_coerce!(map.link::<1>(t, nd5, nd6), SewError);
165
166 let (ld, rd) = (e as DartIdType, map.beta_tx::<2>(t, e as DartIdType)?);
167
168 let lf_anchor = if map.contains_attribute::<FaceAnchor>() {
169 let fid = map.face_id_tx(t, ld)?;
170 map.remove_attribute::<FaceAnchor>(t, fid)?
171 } else {
172 None
173 };
174 if let Some(a) = lf_anchor {
175 if map.contains_attribute::<EdgeAnchor>() {
176 let eid = map.edge_id_tx(t, nd1)?;
177 map.write_attribute(t, eid, EdgeAnchor::from(a))?;
178 }
179 }
180 let rf_anchor = if map.contains_attribute::<FaceAnchor>() {
181 let fid = map.face_id_tx(t, rd)?;
182 map.remove_attribute::<FaceAnchor>(t, fid)?
183 } else {
184 None
185 };
186 if let Some(a) = rf_anchor {
187 if map.contains_attribute::<EdgeAnchor>() {
188 let eid = map.edge_id_tx(t, nd4)?;
189 map.write_attribute(t, eid, EdgeAnchor::from(a))?;
190 }
191 }
192 if map.contains_attribute::<EdgeAnchor>() {
193 if let Some(a) = map.read_attribute::<EdgeAnchor>(t, e)? {
194 let vid1 = map.vertex_id_tx(t, nd1)?;
195 let vid2 = map.vertex_id_tx(t, nd4)?;
196 map.write_attribute(t, vid1, VertexAnchor::from(a))?;
197 map.write_attribute(t, vid2, VertexAnchor::from(a))?;
198 }
199 }
200
201 let (b0ld, b1ld) = (map.beta_tx::<0>(t, ld)?, map.beta_tx::<1>(t, ld)?);
202 let (b0rd, b1rd) = (map.beta_tx::<0>(t, rd)?, map.beta_tx::<1>(t, rd)?);
203
204 let (vid1, vid2) = (map.vertex_id_tx(t, ld)?, map.vertex_id_tx(t, b1ld)?);
205 let new_v = match (map.read_vertex(t, vid1)?, map.read_vertex(t, vid2)?) {
206 (Some(v1), Some(v2)) => Vertex2::average(&v1, &v2),
207 _ => retry()?,
208 };
209 map.write_vertex(t, nd1, new_v)?;
210
211 map.unsew::<2>(t, ld)?;
212 map.unsew::<1>(t, ld)?;
213 map.unsew::<1>(t, b1ld)?;
214 map.unsew::<1>(t, rd)?;
215 map.unsew::<1>(t, b1rd)?;
216
217 map.sew::<2>(t, ld, nd6)?;
218 map.sew::<2>(t, rd, nd3)?;
219
220 map.sew::<1>(t, ld, nd1)?;
221 map.sew::<1>(t, nd1, b0ld)?;
222 map.sew::<1>(t, nd3, b1ld)?;
223 map.sew::<1>(t, b1ld, nd2)?;
224
225 map.sew::<1>(t, rd, nd4)?;
226 map.sew::<1>(t, nd4, b0rd)?;
227 map.sew::<1>(t, nd6, b1rd)?;
228 map.sew::<1>(t, b1rd, nd5)?;
229
230 if let Some(a) = lf_anchor {
232 let fid1 = map.face_id_tx(t, nd1)?;
233 let fid2 = map.face_id_tx(t, nd2)?;
234 map.write_attribute(t, fid1, a)?;
235 map.write_attribute(t, fid2, a)?;
236 }
237 if let Some(a) = rf_anchor {
238 let fid4 = map.face_id_tx(t, nd4)?;
239 let fid5 = map.face_id_tx(t, nd5)?;
240 map.write_attribute(t, fid4, a)?;
241 map.write_attribute(t, fid5, a)?;
242 }
243
244 Ok(())
245}