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: 421 $ * 00038 * $Date: 2011-10-10 13:14:09 +0200 (Mo, 10 Okt 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00042 #ifndef OPENMESH_PROPERTY_HH 00043 #define OPENMESH_PROPERTY_HH 00044 00045 00046 //== INCLUDES ================================================================= 00047 00048 00049 #include <OpenMesh/Core/System/config.h> 00050 #include <OpenMesh/Core/Mesh/Handles.hh> 00051 #include <OpenMesh/Core/Utils/BaseProperty.hh> 00052 #include <vector> 00053 #include <string> 00054 #include <algorithm> 00055 00056 00057 //== NAMESPACES =============================================================== 00058 00059 namespace OpenMesh { 00060 00061 //== CLASS DEFINITION ========================================================= 00062 00081 // TODO: it might be possible to define Property using kind of a runtime info 00082 // structure holding the size of T. Then reserve, swap, resize, etc can be written 00083 // in pure malloc() style w/o virtual overhead. Template member function proved per 00084 // element access to the properties, asserting dynamic_casts in debug 00085 00086 template <class T> 00087 class PropertyT : public BaseProperty 00088 { 00089 public: 00090 00091 typedef T Value; 00092 typedef std::vector<T> vector_type; 00093 typedef T value_type; 00094 typedef typename vector_type::reference reference; 00095 typedef typename vector_type::const_reference const_reference; 00096 00097 public: 00098 00100 PropertyT(const std::string& _name = "<unknown>") 00101 : BaseProperty(_name) 00102 {} 00103 00105 PropertyT(const PropertyT & _rhs) 00106 : BaseProperty( _rhs ), data_( _rhs.data_ ) {} 00107 00108 public: // inherited from BaseProperty 00109 00110 virtual void reserve(size_t _n) { data_.reserve(_n); } 00111 virtual void resize(size_t _n) { data_.resize(_n); } 00112 virtual void clear() { data_.clear(); vector_type().swap(data_); } 00113 virtual void push_back() { data_.push_back(T()); } 00114 virtual void swap(size_t _i0, size_t _i1) 00115 { std::swap(data_[_i0], data_[_i1]); } 00116 00117 public: 00118 00119 virtual void set_persistent( bool _yn ) 00120 { check_and_set_persistent<T>( _yn ); } 00121 00122 virtual size_t n_elements() const { return data_.size(); } 00123 virtual size_t element_size() const { return IO::size_of<T>(); } 00124 00125 #ifndef DOXY_IGNORE_THIS 00126 struct plus { 00127 size_t operator () ( size_t _b, const T& _v ) 00128 { return _b + IO::size_of<T>(_v); } 00129 }; 00130 #endif 00131 00132 virtual size_t size_of(void) const 00133 { 00134 if (element_size() != IO::UnknownSize) 00135 return this->BaseProperty::size_of(n_elements()); 00136 return std::accumulate(data_.begin(), data_.end(), 0, plus()); 00137 } 00138 00139 virtual size_t size_of(size_t _n_elem) const 00140 { return this->BaseProperty::size_of(_n_elem); } 00141 00142 virtual size_t store( std::ostream& _ostr, bool _swap ) const 00143 { 00144 if ( IO::is_streamable<vector_type>() ) 00145 return IO::store(_ostr, data_, _swap ); 00146 size_t bytes = 0; 00147 for (size_t i=0; i<n_elements(); ++i) 00148 bytes += IO::store( _ostr, data_[i], _swap ); 00149 return bytes; 00150 } 00151 00152 virtual size_t restore( std::istream& _istr, bool _swap ) 00153 { 00154 if ( IO::is_streamable<vector_type>() ) 00155 return IO::restore(_istr, data_, _swap ); 00156 size_t bytes = 0; 00157 for (size_t i=0; i<n_elements(); ++i) 00158 bytes += IO::restore( _istr, data_[i], _swap ); 00159 return bytes; 00160 } 00161 00162 public: // data access interface 00163 00165 const T* data() const { 00166 00167 if( data_.empty() ) 00168 return 0; 00169 00170 return &data_[0]; 00171 } 00172 00174 vector_type& data_vector() { 00175 00176 return data_; 00177 } 00178 00180 reference operator[](int _idx) 00181 { 00182 assert( size_t(_idx) < data_.size() ); 00183 return data_[_idx]; 00184 } 00185 00187 const_reference operator[](int _idx) const 00188 { 00189 assert( size_t(_idx) < data_.size()); 00190 return data_[_idx]; 00191 } 00192 00194 PropertyT<T>* clone() const 00195 { 00196 PropertyT<T>* p = new PropertyT<T>( *this ); 00197 return p; 00198 } 00199 00200 00201 private: 00202 00203 vector_type data_; 00204 }; 00205 00206 //----------------------------------------------------------------------------- 00207 00208 00213 template <> 00214 class PropertyT<bool> : public BaseProperty 00215 { 00216 public: 00217 00218 typedef std::vector<bool> vector_type; 00219 typedef bool value_type; 00220 typedef vector_type::reference reference; 00221 typedef vector_type::const_reference const_reference; 00222 00223 public: 00224 00225 PropertyT(const std::string& _name = "<unknown>") 00226 : BaseProperty(_name) 00227 { } 00228 00229 public: // inherited from BaseProperty 00230 00231 virtual void reserve(size_t _n) { data_.reserve(_n); } 00232 virtual void resize(size_t _n) { data_.resize(_n); } 00233 virtual void clear() { data_.clear(); vector_type().swap(data_); } 00234 virtual void push_back() { data_.push_back(bool()); } 00235 virtual void swap(size_t _i0, size_t _i1) 00236 { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; } 00237 00238 public: 00239 00240 virtual void set_persistent( bool _yn ) 00241 { 00242 check_and_set_persistent<bool>( _yn ); 00243 } 00244 00245 virtual size_t n_elements() const { return data_.size(); } 00246 virtual size_t element_size() const { return UnknownSize; } 00247 virtual size_t size_of() const { return size_of( n_elements() ); } 00248 virtual size_t size_of(size_t _n_elem) const 00249 { 00250 return _n_elem / 8 + ((_n_elem % 8)!=0); 00251 } 00252 00253 size_t store( std::ostream& _ostr, bool /* _swap */ ) const 00254 { 00255 size_t bytes = 0; 00256 00257 size_t N = data_.size() / 8; 00258 size_t R = data_.size() % 8; 00259 00260 size_t idx; // element index 00261 size_t bidx; 00262 unsigned char bits; // bitset 00263 00264 for (bidx=idx=0; idx < N; ++idx, bidx+=8) 00265 { 00266 bits = !!data_[bidx] 00267 | (!!data_[bidx+1] << 1) 00268 | (!!data_[bidx+2] << 2) 00269 | (!!data_[bidx+3] << 3) 00270 | (!!data_[bidx+4] << 4) 00271 | (!!data_[bidx+5] << 5) 00272 | (!!data_[bidx+6] << 6) 00273 | (!!data_[bidx+7] << 7); 00274 _ostr << bits; 00275 } 00276 bytes = N; 00277 00278 if (R) 00279 { 00280 bits = 0; 00281 for (idx=0; idx < R; ++idx) 00282 bits |= !!data_[bidx+idx] << idx; 00283 _ostr << bits; 00284 ++bytes; 00285 } 00286 00287 std::cout << std::endl; 00288 00289 assert( bytes == size_of() ); 00290 00291 return bytes; 00292 } 00293 00294 size_t restore( std::istream& _istr, bool /* _swap */ ) 00295 { 00296 size_t bytes = 0; 00297 00298 size_t N = data_.size() / 8; 00299 size_t R = data_.size() % 8; 00300 00301 size_t idx; // element index 00302 size_t bidx; // 00303 unsigned char bits; // bitset 00304 00305 for (bidx=idx=0; idx < N; ++idx, bidx+=8) 00306 { 00307 _istr >> bits; 00308 data_[bidx+0] = !!(bits & 0x01); 00309 data_[bidx+1] = !!(bits & 0x02); 00310 data_[bidx+2] = !!(bits & 0x04); 00311 data_[bidx+3] = !!(bits & 0x08); 00312 data_[bidx+4] = !!(bits & 0x10); 00313 data_[bidx+5] = !!(bits & 0x20); 00314 data_[bidx+6] = !!(bits & 0x40); 00315 data_[bidx+7] = !!(bits & 0x80); 00316 } 00317 bytes = N; 00318 00319 if (R) 00320 { 00321 _istr >> bits; 00322 for (idx=0; idx < R; ++idx) 00323 data_[bidx+idx] = !!(bits & (1<<idx)); 00324 ++bytes; 00325 } 00326 00327 std::cout << std::endl; 00328 00329 return bytes; 00330 } 00331 00332 00333 public: 00334 00336 reference operator[](int _idx) 00337 { 00338 assert( size_t(_idx) < data_.size() ); 00339 return data_[_idx]; 00340 } 00341 00343 const_reference operator[](int _idx) const 00344 { 00345 assert( size_t(_idx) < data_.size()); 00346 return data_[_idx]; 00347 } 00348 00350 PropertyT<bool>* clone() const 00351 { 00352 PropertyT<bool>* p = new PropertyT<bool>( *this ); 00353 return p; 00354 } 00355 00356 00357 private: 00358 00359 vector_type data_; 00360 }; 00361 00362 00363 //----------------------------------------------------------------------------- 00364 00365 00368 template <> 00369 class PropertyT<std::string> : public BaseProperty 00370 { 00371 public: 00372 00373 typedef std::string Value; 00374 typedef std::vector<std::string> vector_type; 00375 typedef std::string value_type; 00376 typedef vector_type::reference reference; 00377 typedef vector_type::const_reference const_reference; 00378 00379 public: 00380 00381 PropertyT(const std::string& _name = "<unknown>") 00382 : BaseProperty(_name) 00383 { } 00384 00385 public: // inherited from BaseProperty 00386 00387 virtual void reserve(size_t _n) { data_.reserve(_n); } 00388 virtual void resize(size_t _n) { data_.resize(_n); } 00389 virtual void clear() { data_.clear(); vector_type().swap(data_); } 00390 virtual void push_back() { data_.push_back(std::string()); } 00391 virtual void swap(size_t _i0, size_t _i1) { 00392 std::swap(data_[_i0], data_[_i1]); 00393 } 00394 00395 public: 00396 00397 virtual void set_persistent( bool _yn ) 00398 { check_and_set_persistent<std::string>( _yn ); } 00399 00400 virtual size_t n_elements() const { return data_.size(); } 00401 virtual size_t element_size() const { return UnknownSize; } 00402 virtual size_t size_of() const 00403 { return IO::size_of( data_ ); } 00404 00405 virtual size_t size_of(size_t /* _n_elem */) const 00406 { return UnknownSize; } 00407 00409 size_t store( std::ostream& _ostr, bool _swap ) const 00410 { return IO::store( _ostr, data_, _swap ); } 00411 00412 size_t restore( std::istream& _istr, bool _swap ) 00413 { return IO::restore( _istr, data_, _swap ); } 00414 00415 public: 00416 00417 const value_type* data() const { 00418 if( data_.empty() ) 00419 return 0; 00420 00421 return (value_type*) &data_[0]; 00422 } 00423 00425 reference operator[](int _idx) { 00426 assert( size_t(_idx) < data_.size()); 00427 return ((value_type*) &data_[0])[_idx]; 00428 } 00429 00431 const_reference operator[](int _idx) const { 00432 assert( size_t(_idx) < data_.size()); 00433 return ((value_type*) &data_[0])[_idx]; 00434 } 00435 00436 PropertyT<value_type>* clone() const { 00437 PropertyT<value_type>* p = new PropertyT<value_type>( *this ); 00438 return p; 00439 } 00440 00441 00442 private: 00443 00444 vector_type data_; 00445 00446 }; 00447 00449 template <class T> 00450 struct BasePropHandleT : public BaseHandle 00451 { 00452 typedef T Value; 00453 typedef std::vector<T> vector_type; 00454 typedef T value_type; 00455 typedef typename vector_type::reference reference; 00456 typedef typename vector_type::const_reference const_reference; 00457 00458 explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {} 00459 }; 00460 00461 00465 template <class T> 00466 struct VPropHandleT : public BasePropHandleT<T> 00467 { 00468 typedef T Value; 00469 typedef T value_type; 00470 00471 explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00472 explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00473 }; 00474 00475 00479 template <class T> 00480 struct HPropHandleT : public BasePropHandleT<T> 00481 { 00482 typedef T Value; 00483 typedef T value_type; 00484 00485 explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00486 explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00487 }; 00488 00489 00493 template <class T> 00494 struct EPropHandleT : public BasePropHandleT<T> 00495 { 00496 typedef T Value; 00497 typedef T value_type; 00498 00499 explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00500 explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00501 }; 00502 00503 00507 template <class T> 00508 struct FPropHandleT : public BasePropHandleT<T> 00509 { 00510 typedef T Value; 00511 typedef T value_type; 00512 00513 explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00514 explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00515 }; 00516 00517 00521 template <class T> 00522 struct MPropHandleT : public BasePropHandleT<T> 00523 { 00524 typedef T Value; 00525 typedef T value_type; 00526 00527 explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00528 explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00529 }; 00530 00531 } // namespace OpenMesh 00532 //============================================================================= 00533 #endif // OPENMESH_PROPERTY_HH defined 00534 //=============================================================================