Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Property.hh

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2005 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   virtual ~BaseProperty() {}
00089 
00090 public: // synchronized array interface
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: // named property interface
00111 
00113   const std::string& name() const { return name_; }
00114 
00115   virtual void stats(std::ostream& _ostr) const;
00116 
00117 public: // I/O support
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   // To be used in a derived class, when overloading set_persistent()
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: // inherited from BaseProperty
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: // data access interface
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: // inherited from BaseProperty
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;  // element index
00353     size_t        bidx;
00354     unsigned char bits; // bitset
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;  // element index
00394     size_t        bidx; //
00395     unsigned char bits; // bitset
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: // inherited from BaseProperty
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 //== CLASS DEFINITION =========================================================
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   //-------------------------------------------------- constructor / destructor
00637 
00638   PropertyContainer() {}
00639   virtual ~PropertyContainer() { clear(); }
00640 
00641 
00642   //------------------------------------------------------------- info / access
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   //--------------------------------------------------------- copy / assignment
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   //--------------------------------------------------------- manage properties
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 && //skip deleted properties
00688           dynamic_cast<PropertyT<T>*>(properties_[idx]) != NULL)//check type
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) //skip deleted properties
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   //---------------------------------------------------- synchronize properties
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: // generic add/get
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   //-------------------------------------------------- synchronization functors
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 } // namespace OpenMesh
00859 //=============================================================================
00860 #endif // OPENMESH_PROPERTY_HH defined
00861 //=============================================================================

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