OpenMesh
|
00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * This file is part of OpenMesh. * 00009 * * 00010 * OpenMesh is free software: you can redistribute it and/or modify * 00011 * it under the terms of the GNU Lesser General Public License as * 00012 * published by the Free Software Foundation, either version 3 of * 00013 * the License, or (at your option) any later version with the * 00014 * following exceptions: * 00015 * * 00016 * If other files instantiate templates or use macros * 00017 * or inline functions from this file, or you compile this file and * 00018 * link it with other files to produce an executable, this file does * 00019 * not by itself cause the resulting executable to be covered by the * 00020 * GNU Lesser General Public License. This exception does not however * 00021 * invalidate any other reasons why the executable file might be * 00022 * covered by the GNU Lesser General Public License. * 00023 * * 00024 * OpenMesh is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU Lesser General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU LesserGeneral Public * 00030 * License along with OpenMesh. If not, * 00031 * see <http://www.gnu.org/licenses/>. * 00032 * * 00033 \*===========================================================================*/ 00034 00035 /*===========================================================================*\ 00036 * * 00037 * $Revision: 362 $ * 00038 * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00042 // Set template keywords and class names properly when 00043 // parsing with doxygen. This only seems to work this way since 00044 // the scope of preprocessor defines is limited to one file in doxy. 00045 #ifdef DOXYGEN 00046 00047 // Only used for correct doxygen parsing 00048 #define OPENMESH_VECTOR_HH 00049 00050 #define DIM N 00051 #define TEMPLATE_HEADER template <typename Scalar, int N> 00052 #define CLASSNAME VectorT 00053 #define DERIVED VectorDataT<Scalar,N> 00054 #define unroll(expr) for (int i=0; i<N; ++i) expr(i) 00055 00056 #endif 00057 00058 #if defined( OPENMESH_VECTOR_HH ) 00059 00060 // ---------------------------------------------------------------------------- 00061 00062 TEMPLATE_HEADER 00063 class CLASSNAME : public DERIVED 00064 { 00065 private: 00066 typedef DERIVED Base; 00067 public: 00068 00069 //---------------------------------------------------------------- class info 00070 00072 typedef Scalar value_type; 00073 00075 typedef VectorT<Scalar,DIM> vector_type; 00076 00078 static inline int dim() { return DIM; } 00079 00081 static inline size_t size() { return DIM; } 00082 00083 static const size_t size_ = DIM; 00084 00085 00086 //-------------------------------------------------------------- constructors 00087 00089 inline VectorT() {} 00090 00092 explicit inline VectorT(const Scalar& v) { 00093 // assert(DIM==1); 00094 // values_[0] = v0; 00095 vectorize(v); 00096 } 00097 00099 inline VectorT(const Scalar& v0, const Scalar& v1) { 00100 assert(DIM==2); 00101 Base::values_[0] = v0; Base::values_[1] = v1; 00102 } 00103 00105 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) { 00106 assert(DIM==3); 00107 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; 00108 } 00109 00111 inline VectorT(const Scalar& v0, const Scalar& v1, 00112 const Scalar& v2, const Scalar& v3) { 00113 assert(DIM==4); 00114 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3; 00115 } 00116 00118 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2, 00119 const Scalar& v3, const Scalar& v4) { 00120 assert(DIM==5); 00121 Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4; 00122 } 00123 00125 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2, 00126 const Scalar& v3, const Scalar& v4, const Scalar& v5) { 00127 assert(DIM==6); 00128 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; 00129 Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5; 00130 } 00131 00133 explicit inline VectorT(const Scalar _values[DIM]) { 00134 memcpy(Base::values_, _values, DIM*sizeof(Scalar)); 00135 } 00136 00137 00138 #ifdef OM_CC_MIPS 00139 00140 // mipspro need this method 00141 inline vector_type& operator=(const vector_type& _rhs) { 00142 memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar)); 00143 return *this; 00144 } 00145 #endif 00146 00147 00149 template<typename otherScalarType> 00150 explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) { 00151 operator=(_rhs); 00152 } 00153 00154 00155 00156 00157 //--------------------------------------------------------------------- casts 00158 00160 template<typename otherScalarType> 00161 inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) { 00162 #define expr(i) Base::values_[i] = (Scalar)_rhs[i]; 00163 unroll(expr); 00164 #undef expr 00165 return *this; 00166 } 00167 00168 // /// cast to Scalar array 00169 // inline operator Scalar*() { return Base::values_; } 00170 00171 // /// cast to const Scalar array 00172 // inline operator const Scalar*() const { return Base::values_; } 00173 00175 inline Scalar* data() { return Base::values_; } 00176 00178 inline const Scalar*data() const { return Base::values_; } 00179 00180 00181 00182 00183 //----------------------------------------------------------- element access 00184 00185 // /// get i'th element read-write 00186 // inline Scalar& operator[](int _i) { 00187 // assert(_i>=0 && _i<DIM); return Base::values_[_i]; 00188 // } 00189 00190 // /// get i'th element read-only 00191 // inline const Scalar& operator[](int _i) const { 00192 // assert(_i>=0 && _i<DIM); return Base::values_[_i]; 00193 // } 00194 00196 inline Scalar& operator[](size_t _i) { 00197 assert(_i<DIM); return Base::values_[_i]; 00198 } 00199 00201 inline const Scalar& operator[](size_t _i) const { 00202 assert(_i<DIM); return Base::values_[_i]; 00203 } 00204 00205 00206 00207 00208 //---------------------------------------------------------------- comparsion 00209 00211 inline bool operator==(const vector_type& _rhs) const { 00212 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false; 00213 unroll(expr); 00214 #undef expr 00215 return true; 00216 } 00217 00219 inline bool operator!=(const vector_type& _rhs) const { 00220 return !(*this == _rhs); 00221 } 00222 00223 00224 00225 00226 //---------------------------------------------------------- scalar operators 00227 00229 inline vector_type& operator*=(const Scalar& _s) { 00230 #define expr(i) Base::values_[i] *= _s; 00231 unroll(expr); 00232 #undef expr 00233 return *this; 00234 } 00235 00238 inline vector_type& operator/=(const Scalar& _s) { 00239 #define expr(i) Base::values_[i] /= _s; 00240 unroll(expr); 00241 #undef expr 00242 return *this; 00243 } 00244 00245 00247 inline vector_type operator*(const Scalar& _s) const { 00248 #if DIM==N 00249 return vector_type(*this) *= _s; 00250 #else 00251 #define expr(i) Base::values_[i] * _s 00252 return vector_type(unroll_csv(expr)); 00253 #undef expr 00254 #endif 00255 } 00256 00257 00259 inline vector_type operator/(const Scalar& _s) const { 00260 #if DIM==N 00261 return vector_type(*this) /= _s; 00262 #else 00263 #define expr(i) Base::values_[i] / _s 00264 return vector_type(unroll_csv(expr)); 00265 #undef expr 00266 #endif 00267 } 00268 00269 00270 00271 00272 00273 00274 //---------------------------------------------------------- vector operators 00275 00277 inline vector_type& operator*=(const vector_type& _rhs) { 00278 #define expr(i) Base::values_[i] *= _rhs[i]; 00279 unroll(expr); 00280 #undef expr 00281 return *this; 00282 } 00283 00285 inline vector_type& operator/=(const vector_type& _rhs) { 00286 #define expr(i) Base::values_[i] /= _rhs[i]; 00287 unroll(expr); 00288 #undef expr 00289 return *this; 00290 } 00291 00293 inline vector_type& operator-=(const vector_type& _rhs) { 00294 #define expr(i) Base::values_[i] -= _rhs[i]; 00295 unroll(expr); 00296 #undef expr 00297 return *this; 00298 } 00299 00301 inline vector_type& operator+=(const vector_type& _rhs) { 00302 #define expr(i) Base::values_[i] += _rhs[i]; 00303 unroll(expr); 00304 #undef expr 00305 return *this; 00306 } 00307 00308 00310 inline vector_type operator*(const vector_type& _v) const { 00311 #if DIM==N 00312 return vector_type(*this) *= _v; 00313 #else 00314 #define expr(i) Base::values_[i] * _v.Base::values_[i] 00315 return vector_type(unroll_csv(expr)); 00316 #undef expr 00317 #endif 00318 } 00319 00320 00322 inline vector_type operator/(const vector_type& _v) const { 00323 #if DIM==N 00324 return vector_type(*this) /= _v; 00325 #else 00326 #define expr(i) Base::values_[i] / _v.Base::values_[i] 00327 return vector_type(unroll_csv(expr)); 00328 #undef expr 00329 #endif 00330 } 00331 00332 00334 inline vector_type operator+(const vector_type& _v) const { 00335 #if DIM==N 00336 return vector_type(*this) += _v; 00337 #else 00338 #define expr(i) Base::values_[i] + _v.Base::values_[i] 00339 return vector_type(unroll_csv(expr)); 00340 #undef expr 00341 #endif 00342 } 00343 00344 00346 inline vector_type operator-(const vector_type& _v) const { 00347 #if DIM==N 00348 return vector_type(*this) -= _v; 00349 #else 00350 #define expr(i) Base::values_[i] - _v.Base::values_[i] 00351 return vector_type(unroll_csv(expr)); 00352 #undef expr 00353 #endif 00354 } 00355 00356 00358 inline vector_type operator-(void) const { 00359 vector_type v; 00360 #define expr(i) v.Base::values_[i] = -Base::values_[i]; 00361 unroll(expr); 00362 #undef expr 00363 return v; 00364 } 00365 00366 00369 inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const 00370 #if DIM==3 00371 { 00372 return 00373 VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1], 00374 Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2], 00375 Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]); 00376 } 00377 #else 00378 ; 00379 #endif 00380 00381 00384 inline Scalar operator|(const vector_type& _rhs) const { 00385 Scalar p(0); 00386 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i]; 00387 unroll(expr); 00388 #undef expr 00389 return p; 00390 } 00391 00392 00393 00394 00395 00396 //------------------------------------------------------------ euclidean norm 00397 00399 00400 00401 inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); } 00402 inline Scalar length() const { return norm(); } // OpenSG interface 00403 00405 inline Scalar sqrnorm() const 00406 { 00407 #if DIM==N 00408 Scalar s(0); 00409 #define expr(i) s += Base::values_[i] * Base::values_[i]; 00410 unroll(expr); 00411 #undef expr 00412 return s; 00413 #else 00414 #define expr(i) Base::values_[i]*Base::values_[i] 00415 return (unroll_comb(expr, +)); 00416 #undef expr 00417 #endif 00418 } 00419 00423 inline vector_type& normalize() 00424 { 00425 *this /= norm(); 00426 return *this; 00427 } 00428 00431 inline vector_type& normalize_cond() 00432 { 00433 Scalar n = norm(); 00434 if (n != (Scalar)0.0) 00435 { 00436 *this /= n; 00437 } 00438 return *this; 00439 } 00440 00442 00443 //------------------------------------------------------------ euclidean norm 00444 00446 00447 00449 inline Scalar l1_norm() const 00450 { 00451 #if DIM==N 00452 Scalar s(0); 00453 #define expr(i) s += abs(Base::values_[i]); 00454 unroll(expr); 00455 #undef expr 00456 return s; 00457 #else 00458 #define expr(i) abs(Base::values_[i]) 00459 return (unroll_comb(expr, +)); 00460 #undef expr 00461 #endif 00462 } 00463 00465 inline Scalar l8_norm() const 00466 { 00467 return max_abs(); 00468 } 00469 00471 00472 //------------------------------------------------------------ max, min, mean 00473 00475 00476 00478 inline Scalar max() const 00479 { 00480 Scalar m(Base::values_[0]); 00481 for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i]; 00482 return m; 00483 } 00484 00486 inline Scalar max_abs() const 00487 { 00488 Scalar m(abs(Base::values_[0])); 00489 for(int i=1; i<DIM; ++i) 00490 if(abs(Base::values_[i])>m) 00491 m=abs(Base::values_[i]); 00492 return m; 00493 } 00494 00495 00497 inline Scalar min() const 00498 { 00499 Scalar m(Base::values_[0]); 00500 for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i]; 00501 return m; 00502 } 00503 00505 inline Scalar min_abs() const 00506 { 00507 Scalar m(abs(Base::values_[0])); 00508 for(int i=1; i<DIM; ++i) 00509 if(abs(Base::values_[i])<m) 00510 m=abs(Base::values_[i]); 00511 return m; 00512 } 00513 00515 inline Scalar mean() const { 00516 Scalar m(Base::values_[0]); 00517 for(int i=1; i<DIM; ++i) m+=Base::values_[i]; 00518 return m/Scalar(DIM); 00519 } 00520 00522 inline Scalar mean_abs() const { 00523 Scalar m(abs(Base::values_[0])); 00524 for(int i=1; i<DIM; ++i) m+=abs(Base::values_[i]); 00525 return m/Scalar(DIM); 00526 } 00527 00528 00530 inline vector_type minimize(const vector_type& _rhs) { 00531 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i]; 00532 unroll(expr); 00533 #undef expr 00534 return *this; 00535 } 00536 00538 inline bool minimized(const vector_type& _rhs) { 00539 bool result(false); 00540 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; } 00541 unroll(expr); 00542 #undef expr 00543 return result; 00544 } 00545 00547 inline vector_type maximize(const vector_type& _rhs) { 00548 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i]; 00549 unroll(expr); 00550 #undef expr 00551 return *this; 00552 } 00553 00555 inline bool maximized(const vector_type& _rhs) { 00556 bool result(false); 00557 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; } 00558 unroll(expr); 00559 #undef expr 00560 return result; 00561 } 00562 00564 inline vector_type min(const vector_type& _rhs) { 00565 return vector_type(*this).minimize(_rhs); 00566 } 00567 00569 inline vector_type max(const vector_type& _rhs) { 00570 return vector_type(*this).maximize(_rhs); 00571 } 00572 00574 00575 //------------------------------------------------------------ misc functions 00576 00578 template<typename Functor> 00579 inline vector_type apply(const Functor& _func) const { 00580 vector_type result; 00581 #define expr(i) result[i] = _func(Base::values_[i]); 00582 unroll(expr); 00583 #undef expr 00584 return result; 00585 } 00586 00588 vector_type& vectorize(const Scalar& _s) { 00589 #define expr(i) Base::values_[i] = _s; 00590 unroll(expr); 00591 #undef expr 00592 return *this; 00593 } 00594 00595 00597 static vector_type vectorized(const Scalar& _s) { 00598 return vector_type().vectorize(_s); 00599 } 00600 00601 00603 bool operator<(const vector_type& _rhs) const { 00604 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \ 00605 return (Base::values_[i] < _rhs.Base::values_[i]); 00606 unroll(expr); 00607 #undef expr 00608 return false; 00609 } 00610 }; 00611 00612 00613 00615 TEMPLATE_HEADER 00616 inline std::istream& 00617 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec) 00618 { 00619 #define expr(i) is >> vec[i]; 00620 unroll(expr); 00621 #undef expr 00622 return is; 00623 } 00624 00625 00627 TEMPLATE_HEADER 00628 inline std::ostream& 00629 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec) 00630 { 00631 #if DIM==N 00632 for(int i=0; i<N-1; ++i) os << vec[i] << " "; 00633 os << vec[N-1]; 00634 #else 00635 #define expr(i) vec[i] 00636 os << unroll_comb(expr, << " " <<); 00637 #undef expr 00638 #endif 00639 00640 return os; 00641 } 00642 00643 00644 // ---------------------------------------------------------------------------- 00645 #endif // included by VectorT.hh 00646 //=============================================================================