Wildmeshing Toolkit
Loading...
Searching...
No Matches
Mesh_attributes.cpp
Go to the documentation of this file.
1#include <numeric>
2#include "Mesh.hpp"
3
6
7#include "Primitive.hpp"
8
9namespace wmtk {
10template <typename T>
12 const std::string& name,
13 PrimitiveType ptype,
14 int64_t size,
15 bool replace,
16 T default_value)
17{
19 *this,
20 register_attribute_typed<T>(name, ptype, size, replace, default_value));
21 return attr;
22}
23
24template <typename T>
26 const std::string& name,
27 PrimitiveType ptype,
28 int64_t size,
29 bool replace,
30 T default_value)
31{
32 auto attr =
33 m_attribute_manager.register_attribute<T>(name, ptype, size, replace, default_value);
34 return attr;
35}
36
37template <typename T>
42
43std::vector<int64_t> Mesh::request_simplex_indices(PrimitiveType type, int64_t count)
44{
45 // passses back a set of new consecutive ids. in hte future this could do
46 // something smarter for re-use but that's probably too much work
47 int64_t current_capacity = capacity(type);
48
49 // enable newly requested simplices
51 int64_t max_size = flag_accessor.base_accessor().reserved_size();
52
53 if (current_capacity + count > max_size) {
54 logger().warn(
55 "Requested more {} simplices than available (have {}, wanted {}, can only have at most "
56 "{}",
58 current_capacity,
59 count,
60 max_size);
61 return {};
62 }
63
64 std::vector<int64_t> ret(count);
65 std::iota(ret.begin(), ret.end(), current_capacity);
66
67
68 int64_t new_capacity = current_capacity + ret.size();
69 assert(ret.back() + 1 == current_capacity + ret.size());
70 size_t primitive_id = get_primitive_type_id(type);
71
72 m_attribute_manager.m_capacities[primitive_id] = new_capacity;
73
74 attribute::IndexFlagAccessor<Mesh>& flag_accessor_indices = flag_accessor.index_access();
75
76 for (const int64_t simplex_index : ret) {
77 // wmtk::logger().trace("Activating {}-simplex {}", primitive_id, simplex_index);
78 flag_accessor_indices.activate(simplex_index);
79 }
80
81 return ret;
82}
83
88
97void Mesh::set_capacities(std::vector<int64_t> capacities)
98{
99 m_attribute_manager.set_capacities(std::move(capacities));
100}
101
102// reserves extra attributes than necessary right now
107// reserves extra attributes than necessary right now
108void Mesh::reserve_more_attributes(const std::vector<int64_t>& sizes)
109{
110 assert(top_cell_dimension() + 1 == sizes.size());
111 for (int64_t j = 0; j < sizes.size(); ++j) {
113 }
114}
119void Mesh::guarantee_at_least_attributes(const std::vector<int64_t>& sizes)
120{
121 assert(top_cell_dimension() + 1 == sizes.size());
122 for (int64_t j = 0; j < sizes.size(); ++j) {
124 }
125}
130void Mesh::guarantee_more_attributes(const std::vector<int64_t>& sizes)
131{
132 assert(top_cell_dimension() + 1 == sizes.size());
133 for (int64_t j = 0; j < sizes.size(); ++j) {
135 }
136}
137
138namespace {
139std::vector<attribute::MeshAttributeHandle::HandleVariant> variant_diff(
140 std::vector<attribute::MeshAttributeHandle::HandleVariant>& a,
141 std::vector<attribute::MeshAttributeHandle::HandleVariant>& b)
142{
143 std::vector<attribute::MeshAttributeHandle::HandleVariant> ret;
144 std::sort(a.begin(), a.end());
145
146 std::sort(b.begin(), b.end());
147
148 std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(ret, ret.begin()));
149 return ret;
150}
151} // namespace
152std::vector<attribute::MeshAttributeHandle::HandleVariant> Mesh::custom_attributes() const
153{
155 auto builtins = builtin_attributes();
156
157 return variant_diff(all, builtins);
158}
159
162{
163 return m_attribute_manager.get_name(handle);
164}
169
171 const std::vector<attribute::MeshAttributeHandle::HandleVariant>& keep_attributes)
172{
173 auto a = this->custom_attributes();
174 auto b = keep_attributes;
175 m_attribute_manager.clear_attributes(variant_diff(a, b));
177}
178void Mesh::clear_attributes(const std::vector<attribute::MeshAttributeHandle>& keep_attributes)
179{
180 std::map<Mesh*, std::vector<attribute::MeshAttributeHandle::HandleVariant>> keeps_t;
181 for (const auto& attr : keep_attributes) {
182 keeps_t[const_cast<Mesh*>(&attr.mesh())].emplace_back(attr.handle());
183 }
184 for (auto& [mptr, handles] : keeps_t) {
185 mptr->clear_attributes(handles);
186 }
187}
189{
190 assert(this == &to_delete.mesh());
191
192 delete_attribute(to_delete.handle());
193}
194
203
208
209std::tuple<std::vector<std::vector<int64_t>>, std::vector<std::vector<int64_t>>> Mesh::consolidate()
210{
211 // Number of dimensions
212 int64_t tcp = top_cell_dimension() + 1;
213
214 // Store the map from new indices to old. First index is dimensions, second simplex id
215 std::vector<std::vector<int64_t>> new2old(tcp);
216 // Store the map from old indices to new. First index is dimensions, second simplex id
217 std::vector<std::vector<int64_t>> old2new(tcp);
218
219 // Initialize both maps
220 for (int64_t d = 0; d < tcp; d++) {
221 attribute::FlagAccessor<Mesh> flag_accessor =
223 for (int64_t i = 0; i < capacity(wmtk::get_primitive_type_from_id(d)); ++i) {
224 if (flag_accessor.index_access().is_active(i)) {
225 old2new[d].push_back(new2old[d].size());
226 new2old[d].push_back(old2new[d].size() - 1); // -1 since we just pushed into it
227 } else {
228 old2new[d].push_back(-1);
229 }
230 }
231 }
232
233 // Use new2oldmap to compact all attributes
234 auto run = [&](auto&& mesh_attrs) {
235 for (int64_t d = 0; d < mesh_attrs.size(); ++d) {
236 auto& ma = mesh_attrs[d];
237 const auto& n2o = new2old[d];
238 ma.reserve(n2o.size());
239
240 for (auto& h : ma.active_attributes()) {
241 ma.attribute(h).consolidate(n2o);
242 }
243 }
244 };
247
249
251
252 // Update the attribute size in the manager
253 for (int64_t d = 0; d < tcp; d++) {
254 m_attribute_manager.m_capacities[d] = new2old[d].size();
255 }
256
257 // Apply old2new to attributes containing indices
258 std::vector<std::vector<TypedAttributeHandle<int64_t>>> handle_indices =
260
261 for (int64_t d = 0; d < tcp; d++) {
262 for (int64_t i = 0; i < handle_indices[d].size(); ++i) {
263 attribute::Accessor<int64_t> accessor = create_accessor<int64_t>(handle_indices[d][i]);
264 accessor.attribute().index_remap(old2new[d]);
265 }
266 }
267
268 {
269 constexpr static int64_t TUPLE_SIZE = multimesh::utils::TUPLE_SIZE; // in terms of int64_t
270 constexpr static int64_t GLOBAL_ID_INDEX = multimesh::utils::GLOBAL_ID_INDEX;
271 const static std::vector<Eigen::Index> image_map_offsets{
272 Eigen::Index(TUPLE_SIZE + GLOBAL_ID_INDEX)};
273 const static std::vector<Eigen::Index> domain_map_offsets{Eigen::Index(GLOBAL_ID_INDEX)};
275 const auto& top_map = old2new[dim];
276 if (auto parent_ptr = m_multi_mesh_manager.m_parent; parent_ptr != nullptr) {
277 {
278 int64_t child_id = m_multi_mesh_manager.m_child_id;
279 const auto& child_data = parent_ptr->m_multi_mesh_manager.m_children[child_id];
280 const auto handle = child_data.map_handle;
281 auto acc = parent_ptr->create_accessor(handle);
282 auto& attr = acc.attribute();
283 attr.index_remap(top_map, image_map_offsets);
284 }
285
286 {
287 const auto handle = m_multi_mesh_manager.map_to_parent_handle;
288 auto acc = create_accessor(handle);
289 auto& attr = acc.attribute();
290 attr.index_remap(top_map, domain_map_offsets);
291 }
292 }
293
294 for (const auto& child_data : m_multi_mesh_manager.m_children) {
295 {
296 const auto handle = child_data.map_handle;
297 auto acc = create_accessor(handle);
298 auto& attr = acc.attribute();
299 attr.index_remap(top_map, domain_map_offsets);
300 }
301 {
302 const auto handle = child_data.mesh->m_multi_mesh_manager.map_to_parent_handle;
303 auto acc = child_data.mesh->create_accessor(handle);
304 auto& attr = acc.attribute();
305 attr.index_remap(top_map, image_map_offsets);
306 }
307 }
308 }
309
310 // Return both maps for custom attribute remapping
311 return {new2old, old2new};
312}
313std::vector<attribute::MeshAttributeHandle::HandleVariant> Mesh::builtin_attributes() const
314{
315 std::vector<attribute::MeshAttributeHandle::HandleVariant> data;
316 for (const auto& vec : connectivity_attributes()) {
317 std::copy(vec.begin(), vec.end(), std::back_inserter(data));
318 }
319
320 data.emplace_back(m_cell_hash_handle);
321 std::copy(m_flag_handles.begin(), m_flag_handles.end(), std::back_inserter(data));
322
323 auto mm_handles = m_multi_mesh_manager.map_handles();
324 std::copy(mm_handles.begin(), mm_handles.end(), std::back_inserter(data));
325 return data;
326}
327
328
330Mesh::register_attribute<char>(const std::string&, PrimitiveType, int64_t, bool, char);
332Mesh::register_attribute<int64_t>(const std::string&, PrimitiveType, int64_t, bool, int64_t);
334Mesh::register_attribute<double>(const std::string&, PrimitiveType, int64_t, bool, double);
336Mesh::register_attribute<Rational>(const std::string&, PrimitiveType, int64_t, bool, Rational);
337
338
340Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, char);
342Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, int64_t);
344Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, double);
346Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, Rational);
347
348template const int64_t& Mesh::get_attribute_default_value(
349 const TypedAttributeHandle<int64_t>& handle) const;
350template const char& Mesh::get_attribute_default_value(
351 const TypedAttributeHandle<char>& handle) const;
352template const double& Mesh::get_attribute_default_value(
353 const TypedAttributeHandle<double>& handle) const;
355 const TypedAttributeHandle<wmtk::Rational>& handle) const;
356} // namespace wmtk
void set_capacities(std::vector< int64_t > capacities)
void clear_attributes()
std::vector< attribute::MeshAttributeHandle::HandleVariant > builtin_attributes() const
std::vector< attribute::MeshAttributeHandle::HandleVariant > custom_attributes() const
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
int64_t capacity(PrimitiveType type) const
read in the m_capacities return the upper bound for the number of entities of the given dimension
attribute::TypedAttributeHandle< T > register_attribute_typed(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
std::vector< TypedAttributeHandle< char > > m_flag_handles
0x1 == true = simplex is active (simplex exists) all flag default to 0
Definition Mesh.hpp:850
void guarantee_more_attributes(PrimitiveType type, int64_t size)
void reserve_more_attributes(PrimitiveType type, int64_t size)
void update_child_handles()
Update the child handles after clearing attributes.
void guarantee_at_least_attributes(PrimitiveType type, int64_t size)
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
multimesh::MultiMeshManager m_multi_mesh_manager
Definition Mesh.hpp:827
multimesh::attribute::AttributeScopeHandle create_scope()
int64_t top_cell_dimension() const
Definition Mesh.hpp:978
void reserve_attributes_to_fit()
reserve space for all attributes data types for all dimensional simplices
attribute::AttributeScopeHandle create_single_mesh_scope()
std::string get_attribute_name(const TypedAttributeHandle< T > &handle) const
Definition Mesh.hpp:935
virtual std::vector< std::vector< TypedAttributeHandle< int64_t > > > connectivity_attributes() const =0
Returns a vector of vectors of attribute handles.
void delete_attribute(const attribute::MeshAttributeHandle &to_delete)
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
virtual std::tuple< std::vector< std::vector< int64_t > >, std::vector< std::vector< int64_t > > > consolidate()
Consolidate the attributes, moving all valid simplexes at the beginning of the corresponding vector.
std::vector< int64_t > request_simplex_indices(PrimitiveType type, int64_t count)
TypedAttributeHandle< int64_t > m_cell_hash_handle
Definition Mesh.hpp:854
const attribute::FlagAccessor< Mesh > get_flag_accessor(PrimitiveType type) const
Definition Mesh.cpp:159
void reserve_attributes(PrimitiveType type, int64_t size)
attribute::AttributeManager m_attribute_manager
Definition Mesh.hpp:825
const T & get_attribute_default_value(const TypedAttributeHandle< T > &handle) const
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition Accessor.hpp:28
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 guarantee_at_least_attributes(int64_t dimension, int64_t size)
const T & get_attribute_default_value(const TypedAttributeHandle< T > &handle) const
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
TypedAttributeHandle< T > register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace, T default_value)
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.
const IndexBaseType & index_access() const
std::variant< TypedAttributeHandle< char >, TypedAttributeHandle< int64_t >, TypedAttributeHandle< double >, TypedAttributeHandle< wmtk::Rational > > HandleVariant
Handle that represents attributes for some mesh.
std::vector< ChildData > m_children
TypedAttributeHandle< int64_t > map_to_parent_handle
std::vector< TypedAttributeHandle< int64_t > > map_handles() const
std::string_view primitive_type_name(PrimitiveType t)
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.
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:58