Wildmeshing Toolkit
Loading...
Searching...
No Matches
ClosedStarIterable.cpp
Go to the documentation of this file.
2
8
9namespace wmtk::simplex {
10
11
13 : m_mesh(mesh)
14 , m_simplex(simplex)
15 , m_tdc_itrbl(mesh, simplex, true)
16 , m_it_end(m_tdc_itrbl.end())
17{}
18
20 : m_container(container)
21 , m_mesh(container.m_mesh)
22 , m_it(container.m_tdc_itrbl, t)
23 , m_t(t)
24{
25 if (m_t.is_null()) {
26 return;
27 }
28
30
31 if (depth() == 3) {
33 }
34
35 init();
36}
37
39{
40 if (depth() == 3) {
41 return step_depth_3();
42 }
43
44 const int8_t s = get_primitive_type_id(m_container.m_simplex.primitive_type());
45
46 if (m_phase == IteratorPhase::Faces) {
47 if (step_faces()) {
48 return *this;
49 } else {
50 m_face_counter = 0;
51 m_pt = s;
53 }
54 }
55
56 if (s == m_mesh.top_cell_dimension()) {
57 m_t = Tuple();
58 m_pt = -1;
59 return *this;
60 }
61
62 switch (m_mesh.top_simplex_type()) {
63 case PrimitiveType::Edge: return step_edge_mesh();
64 case PrimitiveType::Triangle: return step_tri_mesh();
65 case PrimitiveType::Tetrahedron: return step_tet_mesh();
67 default: assert(false); break;
68 }
69
70 // unreachable code
71 m_t = Tuple();
72 m_pt = -1;
73 return *this;
74}
75
77{
78 return (m_t != other.m_t) || (m_pt != other.m_pt);
79}
80
82{
83 return m_container.m_mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt));
84}
85
87{
88 return m_container.m_mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt));
89}
90
92{
93 const simplex::Simplex& simplex = m_container.m_simplex;
96
98}
99
101
103{
104 const simplex::Simplex& simplex = m_container.m_simplex;
105 auto& visited_c = m_container.m_visited_cofaces;
106 auto& visited_l = m_container.m_visited_link;
107
109 assert(simplex.primitive_type() == PrimitiveType::Vertex);
110
111 ++m_pt;
112 while (true) {
113 if (m_phase == IteratorPhase::OpenStar) {
114 if (m_pt == 4) {
115 // go to link
116 m_t = navigate_to_link(*m_it);
117 m_pt = 0;
118 m_face_counter = 0;
119 m_phase = IteratorPhase::Link;
120
121 } else {
122 for (; m_face_counter < 3; ++m_face_counter) {
123 for (; m_pt < 3; ++m_pt) {
124 if (!visited_c[m_pt - 1].is_visited(
126 return *this;
127 }
128 }
130 m_pt = 1;
131 }
132
133 // return tet
134 m_pt = 3;
135 return *this;
136 }
137 }
138 if (m_phase == IteratorPhase::Link) {
139 if (m_pt == 3) {
140 // go to next cell
141 m_phase = IteratorPhase::OpenStar;
142 m_pt = 1;
143 m_face_counter = 0;
144 ++m_it;
145 m_t = *m_it;
146 if (m_t.is_null()) {
147 m_pt = -1;
148 // m_pt = m_pt;
149 return *this;
150 }
151 } else {
152 for (; m_face_counter < 3; ++m_face_counter) {
153 for (; m_pt < 2; ++m_pt) {
154 if (!visited_l[m_pt].is_visited(
156 return *this;
157 }
158 }
160 m_pt = 0;
161 }
162
163 // return face
164 m_pt = 2;
165 return *this;
166 }
167 }
168 }
169}
170
172{
173 ++m_face_counter;
174
175 switch (m_face_counter) {
176 case 1: m_pt = 1; return *this;
177 case 2:
178 m_pt = 0;
180 return *this;
181 default: break;
182 }
183 m_pt = 1;
184 m_face_counter = 1;
185
186 ++m_it;
187 m_t = *m_it;
188
189 if (m_t.is_null()) {
190 m_pt = -1;
191 }
192
193 return *this;
194}
195
197{
198 const simplex::Simplex& simplex = m_container.m_simplex;
199
202
203 ++m_face_counter;
204
205 switch (simplex.primitive_type()) {
206 case PV: {
207 if (m_it.is_intermediate() && m_face_counter == 2) {
208 m_pt = 0;
209 m_t = m_mesh.switch_tuple(m_t, PV);
210 m_face_counter = 4;
211 return *this;
212 }
213 switch (m_face_counter) {
214 case 1: m_pt = 1; return *this;
215 case 2: m_pt = 2; return *this;
216 case 3:
217 m_pt = 0;
218 m_t = m_mesh.switch_tuples(m_t, {PV, PE});
219 return *this;
220 case 4: m_pt = 1; return *this;
221 default: break;
222 }
223 m_pt = 1;
224 break;
225 }
226 case PE: {
227 switch (m_face_counter) {
228 case 1: m_pt = 2; return *this;
229 case 2:
230 m_pt = 1;
231 m_t = m_mesh.switch_tuple(m_t, PE);
232 return *this;
233 case 3:
234 m_pt = 0;
235 m_t = m_mesh.switch_tuples(m_t, {PV, PE});
236 return *this;
237 case 4: m_pt = 1; return *this;
238 default: break;
239 }
240 m_pt = 2;
241 break;
242 }
245 default: assert(false); break;
246 }
247
248 m_face_counter = 1;
249
250 ++m_it;
251 m_t = *m_it;
252
253 if (m_t.is_null()) {
254 m_pt = -1;
255 }
256
257 return *this;
258}
259
261{
262 const simplex::Simplex& simplex = m_container.m_simplex;
263
267
268 ++m_face_counter;
269
270 switch (simplex.primitive_type()) {
271 case PE: {
272 if (m_it.is_intermediate() && m_face_counter == 5) {
273 m_pt = 2;
274 break;
275 }
276 switch (m_face_counter) {
277 case 1: m_pt = 2; return *this; // coface triangle
278 case 2: // link vertex
279 m_pt = 0;
280 m_t = m_mesh.switch_tuples(m_t, {PE, PV});
281 return *this;
282 case 3: m_pt = 1; return *this;
283 case 4: m_t = m_mesh.switch_tuple(m_t, PE); return *this;
284 case 5: m_t = m_mesh.switch_tuples(m_t, {PF, PE}); return *this;
285 case 6: m_pt = 2; return *this;
286 case 7: m_t = m_mesh.switch_tuple(m_t, PF); return *this;
287 case 8: m_pt = 3; return *this;
288 default: break;
289 }
290 m_pt = 2;
291 break;
292 }
293 case PF: {
294 switch (m_face_counter) {
295 case 1: m_pt = 3; return *this;
296 case 2: // link vertex
297 m_pt = 0;
298 m_t = m_mesh.switch_tuples(m_t, {PF, PE, PV});
299 return *this;
300 case 3: m_pt = 1; return *this;
301 case 4: m_pt = 2; return *this;
302 case 5:
303 m_pt = 1;
304 m_t = m_mesh.switch_tuples(m_t, {PF, PE});
305 return *this;
306 case 6: m_pt = 2; return *this;
307 case 7:
308 m_pt = 1;
309 m_t = m_mesh.switch_tuples(m_t, {PF, PE});
310 return *this;
311 case 8: m_pt = 2; return *this;
312 default: break;
313 }
314 m_pt = 3;
315 break;
316 }
319 default: break;
320 }
321
322 m_face_counter = 1;
323
324 ++m_it;
325 m_t = *m_it;
326
327 if (m_t.is_null()) {
328 m_pt = -1;
329 }
330
331 return *this;
332}
333
335{
336 if (t.is_null()) {
337 return t;
338 }
339 const simplex::Simplex& simplex = m_container.m_simplex;
340
341 /*
342 * Assume a tuple that contains the vertices (a,b,c,d) and the simplex is an edge, i.e.,
343 * (a,b). The link contains all the vertices that are not in the simplex. To get a tuple
344 * that represents all simplices of the link, we need to move (a,b) to the end of that
345 * tuple.
346 * (a,b,c,d) becomes (c,d,a,b) with the following permutations
347 * (a,b,c,d)
348 * switch edge: (a,c,b,d)
349 * switch face: (a,c,d,b)
350 * switch vert: (c,a,d,b)
351 * switch edge: (c,d,a,b)
352 *
353 * The following code implements these permutations.
354 */
355 const int8_t m = m_mesh.top_cell_dimension();
356 const int8_t s = get_primitive_type_id(simplex.primitive_type());
357
358 for (int8_t j = s; j > -1; --j) {
359 for (int8_t i = 0; i < m - s; ++i) {
361 }
362 }
363
364
365 return t;
366}
367
369{
370 switch (m_container.m_simplex.primitive_type()) {
371 case PrimitiveType::Vertex: return false;
372 case PrimitiveType::Edge: return step_faces_edge();
373 case PrimitiveType::Triangle: return step_faces_triangle();
374 case PrimitiveType::Tetrahedron: return step_faces_tetrahedron();
375 default: assert(false);
376 }
377 return false;
378}
379
381{
382 if (m_face_counter == 2) {
383 return false;
384 }
385 m_pt = 0;
386 m_t = m_container.m_mesh.switch_tuple(m_t, PrimitiveType::Vertex);
387 ++m_face_counter;
388 return true;
389}
390
392{
393 ++m_pt;
394 if (m_pt > 1) {
395 if (m_face_counter == 3) {
396 return false;
397 }
398 ++m_face_counter;
399 m_pt = 0;
400 m_t = m_container.m_mesh.switch_tuples(m_t, {PrimitiveType::Vertex, PrimitiveType::Edge});
401 }
402 return true;
403}
404
406{
410
411 switch (m_face_counter) {
412 case 0: m_pt = 0; break; // the tet itself
413 case 1: m_pt = 1; break;
414 case 2:
415 m_t = m_mesh.switch_tuples(m_t, {PV, PE});
416 m_pt = 0;
417 break;
418 case 3: m_pt = 1; break;
419 case 4:
420 m_t = m_mesh.switch_tuples(m_t, {PV, PE});
421 m_pt = 0;
422 break;
423 case 5: m_pt = 1; break;
424 case 6: m_pt = 2; break; // base triangle
425 case 7: // opposite vertex
426 m_t = m_mesh.switch_tuples(m_t, {PF, PE, PV});
427 m_pt = 0;
428 break;
429 case 8: m_pt = 1; break;
430 case 9: m_pt = 2; break;
431 case 10:
432 m_t = m_mesh.switch_tuples(m_t, {PF, PE});
433 m_pt = 1;
434 break;
435 case 11: m_pt = 2; break;
436 case 12:
437 m_t = m_mesh.switch_tuples(m_t, {PF, PE});
438 m_pt = 1;
439 break;
440 case 13: m_pt = 2; break;
441 default: return false;
442 }
443
444 ++m_face_counter;
445 return true;
446}
447
448} // namespace wmtk::simplex
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Definition Mesh.hpp:953
int64_t top_cell_dimension() const
Definition Mesh.hpp:978
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
simplex::IdSimplex get_id_simplex(const Tuple &tuple, PrimitiveType pt) const
Retrieve the IdSimplex that is represented by the tuple and primitive type.
Definition Mesh.cpp:28
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
bool is_null() const
Checks if a tuple is "null". This merely implies the global index is -1.
Definition Tuple.hxx:41
Iterator & step_depth_3()
Use breadth first search to find all d-simplices, and iterate through all cofaces in a d-simplex.
bool operator!=(const Iterator &other) const
int64_t depth()
Compute the depth from the mesh and the simplex type.
Iterator(ClosedStarIterable &container, const Tuple &t=Tuple())
void init()
Depending on the depth, the iterator must be initialized differently.
This iterator internally uses TopDimensionCofacesIterable.
ClosedStarIterable(const Mesh &mesh, const Simplex &simplex)
PrimitiveType primitive_type() const
Definition Simplex.hpp:51
constexpr wmtk::PrimitiveType PF
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
constexpr PrimitiveType PE
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.
constexpr PrimitiveType PV