Wildmeshing Toolkit
AttributeManager.cpp
Go to the documentation of this file.
1 #include "AttributeManager.hpp"
2 
3 #include <spdlog/spdlog.h>
4 #include <wmtk/io/MeshWriter.hpp>
6 namespace 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"
17 std::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 }
37 std::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 }
72 void 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 
80 void 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 }
88 void 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 }
95 void 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 }
114 void 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 }
120 void 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 }
127 void 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 
162 int64_t AttributeManager::size() const
163 {
164  return int64_t(m_capacities.size());
165 }
167 {
168  return m_capacities == other.m_capacities && m_char_attributes == other.m_char_attributes &&
172 }
173 
175 {
176  return AttributeScopeHandle(*this);
177 }
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 }
207 void 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 
271 std::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 
302 namespace {
303 template <typename T>
304 class ClearAttrDataT : public std::array<std::vector<AttributeHandle>, 5>
305 {
306 };
307 
308 class ClearAttrData : public ClearAttrDataT<char>,
309  public ClearAttrDataT<int64_t>,
310  public ClearAttrDataT<double>,
311  public ClearAttrDataT<Rational>
312 {
313 public:
314  template <typename T>
315  ClearAttrDataT<T>& get();
316 };
317 template <typename T>
318 ClearAttrDataT<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::vector< int64_t > m_capacities
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.