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