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