First checkin for OpenMesh 2.0

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Jan Möbius
2009-02-06 13:37:46 +00:00
parent c3321ebdd9
commit 97f515985d
417 changed files with 76182 additions and 0 deletions

17
Core/Geometry/ACGMakefile Normal file
View File

@@ -0,0 +1,17 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
SUBDIRS = $(call find-subdirs)
PACKAGES :=
PROJ_LIBS :=
MODULES := cxxlib
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

56
Core/Geometry/Config.hh Normal file
View File

@@ -0,0 +1,56 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1801 $
// $Date: 2008-05-19 11:53:56 +0200 (Mo, 19. Mai 2008) $
//
//=============================================================================
//=============================================================================
//
// Defines
//
//=============================================================================
#ifndef OPENMESH_GEOMETRY_CONFIG_HH
#define OPENMESH_GEOMETRY_CONFIG_HH
//== INCLUDES =================================================================
// OpenMesh Namespace Defines
#include <OpenMesh/Core/System/config.h>
//== NAMESPACES ===============================================================
#define BEGIN_NS_GEOMETRY namespace geometry {
#define END_NS_GEOMETRY }
//=============================================================================
#endif // OPENMESH_GEOMETRY_CONFIG_HH defined
//=============================================================================

View File

@@ -0,0 +1,172 @@
/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* *
* License *
* *
* This library 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, version 2.1. *
* *
* This library 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 Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
\*===========================================================================*/
#ifndef LOOPSCHEMEMASKT_HH
#define LOOPSCHEMEMASKT_HH
#include <math.h>
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
namespace OpenMesh
{
/** implements cache for the weights of the original Loop scheme
supported:
- vertex projection rule on the next level
- vertex projection rule on the limit surface
- vertex projection rule on the k-th (level) step (Barthe, Kobbelt'2003)
- vertex tangents on the limit surface
*/
template <class T_, unsigned int cache_size_ = 100>
class LoopSchemeMaskT
{
public:
enum { cache_size = cache_size_ };
typedef T_ Scalar;
protected:
Scalar proj_weights_[cache_size];
Scalar limit_weights_[cache_size];
Scalar step_weights_[cache_size];
std::vector<Scalar> tang0_weights_[cache_size];
std::vector<Scalar> tang1_weights_[cache_size];
protected:
inline static Scalar compute_proj_weight(uint _valence)
{
//return pow(3.0 / 2.0 + cos(2.0 * M_PI / _valence), 2) / 2.0 - 1.0;
double denom = (3.0 + 2.0*cos(2.0*M_PI/(double)_valence));
double weight = (64.0*_valence)/(40.0 - denom*denom) - _valence;
return (Scalar) weight;
}
inline static Scalar compute_limit_weight(uint _valence)
{
double proj_weight = compute_proj_weight(_valence);
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0));
return (Scalar)weight;
}
inline static Scalar compute_step_weight(uint _valence)
{
double proj_weight = compute_proj_weight(_valence);
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
double weight = proj_weight - (3.0/8.0);
return (Scalar)weight;
}
inline static Scalar compute_tang0_weight(uint _valence, uint _ver_id)
{
return (Scalar)cos(2.0*M_PI*(double)_ver_id/(double)_valence);
}
inline static Scalar compute_tang1_weight(uint _valence, uint _ver_id)
{
return (Scalar)sin(2.0*M_PI*(double)_ver_id/(double)_valence);
}
void cache_weights()
{
proj_weights_[0] = 1;
for (uint k = 1; k < cache_size; ++k)
{
proj_weights_[k] = compute_proj_weight(k);
limit_weights_[k] = compute_limit_weight(k);
step_weights_[k] = compute_step_weight(k);
tang0_weights_[k].resize(k);
tang1_weights_[k].resize(k);
for (uint i = 0; i < k; ++i)
{
tang0_weights_[k][i] = compute_tang0_weight(k,i);
tang1_weights_[k][i] = compute_tang1_weight(k,i);
}
}
}
public:
LoopSchemeMaskT()
{
cache_weights();
}
inline Scalar proj_weight(uint _valence) const
{
assert(_valence < cache_size );
return proj_weights_[_valence];
}
inline Scalar limit_weight(uint _valence) const
{
assert(_valence < cache_size );
return limit_weights_[_valence];
}
inline Scalar step_weight(uint _valence, uint _step) const
{
assert(_valence < cache_size);
return pow(step_weights_[_valence], (int)_step);//can be precomputed
}
inline Scalar tang0_weight(uint _valence, uint _ver_id) const
{
assert(_valence < cache_size );
assert(_ver_id < _valence);
return tang0_weights_[_valence][_ver_id];
}
inline Scalar tang1_weight(uint _valence, uint _ver_id) const
{
assert(_valence < cache_size );
assert(_ver_id < _valence);
return tang1_weights_[_valence][_ver_id];
}
void dump(uint _max_valency = cache_size - 1) const
{
assert(_max_valency <= cache_size - 1);
//CConsole::printf("(k : pw_k, lw_k): ");
for (uint i = 0; i <= _max_valency; ++i)
{
//CConsole::stream() << "(" << i << " : " << proj_weight(i) << ", " << limit_weight(i) << ", " << step_weight(i,1) << "), ";
}
//CConsole::printf("\n");
}
};
typedef LoopSchemeMaskT<double, 100> LoopSchemeMaskDouble;
typedef SingletonT<LoopSchemeMaskDouble> LoopSchemeMaskDoubleSingleton;
};//namespace OpenMesh
#endif//LOOPSCHEMEMASKT_HH

