Visual Computing Library
Loading...
Searching...
No Matches
component.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_BASES_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASES_COMPONENT_H
25
26#include "../detail/component_data.h"
27
28#include <vclib/concepts/mesh/components/component.h>
29#include <vclib/concepts/mesh/elements/element.h>
30#include <vclib/concepts/mesh/mesh_concept.h>
31
32namespace vcl::comp {
33
35
117template<
118 typename DerivedComponent, // CRTP pattern, derived class
119 uint COMP_ID, // component id
120 typename DataType, // data stored by the component
121 typename ParentElemType, // parent element type
122 bool VERT, // true if component vertical
123 bool OPT, // true if component vertical and optional
124 typename... ReferencedTypes> // types of the refs stored by the component
125class Component : public ReferencesComponentTriggerer<ReferencedTypes>...
126{
127public:
132 using DataValueType = DataType;
133
138 static const bool IS_VERTICAL =
139 !std::is_same_v<ParentElemType, void> && VERT;
140
144 static const uint COMPONENT_ID = COMP_ID;
145
150 static const bool IS_OPTIONAL = VERT && OPT;
151
152private:
153 detail::ComponentData<DataValueType, IS_VERTICAL> mData;
154
155public:
167 bool isAvailable() const
168 {
169 return mData.template isComponentAvailable<ParentElemType>(
170 static_cast<const DerivedComponent*>(this));
171 }
172
173protected:
174 DataValueType& data()
175 {
176 return mData.template get<ParentElemType>(
177 static_cast<DerivedComponent*>(this));
178 }
179
180 const DataValueType& data() const
181 {
182 return mData.template get<ParentElemType>(
183 static_cast<const DerivedComponent*>(this));
184 }
185
186 ParentElemType* parentElement()
187 {
188 static_assert(
189 !std::is_same_v<ParentElemType, void>,
190 "The component should know its parent element type to get access "
191 "to its pointer. You should define the component by passing the "
192 "element type as template parameter. E.G., for a Face element:\n"
193 "vcl::face::TriangleVertexPtrs<Vertex<Scalar>, Face<Scalar>>\n"
194 " ^^^^^^^^^^^^ \n");
195
196 return static_cast<ParentElemType*>(this);
197 }
198
199 const ParentElemType* parentElement() const
200 {
201 static_assert(
202 !std::is_same_v<ParentElemType, void>,
203 "The component should know its parent element type to get access "
204 "to its pointer. You should define the component by passing the "
205 "element type as template parameter. E.G., for a Face element:\n"
206 "vcl::face::TriangleVertexPtrs<Vertex<Scalar>, Face<Scalar>>\n"
207 " ^^^^^^^^^^^^ \n");
208
209 return static_cast<const ParentElemType*>(this);
210 }
211};
212
226template<uint COMPONENT_ID, ElementOrMeshConcept T>
227bool isComponentAvailableOn(const T& obj)
228{
229 if constexpr (HasOptionalComponentOfType<T, COMPONENT_ID>) {
230 using ComponentType =
231 ComponentOfType<COMPONENT_ID, typename T::Components>;
232 const ComponentType& c = static_cast<const ComponentType&>(obj);
233 return c.isAvailable();
234 }
235 else
236 return HasComponentOfType<T, COMPONENT_ID>;
237}
238
245template<typename T>
246struct IsComponentPred
247{
248 static const bool value = ComponentConcept<T>;
249};
250
251template<typename T>
252struct IsVerticalComponentPred
253{
254 static const bool value = IsVerticalComponent<T>;
255};
256
258
259} // namespace vcl::comp
260
261#endif // VCL_MESH_COMPONENTS_BASES_COMPONENT_H