Commit df73103b authored by Mike Kremer's avatar Mike Kremer
Browse files

Added vector class and base setting for unit tests

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@21 66977474-1d4b-4f09-8fe9-267525286df2
parent 6c26066a
......@@ -9,10 +9,12 @@ include_directories (
set (directories
.
Core
Geometry
OpenVolumeMesh
OpenVolumeMesh/Utils
OpenHexMesh
OpenHexMesh/Utils
Unittests
)
# collect all header and source files
......
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 17 $ *
* $Date: 2012-01-09 16:39:50 +0100 (Mon, 09 Jan 2012) $ *
* $LastChangedBy: kremer $ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS VectorT originally taken from OpenMesh
//
//=============================================================================
// Don't parse this header file with doxygen since
// for some reason (obviously due to a bug in doxygen,
// bugreport: https://bugzilla.gnome.org/show_bug.cgi?id=629182)
// macro expansion and preprocessor defines
// don't work properly.
#ifndef DOXYGEN
#ifndef OPENVOLUMEMESH_VECTOR_HH
#define OPENVOLUMEMESH_VECTOR_HH
//== INCLUDES =================================================================
#include <iostream>
#include <assert.h>
#include <math.h>
#include <string.h>
#if defined(__GNUC__) && defined(__SSE__)
#include <xmmintrin.h>
#endif
//== NAMESPACES ===============================================================
namespace OpenVolumeMesh {
//== CLASS DEFINITION =========================================================
/** The N values of the template Scalar type are the only data members
of the class VectorT<Scalar,N>. This guarantees 100% compatibility
with arrays of type Scalar and size N, allowing us to define the
cast operators to and from arrays and array pointers.
In addition, this class will be specialized for Vec4f to be 16 bit
aligned, so that aligned SSE instructions can be used on these
vectors.
*/
template <typename Scalar,int N> struct VectorDataT
{
Scalar values_[N];
};
#if defined(__GNUC__) && defined(__SSE__)
/// This specialization enables us to use aligned SSE instructions.
template <> struct VectorDataT<float, 4>
{
union
{
__m128 m128;
float values_[4];
};
};
#endif
//== CLASS DEFINITION =========================================================
#define DIM N
#define TEMPLATE_HEADER template <typename Scalar, int N>
#define CLASSNAME VectorT
#define DERIVED VectorDataT<Scalar,N>
#define unroll(expr) for (int i=0; i<N; ++i) expr(i)
/** \class VectorT VectorT.hh <OpenMesh/Core/Math/VectorT.hh>
A vector is an array of \<N\> values of type \<Scalar\>.
The actual data is stored in an VectorDataT, this class just adds
the necessary operators.
*/
#include "VectorT_inc.hh"
#undef DIM
#undef TEMPLATE_HEADER
#undef CLASSNAME
#undef DERIVED
#undef unroll
//== PARTIAL TEMPLATE SPECIALIZATIONS =========================================
#if OM_PARTIAL_SPECIALIZATION
#define TEMPLATE_HEADER template <typename Scalar>
#define CLASSNAME VectorT<Scalar,DIM>
#define DERIVED VectorDataT<Scalar,DIM>
#define DIM 2
#define unroll(expr) expr(0) expr(1)
#define unroll_comb(expr, op) expr(0) op expr(1)
#define unroll_csv(expr) expr(0), expr(1)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 3
#define unroll(expr) expr(0) expr(1) expr(2)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2)
#define unroll_csv(expr) expr(0), expr(1), expr(2)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 4
#define unroll(expr) expr(0) expr(1) expr(2) expr(3)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3)
#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#undef TEMPLATE_HEADER
#undef CLASSNAME
#undef DERIVED
//== FULL TEMPLATE SPECIALIZATIONS ============================================
#else
/// cross product for Vec3f
template<>
inline VectorT<float,3>
VectorT<float,3>::operator%(const VectorT<float,3>& _rhs) const
{
return
VectorT<float,3>(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1],
values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2],
values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]);
}
/// cross product for Vec3d
template<>
inline VectorT<double,3>
VectorT<double,3>::operator%(const VectorT<double,3>& _rhs) const
{
return
VectorT<double,3>(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1],
values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2],
values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]);
}
#endif
//== GLOBAL FUNCTIONS =========================================================
/// \relates OpenMesh::VectorT
/// scalar * vector
template<typename Scalar,int N>
inline VectorT<Scalar,N> operator*(Scalar _s, const VectorT<Scalar,N>& _v) {
return VectorT<Scalar,N>(_v) *= _s;
}
/// \relates OpenMesh::VectorT
/// symmetric version of the dot product
template<typename Scalar, int N>
inline Scalar
dot(const VectorT<Scalar,N>& _v1, const VectorT<Scalar,N>& _v2) {
return (_v1 | _v2);
}
/// \relates OpenMesh::VectorT
/// symmetric version of the cross product
template<typename Scalar, int N>
inline VectorT<Scalar,N>
cross(const VectorT<Scalar,N>& _v1, const VectorT<Scalar,N>& _v2) {
return (_v1 % _v2);
}
//== TYPEDEFS =================================================================
/** 1-byte signed vector */
typedef VectorT<signed char,1> Vec1c;
/** 1-byte unsigned vector */
typedef VectorT<unsigned char,1> Vec1uc;
/** 1-short signed vector */
typedef VectorT<signed short int,1> Vec1s;
/** 1-short unsigned vector */
typedef VectorT<unsigned short int,1> Vec1us;
/** 1-int signed vector */
typedef VectorT<signed int,1> Vec1i;
/** 1-int unsigned vector */
typedef VectorT<unsigned int,1> Vec1ui;
/** 1-float vector */
typedef VectorT<float,1> Vec1f;
/** 1-double vector */
typedef VectorT<double,1> Vec1d;
/** 2-byte signed vector */
typedef VectorT<signed char,2> Vec2c;
/** 2-byte unsigned vector */
typedef VectorT<unsigned char,2> Vec2uc;
/** 2-short signed vector */
typedef VectorT<signed short int,2> Vec2s;
/** 2-short unsigned vector */
typedef VectorT<unsigned short int,2> Vec2us;
/** 2-int signed vector */
typedef VectorT<signed int,2> Vec2i;
/** 2-int unsigned vector */
typedef VectorT<unsigned int,2> Vec2ui;
/** 2-float vector */
typedef VectorT<float,2> Vec2f;
/** 2-double vector */
typedef VectorT<double,2> Vec2d;
/** 3-byte signed vector */
typedef VectorT<signed char,3> Vec3c;
/** 3-byte unsigned vector */
typedef VectorT<unsigned char,3> Vec3uc;
/** 3-short signed vector */
typedef VectorT<signed short int,3> Vec3s;
/** 3-short unsigned vector */
typedef VectorT<unsigned short int,3> Vec3us;
/** 3-int signed vector */
typedef VectorT<signed int,3> Vec3i;
/** 3-int unsigned vector */
typedef VectorT<unsigned int,3> Vec3ui;
/** 3-float vector */
typedef VectorT<float,3> Vec3f;
/** 3-double vector */
typedef VectorT<double,3> Vec3d;
/** 4-byte signed vector */
typedef VectorT<signed char,4> Vec4c;
/** 4-byte unsigned vector */
typedef VectorT<unsigned char,4> Vec4uc;
/** 4-short signed vector */
typedef VectorT<signed short int,4> Vec4s;
/** 4-short unsigned vector */
typedef VectorT<unsigned short int,4> Vec4us;
/** 4-int signed vector */
typedef VectorT<signed int,4> Vec4i;
/** 4-int unsigned vector */
typedef VectorT<unsigned int,4> Vec4ui;
/** 4-float vector */
typedef VectorT<float,4> Vec4f;
/** 4-double vector */
typedef VectorT<double,4> Vec4d;
/** 6-byte signed vector */
typedef VectorT<signed char,6> Vec6c;
/** 6-byte unsigned vector */
typedef VectorT<unsigned char,6> Vec6uc;
/** 6-short signed vector */
typedef VectorT<signed short int,6> Vec6s;
/** 6-short unsigned vector */
typedef VectorT<unsigned short int,6> Vec6us;
/** 6-int signed vector */
typedef VectorT<signed int,6> Vec6i;
/** 6-int unsigned vector */
typedef VectorT<unsigned int,6> Vec6ui;
/** 6-float vector */
typedef VectorT<float,6> Vec6f;
/** 6-double vector */
typedef VectorT<double,6> Vec6d;
//=============================================================================
} // namespace OpenVolumeMesh
//=============================================================================
#endif // OPENVOLUMEMESH_VECTOR_HH defined
//=============================================================================
#endif // DOXYGEN
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 17 $ *
* $Date: 2012-01-09 16:39:50 +0100 (Mon, 09 Jan 2012) $ *
* $LastChangedBy: kremer $ *
* *
\*===========================================================================*/
// Set template keywords and class names properly when
// parsing with doxygen. This only seems to work this way since
// the scope of preprocessor defines is limited to one file in doxy.
#ifdef DOXYGEN
// Only used for correct doxygen parsing
#define OPENVOLUMEMESH_VECTOR_HH
#define DIM N
#define TEMPLATE_HEADER template <typename Scalar, int N>
#define CLASSNAME VectorT
#define DERIVED VectorDataT<Scalar,N>
#define unroll(expr) for (int i=0; i<N; ++i) expr(i)
#endif
#if defined( OPENVOLUMEMESH_VECTOR_HH )
// ----------------------------------------------------------------------------
TEMPLATE_HEADER
class CLASSNAME : public DERIVED
{
private:
typedef DERIVED Base;
public:
//---------------------------------------------------------------- class info
/// the type of the scalar used in this template
typedef Scalar value_type;
/// type of this vector
typedef VectorT<Scalar,DIM> vector_type;
/// returns dimension of the vector (deprecated)
static inline int dim() { return DIM; }
/// returns dimension of the vector
static inline size_t size() { return DIM; }
static const size_t size_ = DIM;
//-------------------------------------------------------------- constructors
/// default constructor creates uninitialized values.
inline VectorT() {}
/// special constructor for 1D vectors
explicit inline VectorT(const Scalar& v) {
// assert(DIM==1);
// values_[0] = v0;
vectorize(v);
}
/// special constructor for 2D vectors
inline VectorT(const Scalar& v0, const Scalar& v1) {
assert(DIM==2);
Base::values_[0] = v0; Base::values_[1] = v1;
}
/// special constructor for 3D vectors
inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) {
assert(DIM==3);
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
}
/// special constructor for 4D vectors
inline VectorT(const Scalar& v0, const Scalar& v1,
const Scalar& v2, const Scalar& v3) {
assert(DIM==4);
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
}
/// special constructor for 5D vectors
inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
const Scalar& v3, const Scalar& v4) {
assert(DIM==5);
Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
}
/// special constructor for 6D vectors
inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
const Scalar& v3, const Scalar& v4, const Scalar& v5) {
assert(DIM==6);
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
}
/// construct from a value array (explicit)
explicit inline VectorT(const Scalar _values[DIM]) {
memcpy(Base::values_, _values, DIM*sizeof(Scalar));
}
#ifdef OM_CC_MIPS
/// assignment from a vector of the same kind
// mipspro need this method
inline vector_type& operator=(const vector_type& _rhs) {
memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
return *this;
}
#endif
/// copy & cast constructor (explicit)
template<typename otherScalarType>
explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
operator=(_rhs);
}
//--------------------------------------------------------------------- casts
/// cast from vector with a different scalar type
template<typename otherScalarType>
inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
#define expr(i) Base::values_[i] = (Scalar)_rhs[i];
unroll(expr);
#undef expr
return *this;
}
// /// cast to Scalar array
// inline operator Scalar*() { return Base::values_; }
// /// cast to const Scalar array
// inline operator const Scalar*() const { return Base::values_; }
/// access to Scalar array
inline Scalar* data() { return Base::values_; }
/// access to const Scalar array
inline const Scalar*data() const { return Base::values_; }
//----------------------------------------------------------- element access
// /// get i'th element read-write
// inline Scalar& operator[](int _i) {
// assert(_i>=0 && _i<DIM); return Base::values_[_i];
// }
// /// get i'th element read-only
// inline const Scalar& operator[](int _i) const {
// assert(_i>=0 && _i<DIM); return Base::values_[_i];
// }
/// get i'th element read-write
inline Scalar& operator[](size_t _i) {
assert(_i<DIM); return Base::values_[_i];
}
/// get i'th element read-only
inline const Scalar& operator[](size_t _i) const {
assert(_i<DIM); return Base::values_[_i];
}
//---------------------------------------------------------------- comparsion
/// component-wise comparison
inline bool operator==(const vector_type& _rhs) const {
#define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
unroll(expr);
#undef expr
return true;
}
/// component-wise comparison
inline bool operator!=(const vector_type& _rhs) const {
return !(*this == _rhs);
}
//---------------------------------------------------------- scalar operators
/// component-wise self-multiplication with scalar
inline vector_type& operator*=(const Scalar& _s) {
#define expr(i) Base::values_[i] *= _s;
unroll(expr);
#undef expr
return *this;
}
/** component-wise self-division by scalar
\attention v *= (1/_s) is much faster than this */
inline vector_type& operator/=(const Scalar& _s) {
#define expr(i) Base::values_[i] /= _s;
unroll(expr);
#undef expr
return *this;
}
/// component-wise multiplication with scalar
inline vector_type operator*(const Scalar& _s) const {
#if DIM==N
return vector_type(*this) *= _s;
#else
#define expr(i) Base::values_[i] * _s
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise division by with scalar
inline vector_type operator/(const Scalar& _s) const {
#if DIM==N
return vector_type(*this) /= _s;
#else