Visual Computing Library  devel
Loading...
Searching...
No Matches
tangent.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_TANGENT_H
24#define VCL_MESH_COMPONENTS_TANGENT_H
25
26#include "base/component.h"
27#include "base/predicates.h"
28
29#include <vclib/mesh/elements/base/base.h>
30#include <vclib/mesh/exceptions.h>
31
32#include <vclib/base.h>
33#include <vclib/space/core.h>
34
35namespace vcl::comp {
36
62template<PointConcept P, typename ParentElemType = void, bool OPT = false>
63class Tangent :
64 public Component<
65 Tangent<P, ParentElemType, OPT>,
66 CompId::TANGENT,
67 std::pair<P, bool>,
68 ParentElemType,
69 !std::is_same_v<ParentElemType, void>,
70 OPT>
71{
72 using Base = Component<
74 CompId::TANGENT,
75 std::pair<P, bool>,
77 !std::is_same_v<ParentElemType, void>,
78 OPT>;
79
80public:
84 using TangentType = P;
85
86 /* Constructors */
87
92 {
93 if constexpr (!Base::IS_VERTICAL) {
94 init();
95 }
96 }
97
108 void init() { Base::data().second = true; }
109
110 /* Member functions */
111
116 const P& tangent() const { return Base::data().first; }
117
122 P& tangent() { return Base::data().first; }
123
128 bool tangentRightHanded() const { return Base::data().second; }
129
136 bool& tangentRightHanded() { return Base::data().second; }
137
151 P bitangent() const
152 {
153 const ParentElemType& parent =
154 static_cast<const ParentElemType&>(*this);
155
157 // compute bitangent using the tangent and normal
158 // assuming that normal is available
159 const auto& n = static_cast<const ParentElemType&>(*this).normal();
160 return tangentRightHanded() ? n.cross(tangent()) :
161 tangent().cross(n);
162 }
163 else {
165 "Per " +
167 " Normal Component is not enabled.");
168 return P();
169 }
170 }
171
172protected:
173 // Component interface functions
174 template<typename Element>
175 void importFrom(const Element& e, bool = true);
176
177 void serialize(std::ostream& os) const
178 {
180 vcl::serialize(os, tangentRightHanded());
181 }
182
183 void deserialize(std::istream& is)
184 {
185 tangent().deserialize(is);
186 vcl::deserialize(is, tangentRightHanded());
187 }
188};
189
190/* concepts */
191
209template<typename T>
210concept HasTangent = TTB::IsDerivedFromSpecializationOfV<T, Tangent>;
211
222template<typename T>
225
226/* importFrom function */
227
228template<PointConcept P, typename ParentElemType, bool OPT>
229template<typename Element>
230void Tangent<P, ParentElemType, OPT>::importFrom(const Element& e, bool)
231{
232 using ScalarType = TangentType::ScalarType;
233 if constexpr (HasTangent<Element>) {
234 if (isTangentAvailableOn(e)) {
235 tangent() = e.tangent().template cast<ScalarType>();
236 tangentRightHanded() = e.tangentRightHanded();
237 }
238 }
239}
240
241/* Detector function to check if a class has Tangent available */
242
254bool isTangentAvailableOn(const auto& element)
255{
257}
258
259/* Specialization Aliases */
260
274template<typename Scalar, typename ElementType = void, bool OPT = false>
275using Tangent3 = Tangent<Point3<Scalar>, ElementType, OPT>;
276
289template<typename ElementType = void, bool OPT = false>
291
304template<typename ElementType = void, bool OPT = false>
306
307} // namespace vcl::comp
308
309#endif // VCL_MESH_COMPONENTS_TANGENT_H
A class representing a box in N-dimensional space.
Definition box.h:46
void deserialize(std::istream &is)
Deserializes the box from the given input stream.
Definition box.h:476
void serialize(std::ostream &os) const
Serializes the box to the given output stream.
Definition box.h:466
The Element class.
Definition element.h:75
Exception thrown when a mesh/element component is missing (not enabled).
Definition exceptions.h:108
The Tangent class represents a N-Dimensional tangent vector that will be part of an Element (e....
Definition tangent.h:71
const P & tangent() const
Returns a const reference of the tangent of the element.
Definition tangent.h:116
P & tangent()
Returns a reference of the tangent of the element.
Definition tangent.h:122
void init()
Initializes the tangent to (0, 0, 0) right handed.
Definition tangent.h:108
bool & tangentRightHanded()
Returns a reference to the boolean that indicates if the tangent is right handed.
Definition tangent.h:136
P TangentType
Expose the type of the Tangent.
Definition tangent.h:84
bool tangentRightHanded() const
Returns true if the tangent is right handed, false otherwise.
Definition tangent.h:128
Tangent()
Initilizes the Tangent to (0, 0, 0) right handed.
Definition tangent.h:91
P bitangent() const
Computes and returns the bitangent vector using the tangent and normal vectors.
Definition tangent.h:151
A concept that checks whether a type T (that should be a Element) has the Tangent component (inherits...
Definition tangent.h:223
A concept that checks whether a type T (that should be a Element) has the Tangent component (inherits...
Definition tangent.h:210
Evaluates to true if the type T is a component that is stored vertically in its element container,...
Definition component.h:74