Wildmeshing Toolkit
Loading...
Searching...
No Matches
CollapseNewAttributeStrategy.cpp
Go to the documentation of this file.
2#include <fmt/format.h>
4
8
9namespace wmtk::operations {
10template <typename T>
12{
13 return m_will_throw;
14}
15template <typename T>
17{
18 return fmt::format("CollapseNewAttributeStrategy[{}]", m_handle.name());
19}
20
21template <typename T>
24{
25 switch (optype) {
26 default: [[fallthrough]];
28 if constexpr (std::is_same_v<T, double> || std::is_same_v<T, Rational>) {
29 return standard_collapse_strategy(CollapseBasicStrategy::Mean);
30 } else {
31 return standard_collapse_strategy(CollapseBasicStrategy::CopyTuple);
32 }
34 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
35 if (!bs[1] && bs[0]) {
36 return b;
37 } else {
38 return a;
39 }
40 };
42 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
43 if (!bs[0] && bs[1]) {
44 return a;
45 } else {
46 return b;
47 }
48 };
50 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
51 if (bs[0] == bs[1]) {
52 return (a + b) / T(2);
53 } else if (bs[0]) {
54 return a;
55
56 } else {
57 return b;
58 }
59 };
61 return [](const VecType&, const VecType&, const std::bitset<2>&) -> VecType {
62 throw std::runtime_error("Collapse should have a new attribute");
63 };
64 case CollapseBasicStrategy::None: return {};
65 }
66 return {};
67}
68
69template <>
72{
73 switch (optype) {
74 default: [[fallthrough]];
76 return standard_collapse_strategy(CollapseBasicStrategy::Mean);
78 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
79 if (!bs[1] && bs[0]) {
80 return b;
81 } else {
82 return a;
83 }
84 };
86 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
87 if (!bs[0] && bs[1]) {
88 return a;
89 } else {
90 return b;
91 }
92 };
94 return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
95 if (bs[0] == bs[1]) {
96 return (a + b) / Rational(2, true);
97 } else if (bs[0]) {
98 return a;
99
100 } else {
101 return b;
102 }
103 };
105 return [](const VecType&, const VecType&, const std::bitset<2>&) -> VecType {
106 throw std::runtime_error("Collapse should have a new attribute");
107 };
108 case CollapseBasicStrategy::None: return {};
109 }
110 return {};
111}
112
113
114template <typename T>
117 : m_handle(h)
118 , m_collapse_op(nullptr)
119{
120 assert(h.holds<T>());
121
122 auto& mesh = m_handle.mesh();
123 if (mesh.is_free()) {
125 } else {
127 }
128
131 std::make_unique<edge_mesh::CollapseNewAttributeTopoInfo>(static_cast<EdgeMesh&>(mesh));
134 std::make_unique<tri_mesh::CollapseNewAttributeTopoInfo>(static_cast<TriMesh&>(mesh));
137 std::make_unique<tet_mesh::CollapseNewAttributeTopoInfo>(static_cast<TetMesh&>(mesh));
138 } else {
139 throw std::runtime_error("Invalid mesh");
140 }
141}
142
143template <typename T>
145 Mesh& m,
146 const ReturnData& data,
147 const OperationInOutData& op_datas) const
148{
149 if (!bool(m_collapse_op)) {
150 return;
151 }
152 assert(!mesh().is_free()); // attribute new is not valid on free meshes
153
154 if (op_datas.find(&mesh()) == op_datas.end()) return;
155 assert(&mesh() == &m);
156 const std::vector<std::tuple<simplex::NavigatableSimplex, Tuple>>& tuple_pairs =
157 op_datas.at(&mesh());
158
159 const PrimitiveType pt = primitive_type();
160 auto acc = m.create_accessor(m_handle.as<T>());
161
162 for (const auto& tuple_pair : tuple_pairs) {
163 const simplex::NavigatableSimplex& input_simplex = std::get<0>(tuple_pair);
164 const Tuple& output_tuple = std::get<1>(tuple_pair);
165
166
167 const auto& return_data_variant = data.get_variant(mesh(), input_simplex);
168
169 // for (const PrimitiveType pt : wmtk::utils::primitive_below(mesh().top_simplex_type()))
170 {
171 auto merged_simps =
172 m_topo_info->merged_simplices(return_data_variant, input_simplex.tuple(), pt);
173 auto new_simps = m_topo_info->new_simplices(return_data_variant, output_tuple, pt);
174
175
176 assert(merged_simps.size() == new_simps.size());
177
178 for (size_t s = 0; s < merged_simps.size(); ++s) {
179 assign_collapsed(acc, merged_simps[s], new_simps[s]);
180 }
181 }
182 }
183}
184
185
186template <typename T>
189 const std::array<Tuple, 2>& input_simplices,
190 const Tuple& final_simplex) const
191{
192 if (!bool(m_collapse_op)) {
193 return;
194 }
195 assert(acc.primitive_type() == primitive_type());
196 auto old_values = m_handle.mesh().parent_scope([&]() {
197 return std::make_tuple(
198 acc.const_vector_attribute(input_simplices[0]),
199 acc.const_vector_attribute(input_simplices[1]));
200 });
201
202 const auto old_pred = this->evaluate_predicate(acc.primitive_type(), input_simplices);
203
204 VecType a, b;
205 std::tie(a, b) = old_values;
206 auto new_value = acc.vector_attribute(final_simplex);
207
208
209 new_value = m_collapse_op(a, b, old_pred);
210}
211
212
213template <typename T>
215{
216 m_collapse_op = std::move(f);
217 m_will_throw = false;
218}
219template <typename T>
221{
222 set_strategy(standard_collapse_strategy(optype));
223 m_will_throw = optype == CollapseBasicStrategy::Throw;
224}
225
226
227template <typename T>
229{
230 return m_handle.mesh();
231}
232template <typename T>
234{
235 return m_handle.primitive_type();
236}
237template <typename T>
242template <typename T>
244 const attribute::MeshAttributeHandle& handle) const
245{
246 return handle == m_handle;
247}
248
253
254} // namespace wmtk::operations
bool is_free() const
Definition Mesh.hpp:973
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
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
PrimitiveType primitive_type() const
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition Accessor.hpp:28
MapResult< D > vector_attribute(const ArgType &t)
ConstMapResult< D > const_vector_attribute(const ArgType &t) const
CollapseNewAttributeStrategy(const wmtk::attribute::MeshAttributeHandle &h)
BaseCollapseNewAttributeStrategy::OperationInOutData OperationInOutData
void update(Mesh &m, const ReturnData &ret_data, const OperationInOutData &tuples) const override
bool matches_attribute(const attribute::MeshAttributeHandle &) const override
std::unique_ptr< CollapseNewAttributeTopoInfo > m_topo_info
static CollapseFuncType standard_collapse_strategy(CollapseBasicStrategy optype)
std::function< VecType(const VecType &, const VecType &, const std::bitset< 2 > &)> CollapseFuncType
BaseCollapseNewAttributeStrategy::ReturnData ReturnData
void assign_collapsed(wmtk::attribute::Accessor< T > &acc, const std::array< Tuple, 2 > &input_simplices, const Tuple &final_simplex) const