Wildmeshing Toolkit
Loading...
Searching...
No Matches
AttributeManager.cpp
Go to the documentation of this file.
2
3#include <spdlog/spdlog.h>
6namespace wmtk::attribute {
8 : m_char_attributes(size)
9 , m_long_attributes(size)
10 , m_double_attributes(size)
11 , m_rational_attributes(size)
12 , m_capacities(size, 0)
13{}
14
15
16// attribute directly hashes its "child_hashables" components so it overrides "child_hashes"
17std::map<std::string, const wmtk::utils::Hashable*> AttributeManager::child_hashables() const
18{
19 std::map<std::string, const wmtk::utils::Hashable*> ret;
20 for (size_t j = 0; j < m_char_attributes.size(); ++j) {
21 ret[fmt::format("char_attributes_{}", j)] = &m_char_attributes[j];
22 }
23 for (size_t j = 0; j < m_char_attributes.size(); ++j) {
24 ret[fmt::format("char_attributes_{}", j)] = &m_char_attributes[j];
25 }
26 for (size_t j = 0; j < m_long_attributes.size(); ++j) {
27 ret[fmt::format("long_attributes_{}", j)] = &m_long_attributes[j];
28 }
29 for (size_t j = 0; j < m_double_attributes.size(); ++j) {
30 ret[fmt::format("double_attributes_{}", j)] = &m_double_attributes[j];
31 }
32 for (size_t j = 0; j < m_rational_attributes.size(); ++j) {
33 ret[fmt::format("rational_attributes_{}", j)] = &m_rational_attributes[j];
34 }
35 return ret;
36}
37std::map<std::string, std::size_t> AttributeManager::child_hashes() const
38{
39 // default implementation pulls the child attributes (ie the attributes)
40 std::map<std::string, std::size_t> ret = wmtk::utils::MerkleTreeInteriorNode::child_hashes();
41
42 // hash handle data
43 for (size_t j = 0; j < m_capacities.size(); ++j) {
44 ret[fmt::format("capacities_{}", j)] = m_capacities[j];
45 }
46 return ret;
47}
48
49
51
53{
54 for (int64_t dim = 0; dim < m_capacities.size(); ++dim) {
55 if (!writer.write(dim)) continue;
56 m_char_attributes[dim].serialize(dim, writer);
57 m_long_attributes[dim].serialize(dim, writer);
58 m_double_attributes[dim].serialize(dim, writer);
59 m_rational_attributes[dim].serialize(dim, writer);
60 }
61 // now that the WMTK link exists we can write hte capacities to that link
63}
64
66{
67 for (int64_t dim = 0; dim < m_capacities.size(); ++dim) {
68 const int64_t capacity = m_capacities[dim];
69 reserve_attributes(dim, capacity);
70 }
71}
72void AttributeManager::reserve_attributes(int64_t dimension, int64_t capacity)
73{
74 m_char_attributes[dimension].reserve(capacity);
75 m_long_attributes[dimension].reserve(capacity);
76 m_double_attributes[dimension].reserve(capacity);
77 m_rational_attributes[dimension].reserve(capacity);
78}
79
80void AttributeManager::reserve_more_attributes(int64_t dimension, int64_t size)
81{
82 assert(dimension < this->size());
83 m_char_attributes[dimension].reserve_more(size);
84 m_long_attributes[dimension].reserve_more(size);
85 m_double_attributes[dimension].reserve_more(size);
86 m_rational_attributes[dimension].reserve_more(size);
87}
88void AttributeManager::reserve_more_attributes(const std::vector<int64_t>& more_capacities)
89{
90 assert(more_capacities.size() == size());
91 for (int64_t dim = 0; dim < size(); ++dim) {
92 reserve_more_attributes(dim, more_capacities[dim]);
93 }
94}
95void AttributeManager::guarantee_at_least_attributes(int64_t dimension, int64_t size)
96{
97 assert(dimension < this->size());
98
99
100 m_char_attributes[dimension].guarantee_at_least(size);
101 m_long_attributes[dimension].guarantee_at_least(size);
102 m_double_attributes[dimension].guarantee_at_least(size);
103 m_rational_attributes[dimension].guarantee_at_least(size);
104}
105
107 const std::vector<int64_t>& at_least_capacities)
108{
109 assert(at_least_capacities.size() == size());
110 for (int64_t dim = 0; dim < size(); ++dim) {
111 guarantee_at_least_attributes(dim, at_least_capacities[dim]);
112 }
113}
114void AttributeManager::guarantee_more_attributes(int64_t dimension, int64_t size)
115{
116 const int64_t current_capacity = m_capacities[dimension];
117 const int64_t target_capacity = current_capacity + size;
118 guarantee_at_least_attributes(dimension, target_capacity);
119}
120void AttributeManager::guarantee_more_attributes(const std::vector<int64_t>& more_capacities)
121{
122 assert(more_capacities.size() == size());
123 for (int64_t dim = 0; dim < size(); ++dim) {
124 guarantee_more_attributes(dim, more_capacities[dim]);
125 }
126}
127void AttributeManager::set_capacities(std::vector<int64_t> capacities)
128{
129 assert(capacities.size() == m_capacities.size());
130 m_capacities = std::move(capacities);
132}
134{
135 assert(m_char_attributes.size() == m_capacities.size());
136 assert(m_long_attributes.size() == m_capacities.size());
137 assert(m_double_attributes.size() == m_capacities.size());
138 assert(m_rational_attributes.size() == m_capacities.size());
139
140 for (size_t i = 0; i < m_capacities.size(); ++i) {
141 assert(m_capacities[i] > 0);
142 assert(m_char_attributes[i].reserved_size() >= m_capacities[i]);
143 assert(m_long_attributes[i].reserved_size() >= m_capacities[i]);
144 assert(m_double_attributes[i].reserved_size() >= m_capacities[i]);
145 assert(m_rational_attributes[i].reserved_size() >= m_capacities[i]);
146
147 m_char_attributes[i].assert_capacity_valid(m_capacities[i]);
148 m_long_attributes[i].assert_capacity_valid(m_capacities[i]);
149 m_double_attributes[i].assert_capacity_valid(m_capacities[i]);
150 m_rational_attributes[i].assert_capacity_valid(m_capacities[i]);
151 }
152}
153
155{
156 for (int64_t j = 0; j < size(); ++j) {
158 }
159}
160
161
163{
164 return int64_t(m_capacities.size());
165}
173
178
181{
182 std::string name = std::visit(
183 [&](auto&& val) {
184 using T = std::decay_t<decltype(val)>;
185 return this->get_name(std::get<T>(attr));
186 },
187 attr);
188
189 return name;
190}
191
193{
194 for (auto& ma : m_char_attributes) {
195 ma.push_scope();
196 }
197 for (auto& ma : m_long_attributes) {
198 ma.push_scope();
199 }
200 for (auto& ma : m_double_attributes) {
201 ma.push_scope();
202 }
203 for (auto& ma : m_rational_attributes) {
204 ma.push_scope();
205 }
206}
207void AttributeManager::pop_scope(bool apply_updates)
208{
209 for (auto& ma : m_char_attributes) {
210 ma.pop_scope(apply_updates);
211 }
212 for (auto& ma : m_long_attributes) {
213 ma.pop_scope(apply_updates);
214 }
215 for (auto& ma : m_double_attributes) {
216 ma.pop_scope(apply_updates);
217 }
218 for (auto& ma : m_rational_attributes) {
219 ma.pop_scope(apply_updates);
220 }
221}
222
224{
225 for (auto& ma : m_char_attributes) {
226 ma.rollback_current_scope();
227 }
228 for (auto& ma : m_long_attributes) {
229 ma.rollback_current_scope();
230 }
231 for (auto& ma : m_double_attributes) {
232 ma.rollback_current_scope();
233 }
234 for (auto& ma : m_rational_attributes) {
235 ma.rollback_current_scope();
236 }
237}
238
240{
241 for (auto& ma : m_char_attributes) {
242 ma.change_to_parent_scope();
243 }
244 for (auto& ma : m_long_attributes) {
245 ma.change_to_parent_scope();
246 }
247 for (auto& ma : m_double_attributes) {
248 ma.change_to_parent_scope();
249 }
250 for (auto& ma : m_rational_attributes) {
251 ma.change_to_parent_scope();
252 }
253}
254
256{
257 for (auto& ma : m_char_attributes) {
258 ma.change_to_child_scope();
259 }
260 for (auto& ma : m_long_attributes) {
261 ma.change_to_child_scope();
262 }
263 for (auto& ma : m_double_attributes) {
264 ma.change_to_child_scope();
265 }
266 for (auto& ma : m_rational_attributes) {
267 ma.change_to_child_scope();
268 }
269}
270
271std::vector<MeshAttributeHandle::HandleVariant> AttributeManager::get_all_attributes() const
272{
273 std::vector<MeshAttributeHandle::HandleVariant> handles;
274
275 auto run = [&](auto type) {
276 using T = std::decay_t<decltype(type)>;
277
278 const std::vector<MeshAttributes<T>>& mesh_attributes = get<T>();
279 for (size_t pt_index = 0; pt_index < mesh_attributes.size(); ++pt_index) {
280 const PrimitiveType pt = get_primitive_type_from_id(pt_index);
281
282 auto handle_converter = [pt](const AttributeHandle& h) -> TypedAttributeHandle<T> {
283 return {h, pt};
284 return TypedAttributeHandle<T>{h, pt};
285 };
286 size_t count = mesh_attributes[pt_index].attribute_count();
287 const auto active_handles = mesh_attributes[pt_index].active_attributes();
288 std::transform(
289 active_handles.begin(),
290 active_handles.end(),
291 std::back_inserter(handles),
292 handle_converter);
293 }
294 };
295 run(double{});
296 run(int64_t{});
297 run(char{});
298 run(Rational{});
299 return handles;
300}
301
302namespace {
303template <typename T>
304class ClearAttrDataT : public std::array<std::vector<AttributeHandle>, 5>
305{
306};
307
308class ClearAttrData : public ClearAttrDataT<char>,
309 public ClearAttrDataT<int64_t>,
310 public ClearAttrDataT<double>,
311 public ClearAttrDataT<Rational>
312{
313public:
314 template <typename T>
315 ClearAttrDataT<T>& get();
316};
317template <typename T>
318ClearAttrDataT<T>& ClearAttrData::get()
319{
320 return static_cast<ClearAttrDataT<T>&>(*this);
321}
322} // namespace
324 const std::vector<attribute::MeshAttributeHandle::HandleVariant>& custom_attributes)
325{
326 // std::array<std::array<std::vector<AttributeHandle>, 5>, 4>
327 // keeps; // [char/int64_t/...][ptype][attribute]
328
329
330 ClearAttrData customs;
331 for (const attribute::MeshAttributeHandle::HandleVariant& attr : custom_attributes) {
332 std::visit(
333 [&](auto&& val) noexcept {
334 using HandleType = typename std::decay_t<decltype(val)>;
335 if constexpr (attribute::MeshAttributeHandle::template handle_type_is_basic<
336 HandleType>()) {
337 using T = typename HandleType::Type;
338 customs.get<T>()[get_primitive_type_id(val.primitive_type())].emplace_back(
339 val.base_handle());
340 } else {
341 assert(false); // this code doesn't work with hybrid rational types
342 }
343 },
344 attr);
345 }
346
347
348 auto run = [&](auto t) {
349 using T = typename std::decay_t<decltype(t)>;
350 auto& mycustoms = customs.get<T>();
351 const auto& attributes = get<T>();
352
353 for (size_t ptype_id = 0; ptype_id < attributes.size(); ++ptype_id) {
354 const PrimitiveType primitive_type = get_primitive_type_from_id(ptype_id);
355
356
357 get<T>(primitive_type).remove_attributes(mycustoms[ptype_id]);
358 }
359 };
360
361 run(double{});
362 run(int64_t{});
363 run(char{});
364 run(Rational{});
365}
368{
369 std::visit(
370 [&](auto&& val) noexcept {
371 using HandleType = typename std::decay_t<decltype(val)>;
372 if constexpr (attribute::MeshAttributeHandle::template handle_type_is_basic<
373 HandleType>()) {
374 using T = typename HandleType::Type;
375 get<T>(val).remove_attribute(val.base_handle());
376 }
377 },
378 to_delete);
379}
380
381} // namespace wmtk::attribute
virtual bool write(const int dim)=0
virtual void write_capacities(const std::vector< int64_t > &capacities)=0
Internal handle representation used by MeshAttributes.
std::vector< MeshAttributes< double > > m_double_attributes
AttributeScopeHandle create_scope(Mesh &m)
std::vector< MeshAttributes< char > > m_char_attributes
void set_capacities(std::vector< int64_t > capacities)
void serialize(MeshWriter &writer) const
void pop_scope(bool apply_updates=true)
void guarantee_at_least_attributes(int64_t dimension, int64_t size)
std::map< std::string, const wmtk::utils::Hashable * > child_hashables() const override
bool operator==(const AttributeManager &other) const
std::map< std::string, std::size_t > child_hashes() const override
std::vector< MeshAttributes< Rational > > m_rational_attributes
void clear_attributes(const std::vector< attribute::MeshAttributeHandle::HandleVariant > &custom_attributes)
Remove all custom attributes besides the one passed in.
void guarantee_more_attributes(int64_t dimension, int64_t size)
std::vector< MeshAttributeHandle::HandleVariant > get_all_attributes() const
void reserve_more_attributes(int64_t dimension, int64_t size)
std::string get_name(const TypedAttributeHandle< T > &attr) const
void delete_attribute(const attribute::MeshAttributeHandle::HandleVariant &to_delete)
void reserve_attributes(int64_t dimension, int64_t size)
std::vector< MeshAttributes< int64_t > > m_long_attributes
This handle is a wrapper for the MeshManager scope funtions.
std::variant< TypedAttributeHandle< char >, TypedAttributeHandle< int64_t >, TypedAttributeHandle< double >, TypedAttributeHandle< wmtk::Rational > > HandleVariant
Handle that represents attributes for some mesh.
std::map< std::string, std::size_t > child_hashes() const override
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.