148
Core/Geometry/MathDefs.hh Normal file
View File

@@ -0,0 +1,148 @@
/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* *
* License *
* *
* This library 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, version 2.1. *
* *
* This library 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 Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
\*===========================================================================*/
#ifndef MATHDEFS_HH
#define MATHDEFS_HH
#include <math.h>
#include <float.h>
#ifndef M_PI
#define M_PI 3.14159265359
#endif
namespace OpenMesh
{
/** comparison operators with user-selected precision control
*/
template <class T, typename Real>
inline bool is_zero(const T& _a, Real _eps)
{ return fabs(_a) < _eps; }
template <class T1, class T2, typename Real>
inline bool is_eq(const T1& a, const T2& b, Real _eps)
{ return is_zero(a-b, _eps); }
template <class T1, class T2, typename Real>
inline bool is_gt(const T1& a, const T2& b, Real _eps)
{ return (a > b) && !is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_ge(const T1& a, const T2& b, Real _eps)
{ return (a > b) || is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_lt(const T1& a, const T2& b, Real _eps)
{ return (a < b) && !is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_le(const T1& a, const T2& b, Real _eps)
{ return (a < b) || is_eq(a,b,_eps); }
/*const float flt_eps__ = 10*FLT_EPSILON;
const double dbl_eps__ = 10*DBL_EPSILON;*/
const float flt_eps__ = (float)1e-05;
const double dbl_eps__ = 1e-09;
inline float eps__(float)
{ return flt_eps__; }
inline double eps__(double)
{ return dbl_eps__; }
template <class T>
inline bool is_zero(const T& a)
{ return is_zero(a, eps__(a)); }
template <class T1, class T2>
inline bool is_eq(const T1& a, const T2& b)
{ return is_zero(a-b); }
template <class T1, class T2>
inline bool is_gt(const T1& a, const T2& b)
{ return (a > b) && !is_eq(a,b); }
template <class T1, class T2>
inline bool is_ge(const T1& a, const T2& b)
{ return (a > b) || is_eq(a,b); }
template <class T1, class T2>
inline bool is_lt(const T1& a, const T2& b)
{ return (a < b) && !is_eq(a,b); }
template <class T1, class T2>
inline bool is_le(const T1& a, const T2& b)
{ return (a < b) || is_eq(a,b); }
/// Trigonometry/angles - related
template <class T>
inline T sane_aarg(T _aarg)
{
if (_aarg < -1)
{
_aarg = -1;
}
else if (_aarg > 1)
{
_aarg = 1;
}
return _aarg;
}
/** returns the angle determined by its cos and the sign of its sin
result is positive if the angle is in [0:pi]
and negative if it is in [pi:2pi]
*/
template <class T>
T angle(T _cos_angle, T _sin_angle)
{//sanity checks - otherwise acos will return nan
_cos_angle = sane_aarg(_cos_angle);
return (T) _sin_angle >= 0 ? acos(_cos_angle) : -acos(_cos_angle);
}
template <class T>
inline T positive_angle(T _angle)
{ return _angle < 0 ? (2*M_PI + _angle) : _angle; }
template <class T>
inline T positive_angle(T _cos_angle, T _sin_angle)
{ return positive_angle(angle(_cos_angle, _sin_angle)); }
template <class T>
inline T deg_to_rad(const T& _angle)
{ return M_PI*(_angle/180); }
template <class T>
inline T rad_to_deg(const T& _angle)
{ return 180*(_angle/M_PI); }
inline double log_(double _value)
{ return log(_value); }
};//namespace OpenMesh
#endif//MATHDEFS_HH

99
Core/Geometry/Plane3d.hh Normal file
View File

@@ -0,0 +1,99 @@
/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2001-2003 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* *
* License *
* *
* This library 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, version 2.1. *
* *
* This library 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 Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS Plane3D
//
//=============================================================================
#ifndef OPENMESH_PLANE3D_HH
#define OPENMESH_PLANE3D_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
//== FORWARDDECLARATIONS ======================================================
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace VDPM {
//== CLASS DEFINITION =========================================================
/** \class Plane3d Plane3d.hh <OpenMesh/Tools/VDPM/Plane3d.hh>
ax + by + cz + d = 0
*/
class Plane3d
{
public:
typedef OpenMesh::Vec3f vector_type;
typedef vector_type::value_type value_type;
public:
Plane3d()
: d_(0)
{ }
Plane3d(const vector_type &_dir, const vector_type &_pnt)
: n_(_dir), d_(0)
{
n_.normalize();
d_ = -dot(n_,_pnt);
}
value_type signed_distance(const OpenMesh::Vec3f &_p)
{
return dot(n_ , _p) + d_;
}
// back compatibility
value_type singed_distance(const OpenMesh::Vec3f &point)
{ return signed_distance( point ); }
public:
vector_type n_;
value_type d_;
};
//=============================================================================
} // namespace VDPM
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_PLANE3D_HH defined
//=============================================================================

260
Core/Geometry/QuadricT.hh Normal file
View File

@@ -0,0 +1,260 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1801 $
// $Date: 2008-05-19 11:53:56 +0200 (Mo, 19. Mai 2008) $
//
//=============================================================================
/** \file QuadricT.hh
*/
//=============================================================================
//
// CLASS QuadricT
//
//=============================================================================
#ifndef OPENMESH_GEOMETRY_QUADRIC_HH
#define OPENMESH_GEOMETRY_QUADRIC_HH
//== INCLUDES =================================================================
#include "Config.hh"
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
//== NAMESPACE ================================================================
namespace OpenMesh { //BEGIN_NS_OPENMESH
namespace Geometry { //BEGIN_NS_GEOMETRY
//== CLASS DEFINITION =========================================================
/** /class QuadricT QuadricT.hh <OSG/Geometry/Types/QuadricT.hh>
Stores a quadric as a 4x4 symmetrix matrix. Used by the
error quadric based mesh decimation algorithms.
**/
template <class Scalar>
class QuadricT
{
public:
typedef Scalar value_type;
typedef QuadricT<Scalar> type;
typedef QuadricT<Scalar> Self;
// typedef VectorInterface<Scalar, VecStorage3<Scalar> > Vec3;
// typedef VectorInterface<Scalar, VecStorage4<Scalar> > Vec4;
//typedef Vector3Elem Vec3;
//typedef Vector4Elem Vec4;
/// construct with upper triangle of symmetrix 4x4 matrix
QuadricT(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
Scalar _e, Scalar _f, Scalar _g,
Scalar _h, Scalar _i,
Scalar _j)
: a_(_a), b_(_b), c_(_c), d_(_d),
e_(_e), f_(_f), g_(_g),
h_(_h), i_(_i),
j_(_j)
{
}
/// constructor from given plane equation: ax+by+cz+d_=0
QuadricT( Scalar _a=0.0, Scalar _b=0.0, Scalar _c=0.0, Scalar _d=0.0 )
: a_(_a*_a), b_(_a*_b), c_(_a*_c), d_(_a*_d),
e_(_b*_b), f_(_b*_c), g_(_b*_d),
h_(_c*_c), i_(_c*_d),
j_(_d*_d)
{}
template <class _Point>
QuadricT(const _Point& _pt)
{
set_distance_to_point(_pt);
}
template <class _Normal, class _Point>
QuadricT(const _Normal& _n, const _Point& _p)
{
set_distance_to_plane(_n,_p);
}
//set operator
void set(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
Scalar _e, Scalar _f, Scalar _g,
Scalar _h, Scalar _i,
Scalar _j)
{
a_ = _a; b_ = _b; c_ = _c; d_ = _d;
e_ = _e; f_ = _f; g_ = _g;
h_ = _h; i_ = _i;
j_ = _j;
}
//sets the quadric representing the squared distance to _pt
template <class _Point>
void set_distance_to_point(const _Point& _pt)
{
set(1, 0, 0, -_pt[0],
1, 0, -_pt[1],
1, -_pt[2],
dot(_pt,_pt));
}
//sets the quadric representing the squared distance to the plane [_a,_b,_c,_d]
void set_distance_to_plane(Scalar _a, Scalar _b, Scalar _c, Scalar _d)
{
a_ = _a*_a; b_ = _a*_b; c_ = _a*_c; d_ = _a*_d;
e_ = _b*_b; f_ = _b*_c; g_ = _b*_d;
h_ = _c*_c; i_ = _c*_d;
j_ = _d*_d;
}
//sets the quadric representing the squared distance to the plane
//determined by the normal _n and the point _p
template <class _Normal, class _Point>
void set_distance_to_plane(const _Normal& _n, const _Point& _p)
{
set_distance_to_plane(_n[0], _n[1], _n[2], -dot(_n,_p));
}
/// set all entries to zero
void clear() { a_ = b_ = c_ = d_ = e_ = f_ = g_ = h_ = i_ = j_ = 0.0; }
/// add quadrics
QuadricT<Scalar>& operator+=( const QuadricT<Scalar>& _q )
{
a_ += _q.a_; b_ += _q.b_; c_ += _q.c_; d_ += _q.d_;
e_ += _q.e_; f_ += _q.f_; g_ += _q.g_;
h_ += _q.h_; i_ += _q.i_;
j_ += _q.j_;
return *this;
}
/// multiply by scalar
QuadricT<Scalar>& operator*=( Scalar _s)
{
a_ *= _s; b_ *= _s; c_ *= _s; d_ *= _s;
e_ *= _s; f_ *= _s; g_ *= _s;
h_ *= _s; i_ *= _s;
j_ *= _s;
return *this;
}
/// multiply 4D vector from right: Q*v
template <class _Vec4>
_Vec4 operator*(const _Vec4& _v) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
return _Vec4(x*a_ + y*b_ + z*c_ + w*d_,
x*b_ + y*e_ + z*f_ + w*g_,
x*c_ + y*f_ + z*h_ + w*i_,
x*d_ + y*g_ + z*i_ + w*j_);
}
/// evaluate quadric Q at (3D or 4D) vector v: v*Q*v
template <class _Vec>
Scalar operator()(const _Vec& _v) const
{
return evaluate(_v, GenProg::Int2Type<_Vec::size_>());
}
Scalar a() const { return a_; }
Scalar b() const { return b_; }
Scalar c() const { return c_; }
Scalar d() const { return d_; }
Scalar e() const { return e_; }
Scalar f() const { return f_; }
Scalar g() const { return g_; }
Scalar h() const { return h_; }
Scalar i() const { return i_; }
Scalar j() const { return j_; }
Scalar xx() const { return a_; }
Scalar xy() const { return b_; }
Scalar xz() const { return c_; }
Scalar xw() const { return d_; }
Scalar yy() const { return e_; }
Scalar yz() const { return f_; }
Scalar yw() const { return g_; }
Scalar zz() const { return h_; }
Scalar zw() const { return i_; }
Scalar ww() const { return j_; }
protected:
/// evaluate quadric Q at 3D vector v: v*Q*v
template <class _Vec3>
Scalar evaluate(const _Vec3& _v, GenProg::Int2Type<3>/*_dimension*/) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]);
return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x
+ e_*y*y + 2.0*f_*y*z + 2.0*g_*y
+ h_*z*z + 2.0*i_*z
+ j_;
}
/// evaluate quadric Q at 4D vector v: v*Q*v
template <class _Vec4>
Scalar evaluate(const _Vec4& _v, GenProg::Int2Type<4>/*_dimension*/) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x*w
+ e_*y*y + 2.0*f_*y*z + 2.0*g_*y*w
+ h_*z*z + 2.0*i_*z*w
+ j_*w*w;
}
private:
Scalar a_, b_, c_, d_,
e_, f_, g_,
h_, i_,
j_;
};
/// Quadric using floats
typedef QuadricT<float> Quadricf;
/// Quadric using double
typedef QuadricT<double> Quadricd;
//=============================================================================
} // END_NS_GEOMETRY
} // END_NS_OPENMESH
//============================================================================
#endif // OPENMESH_GEOMETRY_HH defined
//=============================================================================

