00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef OPENMESH_PROPERTY_HH
00027 #define OPENMESH_PROPERTY_HH
00028
00029
00030
00031
00032
00033 #include <OpenMesh/Core/System/config.hh>
00034 #include <OpenMesh/Core/System/omstream.hh>
00035 #include <OpenMesh/Core/Mesh/Kernels/Common/Handles.hh>
00036 #include <OpenMesh/Core/IO/StoreRestore.hh>
00037 #include <vector>
00038 #include <string>
00039 #include <algorithm>
00040
00041
00042
00043
00044 namespace OpenMesh {
00045 class BaseKernel;
00046 }
00047
00048
00049
00050
00051 namespace OpenMesh {
00052
00053
00054
00055
00061 class BaseProperty
00062 {
00063 public:
00064
00066 static const size_t UnknownSize = size_t(-1);
00067
00068 public:
00069
00084 BaseProperty(const std::string& _name = "<unknown>")
00085 : name_(_name), persistent_(false) {}
00086
00088 BaseProperty(const BaseProperty & _rhs)
00089 : name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {}
00090
00092 virtual ~BaseProperty() {}
00093
00094 public:
00095
00097 virtual void reserve(size_t _n) = 0;
00098
00100 virtual void resize(size_t _n) = 0;
00101
00103 virtual void free_mem() = 0;
00104
00106 virtual void push_back() = 0;
00107
00109 virtual void swap(size_t _i0, size_t _i1) = 0;
00110
00112 virtual BaseProperty* clone () const = 0;
00113
00114 public:
00115
00117 const std::string& name() const { return name_; }
00118
00119 virtual void stats(std::ostream& _ostr) const;
00120
00121 public:
00122
00124 bool persistent(void) const { return persistent_; }
00125
00128 virtual void set_persistent( bool _yn ) = 0;
00129
00131 virtual size_t n_elements() const = 0;
00132
00134 virtual size_t element_size() const = 0;
00135
00137 virtual size_t size_of() const
00138 {
00139 return size_of( n_elements() );
00140 }
00141
00144 virtual size_t size_of(size_t _n_elem) const
00145 {
00146 return (element_size()!=UnknownSize)
00147 ? (_n_elem*element_size())
00148 : UnknownSize;
00149 }
00150
00152 virtual size_t store( std::ostream& _ostr, bool _swap ) const = 0;
00153
00157 virtual size_t restore( std::istream& _istr, bool _swap ) = 0;
00158
00159 protected:
00160
00161
00162 template < typename T >
00163 void check_and_set_persistent( bool _yn )
00164 {
00165 if ( _yn && !IO::is_streamable<T>() )
00166 omerr() << "Warning! Type of property value is not binary storable!\n";
00167 persistent_ = IO::is_streamable<T>() && _yn;
00168 }
00169
00170 private:
00171
00172 std::string name_;
00173 bool persistent_;
00174 };
00175
00176
00177
00178
00196 template <class T>
00197 class PropertyT : public BaseProperty
00198 {
00199 public:
00200
00201 typedef T Value;
00202 typedef std::vector<T> vector_type;
00203 typedef T value_type;
00204 typedef typename vector_type::reference reference;
00205 typedef typename vector_type::const_reference const_reference;
00206
00207 public:
00208
00210 PropertyT(const std::string& _name = "<unknown>")
00211 : BaseProperty(_name)
00212 {}
00213
00215 PropertyT(const PropertyT & _rhs)
00216 : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
00217
00218
00219 public:
00220
00221 virtual void reserve(size_t _n) { data_.reserve(_n); }
00222 virtual void resize(size_t _n) { data_.resize(_n); }
00223 virtual void push_back() { data_.push_back(T()); }
00224 virtual void free_mem() { vector_type(data_).swap(data_); }
00225 virtual void swap(size_t _i0, size_t _i1)
00226 { std::swap(data_[_i0], data_[_i1]); }
00227
00228 public:
00229
00230 virtual void set_persistent( bool _yn )
00231 { check_and_set_persistent<T>( _yn ); }
00232
00233 virtual size_t n_elements() const { return data_.size(); }
00234 virtual size_t element_size() const { return IO::size_of<T>(); }
00235
00236 #ifndef DOXY_IGNORE_THIS
00237 struct plus {
00238 size_t operator () ( size_t _b, const T& _v )
00239 { return _b + IO::size_of<T>(_v); }
00240 };
00241 #endif
00242
00243 virtual size_t size_of(void) const
00244 {
00245 if (element_size() != IO::UnknownSize)
00246 return this->BaseProperty::size_of(n_elements());
00247 return std::accumulate(data_.begin(), data_.end(), 0, plus());
00248 }
00249
00250 virtual size_t size_of(size_t _n_elem) const
00251 { return this->BaseProperty::size_of(_n_elem); }
00252
00253 virtual size_t store( std::ostream& _ostr, bool _swap ) const
00254 {
00255 if ( IO::is_streamable<vector_type>() )
00256 return IO::store(_ostr, data_, _swap );
00257 size_t bytes = 0;
00258 for (size_t i=0; i<n_elements(); ++i)
00259 bytes += IO::store( _ostr, data_[i], _swap );
00260 return bytes;
00261 }
00262
00263 virtual size_t restore( std::istream& _istr, bool _swap )
00264 {
00265 if ( IO::is_streamable<vector_type>() )
00266 return IO::restore(_istr, data_, _swap );
00267 size_t bytes = 0;
00268 for (size_t i=0; i<n_elements(); ++i)
00269 bytes += IO::restore( _istr, data_[i], _swap );
00270 return bytes;
00271 }
00272
00273 public:
00274
00276 const T* data() const { return &data_[0]; }
00277
00279 reference operator[](int _idx)
00280 {
00281 assert( size_t(_idx) < data_.size() );
00282 return data_[_idx];
00283 }
00284
00286 const_reference operator[](int _idx) const
00287 {
00288 assert( size_t(_idx) < data_.size());
00289 return data_[_idx];
00290 }
00291
00293 PropertyT<T>* clone() const
00294 {
00295 PropertyT<T>* p = new PropertyT<T>( *this );
00296 return p;
00297 }
00298
00299
00300 private:
00301
00302 vector_type data_;
00303 };
00304
00305
00306
00307
00313 template <>
00314 class PropertyT<bool> : public BaseProperty
00315 {
00316 public:
00317
00318 typedef std::vector<bool> vector_type;
00319 typedef bool value_type;
00320 typedef vector_type::reference reference;
00321 typedef vector_type::const_reference const_reference;
00322
00323 public:
00324
00325 PropertyT(const std::string& _name = "<unknown>")
00326 : BaseProperty(_name)
00327 { }
00328
00329 PropertyT(const PropertyT & _rhs)
00330 : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
00331
00332 public:
00333
00334 virtual void reserve(size_t _n) { data_.reserve(_n); }
00335 virtual void resize(size_t _n) { data_.resize(_n); }
00336 virtual void push_back() { data_.push_back(bool()); }
00337 virtual void free_mem() { vector_type(data_).swap(data_); }
00338 virtual void swap(size_t _i0, size_t _i1)
00339 { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
00340
00341 public:
00342
00343 virtual void set_persistent( bool _yn )
00344 {
00345 check_and_set_persistent<bool>( _yn );
00346 }
00347
00348 virtual size_t n_elements() const { return data_.size(); }
00349 virtual size_t element_size() const { return UnknownSize; }
00350 virtual size_t size_of() const { return size_of( n_elements() ); }
00351 virtual size_t size_of(size_t _n_elem) const
00352 {
00353 return _n_elem / 8 + ((_n_elem % 8)!=0);
00354 }
00355
00356 size_t store( std::ostream& _ostr, bool _swap ) const
00357 {
00358 size_t bytes = 0;
00359
00360 size_t N = data_.size() / 8;
00361 size_t R = data_.size() % 8;
00362
00363 size_t idx;
00364 size_t bidx;
00365 unsigned char bits;
00366
00367 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00368 {
00369 bits = !!data_[bidx]
00370 | (!!data_[bidx+1] << 1)
00371 | (!!data_[bidx+2] << 2)
00372 | (!!data_[bidx+3] << 3)
00373 | (!!data_[bidx+4] << 4)
00374 | (!!data_[bidx+5] << 5)
00375 | (!!data_[bidx+6] << 6)
00376 | (!!data_[bidx+7] << 7);
00377 _ostr << bits;
00378 }
00379 bytes = N;
00380
00381 if (R)
00382 {
00383 bits = 0;
00384 for (idx=0; idx < R; ++idx)
00385 bits |= !!data_[bidx+idx] << idx;
00386 _ostr << bits;
00387 ++bytes;
00388 }
00389
00390 std::cout << std::endl;
00391
00392 assert( bytes == size_of() );
00393
00394 return bytes;
00395 }
00396
00397 size_t restore( std::istream& _istr, bool _swap )
00398 {
00399 size_t bytes = 0;
00400
00401 size_t N = data_.size() / 8;
00402 size_t R = data_.size() % 8;
00403
00404 size_t idx;
00405 size_t bidx;
00406 unsigned char bits;
00407
00408 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00409 {
00410 _istr >> bits;
00411 data_[bidx+0] = !!(bits & 0x01);
00412 data_[bidx+1] = !!(bits & 0x02);
00413 data_[bidx+2] = !!(bits & 0x04);
00414 data_[bidx+3] = !!(bits & 0x08);
00415 data_[bidx+4] = !!(bits & 0x10);
00416 data_[bidx+5] = !!(bits & 0x20);
00417 data_[bidx+6] = !!(bits & 0x40);
00418 data_[bidx+7] = !!(bits & 0x80);
00419 }
00420 bytes = N;
00421
00422 if (R)
00423 {
00424 _istr >> bits;
00425 for (idx=0; idx < R; ++idx)
00426 data_[bidx+idx] = !!(bits & (1<<idx));
00427 ++bytes;
00428 }
00429
00430 std::cout << std::endl;
00431
00432 return bytes;
00433 }
00434
00435
00436 public:
00437
00439 reference operator[](int _idx)
00440 {
00441 assert( size_t(_idx) < data_.size() );
00442 return data_[_idx];
00443 }
00444
00446 const_reference operator[](int _idx) const
00447 {
00448 assert( size_t(_idx) < data_.size());
00449 return data_[_idx];
00450 }
00451
00453 PropertyT<bool>* clone() const
00454 {
00455 PropertyT<bool>* p = new PropertyT<bool>( *this );
00456 return p;
00457 }
00458
00459
00460 private:
00461
00462 vector_type data_;
00463 };
00464
00465
00466
00467
00468
00473 template <>
00474 class PropertyT<std::string> : public BaseProperty
00475 {
00476 public:
00477
00478 typedef std::string Value;
00479 typedef std::vector<std::string> vector_type;
00480 typedef std::string value_type;
00481 typedef vector_type::reference reference;
00482 typedef vector_type::const_reference const_reference;
00483
00484 public:
00485
00486 PropertyT(const std::string& _name = "<unknown>")
00487 : BaseProperty(_name)
00488 { }
00489
00490 PropertyT(const PropertyT & _rhs)
00491 : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
00492
00493
00494 public:
00495
00496 virtual void reserve(size_t _n) { data_.reserve(_n); }
00497 virtual void resize(size_t _n) { data_.resize(_n); }
00498 virtual void push_back() { data_.push_back(std::string()); }
00499 virtual void free_mem() { vector_type(data_).swap(data_); }
00500 virtual void swap(size_t _i0, size_t _i1) {
00501 std::swap(data_[_i0], data_[_i1]);
00502 }
00503
00504 public:
00505
00506 virtual void set_persistent( bool _yn )
00507 { check_and_set_persistent<std::string>( _yn ); }
00508
00509 virtual size_t n_elements() const { return data_.size(); }
00510 virtual size_t element_size() const { return UnknownSize; }
00511 virtual size_t size_of() const
00512 { return IO::size_of( data_ ); }
00513
00514 virtual size_t size_of(size_t _n_elem) const
00515 { return UnknownSize; }
00516
00518 size_t store( std::ostream& _ostr, bool _swap ) const
00519 { return IO::store( _ostr, data_, _swap ); }
00520
00521 size_t restore( std::istream& _istr, bool _swap )
00522 { return IO::restore( _istr, data_, _swap ); }
00523
00524 public:
00525
00526 const value_type* data() const { return (value_type*) &data_[0]; }
00527
00529 reference operator[](int _idx) {
00530 assert( size_t(_idx) < data_.size());
00531 return ((value_type*) &data_[0])[_idx];
00532 }
00533
00535 const_reference operator[](int _idx) const {
00536 assert( size_t(_idx) < data_.size());
00537 return ((value_type*) &data_[0])[_idx];
00538 }
00539
00540 PropertyT<value_type>* clone() const {
00541 PropertyT<value_type>* p = new PropertyT<value_type>( *this );
00542 return p;
00543 }
00544
00545
00546 private:
00547
00548 vector_type data_;
00549
00550 };
00551
00552
00553
00554
00555
00557 template <class T>
00558 struct BasePropHandleT : public BaseHandle
00559 {
00560 typedef T Value;
00561 typedef std::vector<T> vector_type;
00562 typedef T value_type;
00563 typedef typename vector_type::reference reference;
00564 typedef typename vector_type::const_reference const_reference;
00565
00566 explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
00567 };
00568
00569
00573 template <class T>
00574 struct VPropHandleT : public BasePropHandleT<T>
00575 {
00576 typedef T Value;
00577 typedef T value_type;
00578
00579 explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00580 explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00581 };
00582
00583
00587 template <class T>
00588 struct HPropHandleT : public BasePropHandleT<T>
00589 {
00590 typedef T Value;
00591 typedef T value_type;
00592
00593 explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00594 explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00595 };
00596
00597
00601 template <class T>
00602 struct EPropHandleT : public BasePropHandleT<T>
00603 {
00604 typedef T Value;
00605 typedef T value_type;
00606
00607 explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00608 explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00609 };
00610
00611
00615 template <class T>
00616 struct FPropHandleT : public BasePropHandleT<T>
00617 {
00618 typedef T Value;
00619 typedef T value_type;
00620
00621 explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00622 explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00623 };
00624
00625
00629 template <class T>
00630 struct MPropHandleT : public BasePropHandleT<T>
00631 {
00632 typedef T Value;
00633 typedef T value_type;
00634
00635 explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00636 explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00637 };
00638
00639
00640
00641
00642
00643
00645 class PropertyContainer
00646 {
00647 public:
00648
00649
00650
00651 PropertyContainer() {}
00652 virtual ~PropertyContainer() { clear(); }
00653
00654
00655
00656
00657 typedef std::vector<BaseProperty*> Properties;
00658 const Properties& properties() const { return properties_; }
00659 size_t size() const { return properties_.size(); }
00660
00661
00662
00663
00664
00665 PropertyContainer(const PropertyContainer& _rhs) { operator=(_rhs); }
00666
00667 PropertyContainer& operator=(const PropertyContainer& _rhs)
00668 {
00669 clear();
00670 properties_ = _rhs.properties_;
00671 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00672 for (; p_it!=p_end; ++p_it)
00673 if (*p_it)
00674 *p_it = (*p_it)->clone();
00675 return *this;
00676 }
00677
00678
00679
00680
00681
00682 template <class T>
00683 BasePropHandleT<T> add(const T&, const std::string& _name="<unknown>")
00684 {
00685 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00686 int idx=0;
00687 for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx);
00688 if (p_it==p_end) properties_.push_back(NULL);
00689 properties_[idx] = new PropertyT<T>(_name);
00690 return BasePropHandleT<T>(idx);
00691 }
00692
00693
00694 template <class T>
00695 BasePropHandleT<T> handle(const T&, const std::string& _name) const
00696 {
00697 Properties::const_iterator p_it = properties_.begin();
00698 for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
00699 {
00700 if (*p_it != NULL && (*p_it)->name() == _name &&
00701 dynamic_cast<PropertyT<T>*>(properties_[idx]) != NULL)
00702 {
00703 return BasePropHandleT<T>(idx);
00704 }
00705 }
00706 return BasePropHandleT<T>();
00707 }
00708
00709 BaseProperty* property( const std::string& _name ) const
00710 {
00711 Properties::const_iterator p_it = properties_.begin();
00712 for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
00713 {
00714 if (*p_it != NULL && (*p_it)->name() == _name)
00715 {
00716 return *p_it;
00717 }
00718 }
00719 return NULL;
00720 }
00721
00722 template <class T> PropertyT<T>& property(BasePropHandleT<T> _h)
00723 {
00724 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00725 assert(properties_[_h.idx()] != NULL);
00726 #ifdef NDEBUG
00727 return *static_cast <PropertyT<T>*> (properties_[_h.idx()]);
00728 #else
00729 PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
00730 assert(p != NULL);
00731 return *p;
00732 #endif
00733 }
00734
00735
00736 template <class T> const PropertyT<T>& property(BasePropHandleT<T> _h) const
00737 {
00738 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00739 assert(properties_[_h.idx()] != NULL);
00740 #ifdef NDEBUG
00741 return *static_cast<PropertyT<T>*>(properties_[_h.idx()]);
00742 #else
00743 PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
00744 assert(p != NULL);
00745 return *p;
00746 #endif
00747 }
00748
00749
00750 template <class T> void remove(BasePropHandleT<T> _h)
00751 {
00752 assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
00753 delete properties_[_h.idx()];
00754 properties_[_h.idx()] = NULL;
00755 }
00756
00757
00758 void clear()
00759 {
00760 std::for_each(properties_.begin(), properties_.end(), Delete());
00761 }
00762
00763
00764
00765
00766 void reserve(size_t _n) const {
00767 std::for_each(properties_.begin(), properties_.end(), Reserve(_n));
00768 }
00769
00770 void resize(size_t _n) const {
00771 std::for_each(properties_.begin(), properties_.end(), Resize(_n));
00772 }
00773
00774 void free_mem() const {
00775 std::for_each(properties_.begin(), properties_.end(), FreeMem());
00776 }
00777
00778 void swap(size_t _i0, size_t _i1) const {
00779 std::for_each(properties_.begin(), properties_.end(), Swap(_i0, _i1));
00780 }
00781
00782
00783
00784 protected:
00785
00786 size_t _add( BaseProperty* _bp )
00787 {
00788 Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
00789 size_t idx=0;
00790 for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx);
00791 if (p_it==p_end) properties_.push_back(NULL);
00792 properties_[idx] = _bp;
00793 return idx;
00794 }
00795
00796 BaseProperty& _property( size_t _idx )
00797 {
00798 assert( _idx < properties_.size());
00799 assert( properties_[_idx] != NULL);
00800 BaseProperty *p = properties_[_idx];
00801 assert( p != NULL );
00802 return *p;
00803 }
00804
00805 const BaseProperty& _property( size_t _idx ) const
00806 {
00807 assert( _idx < properties_.size());
00808 assert( properties_[_idx] != NULL);
00809 BaseProperty *p = properties_[_idx];
00810 assert( p != NULL );
00811 return *p;
00812 }
00813
00814
00815 typedef Properties::iterator iterator;
00816 typedef Properties::const_iterator const_iterator;
00817 iterator begin() { return properties_.begin(); }
00818 iterator end() { return properties_.end(); }
00819 const_iterator begin() const { return properties_.begin(); }
00820 const_iterator end() const { return properties_.end(); }
00821
00822 friend class BaseKernel;
00823
00824 private:
00825
00826
00827
00828 #ifndef DOXY_IGNORE_THIS
00829
00830 struct Reserve
00831 {
00832 Reserve(size_t _n) : n_(_n) {}
00833 void operator()(BaseProperty* _p) const { if (_p) _p->reserve(n_); }
00834 size_t n_;
00835 };
00836
00837 struct Resize
00838 {
00839 Resize(size_t _n) : n_(_n) {}
00840 void operator()(BaseProperty* _p) const { if (_p) _p->resize(n_); }
00841 size_t n_;
00842 };
00843
00844 struct FreeMem
00845 {
00846 FreeMem() {}
00847 void operator()(BaseProperty* _p) const { if (_p) _p->free_mem(); }
00848 };
00849
00850 struct Swap
00851 {
00852 Swap(size_t _i0, size_t _i1) : i0_(_i0), i1_(_i1) {}
00853 void operator()(BaseProperty* _p) const { if (_p) _p->swap(i0_, i1_); }
00854 size_t i0_, i1_;
00855 };
00856
00857 struct Delete
00858 {
00859 Delete() {}
00860 void operator()(BaseProperty* _p) const { if (_p) delete _p; _p=NULL; }
00861 };
00862
00863 #endif
00864
00865 Properties properties_;
00866 };
00867
00868
00869
00870
00871 }
00872
00873 #endif // OPENMESH_PROPERTY_HH defined
00874