- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# Core/Utils/Property.hh

    00001 /*===========================================================================*\
    00002  *                                                                           *
    00003  *                               OpenMesh                                    *
    00004  *      Copyright (C) 2001-2003 by Computer Graphics Group, RWTH Aachen      *
    00005  *                           www.openmesh.org                                *
    00006  *                                                                           *
    00007  *---------------------------------------------------------------------------*
    00008  *                                                                           *
    00009  *                                License                                    *
    00010  *                                                                           *
    00011  *  This library is free software; you can redistribute it and/or modify it  *
    00012  *  under the terms of the GNU Library General Public License as published   *
    00013  *  by the Free Software Foundation, version 2.                              *
    00014  *                                                                           *
    00015  *  This library is distributed in the hope that it will be useful, but      *
    00016  *  WITHOUT ANY WARRANTY; without even the implied warranty of               *
    00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
    00018  *  Library General Public License for more details.                         *
    00019  *                                                                           *
    00020  *  You should have received a copy of the GNU Library General Public        *
    00021  *  License along with this library; if not, write to the Free Software      *
    00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                *
    00023  *                                                                           *
    00024 \*===========================================================================*/
    00025
    00026 #ifndef OPENMESH_PROPERTY_HH
    00027 #define OPENMESH_PROPERTY_HH
    00028
    00029
    00030 //== INCLUDES =================================================================
    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 //== FORWARDDECLARATIONS ======================================================
    00043
    00044 namespace OpenMesh {
    00045   class BaseKernel;
    00046 }
    00047
    00048
    00049 //== NAMESPACES ===============================================================
    00050
    00051 namespace OpenMesh {
    00052
    00053
    00054 //== CLASS DEFINITION =========================================================
    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: // synchronized array interface
    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: // named property interface
    00115
    00117   const std::string& name() const { return name_; }
    00118
    00119   virtual void stats(std::ostream& _ostr) const;
    00120
    00121 public: // I/O support
    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   // To be used in a derived class, when overloading set_persistent()
    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: // inherited from BaseProperty
    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: // data access interface
    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: // inherited from BaseProperty
    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;  // element index
    00364     size_t        bidx;
    00365     unsigned char bits; // bitset
    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;  // element index
    00405     size_t        bidx; //
    00406     unsigned char bits; // bitset
    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: // inherited from BaseProperty
    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 //== CLASS DEFINITION =========================================================
    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   //-------------------------------------------------- constructor / destructor
    00650
    00651   PropertyContainer() {}
    00652   virtual ~PropertyContainer() { clear(); }
    00653
    00654
    00655   //------------------------------------------------------------- info / access
    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   //--------------------------------------------------------- copy / assignment
    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   //--------------------------------------------------------- manage properties
    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 && //skip deleted properties
    00701           dynamic_cast<PropertyT<T>*>(properties_[idx]) != NULL)//check type
    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) //skip deleted properties
    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   //---------------------------------------------------- synchronize properties
    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: // generic add/get
    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   //-------------------------------------------------- synchronization functors
    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 } // namespace OpenMesh
    00872 //=============================================================================
    00873 #endif // OPENMESH_PROPERTY_HH defined
    00874 //=============================================================================