Wildmeshing Toolkit
find_local_switch_sequence.cpp
Go to the documentation of this file.
2 
3 #include <cassert>
4 #include <optional>
5 #include <stdexcept>
7 #include "local_switch_tuple.hpp"
8 namespace wmtk::multimesh::utils {
9 
10 
11 namespace {
12 
13 bool hash_free_tuple_equality(const Tuple& a, const Tuple& b)
14 {
19 }
20 
21 std::optional<std::vector<PrimitiveType>> find_local_switch_sequence_on_edge(
22  const PrimitiveType mesh_pt,
23  const Tuple& source,
24  const Tuple& target)
25 {
26  assert(mesh_pt >= PrimitiveType::Edge);
27  if (hash_free_tuple_equality(source, target)) {
28  return std::vector<PrimitiveType>{};
29  } else if (hash_free_tuple_equality(
30  local_switch_tuple(mesh_pt, source, PrimitiveType::Vertex),
31  target)) {
32  return std::vector<PrimitiveType>{PrimitiveType::Vertex};
33  }
34  return std::nullopt;
35 }
36 
37 std::optional<std::vector<PrimitiveType>> find_local_switch_sequence_on_triangle(
38  const PrimitiveType mesh_pt,
39  const Tuple& source,
40  const Tuple& target)
41 {
42  assert(mesh_pt >= PrimitiveType::Triangle);
43 
44  Tuple cur_tuple = source;
45  std::vector<PrimitiveType> switches;
46  {
47  const auto edge_local_operations =
48  find_local_switch_sequence_on_edge(mesh_pt, cur_tuple, target);
49  if (edge_local_operations.has_value()) {
50  return edge_local_operations.value();
51  }
52  }
53  switches.emplace_back(PrimitiveType::Edge);
54  cur_tuple = local_switch_tuples(mesh_pt, source, switches);
55  {
56  const auto edge_local_operations =
57  find_local_switch_sequence_on_edge(mesh_pt, cur_tuple, target);
58  if (edge_local_operations.has_value()) {
59  switches.insert(
60  switches.end(),
61  edge_local_operations.value().begin(),
62  edge_local_operations.value().end());
63  return switches;
64  }
65  }
66 
67  switches.insert(switches.begin(), PrimitiveType::Vertex);
68  cur_tuple = local_switch_tuples(mesh_pt, source, switches);
69  {
70  const auto edge_local_operations =
71  find_local_switch_sequence_on_edge(mesh_pt, cur_tuple, target);
72  if (edge_local_operations.has_value()) {
73  switches.insert(
74  switches.end(),
75  edge_local_operations.value().begin(),
76  edge_local_operations.value().end());
77  return switches;
78  }
79  }
80  return std::nullopt;
81 }
82 
83 std::optional<std::vector<PrimitiveType>> find_local_switch_sequence_on_tet(
84  const PrimitiveType mesh_pt,
85  const Tuple& source,
86  const Tuple& target)
87 {
88  assert(mesh_pt == PrimitiveType::Tetrahedron);
89  Tuple cur_tuple = source;
90  std::vector<PrimitiveType> switches;
91 
92  {
93  const auto triangle_local_operations =
94  find_local_switch_sequence_on_triangle(mesh_pt, cur_tuple, target);
95  if (triangle_local_operations.has_value()) {
96  return triangle_local_operations.value();
97  }
98  }
99  switches.emplace_back(PrimitiveType::Triangle);
100  cur_tuple = local_switch_tuples(mesh_pt, source, switches);
101  {
102  const auto triangle_local_operations =
103  find_local_switch_sequence_on_triangle(mesh_pt, cur_tuple, target);
104  if (triangle_local_operations.has_value()) {
105  switches.insert(
106  switches.end(),
107  triangle_local_operations.value().begin(),
108  triangle_local_operations.value().end());
109  return switches;
110  }
111  }
112 
113  switches.insert(switches.begin(), PrimitiveType::Edge);
114  cur_tuple = local_switch_tuples(mesh_pt, source, switches);
115  {
116  const auto triangle_local_operations =
117  find_local_switch_sequence_on_triangle(mesh_pt, cur_tuple, target);
118  if (triangle_local_operations.has_value()) {
119  switches.insert(
120  switches.end(),
121  triangle_local_operations.value().begin(),
122  triangle_local_operations.value().end());
123  return switches;
124  }
125  }
126 
127  switches.insert(switches.begin(), PrimitiveType::Vertex);
128  cur_tuple = local_switch_tuples(mesh_pt, source, switches);
129  {
130  const auto triangle_local_operations =
131  find_local_switch_sequence_on_triangle(mesh_pt, cur_tuple, target);
132  if (triangle_local_operations.has_value()) {
133  switches.insert(
134  switches.end(),
135  triangle_local_operations.value().begin(),
136  triangle_local_operations.value().end());
137  return switches;
138  }
139  }
140  return std::nullopt;
141 }
142 
143 } // namespace
144 
145 // Maps the tuple source according to the operation sequence
146 // std::vector<PrimitiveType> operations where operations satisfies
147 // base_target = switch_tuples(base_source, operations)
148 std::vector<PrimitiveType>
149 find_local_switch_sequence(const Tuple& source, const Tuple& target, PrimitiveType primitive_type)
150 {
151  switch (primitive_type) {
152  case PrimitiveType::Edge: {
153  const auto operations =
154  find_local_switch_sequence_on_edge(PrimitiveType::Edge, source, target);
155  if (!operations.has_value()) {
156  throw std::runtime_error(
157  "switch sequence was unable to find a sequence of switches to match tuples");
158  }
159  return operations.value();
160  }
162  const auto operations =
163  find_local_switch_sequence_on_triangle(PrimitiveType::Triangle, source, target);
164  if (!operations.has_value()) {
165  throw std::runtime_error(
166  "switch sequence was unable to find a sequence of switches to match tuples");
167  }
168  return operations.value();
169  }
171  const auto operations =
172  find_local_switch_sequence_on_tet(PrimitiveType::Tetrahedron, source, target);
173  if (!operations.has_value()) {
174  throw std::runtime_error(
175  "switch sequence was unable to find a sequence of switches to match tuples");
176  }
177  return operations.value();
178  }
179  case PrimitiveType::Vertex: return {};
180  default: return {};
181  }
182 }
183 } // namespace wmtk::multimesh::utils
static int8_t local_eid(const Tuple &t)
static int64_t global_cid(const Tuple &t)
static int8_t local_vid(const Tuple &t)
static int8_t local_fid(const Tuple &t)
std::vector< PrimitiveType > find_local_switch_sequence(const Tuple &source, const Tuple &target, PrimitiveType primitive_type)
Tuple local_switch_tuples(PrimitiveType mesh_primitive_type, const Tuple &tuple, const std::initializer_list< PrimitiveType > &op_sequence)
Tuple local_switch_tuple(PrimitiveType mesh_primitive_type, const Tuple &source, PrimitiveType primitive_type)