OpenMesh
OpenMesh/Core/Utils/Property.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 362 $                                                         *
00038  *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 #ifndef OPENMESH_PROPERTY_HH
00043 #define OPENMESH_PROPERTY_HH
00044 
00045 
00046 //== INCLUDES =================================================================
00047 
00048 
00049 #include <OpenMesh/Core/System/config.h>
00050 #include <OpenMesh/Core/Mesh/Handles.hh>
00051 #include <OpenMesh/Core/Utils/BaseProperty.hh>
00052 #include <vector>
00053 #include <string>
00054 #include <algorithm>
00055 
00056 
00057 //== NAMESPACES ===============================================================
00058 
00059 namespace OpenMesh {
00060 
00061 //== CLASS DEFINITION =========================================================
00062 
00081 // TODO: it might be possible to define Property using kind of a runtime info
00082 // structure holding the size of T. Then reserve, swap, resize, etc can be written
00083 // in pure malloc() style w/o virtual overhead. Template member function proved per
00084 // element access to the properties, asserting dynamic_casts in debug
00085 
00086 template <class T>
00087 class PropertyT : public BaseProperty
00088 {
00089 public:
00090 
00091   typedef T                                       Value;
00092   typedef std::vector<T>                          vector_type;
00093   typedef T                                       value_type;
00094   typedef typename vector_type::reference         reference;
00095   typedef typename vector_type::const_reference   const_reference;
00096 
00097 public:
00098 
00100   PropertyT(const std::string& _name = "<unknown>")
00101   : BaseProperty(_name)
00102   {}
00103 
00105   PropertyT(const PropertyT & _rhs)
00106       : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
00107 
00108 public: // inherited from BaseProperty
00109 
00110   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00111   virtual void resize(size_t _n)  { data_.resize(_n);     }
00112   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00113   virtual void push_back()        { data_.push_back(T()); }
00114   virtual void swap(size_t _i0, size_t _i1)
00115   { std::swap(data_[_i0], data_[_i1]); }
00116 
00117 public:
00118 
00119   virtual void set_persistent( bool _yn )
00120   { check_and_set_persistent<T>( _yn ); }
00121 
00122   virtual size_t       n_elements()   const { return data_.size(); }
00123   virtual size_t       element_size() const { return IO::size_of<T>(); }
00124 
00125 #ifndef DOXY_IGNORE_THIS
00126   struct plus {
00127     size_t operator () ( size_t _b, const T& _v )
00128     { return _b + IO::size_of<T>(_v); }
00129   };
00130 #endif
00131 
00132   virtual size_t size_of(void) const
00133   {
00134     if (element_size() != IO::UnknownSize)
00135       return this->BaseProperty::size_of(n_elements());
00136     return std::accumulate(data_.begin(), data_.end(), 0, plus());
00137   }
00138 
00139   virtual size_t size_of(size_t _n_elem) const
00140   { return this->BaseProperty::size_of(_n_elem); }
00141 
00142   virtual size_t store( std::ostream& _ostr, bool _swap ) const
00143   {
00144     if ( IO::is_streamable<vector_type>() )
00145       return IO::store(_ostr, data_, _swap );
00146     size_t bytes = 0;
00147     for (size_t i=0; i<n_elements(); ++i)
00148       bytes += IO::store( _ostr, data_[i], _swap );
00149     return bytes;
00150   }
00151 
00152   virtual size_t restore( std::istream& _istr, bool _swap )
00153   {
00154     if ( IO::is_streamable<vector_type>() )
00155       return IO::restore(_istr, data_, _swap );
00156     size_t bytes = 0;
00157     for (size_t i=0; i<n_elements(); ++i)
00158       bytes += IO::restore( _istr, data_[i], _swap );
00159     return bytes;
00160   }
00161 
00162 public: // data access interface
00163 
00165   const T* data() const {
00166 
00167     if( data_.empty() )
00168       return 0;
00169 
00170     return &data_[0];
00171   }
00172 
00174   vector_type& data_vector() {
00175 
00176     return data_;
00177   }
00178 
00180   reference operator[](int _idx)
00181   {
00182     assert( size_t(_idx) < data_.size() );
00183     return data_[_idx];
00184   }
00185 
00187   const_reference operator[](int _idx) const
00188   {
00189     assert( size_t(_idx) < data_.size());
00190     return data_[_idx];
00191   }
00192 
00194   PropertyT<T>* clone() const
00195   {
00196     PropertyT<T>* p = new PropertyT<T>( *this );
00197     return p;
00198   }
00199 
00200 
00201 private:
00202 
00203   vector_type data_;
00204 };
00205 
00206 //-----------------------------------------------------------------------------
00207 
00208 
00214 template <>
00215 class PropertyT<bool> : public BaseProperty
00216 {
00217 public:
00218 
00219   typedef std::vector<bool>                       vector_type;
00220   typedef bool                                    value_type;
00221   typedef vector_type::reference                  reference;
00222   typedef vector_type::const_reference            const_reference;
00223 
00224 public:
00225 
00226   PropertyT(const std::string& _name = "<unknown>")
00227     : BaseProperty(_name)
00228   { }
00229 
00230 public: // inherited from BaseProperty
00231 
00232   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00233   virtual void resize(size_t _n)  { data_.resize(_n);     }
00234   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00235   virtual void push_back()        { data_.push_back(bool()); }
00236   virtual void swap(size_t _i0, size_t _i1)
00237   { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
00238 
00239 public:
00240 
00241   virtual void set_persistent( bool _yn )
00242   {
00243     check_and_set_persistent<bool>( _yn );
00244   }
00245 
00246   virtual size_t       n_elements()   const { return data_.size();  }
00247   virtual size_t       element_size() const { return UnknownSize;    }
00248   virtual size_t       size_of() const      { return size_of( n_elements() ); }
00249   virtual size_t       size_of(size_t _n_elem) const
00250   {
00251     return _n_elem / 8 + ((_n_elem % 8)!=0);
00252   }
00253 
00254   size_t store( std::ostream& _ostr, bool /* _swap */ ) const
00255   {
00256     size_t bytes = 0;
00257 
00258     size_t N = data_.size() / 8;
00259     size_t R = data_.size() % 8;
00260 
00261     size_t        idx;  // element index
00262     size_t        bidx;
00263     unsigned char bits; // bitset
00264 
00265     for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00266     {
00267       bits = !!data_[bidx]
00268         | (!!data_[bidx+1] << 1)
00269         | (!!data_[bidx+2] << 2)
00270         | (!!data_[bidx+3] << 3)
00271         | (!!data_[bidx+4] << 4)
00272         | (!!data_[bidx+5] << 5)
00273         | (!!data_[bidx+6] << 6)
00274         | (!!data_[bidx+7] << 7);
00275       _ostr << bits;
00276     }
00277     bytes = N;
00278 
00279     if (R)
00280     {
00281       bits = 0;
00282       for (idx=0; idx < R; ++idx)
00283         bits |= !!data_[bidx+idx] << idx;
00284       _ostr << bits;
00285       ++bytes;
00286     }
00287 
00288     std::cout << std::endl;
00289 
00290     assert( bytes == size_of() );
00291 
00292     return bytes;
00293   }
00294 
00295   size_t restore( std::istream& _istr, bool /* _swap */ )
00296   {
00297     size_t bytes = 0;
00298 
00299     size_t N = data_.size() / 8;
00300     size_t R = data_.size() % 8;
00301 
00302     size_t        idx;  // element index
00303     size_t        bidx; //
00304     unsigned char bits; // bitset
00305 
00306     for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00307     {
00308       _istr >> bits;
00309       data_[bidx+0] = !!(bits & 0x01);
00310       data_[bidx+1] = !!(bits & 0x02);
00311       data_[bidx+2] = !!(bits & 0x04);
00312       data_[bidx+3] = !!(bits & 0x08);
00313       data_[bidx+4] = !!(bits & 0x10);
00314       data_[bidx+5] = !!(bits & 0x20);
00315       data_[bidx+6] = !!(bits & 0x40);
00316       data_[bidx+7] = !!(bits & 0x80);
00317     }
00318     bytes = N;
00319 
00320     if (R)
00321     {
00322       _istr >> bits;
00323       for (idx=0; idx < R; ++idx)
00324         data_[bidx+idx] = !!(bits & (1<<idx));
00325       ++bytes;
00326     }
00327 
00328     std::cout << std::endl;
00329 
00330     return bytes;
00331   }
00332 
00333 
00334 public:
00335 
00337   reference operator[](int _idx)
00338   {
00339     assert( size_t(_idx) < data_.size() );
00340     return data_[_idx];
00341   }
00342 
00344   const_reference operator[](int _idx) const
00345   {
00346     assert( size_t(_idx) < data_.size());
00347     return data_[_idx];
00348   }
00349 
00351   PropertyT<bool>* clone() const
00352   {
00353     PropertyT<bool>* p = new PropertyT<bool>( *this );
00354     return p;
00355   }
00356 
00357 
00358 private:
00359 
00360   vector_type data_;
00361 };
00362 
00363 
00364 //-----------------------------------------------------------------------------
00365 
00366 
00371 template <>
00372 class PropertyT<std::string> : public BaseProperty
00373 {
00374 public:
00375 
00376   typedef std::string                             Value;
00377   typedef std::vector<std::string>                vector_type;
00378   typedef std::string                             value_type;
00379   typedef vector_type::reference                  reference;
00380   typedef vector_type::const_reference            const_reference;
00381 
00382 public:
00383 
00384   PropertyT(const std::string& _name = "<unknown>")
00385     : BaseProperty(_name)
00386   { }
00387 
00388 public: // inherited from BaseProperty
00389 
00390   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00391   virtual void resize(size_t _n)  { data_.resize(_n);     }
00392   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00393   virtual void push_back()        { data_.push_back(std::string()); }
00394   virtual void swap(size_t _i0, size_t _i1) {
00395     std::swap(data_[_i0], data_[_i1]);
00396   }
00397 
00398 public:
00399 
00400   virtual void set_persistent( bool _yn )
00401   { check_and_set_persistent<std::string>( _yn ); }
00402 
00403   virtual size_t       n_elements()   const { return data_.size();  }
00404   virtual size_t       element_size() const { return UnknownSize;    }
00405   virtual size_t       size_of() const
00406   { return IO::size_of( data_ ); }
00407 
00408   virtual size_t       size_of(size_t /* _n_elem */) const
00409   { return UnknownSize; }
00410 
00412   size_t store( std::ostream& _ostr, bool _swap ) const
00413   { return IO::store( _ostr, data_, _swap ); }
00414 
00415   size_t restore( std::istream& _istr, bool _swap )
00416   { return IO::restore( _istr, data_, _swap ); }
00417 
00418 public:
00419 
00420   const value_type* data() const {
00421       if( data_.empty() )
00422           return 0;
00423 
00424       return (value_type*) &data_[0];
00425   }
00426 
00428   reference operator[](int _idx) {
00429     assert( size_t(_idx) < data_.size());
00430     return ((value_type*) &data_[0])[_idx];
00431   }
00432 
00434   const_reference operator[](int _idx) const {
00435     assert( size_t(_idx) < data_.size());
00436     return ((value_type*) &data_[0])[_idx];
00437   }
00438 
00439   PropertyT<value_type>* clone() const {
00440     PropertyT<value_type>* p = new PropertyT<value_type>( *this );
00441     return p;
00442   }
00443 
00444 
00445 private:
00446 
00447   vector_type data_;
00448 
00449 };
00450 
00452 template <class T>
00453 struct BasePropHandleT : public BaseHandle
00454 {
00455   typedef T                                       Value;
00456   typedef std::vector<T>                          vector_type;
00457   typedef T                                       value_type;
00458   typedef typename vector_type::reference         reference;
00459   typedef typename vector_type::const_reference   const_reference;
00460 
00461   explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
00462 };
00463 
00464 
00468 template <class T>
00469 struct VPropHandleT : public BasePropHandleT<T>
00470 {
00471   typedef T                       Value;
00472   typedef T                       value_type;
00473 
00474   explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00475   explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00476 };
00477 
00478 
00482 template <class T>
00483 struct HPropHandleT : public BasePropHandleT<T>
00484 {
00485   typedef T                       Value;
00486   typedef T                       value_type;
00487 
00488   explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00489   explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00490 };
00491 
00492 
00496 template <class T>
00497 struct EPropHandleT : public BasePropHandleT<T>
00498 {
00499   typedef T                       Value;
00500   typedef T                       value_type;
00501 
00502   explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00503   explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00504 };
00505 
00506 
00510 template <class T>
00511 struct FPropHandleT : public BasePropHandleT<T>
00512 {
00513   typedef T                       Value;
00514   typedef T                       value_type;
00515 
00516   explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00517   explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00518 };
00519 
00520 
00524 template <class T>
00525 struct MPropHandleT : public BasePropHandleT<T>
00526 {
00527   typedef T                       Value;
00528   typedef T                       value_type;
00529 
00530   explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00531   explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00532 };
00533 
00534 } // namespace OpenMesh
00535 //=============================================================================
00536 #endif // OPENMESH_PROPERTY_HH defined
00537 //=============================================================================