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

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.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 //== 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(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: // named property interface
00108 
00110   const std::string& name() const { return name_; }
00111 
00112 public: // I/O support
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   // To be used in a derived class, when overloading set_persistent()
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: // inherited from BaseProperty
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: // data access interface
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: // inherited from BaseProperty
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;  // element index
00339     size_t        bidx;
00340     unsigned char bits; // bitset
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;  // element index
00380     size_t        bidx; //
00381     unsigned char bits; // bitset
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: // inherited from BaseProperty
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 //== CLASS DEFINITION =========================================================
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   //-------------------------------------------------- constructor / destructor
00597 
00598   PropertyContainer() {}
00599   virtual ~PropertyContainer() { clear(); }
00600 
00601 
00602   //------------------------------------------------------------- info / access
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   //--------------------------------------------------------- copy / assignment
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   //--------------------------------------------------------- manage properties
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   //---------------------------------------------------- synchronize properties
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: // generic add/get
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   //-------------------------------------------------- synchronization functors
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 } // namespace OpenMesh
00801 //=============================================================================
00802 #endif // OPENMESH_PROPERTY_HH defined
00803 //=============================================================================

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