329
Core/Geometry/VectorT.hh Normal file
View File

@@ -0,0 +1,329 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 4254 $
// $Date: 2009-01-12 14:44:00 +0100 (Mo, 12. Jan 2009) $
//
//=============================================================================
//=============================================================================
//
// CLASS VectorT
//
//=============================================================================
#ifndef OPENMESH_VECTOR_HH
#define OPENMESH_VECTOR_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <iostream>
#include <assert.h>
#include <math.h>
#if defined(__GNUC__) && defined(__SSE__)
#include <xmmintrin.h>
#endif
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== 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
# ifndef DOXY_IGNORE_THIS
/// 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 // DOXY_IGNORE_THIS
#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 OpenMesh
//=============================================================================
#endif // OPENMESH_VECTOR_HH defined
//=============================================================================

View File

@@ -0,0 +1,541 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1801 $
// $Date: 2008-05-19 11:53:56 +0200 (Mo, 19. Mai 2008) $
//
//=============================================================================
#if defined( OPENMESH_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
#define expr(i) Base::values_[i] / _s
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
//---------------------------------------------------------- vector operators
/// component-wise self-multiplication
inline vector_type& operator*=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] *= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// component-wise self-division
inline vector_type& operator/=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] /= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// vector difference from this
inline vector_type& operator-=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] -= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// vector self-addition
inline vector_type& operator+=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] += _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// component-wise vector multiplication
inline vector_type operator*(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) *= _v;
#else
#define expr(i) Base::values_[i] * _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector division
inline vector_type operator/(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) /= _v;
#else
#define expr(i) Base::values_[i] / _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector addition
inline vector_type operator+(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) += _v;
#else
#define expr(i) Base::values_[i] + _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector difference
inline vector_type operator-(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) -= _v;
#else
#define expr(i) Base::values_[i] - _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// unary minus
inline vector_type operator-(void) const {
vector_type v;
#define expr(i) v.Base::values_[i] = -Base::values_[i];
unroll(expr);
#undef expr
return v;
}
/// cross product: only defined for Vec3* as specialization
/// \see OpenMesh::cross
inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
#if DIM==3
{
return
VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
}
#else
;
#endif
/// compute scalar product
/// \see OpenMesh::dot
inline Scalar operator|(const vector_type& _rhs) const {
Scalar p(0);
#define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
unroll(expr);
#undef expr
return p;
}
//------------------------------------------------------------ euclidean norm
/// \name Euclidean norm calculations
//@{
/// compute euclidean norm
inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
inline Scalar length() const { return norm(); } // OpenSG interface
/// compute squared euclidean norm
inline Scalar sqrnorm() const
{
#if DIM==N
Scalar s(0);
#define expr(i) s += Base::values_[i] * Base::values_[i];
unroll(expr);
#undef expr
return s;
#else
#define expr(i) Base::values_[i]*Base::values_[i]
return (unroll_comb(expr, +));
#undef expr
#endif
}
//@}
/** normalize vector, return normalized vector
*/
inline vector_type& normalize()
{
*this /= norm();
return *this;
}
/** normalize vector, return normalized vector and avoids div by zero
*/
inline vector_type& normalize_cond()
{
Scalar n = norm();
if (n != (Scalar)0.0)
{
*this /= n;
}
return *this;
}
//------------------------------------------------------------ max, min, mean
/// return the maximal component
inline Scalar max() const
{
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
return m;
}
/// return the minimal component
inline Scalar min() const
{
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
return m;
}
/// return arithmetic mean
inline Scalar mean() const {
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) m+=Base::values_[i];
return m/Scalar(DIM);
}
/// minimize values: same as *this = min(*this, _rhs), but faster
inline vector_type minimize(const vector_type& _rhs) {
#define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// maximize values: same as *this = max(*this, _rhs), but faster
inline vector_type maximize(const vector_type& _rhs) {
#define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// component-wise min
inline vector_type min(const vector_type& _rhs) {
return vector_type(*this).minimize(_rhs);
}
/// component-wise max
inline vector_type max(const vector_type& _rhs) {
return vector_type(*this).maximize(_rhs);
}
//------------------------------------------------------------ misc functions
/// component-wise apply function object with Scalar operator()(Scalar).
template<typename Functor>
inline vector_type apply(const Functor& _func) const {
vector_type result;
#define expr(i) result[i] = _func(Base::values_[i]);
unroll(expr);
#undef expr
return result;
}
/// store the same value in each component (e.g. to clear all entries)
vector_type& vectorize(const Scalar& _s) {
#define expr(i) Base::values_[i] = _s;
unroll(expr);
#undef expr
return *this;
}
/// store the same value in each component
static vector_type vectorized(const Scalar& _s) {
return vector_type().vectorize(_s);
}
/// lexicographical comparison
bool operator<(const vector_type& _rhs) const {
#define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
return (Base::values_[i] < _rhs.Base::values_[i]);
unroll(expr);
#undef expr
return false;
}
};
/// read the space-separated components of a vector from a stream
TEMPLATE_HEADER
inline std::istream&
operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
{
#define expr(i) is >> vec[i];
unroll(expr);
#undef expr
return is;
}
/// output a vector by printing its space-separated compontens
TEMPLATE_HEADER
inline std::ostream&
operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
{
#if DIM==N
for(int i=0; i<N-1; ++i) os << vec[i] << " ";
os << vec[N-1];
#else
#define expr(i) vec[i]
os << unroll_comb(expr, << " " <<);
#undef expr
#endif
return os;
}
// ----------------------------------------------------------------------------
#endif // included by VectorT.hh
//=============================================================================