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 #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 00214 template <> 00215 class PropertyT<bool> : public BaseProperty 00216 { 00217 public: 00218 00219 typedef std::vector<bool> vector_type; 00220 typedef bool value_type; 00221 typedef vector_type::reference reference; 00222 typedef vector_type::const_reference const_reference; 00223 00224 public: 00225 00226 PropertyT(const std::string& _name = "<unknown>") 00227 : BaseProperty(_name) 00228 { } 00229 00230 public: // inherited from BaseProperty 00231 00232 virtual void reserve(size_t _n) { data_.reserve(_n); } 00233 virtual void resize(size_t _n) { data_.resize(_n); } 00234 virtual void clear() { data_.clear(); vector_type().swap(data_); } 00235 virtual void push_back() { data_.push_back(bool()); } 00236 virtual void swap(size_t _i0, size_t _i1) 00237 { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; } 00238 00239 public: 00240 00241 virtual void set_persistent( bool _yn ) 00242 { 00243 check_and_set_persistent<bool>( _yn ); 00244 } 00245 00246 virtual size_t n_elements() const { return data_.size(); } 00247 virtual size_t element_size() const { return UnknownSize; } 00248 virtual size_t size_of() const { return size_of( n_elements() ); } 00249 virtual size_t size_of(size_t _n_elem) const 00250 { 00251 return _n_elem / 8 + ((_n_elem % 8)!=0); 00252 } 00253 00254 size_t store( std::ostream& _ostr, bool /* _swap */ ) const 00255 { 00256 size_t bytes = 0; 00257 00258 size_t N = data_.size() / 8; 00259 size_t R = data_.size() % 8; 00260 00261 size_t idx; // element index 00262 size_t bidx; 00263 unsigned char bits; // bitset 00264 00265 for (bidx=idx=0; idx < N; ++idx, bidx+=8) 00266 { 00267 bits = !!data_[bidx] 00268 | (!!data_[bidx+1] << 1) 00269 | (!!data_[bidx+2] << 2) 00270 | (!!data_[bidx+3] << 3) 00271 | (!!data_[bidx+4] << 4) 00272 | (!!data_[bidx+5] << 5) 00273 | (!!data_[bidx+6] << 6) 00274 | (!!data_[bidx+7] << 7); 00275 _ostr << bits; 00276 } 00277 bytes = N; 00278 00279 if (R) 00280 { 00281 bits = 0; 00282 for (idx=0; idx < R; ++idx) 00283 bits |= !!data_[bidx+idx] << idx; 00284 _ostr << bits; 00285 ++bytes; 00286 } 00287 00288 std::cout << std::endl; 00289 00290 assert( bytes == size_of() ); 00291 00292 return bytes; 00293 } 00294 00295 size_t restore( std::istream& _istr, bool /* _swap */ ) 00296 { 00297 size_t bytes = 0; 00298 00299 size_t N = data_.size() / 8; 00300 size_t R = data_.size() % 8; 00301 00302 size_t idx; // element index 00303 size_t bidx; // 00304 unsigned char bits; // bitset 00305 00306 for (bidx=idx=0; idx < N; ++idx, bidx+=8) 00307 { 00308 _istr >> bits; 00309 data_[bidx+0] = !!(bits & 0x01); 00310 data_[bidx+1] = !!(bits & 0x02); 00311 data_[bidx+2] = !!(bits & 0x04); 00312 data_[bidx+3] = !!(bits & 0x08); 00313 data_[bidx+4] = !!(bits & 0x10); 00314 data_[bidx+5] = !!(bits & 0x20); 00315 data_[bidx+6] = !!(bits & 0x40); 00316 data_[bidx+7] = !!(bits & 0x80); 00317 } 00318 bytes = N; 00319 00320 if (R) 00321 { 00322 _istr >> bits; 00323 for (idx=0; idx < R; ++idx) 00324 data_[bidx+idx] = !!(bits & (1<<idx)); 00325 ++bytes; 00326 } 00327 00328 std::cout << std::endl; 00329 00330 return bytes; 00331 } 00332 00333 00334 public: 00335 00337 reference operator[](int _idx) 00338 { 00339 assert( size_t(_idx) < data_.size() ); 00340 return data_[_idx]; 00341 } 00342 00344 const_reference operator[](int _idx) const 00345 { 00346 assert( size_t(_idx) < data_.size()); 00347 return data_[_idx]; 00348 } 00349 00351 PropertyT<bool>* clone() const 00352 { 00353 PropertyT<bool>* p = new PropertyT<bool>( *this ); 00354 return p; 00355 } 00356 00357 00358 private: 00359 00360 vector_type data_; 00361 }; 00362 00363 00364 //----------------------------------------------------------------------------- 00365 00366 00371 template <> 00372 class PropertyT<std::string> : public BaseProperty 00373 { 00374 public: 00375 00376 typedef std::string Value; 00377 typedef std::vector<std::string> vector_type; 00378 typedef std::string value_type; 00379 typedef vector_type::reference reference; 00380 typedef vector_type::const_reference const_reference; 00381 00382 public: 00383 00384 PropertyT(const std::string& _name = "<unknown>") 00385 : BaseProperty(_name) 00386 { } 00387 00388 public: // inherited from BaseProperty 00389 00390 virtual void reserve(size_t _n) { data_.reserve(_n); } 00391 virtual void resize(size_t _n) { data_.resize(_n); } 00392 virtual void clear() { data_.clear(); vector_type().swap(data_); } 00393 virtual void push_back() { data_.push_back(std::string()); } 00394 virtual void swap(size_t _i0, size_t _i1) { 00395 std::swap(data_[_i0], data_[_i1]); 00396 } 00397 00398 public: 00399 00400 virtual void set_persistent( bool _yn ) 00401 { check_and_set_persistent<std::string>( _yn ); } 00402 00403 virtual size_t n_elements() const { return data_.size(); } 00404 virtual size_t element_size() const { return UnknownSize; } 00405 virtual size_t size_of() const 00406 { return IO::size_of( data_ ); } 00407 00408 virtual size_t size_of(size_t /* _n_elem */) const 00409 { return UnknownSize; } 00410 00412 size_t store( std::ostream& _ostr, bool _swap ) const 00413 { return IO::store( _ostr, data_, _swap ); } 00414 00415 size_t restore( std::istream& _istr, bool _swap ) 00416 { return IO::restore( _istr, data_, _swap ); } 00417 00418 public: 00419 00420 const value_type* data() const { 00421 if( data_.empty() ) 00422 return 0; 00423 00424 return (value_type*) &data_[0]; 00425 } 00426 00428 reference operator[](int _idx) { 00429 assert( size_t(_idx) < data_.size()); 00430 return ((value_type*) &data_[0])[_idx]; 00431 } 00432 00434 const_reference operator[](int _idx) const { 00435 assert( size_t(_idx) < data_.size()); 00436 return ((value_type*) &data_[0])[_idx]; 00437 } 00438 00439 PropertyT<value_type>* clone() const { 00440 PropertyT<value_type>* p = new PropertyT<value_type>( *this ); 00441 return p; 00442 } 00443 00444 00445 private: 00446 00447 vector_type data_; 00448 00449 }; 00450 00452 template <class T> 00453 struct BasePropHandleT : public BaseHandle 00454 { 00455 typedef T Value; 00456 typedef std::vector<T> vector_type; 00457 typedef T value_type; 00458 typedef typename vector_type::reference reference; 00459 typedef typename vector_type::const_reference const_reference; 00460 00461 explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {} 00462 }; 00463 00464 00468 template <class T> 00469 struct VPropHandleT : public BasePropHandleT<T> 00470 { 00471 typedef T Value; 00472 typedef T value_type; 00473 00474 explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00475 explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00476 }; 00477 00478 00482 template <class T> 00483 struct HPropHandleT : public BasePropHandleT<T> 00484 { 00485 typedef T Value; 00486 typedef T value_type; 00487 00488 explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00489 explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00490 }; 00491 00492 00496 template <class T> 00497 struct EPropHandleT : public BasePropHandleT<T> 00498 { 00499 typedef T Value; 00500 typedef T value_type; 00501 00502 explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00503 explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00504 }; 00505 00506 00510 template <class T> 00511 struct FPropHandleT : public BasePropHandleT<T> 00512 { 00513 typedef T Value; 00514 typedef T value_type; 00515 00516 explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00517 explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00518 }; 00519 00520 00524 template <class T> 00525 struct MPropHandleT : public BasePropHandleT<T> 00526 { 00527 typedef T Value; 00528 typedef T value_type; 00529 00530 explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {} 00531 explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {} 00532 }; 00533 00534 } // namespace OpenMesh 00535 //============================================================================= 00536 #endif // OPENMESH_PROPERTY_HH defined 00537 //=============================================================================