Visual Computing Library
Loading...
Searching...
No Matches
custom_components_vector_map.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MESH_CONTAINERS_CUSTOM_COMPONENTS_VECTOR_MAP_H
24#define VCL_MESH_CONTAINERS_CUSTOM_COMPONENTS_VECTOR_MAP_H
25
26#include <vclib/exceptions/mesh.h>
27#include <vclib/misc/compactness.h>
28#include <vclib/types.h>
29
30#include <any>
31#include <string>
32#include <typeindex>
33#include <unordered_map>
34#include <vector>
35
36namespace vcl::mesh {
37
64template<bool HasCustomComponent>
68
69template<>
71{
72 // the actual map containing, for each name of a custom component, the
73 // vector of values (a value for each element(vertex/face...) of the mesh)
74 std::unordered_map<std::string, std::vector<std::any>> mMap;
75 // map that stores if some custom components need to be initialized.
76 // this happens when we resize the container of an element: we need to
77 // resize also the vectors of the custom components, but we cannot
78 // initialize them with the right type (because we don't know it in resize
79 // phase). The initialization will be made when the type is known (get of
80 // the custom component vector).
81 mutable std::unordered_map<std::string, bool> mNeedToInitialize;
82 // types used for each custom component
83 std::unordered_map<std::string, std::type_index> mCompType;
84
85public:
89 void clear()
90 {
91 mMap.clear();
92 mNeedToInitialize.clear();
93 mCompType.clear();
94 }
95
100 void reserve(uint size)
101 {
102 for (auto& p : mMap) {
103 p.second.reserve(size);
104 }
105 }
106
112 void resize(uint size)
113 {
114 for (auto& p : mMap) {
115 // At this call, we don't know statically the types of each custom
116 // component, therefore we cannot initialize them (std::any of each
117 // vector will be in an invalid state). Therefore, we mark all the
118 // resized custom components as 'needToInitialize'. Initiaization
119 // will be made just on the uninitialized values of the vectors at
120 // the first access of each custom component.
121 if (p.second.size() < size)
122 mNeedToInitialize.at(p.first) = true;
123 p.second.resize(size);
124 }
125 }
126
139 void compact(const std::vector<uint>& newIndices)
140 {
141 for (auto& p : mMap) {
142 compactVector(p.second, newIndices);
143 }
144 }
145
159 template<typename CompType>
160 void addNewComponent(const std::string& name, uint size)
161 {
162 std::vector<std::any>& v = mMap[name];
163 v.resize(size, CompType());
164 mNeedToInitialize[name] = false;
165 mCompType.emplace(name, typeid(CompType));
166 }
167
173 void deleteComponent(const std::string& name)
174 {
175 mMap.erase(name);
176 mNeedToInitialize.erase(name);
177 mCompType.erase(name);
178 }
179
185 void assertComponentExists(const std::string& compName) const
186 {
187 (void) (compName);
188 assert(mMap.find(compName) != mMap.end());
189 }
190
196 bool componentExists(const std::string& compName) const
197 {
198 return (mMap.find(compName) != mMap.end());
199 }
200
206 std::vector<std::string> allComponentNames() const
207 {
208 std::vector<std::string> names;
209 names.reserve(mMap.size());
210 for (const auto& p : mMap)
211 names.push_back(p.first);
212 return names;
213 }
214
224 template<typename CompType>
225 bool isComponentOfType(const std::string& compName) const
226 {
227 std::type_index t(typeid(CompType));
228
229 return t == mCompType.at(compName);
230 }
231
241 std::type_index componentType(const std::string& compName) const
242 {
243 return mCompType.at(compName);
244 }
245
254 template<typename CompType>
255 std::vector<std::string> allComponentNamesOfType() const
256 {
257 std::vector<std::string> names;
258 std::type_index t(typeid(CompType));
259 for (const auto& p : mCompType) {
260 if (p.second == t)
261 names.push_back(p.first);
262 }
263 return names;
264 }
265
278 template<typename CompType>
279 const std::vector<std::any>& componentVector(
280 const std::string& compName) const
281 {
283 std::vector<std::any>& v =
284 const_cast<std::vector<std::any>&>(mMap.at(compName));
285 // if the component needs to be initialized (e.g. we made a resize)
286 if (mNeedToInitialize.at(compName)) {
287 for (std::any& a : v) {
288 if (!a.has_value())
289 a = CompType();
290 }
291 mNeedToInitialize.at(compName) = false;
292 }
293 return v;
294 }
295
311 template<typename CompType>
312 std::vector<std::any>& componentVector(const std::string& compName)
313 {
315 std::vector<std::any>& v = mMap.at(compName);
316 // if the component needs to be initialized (e.g. we made a resize)
317 if (mNeedToInitialize.at(compName)) {
318 for (std::any& a : v) {
319 if (!a.has_value())
320 a = CompType();
321 }
322 mNeedToInitialize.at(compName) = false;
323 }
324 return v;
325 }
326
327 void importSameCustomComponentFrom(
330 const std::string& compName,
332 {
333 if (other.componentExists(compName) && componentExists(compName)) {
334 if (other.componentType(compName) == componentType(compName)) {
335 mMap.at(compName)[thisPos] = other.mMap.at(compName)[otherPos];
336 }
337 }
338 }
339
340private:
341 template<typename CompType>
342 void checkComponentType(const std::string& compName) const
343 {
344 std::type_index t(typeid(CompType));
345 if (t != mCompType.at(compName)) {
346 throw BadCustomComponentTypeException(
347 "Expected type " + std::string(mCompType.at(compName).name()) +
348 " for " + compName + ", but was " + std::string(t.name()) +
349 ".");
350 }
351 }
352};
353
354} // namespace vcl::mesh
355
356#endif // VCL_MESH_CONTAINERS_CUSTOM_COMPONENTS_VECTOR_MAP_H
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
const std::vector< std::any > & componentVector(const std::string &compName) const
Returns a const reference of std::vector<std::any> of the custom component with the given name and th...
Definition custom_components_vector_map.h:279
std::vector< std::string > allComponentNames() const
Returns a vector of std::string containing all the custom components, regardless the types of the cus...
Definition custom_components_vector_map.h:206
std::vector< std::string > allComponentNamesOfType() const
Returns a vector of strings of all the custom components having as type the given template argument C...
Definition custom_components_vector_map.h:255
void deleteComponent(const std::string &name)
Deletes the custom component vector with the given name. It does nothing if the element does not exis...
Definition custom_components_vector_map.h:173
bool isComponentOfType(const std::string &compName) const
Returns true if the type associated to the compName custom component is the same of the given templat...
Definition custom_components_vector_map.h:225
void compact(const std::vector< uint > &newIndices)
Compacts each custom component vector according to the given indices.
Definition custom_components_vector_map.h:139
void clear()
Removes all the custom component vectors stored in the mMap.
Definition custom_components_vector_map.h:89
std::vector< std::any > & componentVector(const std::string &compName)
Returns a reference of std::vector<std::any> of the custom component with the given name and the give...
Definition custom_components_vector_map.h:312
bool componentExists(const std::string &compName) const
Returns true if the compName exists.
Definition custom_components_vector_map.h:196
void addNewComponent(const std::string &name, uint size)
Adds a new vector of custom components having the given size, the given name and with the template ar...
Definition custom_components_vector_map.h:160
void reserve(uint size)
For each custom component vector, it reserves the given size.
Definition custom_components_vector_map.h:100
void assertComponentExists(const std::string &compName) const
Asserts that the compName component exists.
Definition custom_components_vector_map.h:185
std::type_index componentType(const std::string &compName) const
Returns the std::type_index of the type of the CustomComponent having the input name.
Definition custom_components_vector_map.h:241
void resize(uint size)
For each custom component vector, it resizes the vector to the given size.
Definition custom_components_vector_map.h:112
The CustomComponentsVectorMap class stores a map of vectors of custom components.
Definition custom_components_vector_map.h:66