Visual Computing Library
Loading...
Searching...
No Matches
custom_components_data.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_COMPONENTS_DETAIL_CUSTOM_COMPONENTS_DATA_H
24#define VCL_MESH_COMPONENTS_DETAIL_CUSTOM_COMPONENTS_DATA_H
25
26#include <vclib/types.h>
27
28#include <any>
29#include <string>
30#include <typeindex>
31#include <unordered_map>
32#include <vector>
33
34namespace vcl::comp::detail {
35
36/*
37 * The CustomComponentData is the data structure that manages the access to the
38 * custom components from an Element. If the custom components are horizontal,
39 * they need to be stored in the Element memory frame, if they are vertical they
40 * need to be stored by the Container of elements.
41 *
42 * The CustomComponentData stores the data horizontally
43 * The CustomComponentData<El, true> (specialized on the boolean template)
44 * stores the data vertically.
45 */
46
47// horizontal, not specialized. Store the custom component in this struct
48template<typename ElementType, bool VERTICAL>
49class CustomComponentsData
50{
51 std::unordered_map<std::string, std::any> mMap;
52 std::unordered_map<std::string, std::type_index> mCompType;
53
54public:
55 bool componentExists(const std::string& compName, const ElementType*) const
56 {
57 return (mMap.find(compName) != mMap.end());
58 }
59
60 template<typename CompType>
61 bool isComponentOfType(const std::string& compName, const ElementType*)
62 const
63 {
64 std::type_index t(typeid(CompType));
65 return t == mCompType.at(compName);
66 }
67
68 std::type_index componentType(
69 const std::string& compName,
70 const ElementType*) const
71 {
72 return mCompType.at(compName);
73 }
74
75 template<typename CompType>
76 std::vector<std::string> componentNamesOfType(const ElementType*) const
77 {
78 std::vector<std::string> names;
79 std::type_index t(typeid(CompType));
80 for (const auto& p : mCompType) {
81 if (p.second == t)
82 names.push_back(p.first);
83 }
84 return names;
85 }
86
87 template<typename CompType>
88 const CompType& get(const std::string& compName, const ElementType*) const
89 {
90 return std::any_cast<const CompType&>(mMap.at(compName));
91 }
92
93 template<typename CompType>
94 CompType& get(const std::string& compName, ElementType*)
95 {
96 return std::any_cast<CompType&>(mMap.at(compName));
97 }
98
99 template<typename CompType>
100 void addCustomComponent(
101 const std::string& compName,
102 const CompType c = CompType())
103 {
104 mMap[compName] = c;
105 mCompType.emplace(compName, typeid(CompType));
106 }
107
108 void deleteCustomComponent(const std::string& compName)
109 {
110 mMap.erase(compName);
111 mCompType.erase(compName);
112 }
113};
114
115// vertical, specialized on the boolean.
116// Access to the data stored in the Container of elements, trough the
117// member function ccVec(elem), where elem is the pointer to the Element
118// that is asking for the data
119template<typename ElementType>
120class CustomComponentsData<ElementType, true>
121{
122public:
123 bool componentExists(const std::string& compName, const ElementType* elem)
124 const
125 {
126 return ccVec(elem).componentExists(compName);
127 }
128
129 template<typename CompType>
130 bool isComponentOfType(const std::string& compName, const ElementType* elem)
131 const
132 {
133 return ccVec(elem).template isComponentOfType<CompType>(compName);
134 }
135
136 std::type_index componentType(
137 const std::string& compName,
138 const ElementType* elem) const
139 {
140 return ccVec(elem).componentType(compName);
141 }
142
143 template<typename CompType>
144 std::vector<std::string> componentNamesOfType(const ElementType* elem) const
145 {
146 return ccVec(elem).template allComponentNamesOfType<CompType>();
147 }
148
149 template<typename CompType>
150 const CompType& get(const std::string& compName, const ElementType* elem)
151 const
152 {
153 return std::any_cast<const CompType&>(
154 ccVec(elem).template componentVector<CompType>(
155 compName)[thisId(elem)]);
156 }
157
158 template<typename CompType>
159 CompType& get(const std::string& compName, ElementType* elem)
160 {
161 return std::any_cast<CompType&>(
162 ccVec(elem).template componentVector<CompType>(
163 compName)[thisId(elem)]);
164 }
165
166private:
167 uint thisId(const ElementType* elem) const
168 {
169 assert(elem->parentMesh());
170 return elem->index();
171 }
172
173 auto& ccVec(ElementType* elem)
174 {
175 assert(elem->parentMesh());
176 // get the vector of custom components
177 return elem->parentMesh()->template customComponents<ElementType>();
178 }
179
180 const auto& ccVec(const ElementType* elem) const
181 {
182 assert(elem->parentMesh());
183 // get the vector of custom components
184 return elem->parentMesh()->template customComponents<ElementType>();
185 }
186};
187
188} // namespace vcl::comp::detail
189
190#endif // VCL_MESH_COMPONENTS_DETAIL_CUSTOM_COMPONENTS_DATA_H