Visual Computing Library
Loading...
Searching...
No Matches
component_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_COMPONENT_DATA_H
24#define VCL_MESH_COMPONENTS_DETAIL_COMPONENT_DATA_H
25
26#include <vclib/concepts/mesh/components/component.h>
27
28namespace vcl::comp::detail {
29
30// store the data if horizontal
31template<typename Data, bool VERTICAL>
32class ComponentData
33{
34 Data mData;
35
36public:
37 template<typename, typename Comp>
38 Data& get(Comp*)
39 {
40 return mData;
41 }
42
43 template<typename, typename Comp>
44 const Data& get(const Comp*) const
45 {
46 return mData;
47 }
48
49 template<typename, typename Comp>
50 constexpr bool isComponentAvailable(const Comp*) const
51 {
52 return true;
53 }
54};
55
56// do not store data if vertical; it will be fetched by vertical vectors in the
57// element container
58template<typename Data>
59class ComponentData<Data, true>
60{
61public:
62 /*
63 * These member functions allow to access to the data of a vertical
64 * component.
65 *
66 * We are in the in the scenario where, a vertical component ComponentType
67 * of an element ElementType wants to access to its data, which is not
68 * stored in the Component itself, but in the tuple of vectors stored in the
69 * element container.
70 *
71 * To do that, these functions ask for two template parameters:
72 * - ElementType, the class of the element (Vertex, Face)..
73 * - ComponentType, the component from which the ElementType is the derived
74 * class. And a parameter comp, which is the 'this' pointer of the
75 * ComponentType instance that performs the function call.
76 *
77 * These member functions first perform a static cast from the Component to
78 * the Element (this operation is safe also in case of multiple inheritance
79 * - see https://stackoverflow.com/questions/65177399/), then access to the
80 * parent mesh of the Element and asks for access to the tuple of vectors of
81 * vertical components of the element (they are private, but ComponentData
82 * is friends of the Mesh). Then, gets the vector of the given component and
83 * then the component associated to the index of the element.
84 */
85
86 template<typename ElementType, typename ComponentType>
87 Data& get(ComponentType* comp)
88 {
89 ElementType* elem = static_cast<ElementType*>(comp);
90 assert(elem->parentMesh());
91
92 // get the tuple of vector of vertical components
93 auto& tvc =
94 elem->parentMesh()->template verticalComponents<ElementType>();
95
96 // get the vector of the required component
97 auto& vc = tvc.template vector<ComponentType>();
98
99 // return the component at the index of this vertex
100 return vc[elem->index()];
101 }
102
103 template<typename ElementType, typename ComponentType>
104 const Data& get(const ComponentType* comp) const
105 {
106 const ElementType* elem = static_cast<const ElementType*>(comp);
107 assert(elem->parentMesh());
108
109 // get the tuple of vector of vertical components
110 auto& tvc =
111 elem->parentMesh()->template verticalComponents<ElementType>();
112
113 // get the vector of the required component
114 auto& vc = tvc.template vector<ComponentType>();
115
116 // return the component at the index of this vertex
117 return vc[elem->index()];
118 }
119
120 template<typename ElementType, typename ComponentType>
121 bool isComponentAvailable(const ComponentType* comp) const
122 {
123 // just vertical component
124 if constexpr (!IsOptionalComponent<ComponentType>) {
125 return true;
126 }
127 // optional component -> need to check at runtime the vector tuple
128 else {
129 const ElementType* elem = static_cast<const ElementType*>(comp);
130 assert(elem->parentMesh());
131
132 // get the tuple of vector of vertical components
133 auto& tvc =
134 elem->parentMesh()->template verticalComponents<ElementType>();
135
136 return tvc.template isComponentEnabled<ComponentType>();
137 }
138 }
139};
140
141} // namespace vcl::comp::detail
142
143#endif // VCL_MESH_COMPONENTS_DETAIL_COMPONENT_DATA_H