honeycomb_core/cmap/dim3/sews/
two.rs

1//! 2D sew implementations
2
3use crate::{
4    attributes::{AttributeStorage, UnknownAttributeStorage},
5    cmap::{CMap3, DartIdType, NULL_DART_ID, SewError},
6    geometry::CoordsFloat,
7    stm::{Transaction, TransactionClosureResult, abort, try_or_coerce},
8};
9
10/// **2-(un)sews internals**
11impl<T: CoordsFloat> CMap3<T> {
12    #[allow(clippy::too_many_lines)]
13    /// 2-sew transactional operation.
14    pub(crate) fn two_sew(
15        &self,
16        trans: &mut Transaction,
17        ld: DartIdType,
18        rd: DartIdType,
19    ) -> TransactionClosureResult<(), SewError> {
20        let b1ld = self.betas[(1, ld)].read(trans)?;
21        let b1rd = self.betas[(1, rd)].read(trans)?;
22        // match (is lhs 1-free, is rhs 1-free)
23        match (b1ld == NULL_DART_ID, b1rd == NULL_DART_ID) {
24            // trivial case, no update needed
25            (true, true) => {
26                let eid_l = self.edge_id_transac(trans, ld)?;
27                let eid_r = self.edge_id_transac(trans, b1rd)?;
28                try_or_coerce!(self.betas.two_link_core(trans, ld, rd), SewError);
29                let eid_new = self.edge_id_transac(trans, ld)?;
30                try_or_coerce!(
31                    self.attributes
32                        .merge_edge_attributes(trans, eid_new, eid_l, eid_r),
33                    SewError
34                );
35            }
36            // update vertex associated to b1rhs/lhs
37            (true, false) => {
38                // fetch vertices ID before topology update
39                let eid_l = self.edge_id_transac(trans, ld)?;
40                let eid_r = self.edge_id_transac(trans, b1rd)?;
41                let vid_l = self.vertex_id_transac(trans, ld)?;
42                let vid_b1r = self.vertex_id_transac(trans, b1rd)?;
43                // update the topology
44                try_or_coerce!(self.betas.two_link_core(trans, ld, rd), SewError);
45                // merge vertices & attributes from the old IDs to the new one
46                let vid_l_new = self.vertex_id_transac(trans, ld)?;
47                let eid_new = self.edge_id_transac(trans, ld)?;
48                try_or_coerce!(
49                    self.vertices.merge(trans, vid_l_new, vid_l, vid_b1r),
50                    SewError
51                );
52                try_or_coerce!(
53                    self.attributes
54                        .merge_vertex_attributes(trans, vid_l_new, vid_l, vid_b1r),
55                    SewError
56                );
57                try_or_coerce!(
58                    self.attributes
59                        .merge_edge_attributes(trans, eid_new, eid_l, eid_r),
60                    SewError
61                );
62            }
63            // update vertex associated to b1lhs/rhs
64            (false, true) => {
65                // fetch vertices ID before topology update
66                let eid_l = self.edge_id_transac(trans, ld)?;
67                let eid_r = self.edge_id_transac(trans, b1rd)?;
68                let vid_b1l = self.vertex_id_transac(trans, b1ld)?;
69                let vid_r = self.vertex_id_transac(trans, rd)?;
70                // update the topology
71                try_or_coerce!(self.betas.two_link_core(trans, ld, rd), SewError);
72                // merge vertices & attributes from the old IDs to the new one
73                let vid_r_new = self.vertex_id_transac(trans, rd)?;
74                let eid_new = self.edge_id_transac(trans, ld)?;
75                try_or_coerce!(
76                    self.vertices.merge(trans, vid_r_new, vid_b1l, vid_r),
77                    SewError
78                );
79                try_or_coerce!(
80                    self.attributes
81                        .merge_vertex_attributes(trans, vid_r_new, vid_b1l, vid_r),
82                    SewError
83                );
84                try_or_coerce!(
85                    self.attributes
86                        .merge_edge_attributes(trans, eid_new, eid_l, eid_r),
87                    SewError
88                );
89            }
90            // update both vertices making up the edge
91            (false, false) => {
92                // fetch vertices ID before topology update
93                let eid_l = self.edge_id_transac(trans, ld)?;
94                let eid_r = self.edge_id_transac(trans, b1rd)?;
95                // (lhs/b1rhs) vertex
96                let vid_l = self.vertex_id_transac(trans, ld)?;
97                let vid_b1r = self.vertex_id_transac(trans, b1rd)?;
98                // (b1lhs/rhs) vertex
99                let vid_b1l = self.vertex_id_transac(trans, b1ld)?;
100                let vid_r = self.vertex_id_transac(trans, rd)?;
101
102                // check orientation
103                if let (
104                    // (lhs/b1rhs) vertices
105                    Ok(Some(l_vertex)),
106                    Ok(Some(b1r_vertex)),
107                    // (b1lhs/rhs) vertices
108                    Ok(Some(b1l_vertex)),
109                    Ok(Some(r_vertex)),
110                ) = (
111                    // (lhs/b1rhs)
112                    self.vertices.read(trans, vid_l),
113                    self.vertices.read(trans, vid_b1r),
114                    // (b1lhs/rhs)
115                    self.vertices.read(trans, vid_b1l),
116                    self.vertices.read(trans, vid_r),
117                ) {
118                    let lhs_vector = b1l_vertex - l_vertex;
119                    let rhs_vector = b1r_vertex - r_vertex;
120                    // dot product should be negative if the two darts have opposite direction
121                    // we could also put restriction on the angle made by the two darts to prevent
122                    // drastic deformation
123                    if lhs_vector.dot(&rhs_vector) >= T::zero() {
124                        abort(SewError::BadGeometry(2, ld, rd))?;
125                    }
126                }
127
128                // update the topology
129                try_or_coerce!(self.betas.two_link_core(trans, ld, rd), SewError);
130                // merge vertices & attributes from the old IDs to the new one
131                let vid_l_new = self.vertex_id_transac(trans, ld)?;
132                let vid_r_new = self.vertex_id_transac(trans, rd)?;
133                let eid_new = self.edge_id_transac(trans, ld)?;
134                try_or_coerce!(
135                    self.vertices.merge(trans, vid_l_new, vid_l, vid_b1r),
136                    SewError
137                );
138                try_or_coerce!(
139                    self.vertices.merge(trans, vid_r_new, vid_b1l, vid_r),
140                    SewError
141                );
142                try_or_coerce!(
143                    self.attributes
144                        .merge_vertex_attributes(trans, vid_l_new, vid_l, vid_b1r),
145                    SewError
146                );
147                try_or_coerce!(
148                    self.attributes
149                        .merge_vertex_attributes(trans, vid_r_new, vid_b1l, vid_r),
150                    SewError
151                );
152                try_or_coerce!(
153                    self.attributes
154                        .merge_edge_attributes(trans, eid_new, eid_l, eid_r),
155                    SewError
156                );
157            }
158        }
159        Ok(())
160    }
161
162    /// 2-unsew transactional operation.
163    pub(crate) fn two_unsew(
164        &self,
165        trans: &mut Transaction,
166        ld: DartIdType,
167    ) -> TransactionClosureResult<(), SewError> {
168        let rd = self.betas[(2, ld)].read(trans)?;
169        let b1ld = self.betas[(1, ld)].read(trans)?;
170        let b1rd = self.betas[(1, rd)].read(trans)?;
171        // match (is lhs 1-free, is rhs 1-free)
172        match (b1ld == NULL_DART_ID, b1rd == NULL_DART_ID) {
173            (true, true) => {
174                // fetch IDs before topology update
175                let eid_old = self.edge_id_transac(trans, ld)?;
176                // update the topology
177                try_or_coerce!(self.betas.two_unlink_core(trans, ld), SewError);
178                // split attributes from the old ID to the new ones
179                // FIXME: VertexIdentifier should be cast to DartIdentifier
180                try_or_coerce!(
181                    self.attributes
182                        .split_edge_attributes(trans, ld, rd, eid_old),
183                    SewError
184                );
185            }
186            (true, false) => {
187                // fetch IDs before topology update
188                let eid_old = self.edge_id_transac(trans, ld)?;
189                let vid_l = self.vertex_id_transac(trans, ld)?;
190                // update the topology
191                try_or_coerce!(self.betas.two_unlink_core(trans, ld), SewError);
192                // split vertex & attributes from the old ID to the new ones
193                // FIXME: VertexIdentifier should be cast to DartIdentifier
194                try_or_coerce!(
195                    self.attributes
196                        .split_edge_attributes(trans, ld, rd, eid_old),
197                    SewError
198                );
199                let (vid_l_newl, vid_l_newr) = (
200                    self.vertex_id_transac(trans, ld)?,
201                    self.vertex_id_transac(trans, b1rd)?,
202                );
203                try_or_coerce!(
204                    self.vertices.split(trans, vid_l_newl, vid_l_newr, vid_l),
205                    SewError
206                );
207                try_or_coerce!(
208                    self.attributes
209                        .split_vertex_attributes(trans, vid_l_newl, vid_l_newr, vid_l),
210                    SewError
211                );
212            }
213            (false, true) => {
214                // fetch IDs before topology update
215                let eid_old = self.edge_id_transac(trans, ld)?;
216                let vid_r = self.vertex_id_transac(trans, rd)?;
217                // update the topology
218                try_or_coerce!(self.betas.two_unlink_core(trans, ld), SewError);
219                // split vertex & attributes from the old ID to the new ones
220                // FIXME: VertexIdentifier should be cast to DartIdentifier
221                try_or_coerce!(
222                    self.attributes
223                        .split_edge_attributes(trans, ld, rd, eid_old),
224                    SewError
225                );
226                let (vid_r_newl, vid_r_newr) = (
227                    self.vertex_id_transac(trans, b1ld)?,
228                    self.vertex_id_transac(trans, rd)?,
229                );
230                try_or_coerce!(
231                    self.vertices.split(trans, vid_r_newl, vid_r_newr, vid_r),
232                    SewError
233                );
234                try_or_coerce!(
235                    self.attributes
236                        .split_vertex_attributes(trans, vid_r_newl, vid_r_newr, vid_r),
237                    SewError
238                );
239            }
240            (false, false) => {
241                // fetch IDs before topology update
242                let eid_old = self.edge_id_transac(trans, ld)?;
243                let vid_l = self.vertex_id_transac(trans, ld)?;
244                let vid_r = self.vertex_id_transac(trans, rd)?;
245                // update the topology
246                try_or_coerce!(self.betas.two_unlink_core(trans, ld), SewError);
247                // split vertices & attributes from the old ID to the new ones
248                // FIXME: VertexIdentifier should be cast to DartIdentifier
249                try_or_coerce!(
250                    self.attributes
251                        .split_edge_attributes(trans, ld, rd, eid_old),
252                    SewError
253                );
254                let (vid_l_newl, vid_l_newr) = (
255                    self.vertex_id_transac(trans, ld)?,
256                    self.vertex_id_transac(trans, b1rd)?,
257                );
258                let (vid_r_newl, vid_r_newr) = (
259                    self.vertex_id_transac(trans, b1ld)?,
260                    self.vertex_id_transac(trans, rd)?,
261                );
262                try_or_coerce!(
263                    self.vertices.split(trans, vid_l_newl, vid_l_newr, vid_l),
264                    SewError
265                );
266                try_or_coerce!(
267                    self.vertices.split(trans, vid_r_newl, vid_r_newr, vid_r),
268                    SewError
269                );
270                try_or_coerce!(
271                    self.attributes
272                        .split_vertex_attributes(trans, vid_l_newl, vid_l_newr, vid_l),
273                    SewError
274                );
275                try_or_coerce!(
276                    self.attributes
277                        .split_vertex_attributes(trans, vid_r_newl, vid_r_newr, vid_r),
278                    SewError
279                );
280            }
281        }
282        Ok(())
283    }
284}