Wildmeshing Toolkit
Loading...
Searching...
No Matches
TypedAttributeManager.cpp
Go to the documentation of this file.
5
10
11#include <cassert>
12#include <functional>
13#include <stdexcept>
14#include <string>
15#include <utility>
16
17namespace wmtk::attribute {
18
19
20template <typename T>
21void TypedAttributeManager<T>::serialize(const int dim, MeshWriter& writer) const
22{
23 std::vector<std::string> attribute_names;
24 std::transform(
25 m_attributes.begin(),
26 m_attributes.end(),
27 std::back_inserter(attribute_names),
28 [](const auto& ptr) -> std::string {
29 if (ptr) {
30 return ptr->name();
31 } else {
32 return {};
33 }
34 });
35
36 attribute_names.erase(
37 std::remove_if(
38 attribute_names.begin(),
39 attribute_names.end(),
40 [](const std::string& name) { return name.empty(); }),
41 attribute_names.end());
42
43 HDF5Writer* hdf5_w = dynamic_cast<HDF5Writer*>(&writer);
44 if (hdf5_w != nullptr) {
45 hdf5_w->write_attribute_names<T>(dim, attribute_names);
46 }
47
48 for (const auto& attr_ptr : m_attributes) {
49 if (bool(attr_ptr)) {
50 attr_ptr->serialize(dim, writer);
51 }
52 }
53}
54
55template <typename T>
56std::map<std::string, std::size_t> TypedAttributeManager<T>::child_hashes() const
57{
58 // default implementation pulls the child attributes (ie the attributes)
59 std::map<std::string, std::size_t> ret = wmtk::utils::MerkleTreeInteriorNode::child_hashes();
60
61 for (int64_t i = 0; i < m_attributes.size(); ++i) {
62 if (!m_attributes[i]) {
63 continue;
64 }
65 const std::string& name = m_attributes[i]->name();
66 AttributeHandle handle(i);
67 ret["attr_handle_" + name] = std::hash<AttributeHandle>{}(handle);
68 }
69
70 return ret;
71}
72template <typename T>
73std::map<std::string, const wmtk::utils::Hashable*> TypedAttributeManager<T>::child_hashables()
74 const
75
76{
77 std::map<std::string, const wmtk::utils::Hashable*> ret;
78
79 for (int64_t i = 0; i < m_attributes.size(); ++i) {
80 if (!m_attributes[i]) {
81 continue;
82 }
83 const std::string& name = m_attributes[i]->name();
84 AttributeHandle handle(i);
85 const auto& attr = attribute(handle);
86
87 ret["attr_" + name] = &attr;
88 }
89
90 return ret;
91}
92
93template <typename T>
95{
96 for (auto& attr_ptr : m_attributes) {
97 if (bool(attr_ptr)) {
98 attr_ptr->push_scope();
99 }
100 }
101}
102template <typename T>
104{
105 for (auto& attr_ptr : m_attributes) {
106 if (bool(attr_ptr)) {
107 attr_ptr->pop_scope(apply_updates);
108 }
109 }
110}
111template <typename T>
113{
114 for (auto& attr_ptr : m_attributes) {
115 if (bool(attr_ptr)) {
116 attr_ptr->rollback_current_scope();
117 }
118 }
119}
120template <typename T>
122{
123 for (const auto& attr_ptr : m_attributes) {
124 if (bool(attr_ptr)) {
125 attr_ptr->change_to_next_scope();
126 }
127 }
128}
129
130template <typename T>
132{
133 for (const auto& attr_ptr : m_attributes) {
134 if (bool(attr_ptr)) {
135 attr_ptr->change_to_previous_scope();
136 }
137 }
138}
139
140template <typename T>
142 const std::string& name,
143 int64_t dimension,
144 bool replace,
145 T default_value)
146{
147 if (!replace && has_attribute(name)) {
149 "Cannot register attribute '{}' because it exists already. Set replace to true if you "
150 "want to overwrite the attribute",
151 name);
152 }
153
154 if (replace) {
155 for (int64_t i = 0; i < m_attributes.size(); ++i) {
156 if (!m_attributes[i]) {
157 continue;
158 }
159 if (m_attributes[i]->name() == name) {
160 return i;
161 }
162 }
163 }
164
165 AttributeHandle handle(m_attributes.size());
166 m_attributes.emplace_back(
167 std::make_unique<CachingAttribute<T>>(name, dimension, default_value, reserved_size()));
168
169 return handle;
170}
171
172template <typename T>
174{
175 for (const auto& a : m_attributes) {
176 if (bool(a)) {
177 assert(a->reserved_size() >= cap);
178 }
179 }
180}
181template <typename T>
183{
184 for (int64_t i = 0; i < m_attributes.size(); ++i) {
185 if (!m_attributes[i]) {
186 continue;
187 }
188 if (m_attributes[i]->name() == name) {
189 return i;
190 }
191 }
192
193 log_and_throw_error("Cannot find handle for attribute named {}", name);
194}
195template <typename T>
196bool TypedAttributeManager<T>::has_attribute(const std::string& name) const
197{
198 for (int64_t i = 0; i < m_attributes.size(); ++i) {
199 if (!m_attributes[i]) {
200 continue;
201 }
202 if (m_attributes[i]->name() == name) {
203 return true;
204 }
205 }
206
207 return false;
208}
209
210template <typename T>
212{
213 if (m_attributes.size() != other.m_attributes.size()) {
214 return false;
215 }
216 for (size_t j = 0; j < m_attributes.size(); ++j) {
217 const bool exists = bool(m_attributes[j]);
218 const bool o_exists = bool(other.m_attributes[j]);
219 if (exists != o_exists) {
220 return false;
221 } else if (exists && o_exists && !(*m_attributes[j] == *other.m_attributes[j])) {
222 return false;
223 }
224 }
225 return true;
226}
227
228
229template <typename T>
230void TypedAttributeManager<T>::set(const AttributeHandle& handle, std::vector<T> val)
231{
232 // TODO: should we validate the size of val compared to the internally held data?
233 auto& attr_ptr = m_attributes[handle.index()];
234 assert(bool(attr_ptr));
235 auto& attr = *attr_ptr;
236 attr.set(std::move(val));
237}
238
239template <typename T>
241{
242 auto& attr_ptr = m_attributes[handle.index()];
243 assert(bool(attr_ptr));
244 return attr_ptr->reserved_size();
245}
246
247template <typename T>
249{
250 return m_reserved_size;
251}
252
253template <typename T>
255{
256 return active_attributes().size();
257}
258template <typename T>
260{
261 std::vector<AttributeHandle> handles;
262 handles.reserve(m_attributes.size());
263 for (size_t j = 0; j < m_attributes.size(); ++j) {
264 if (bool(m_attributes[j])) {
265 handles.emplace_back(AttributeHandle(j));
266 }
267 }
268
269 return handles;
270}
271template <typename T>
273{
274 const size_t index = h.index();
275 assert(index < m_attributes.size());
276 return bool(m_attributes[index]);
277}
278
279template <typename T>
280void TypedAttributeManager<T>::reserve(const int64_t size)
281{
282 m_reserved_size = size;
283 for (auto& attr_ptr : m_attributes) {
284 if (bool(attr_ptr)) {
285 attr_ptr->reserve(size);
286 }
287 }
288}
289
290template <typename T>
292{
293 reserve(m_reserved_size + size);
294}
295
296template <typename T>
298{
299 if (size > m_reserved_size) {
300 // logger().warn("Pre-reserve enough simplices before your operation.");
301 reserve(size);
302 }
303}
304
305template <typename T>
306void TypedAttributeManager<T>::remove_attributes(const std::vector<AttributeHandle>& attributes)
307{
308 for (const AttributeHandle& i : attributes) {
309 remove_attribute(i);
310 }
311}
312
313
314template <typename T>
316{
317 auto& attr = m_attributes[attribute.index()];
318 if (!attr) {
319 logger().warn("Attribute was already deleted.");
320 return;
321 }
322
323 m_attributes[attribute.index()].reset();
324}
325
326template <typename T>
328{
329 if (handle.index() >= m_attributes.size()) {
330 logger().warn("Handle index is larger than the attribute vector");
331 return false;
332 }
333
334 if (!m_attributes[handle.index()]) {
335 return false;
336 }
337
338 return true;
339}
340
341template <typename T>
343{
344 size_t old_index = 0;
345 size_t new_index = 0;
346 std::vector<int64_t> old_to_new_id(m_attributes.size(), -1);
347 for (old_index = 0; old_index < m_attributes.size(); ++old_index) {
348 if (bool(m_attributes[old_index])) {
349 old_to_new_id[old_index] = new_index;
350 m_attributes[new_index++] = std::move(m_attributes[old_index]);
351 }
352 }
353 m_attributes.resize(new_index);
354}
355template <typename T>
357{
358 assert(handle.index() < m_attributes.size());
359 if (m_attributes[handle.index()]) {
360 return m_attributes[handle.index()]->name();
361 }
362 throw std::runtime_error("Could not find handle in TypedAttributeManager");
363 return "UNKNOWN";
364}
365
366template <typename T>
367void TypedAttributeManager<T>::set_name(const AttributeHandle& handle, const std::string& name)
368{
369 const std::string old_name = get_name(handle);
370
371 if (old_name == name) {
372 return;
373 }
374
375 auto& attr = m_attributes[handle.index()];
376 assert(bool(attr));
377 assert(attr->name() == old_name);
378
379 assert(!has_attribute(name)); // name should not exist already
380
381 attr->set_name(name);
382}
383
384template class TypedAttributeManager<char>;
385template class TypedAttributeManager<int64_t>;
386template class TypedAttributeManager<double>;
388
389} // namespace wmtk::attribute
void write_attribute_names(int dim, const std::vector< std::string > &names)
Internal handle representation used by TypedAttributeManager.
int64_t index() const noexcept
Contains all attributes of type T for a single mesh.
std::vector< std::unique_ptr< CachingAttribute< T > > > m_attributes
void serialize(const int dim, MeshWriter &writer) const
std::map< std::string, std::size_t > child_hashes() const override
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:58