1use crate::{
4 attributes::{AttributeStorage, UnknownAttributeStorage},
5 cmap::{CMap3, DartIdType, EdgeIdType, NULL_DART_ID, OrbitPolicy, SewError, VertexIdType},
6 geometry::CoordsFloat,
7 stm::{Transaction, TransactionClosureResult, abort, try_or_coerce},
8};
9
10impl<T: CoordsFloat> CMap3<T> {
12 pub(crate) fn three_sew(
14 &self,
15 trans: &mut Transaction,
16 ld: DartIdType,
17 rd: DartIdType,
18 ) -> TransactionClosureResult<(), SewError> {
19 let l_face = self
22 .orbit(OrbitPolicy::Custom(&[1, 0]), ld)
23 .min()
24 .expect("E: unreachable");
25 let r_face = self
26 .orbit(OrbitPolicy::Custom(&[0, 1]), rd)
27 .min()
28 .expect("E: unreachable");
29 let mut edges: Vec<(EdgeIdType, EdgeIdType)> = Vec::with_capacity(10);
30 let mut vertices: Vec<(VertexIdType, VertexIdType)> = Vec::with_capacity(10);
31
32 for (l, r) in self
34 .orbit(OrbitPolicy::Custom(&[1, 0]), ld)
35 .zip(self.orbit(OrbitPolicy::Custom(&[0, 1]), rd))
36 {
37 edges.push((
38 self.edge_id_transac(trans, l)?,
39 self.edge_id_transac(trans, r)?,
40 ));
41 let b1l = self.beta_transac::<1>(trans, l)?;
42 let b2l = self.beta_transac::<2>(trans, l)?;
43 vertices.push((
45 self.vertex_id_transac(trans, if b1l == NULL_DART_ID { b2l } else { b1l })?,
46 self.vertex_id_transac(trans, r)?,
47 ));
48 if self.beta_transac::<0>(trans, l)? == NULL_DART_ID {
50 let b1r = self.beta_transac::<1>(trans, r)?;
51 let b2r = self.beta_transac::<2>(trans, r)?;
52 vertices.push((
53 self.vertex_id_transac(trans, l)?,
54 self.vertex_id_transac(trans, if b1r == NULL_DART_ID { b2r } else { b1r })?,
55 ));
56 }
57 }
58
59 {
62 let (l, r) = (ld, rd);
63 let (b1l, b2l, b1r, b2r) = (
64 self.beta_transac::<1>(trans, l)?,
65 self.beta_transac::<2>(trans, l)?,
66 self.beta_transac::<1>(trans, r)?,
67 self.beta_transac::<2>(trans, r)?,
68 );
69 let (vid_l, vid_r, vid_b1l, vid_b1r) = (
70 self.vertex_id_transac(trans, l)?,
71 self.vertex_id_transac(trans, r)?,
72 self.vertex_id_transac(trans, if b1l == NULL_DART_ID { b2l } else { b1l })?,
73 self.vertex_id_transac(trans, if b1r == NULL_DART_ID { b2r } else { b1r })?,
74 );
75
76 if let (
77 Some(l_vertex),
79 Some(b1r_vertex),
80 Some(b1l_vertex),
82 Some(r_vertex),
83 ) = (
84 self.vertices.read(trans, vid_l)?,
86 self.vertices.read(trans, vid_b1r)?,
87 self.vertices.read(trans, vid_b1l)?,
89 self.vertices.read(trans, vid_r)?,
90 ) {
91 let lhs_vector = b1l_vertex - l_vertex;
92 let rhs_vector = b1r_vertex - r_vertex;
93 if lhs_vector.dot(&rhs_vector) >= T::zero() {
97 abort(SewError::BadGeometry(3, ld, rd))?;
98 }
99 }
100 }
101
102 try_or_coerce!(self.three_link(trans, ld, rd), SewError);
106
107 try_or_coerce!(
109 self.attributes
110 .merge_face_attributes(trans, l_face.min(r_face), l_face, r_face),
111 SewError
112 );
113
114 for (eid_l, eid_r) in edges.into_iter().filter(|&(eid_l, eid_r)| {
115 eid_l != eid_r && eid_l != NULL_DART_ID && eid_r != NULL_DART_ID
116 }) {
117 try_or_coerce!(
118 self.attributes
119 .merge_edge_attributes(trans, eid_l.min(eid_r), eid_l, eid_r),
120 SewError
121 );
122 }
123 for (vid_l, vid_r) in vertices.into_iter().filter(|&(vid_l, vid_r)| {
124 vid_l != vid_r && vid_l != NULL_DART_ID && vid_r != NULL_DART_ID
125 }) {
126 try_or_coerce!(
127 self.vertices.merge(trans, vid_l.min(vid_r), vid_l, vid_r),
128 SewError
129 );
130 try_or_coerce!(
131 self.attributes
132 .merge_vertex_attributes(trans, vid_l.min(vid_r), vid_l, vid_r),
133 SewError
134 );
135 }
136
137 Ok(())
138 }
139
140 pub(crate) fn three_unsew(
142 &self,
143 trans: &mut Transaction,
144 ld: DartIdType,
145 ) -> TransactionClosureResult<(), SewError> {
146 let rd = self.beta_transac::<3>(trans, ld)?;
147
148 try_or_coerce!(self.unlink::<3>(trans, ld), SewError);
149
150 let l_face = self
152 .orbit(OrbitPolicy::Custom(&[1, 0]), ld)
153 .min()
154 .expect("E: unreachable");
155 let r_face = self
156 .orbit(OrbitPolicy::Custom(&[0, 1]), rd)
157 .min()
158 .expect("E: unreachable");
159 try_or_coerce!(
160 self.attributes
161 .split_face_attributes(trans, l_face, r_face, l_face.max(r_face)),
162 SewError
163 );
164
165 for (l, r) in self
166 .orbit(OrbitPolicy::Custom(&[1, 0]), ld)
167 .zip(self.orbit(OrbitPolicy::Custom(&[0, 1]), rd))
168 {
169 let (eid_l, eid_r) = (
171 self.edge_id_transac(trans, l)?,
172 self.edge_id_transac(trans, r)?,
173 );
174 try_or_coerce!(
175 self.attributes
176 .split_edge_attributes(trans, eid_l, eid_r, eid_l.max(eid_r)),
177 SewError
178 );
179
180 let b1l = self.beta_transac::<1>(trans, l)?;
182 let b2l = self.beta_transac::<2>(trans, l)?;
183 let (vid_l, vid_r) = (
184 self.vertex_id_transac(trans, if b1l == NULL_DART_ID { b2l } else { b1l })?,
185 self.vertex_id_transac(trans, r)?,
186 );
187 try_or_coerce!(
188 self.vertices.split(trans, vid_l, vid_r, vid_l.max(vid_r)),
189 SewError
190 );
191 try_or_coerce!(
192 self.attributes
193 .split_vertex_attributes(trans, vid_l, vid_r, vid_l.max(vid_r)),
194 SewError
195 );
196 if self.beta_transac::<0>(trans, l)? == NULL_DART_ID {
197 let b1r = self.beta_transac::<1>(trans, r)?;
198 let b2r = self.beta_transac::<2>(trans, r)?;
199 let (lvid_l, lvid_r) = (
200 self.vertex_id_transac(trans, l)?,
201 self.vertex_id_transac(trans, if b1r == NULL_DART_ID { b2r } else { b1r })?,
202 );
203 try_or_coerce!(
204 self.vertices
205 .split(trans, lvid_l, lvid_r, lvid_l.max(lvid_r)),
206 SewError
207 );
208 try_or_coerce!(
209 self.attributes.split_vertex_attributes(
210 trans,
211 lvid_l,
212 lvid_r,
213 lvid_l.max(lvid_r),
214 ),
215 SewError
216 );
217 }
218 }
219 Ok(())
220 }
221}