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 //=============================================================================

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .