@@ -67,7 +67,6 @@
|
|||||||
|
|
||||||
//== INCLUDES =================================================================
|
//== INCLUDES =================================================================
|
||||||
|
|
||||||
|
|
||||||
#include <OpenMesh/Core/System/config.h>
|
#include <OpenMesh/Core/System/config.h>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -78,6 +77,11 @@
|
|||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
#include <array>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
//== NAMESPACES ===============================================================
|
//== NAMESPACES ===============================================================
|
||||||
|
|
||||||
@@ -88,6 +92,23 @@ namespace OpenMesh {
|
|||||||
//== CLASS DEFINITION =========================================================
|
//== CLASS DEFINITION =========================================================
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
/*
|
||||||
|
* Helpers for VectorT
|
||||||
|
*/
|
||||||
|
namespace {
|
||||||
|
template<typename... Ts>
|
||||||
|
struct are_convertible_to;
|
||||||
|
|
||||||
|
template<typename To, typename From, typename... Froms>
|
||||||
|
struct are_convertible_to<To, From, Froms...> {
|
||||||
|
static constexpr bool value = std::is_convertible<From, To>::value && are_convertible_to<To, Froms...>::value;
|
||||||
|
};
|
||||||
|
template<typename To, typename From>
|
||||||
|
struct are_convertible_to<To, From> : public std::is_convertible<From, To> {};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** The N values of the template Scalar type are the only data members
|
/** The N values of the template Scalar type are the only data members
|
||||||
of the class VectorT<Scalar,N>. This guarantees 100% compatibility
|
of the class VectorT<Scalar,N>. This guarantees 100% compatibility
|
||||||
@@ -98,22 +119,45 @@ namespace OpenMesh {
|
|||||||
aligned, so that aligned SSE instructions can be used on these
|
aligned, so that aligned SSE instructions can be used on these
|
||||||
vectors.
|
vectors.
|
||||||
*/
|
*/
|
||||||
template <typename Scalar,int N> struct VectorDataT
|
template<typename Scalar, int N> class VectorDataT {
|
||||||
{
|
public:
|
||||||
Scalar values_[N];
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
VectorDataT() {}
|
||||||
|
|
||||||
|
template<typename... T>
|
||||||
|
constexpr VectorDataT(T... vs) : values_ {vs...} {
|
||||||
|
static_assert(sizeof...(vs) == N,
|
||||||
|
"Incorrect number of vector components supplied.");
|
||||||
|
}
|
||||||
|
std::array<Scalar, N> values_;
|
||||||
|
#else
|
||||||
|
Scalar values_[N];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__SSE__)
|
#if defined(__GNUC__) && defined(__SSE__)
|
||||||
|
|
||||||
/// This specialization enables us to use aligned SSE instructions.
|
/// This specialization enables us to use aligned SSE instructions.
|
||||||
template <> struct VectorDataT<float, 4>
|
template<> class VectorDataT<float, 4> {
|
||||||
{
|
public:
|
||||||
union
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
{
|
VectorDataT() {}
|
||||||
__m128 m128;
|
|
||||||
float values_[4];
|
template<typename... T>
|
||||||
};
|
constexpr VectorDataT(T... vs) : values_ {vs...} {
|
||||||
|
static_assert(sizeof...(vs) == 4,
|
||||||
|
"Incorrect number of vector components supplied.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
union {
|
||||||
|
__m128 m128;
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
std::array<float, 4> values_;
|
||||||
|
#else
|
||||||
|
float values_[4];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -386,6 +430,26 @@ typedef VectorT<double,6> Vec6d;
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
} // namespace OpenMesh
|
} // namespace OpenMesh
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
/**
|
||||||
|
* Literal operator for inline specification of colors in HTML syntax.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \code{.cpp}
|
||||||
|
* OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor;
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
constexpr OpenMesh::Vec4f operator"" _htmlColor(unsigned long long raw_color) {
|
||||||
|
return OpenMesh::Vec4f(
|
||||||
|
((raw_color >> 24) & 0xFF) / 255.0f,
|
||||||
|
((raw_color >> 16) & 0xFF) / 255.0f,
|
||||||
|
((raw_color >> 8) & 0xFF) / 255.0f,
|
||||||
|
((raw_color >> 0) & 0xFF) / 255.0f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // OPENMESH_VECTOR_HH defined
|
#endif // OPENMESH_VECTOR_HH defined
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
#endif // DOXYGEN
|
#endif // DOXYGEN
|
||||||
|
|||||||
@@ -97,6 +97,28 @@ public:
|
|||||||
/// default constructor creates uninitialized values.
|
/// default constructor creates uninitialized values.
|
||||||
inline VectorT() {}
|
inline VectorT() {}
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
explicit inline VectorT(const Scalar &v) {
|
||||||
|
vectorize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T,
|
||||||
|
typename = typename std::enable_if<sizeof...(T) == DIM>::type,
|
||||||
|
typename = typename std::enable_if<are_convertible_to<float, T...>::value>::type>
|
||||||
|
constexpr VectorT(T... vs) : Base { static_cast<Scalar>(vs)...}
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<int D = DIM, typename = typename std::enable_if<D == DIM>::type>
|
||||||
|
typename std::enable_if<D==4, VectorT>::type
|
||||||
|
homogenized() const {
|
||||||
|
return VectorT(
|
||||||
|
Base::values_[0]/Base::values_[3],
|
||||||
|
Base::values_[1]/Base::values_[3],
|
||||||
|
Base::values_[2]/Base::values_[3],
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
/// special constructor for 1D vectors
|
/// special constructor for 1D vectors
|
||||||
explicit inline VectorT(const Scalar& v) {
|
explicit inline VectorT(const Scalar& v) {
|
||||||
// assert(DIM==1);
|
// assert(DIM==1);
|
||||||
@@ -124,6 +146,8 @@ public:
|
|||||||
const Scalar v2, const Scalar v3) {
|
const Scalar v2, const Scalar v3) {
|
||||||
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
|
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorT homogenized() const { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DIM == 5
|
#if DIM == 5
|
||||||
@@ -141,11 +165,12 @@ public:
|
|||||||
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
|
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
|
||||||
Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
|
Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// construct from a value array (explicit)
|
/// construct from a value array (explicit)
|
||||||
explicit inline VectorT(const Scalar _values[DIM]) {
|
explicit inline VectorT(const Scalar _values[DIM]) {
|
||||||
memcpy(Base::values_, _values, DIM*sizeof(Scalar));
|
memcpy(data(), _values, DIM*sizeof(Scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -185,11 +210,19 @@ public:
|
|||||||
// /// cast to const Scalar array
|
// /// cast to const Scalar array
|
||||||
// inline operator const Scalar*() const { return Base::values_; }
|
// inline operator const Scalar*() const { return Base::values_; }
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
/// access to Scalar array
|
||||||
|
inline Scalar* data() { return Base::values_.data(); }
|
||||||
|
|
||||||
|
/// access to const Scalar array
|
||||||
|
inline const Scalar*data() const { return Base::values_.data(); }
|
||||||
|
#else
|
||||||
/// access to Scalar array
|
/// access to Scalar array
|
||||||
inline Scalar* data() { return Base::values_; }
|
inline Scalar* data() { return Base::values_; }
|
||||||
|
|
||||||
/// access to const Scalar array
|
/// access to const Scalar array
|
||||||
inline const Scalar*data() const { return Base::values_; }
|
inline const Scalar*data() const { return Base::values_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,48 @@ TEST_F(OpenMeshVectorTest, VectorCasting) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
TEST_F(OpenMeshVectorTest, cpp11_constructors) {
|
||||||
|
OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 };
|
||||||
|
|
||||||
|
EXPECT_EQ(1.2, vec1[0]);
|
||||||
|
EXPECT_EQ(2.0, vec1[1]);
|
||||||
|
EXPECT_EQ(3.0, vec1[2]);
|
||||||
|
|
||||||
|
OpenMesh::Vec4f vec2 { 1.2f, 3.5f, 1.0f, 0.0f };
|
||||||
|
|
||||||
|
EXPECT_EQ(1.2f, vec2[0]);
|
||||||
|
EXPECT_EQ(3.5f, vec2[1]);
|
||||||
|
EXPECT_EQ(1.0f, vec2[2]);
|
||||||
|
EXPECT_EQ(0.0f, vec2[3]);
|
||||||
|
|
||||||
|
OpenMesh::Vec4f vec2b { vec2 };
|
||||||
|
|
||||||
|
EXPECT_EQ(1.2f, vec2b[0]);
|
||||||
|
EXPECT_EQ(3.5f, vec2b[1]);
|
||||||
|
EXPECT_EQ(1.0f, vec2b[2]);
|
||||||
|
EXPECT_EQ(0.0f, vec2b[3]);
|
||||||
|
|
||||||
|
OpenMesh::Vec4d vec4d { 1.23 };
|
||||||
|
EXPECT_EQ(1.23, vec4d[0]);
|
||||||
|
EXPECT_EQ(1.23, vec4d[1]);
|
||||||
|
EXPECT_EQ(1.23, vec4d[2]);
|
||||||
|
EXPECT_EQ(1.23, vec4d[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshVectorTest, cpp11_htmlColorLiteral) {
|
||||||
|
static constexpr OpenMesh::Vec4f rose = 0xFFC7F1FF_htmlColor;
|
||||||
|
|
||||||
|
const OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor;
|
||||||
|
EXPECT_LE((OpenMesh::Vec4f(0.1215686274f, 0.8117647058f, 1.0f, 1.0f)
|
||||||
|
- light_blue).sqrnorm(), 1e-10);
|
||||||
|
|
||||||
|
const auto light_blue_2 = 0x1FCFFFFF_htmlColor;
|
||||||
|
// Check whether auto type deduction works as expected.
|
||||||
|
static_assert(std::is_same<decltype(light_blue_2), decltype(light_blue)>
|
||||||
|
::value, "Bad type deduced from _htmlColor literal.");
|
||||||
|
EXPECT_EQ(light_blue, light_blue_2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user