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