Visual Computing Library  devel
Loading...
Searching...
No Matches
element.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_ELEMENTS_BASE_ELEMENT_H
24#define VCL_MESH_ELEMENTS_BASE_ELEMENT_H
25
26#include "base.h"
27
28#include <vclib/mesh/components/base/component.h>
29#include <vclib/mesh/components/parent_mesh_pointer.h>
30
31#include <vclib/base.h>
32
49namespace vcl {
50
51/* Concepts */
52
53template<typename T>
54concept ElementConcept = requires (T&& obj) {
55 RemoveRef<T>::ELEMENT_ID;
56 typename RemoveRef<T>::Components;
57 typename RemoveRef<T>::ParentMeshType;
58 { obj.index() } -> std::same_as<uint>;
59};
60
61namespace mesh {
62
63template<ElementConcept>
65
66} // namespace mesh
67
73template<uint ELEM_ID, typename MeshType, comp::ComponentConcept... Comps>
74class Element : public comp::ParentMeshPointer<MeshType>, public Comps...
75{
76 template<ElementConcept>
77 friend class mesh::ElementContainer;
78
79public:
80 using ParentMeshType = MeshType;
81
86 using Components = TypeWrapper<Comps...>;
87
88 static const uint ELEMENT_ID = ELEM_ID;
89
90 uint index() const
91 {
94 ->template elementIndex<ELEM_ID>(this);
95 }
96
97 template<uint COMP_ID>
98 auto& component()
99 {
100 using Comp = GetComponentFromID<COMP_ID>::type;
101 return *static_cast<Comp*>(this);
102 }
103
104 template<uint COMP_ID>
105 const auto& component() const
106 {
107 using Comp = GetComponentFromID<COMP_ID>::type;
108 return *static_cast<const Comp*>(this);
109 }
110
111 template<typename ElType>
112 void importFrom(const ElType& v, bool importRefs = true)
113 {
114 // we need to call importFrom for each component of the Element,
115 // but importFrom must be called only on components that are
116 // available (e.g. optional and not enabled)
117 (importComponent<Comps>(v, importRefs), ...);
118 }
119
120 void serialize(std::ostream& out) const
121 {
122 // we need to call serialize for each component of the Element,
123 // but serialize must be called only on components that are
124 // available (e.g. optional and not enabled)
125 (serializeComponent<Comps>(out), ...);
126 }
127
128 void deserialize(std::istream& in)
129 {
130 // we need to call deserialize for each component of the Element,
131 // but deserialize must be called only on components that are
132 // available (e.g. optional and not enabled)
133 (deserializeComponent<Comps>(in), ...);
134 }
135
136private:
137 // hide init and isAvailable members
138 void init() {}
139
140 bool isAvailable() const { return true; }
141
142 // init to call after set parent mesh
143 void initVerticalComponents() { (construct<Comps>(), ...); }
144
145 template<typename Comp>
146 void construct()
147 {
148 if constexpr (
149 comp::IsVerticalComponent<Comp> &&
150 comp::HasInitMemberFunction<Comp>) {
151 if constexpr (comp::HasIsAvailableMemberFunction<Comp>) {
152 if (Comp::isAvailable()) {
153 Comp::init();
154 }
155 }
156 // no possibility to check if is available, it means that is always
157 // available
158 else {
159 Comp::init();
160 }
161 }
162 }
163
164 template<typename Comp, typename ElType>
165 void importComponent(const ElType& v, bool importRefs)
166 {
167 if constexpr (!comp::IsOptionalComponent<Comp>) {
168 Comp::importFrom(v, importRefs); // safe to call importFrom
169 }
170 else { // it is optional...
171 if (Comp::isAvailable()) { // check if it is available
172 Comp::importFrom(v, importRefs);
173 }
174 }
175 }
176
177 template<typename Comp>
178 void serializeComponent(std::ostream& out) const
179 {
180 if constexpr (!comp::IsOptionalComponent<Comp>) {
181 Comp::serialize(out); // safe to call serialize
182 }
183 else { // it is optional...
184 if (Comp::isAvailable()) { // check if it is available
185 Comp::serialize(out);
186 }
187 }
188 }
189
190 template<typename Comp>
191 void deserializeComponent(std::istream& in)
192 {
193 if constexpr (!comp::IsOptionalComponent<Comp>) {
194 Comp::deserialize(in); // safe to call deserialize
195 }
196 else { // it is optional...
197 if (Comp::isAvailable()) { // check if it is available
198 Comp::deserialize(in);
199 }
200 }
201 }
202
203 // Predicate structures
204
205 // Components can be individuated with their ID, which is an unsigned int.
206 // This struct sets its bool `value` to true if this Element has a Component
207 // with the given unsigned integer COMP_ID. Sets also `type` with a
208 // TypeWrapper containing the Component that satisfied the condition. The
209 // TypeWrapper will be empty if no Components were found.
210 template<uint COMP_ID>
212 {
213 private:
214 template<typename Cont>
216 {
217 static constexpr bool value = Cont::COMPONENT_ID == COMP_ID;
218 };
219
220 public:
221 // TypeWrapper of the found component, if any
223 static constexpr bool value = NumberOfTypes<type>::value == 1;
224 };
225
226 template<uint COMP_ID>
228 {
229 private:
230 template<typename>
232 {
233 };
234
235 template<typename C>
237 {
238 using type = C;
239 };
240
241 public:
242 using type =
244 };
245};
246
247} // namespace vcl
248
249#endif // VCL_MESH_ELEMENTS_BASE_ELEMENT_H
A class representing a box in N-dimensional space.
Definition box.h:46
The Element class.
Definition element.h:75
The ParentMeshPointer class.
Definition parent_mesh_pointer.h:34
Definition element.h:64
Definition element.h:54
The ComponentConcept is evaluated to true whenever the type T is a valid component,...
Definition component.h:46
Definition element.h:212
Definition element.h:228
Get the number of types in a pack of types (variadic templates) or a TypeWrapper.
Definition variadic_templates.h:189
A simple structure that wraps a list of variadic templates, without instantiating anything....
Definition type_wrapper.h:39