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