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 = comp::ComponentTypeFromID<COMP_ID, Components>;
101 return *static_cast<Comp*>(this);
102 }
103
104 template<uint COMP_ID>
105 const auto& component() const
106 {
107 using Comp = comp::ComponentTypeFromID<COMP_ID, Components>;
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 swap(Element& other)
121 {
122 using PM = comp::ParentMeshPointer<MeshType>;
123
124 assert(PM::parentMesh() == other.parentMesh());
125 using std::swap;
126 (swap((Comps&) *this, (Comps&) other), ...);
127 if (PM::parentMesh()) {
128 PM::parentMesh()->swapVerticalComponents(*this, other);
129 }
130 }
131
132 friend void swap(Element& a, Element& b) { a.swap(b); }
133
134 void serialize(std::ostream& out) const
135 {
136 // we need to call serialize for each component of the Element,
137 // but serialize must be called only on components that are
138 // available (e.g. optional and not enabled)
139 (serializeComponent<Comps>(out), ...);
140 }
141
142 void deserialize(std::istream& in)
143 {
144 // we need to call deserialize for each component of the Element,
145 // but deserialize must be called only on components that are
146 // available (e.g. optional and not enabled)
147 (deserializeComponent<Comps>(in), ...);
148 }
149
150private:
151 // hide init and isAvailable members
152 void init() {}
153
154 bool isAvailable() const { return true; }
155
156 // init to call after set parent mesh
157 void initVerticalComponents() { (construct<Comps>(), ...); }
158
159 template<typename Comp>
160 void construct()
161 {
162 if constexpr (
163 comp::IsVerticalComponent<Comp> &&
164 comp::HasInitMemberFunction<Comp>) {
165 if constexpr (comp::HasIsAvailableMemberFunction<Comp>) {
166 if (Comp::isAvailable()) {
167 Comp::init();
168 }
169 }
170 // no possibility to check if is available, it means that is always
171 // available
172 else {
173 Comp::init();
174 }
175 }
176 }
177
178 template<typename Comp, typename ElType>
179 void importComponent(const ElType& v, bool importRefs)
180 {
181 if constexpr (!comp::IsOptionalComponent<Comp>) {
182 Comp::importFrom(v, importRefs); // safe to call importFrom
183 }
184 else { // it is optional...
185 if (Comp::isAvailable()) { // check if it is available
186 Comp::importFrom(v, importRefs);
187 }
188 }
189 }
190
191 template<typename Comp>
192 void serializeComponent(std::ostream& out) const
193 {
194 if constexpr (!comp::IsOptionalComponent<Comp>) {
195 Comp::serialize(out); // safe to call serialize
196 }
197 else { // it is optional...
198 if (Comp::isAvailable()) { // check if it is available
199 Comp::serialize(out);
200 }
201 }
202 }
203
204 template<typename Comp>
205 void deserializeComponent(std::istream& in)
206 {
207 if constexpr (!comp::IsOptionalComponent<Comp>) {
208 Comp::deserialize(in); // safe to call deserialize
209 }
210 else { // it is optional...
211 if (Comp::isAvailable()) { // check if it is available
212 Comp::deserialize(in);
213 }
214 }
215 }
216};
217
218} // namespace vcl
219
220#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
A simple structure that wraps a list of variadic templates, without instantiating anything....
Definition type_wrapper.h:39