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: 537 $                                                         *
00038  *   $Date: 2012-02-24 11:11:01 +0100 (Fr, 24 Feb 2012) $                   *
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 
00213 template <>
00214 class PropertyT<bool> : public BaseProperty
00215 {
00216 public:
00217 
00218   typedef std::vector<bool>                       vector_type;
00219   typedef bool                                    value_type;
00220   typedef vector_type::reference                  reference;
00221   typedef vector_type::const_reference            const_reference;
00222 
00223 public:
00224 
00225   PropertyT(const std::string& _name = "<unknown>")
00226     : BaseProperty(_name)
00227   { }
00228 
00229 public: // inherited from BaseProperty
00230 
00231   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00232   virtual void resize(size_t _n)  { data_.resize(_n);     }
00233   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00234   virtual void push_back()        { data_.push_back(bool()); }
00235   virtual void swap(size_t _i0, size_t _i1)
00236   { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
00237 
00238 public:
00239 
00240   virtual void set_persistent( bool _yn )
00241   {
00242     check_and_set_persistent<bool>( _yn );
00243   }
00244 
00245   virtual size_t       n_elements()   const { return data_.size();  }
00246   virtual size_t       element_size() const { return UnknownSize;    }
00247   virtual size_t       size_of() const      { return size_of( n_elements() ); }
00248   virtual size_t       size_of(size_t _n_elem) const
00249   {
00250     return _n_elem / 8 + ((_n_elem % 8)!=0);
00251   }
00252 
00253   size_t store( std::ostream& _ostr, bool /* _swap */ ) const
00254   {
00255     size_t bytes = 0;
00256 
00257     size_t N = data_.size() / 8;
00258     size_t R = data_.size() % 8;
00259 
00260     size_t        idx;  // element index
00261     size_t        bidx;
00262     unsigned char bits; // bitset
00263 
00264     for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00265     {
00266       bits = !!data_[bidx]
00267         | (!!data_[bidx+1] << 1)
00268         | (!!data_[bidx+2] << 2)
00269         | (!!data_[bidx+3] << 3)
00270         | (!!data_[bidx+4] << 4)
00271         | (!!data_[bidx+5] << 5)
00272         | (!!data_[bidx+6] << 6)
00273         | (!!data_[bidx+7] << 7);
00274       _ostr << bits;
00275     }
00276     bytes = N;
00277 
00278     if (R)
00279     {
00280       bits = 0;
00281       for (idx=0; idx < R; ++idx)
00282         bits |= !!data_[bidx+idx] << idx;
00283       _ostr << bits;
00284       ++bytes;
00285     }
00286 
00287     std::cout << std::endl;
00288 
00289     assert( bytes == size_of() );
00290 
00291     return bytes;
00292   }
00293 
00294   size_t restore( std::istream& _istr, bool /* _swap */ )
00295   {
00296     size_t bytes = 0;
00297 
00298     size_t N = data_.size() / 8;
00299     size_t R = data_.size() % 8;
00300 
00301     size_t        idx;  // element index
00302     size_t        bidx; //
00303     unsigned char bits; // bitset
00304 
00305     for (bidx=idx=0; idx < N; ++idx, bidx+=8)
00306     {
00307       _istr >> bits;
00308       data_[bidx+0] = !!(bits & 0x01);
00309       data_[bidx+1] = !!(bits & 0x02);
00310       data_[bidx+2] = !!(bits & 0x04);
00311       data_[bidx+3] = !!(bits & 0x08);
00312       data_[bidx+4] = !!(bits & 0x10);
00313       data_[bidx+5] = !!(bits & 0x20);
00314       data_[bidx+6] = !!(bits & 0x40);
00315       data_[bidx+7] = !!(bits & 0x80);
00316     }
00317     bytes = N;
00318 
00319     if (R)
00320     {
00321       _istr >> bits;
00322       for (idx=0; idx < R; ++idx)
00323         data_[bidx+idx] = !!(bits & (1<<idx));
00324       ++bytes;
00325     }
00326 
00327     std::cout << std::endl;
00328 
00329     return bytes;
00330   }
00331 
00332 
00333 public:
00334 
00336   vector_type& data_vector() {
00337 
00338     return data_;
00339   }
00340 
00342   reference operator[](int _idx)
00343   {
00344     assert( size_t(_idx) < data_.size() );
00345     return data_[_idx];
00346   }
00347 
00349   const_reference operator[](int _idx) const
00350   {
00351     assert( size_t(_idx) < data_.size());
00352     return data_[_idx];
00353   }
00354 
00356   PropertyT<bool>* clone() const
00357   {
00358     PropertyT<bool>* p = new PropertyT<bool>( *this );
00359     return p;
00360   }
00361 
00362 
00363 private:
00364 
00365   vector_type data_;
00366 };
00367 
00368 
00369 //-----------------------------------------------------------------------------
00370 
00371 
00374 template <>
00375 class PropertyT<std::string> : public BaseProperty
00376 {
00377 public:
00378 
00379   typedef std::string                             Value;
00380   typedef std::vector<std::string>                vector_type;
00381   typedef std::string                             value_type;
00382   typedef vector_type::reference                  reference;
00383   typedef vector_type::const_reference            const_reference;
00384 
00385 public:
00386 
00387   PropertyT(const std::string& _name = "<unknown>")
00388     : BaseProperty(_name)
00389   { }
00390 
00391 public: // inherited from BaseProperty
00392 
00393   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00394   virtual void resize(size_t _n)  { data_.resize(_n);     }
00395   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00396   virtual void push_back()        { data_.push_back(std::string()); }
00397   virtual void swap(size_t _i0, size_t _i1) {
00398     std::swap(data_[_i0], data_[_i1]);
00399   }
00400 
00401 public:
00402 
00403   virtual void set_persistent( bool _yn )
00404   { check_and_set_persistent<std::string>( _yn ); }
00405 
00406   virtual size_t       n_elements()   const { return data_.size();  }
00407   virtual size_t       element_size() const { return UnknownSize;    }
00408   virtual size_t       size_of() const
00409   { return IO::size_of( data_ ); }
00410 
00411   virtual size_t       size_of(size_t /* _n_elem */) const
00412   { return UnknownSize; }
00413 
00415   size_t store( std::ostream& _ostr, bool _swap ) const
00416   { return IO::store( _ostr, data_, _swap ); }
00417 
00418   size_t restore( std::istream& _istr, bool _swap )
00419   { return IO::restore( _istr, data_, _swap ); }
00420 
00421 public:
00422 
00423   const value_type* data() const {
00424       if( data_.empty() )
00425           return 0;
00426 
00427       return (value_type*) &data_[0];
00428   }
00429 
00431   reference operator[](int _idx) {
00432     assert( size_t(_idx) < data_.size());
00433     return ((value_type*) &data_[0])[_idx];
00434   }
00435 
00437   const_reference operator[](int _idx) const {
00438     assert( size_t(_idx) < data_.size());
00439     return ((value_type*) &data_[0])[_idx];
00440   }
00441 
00442   PropertyT<value_type>* clone() const {
00443     PropertyT<value_type>* p = new PropertyT<value_type>( *this );
00444     return p;
00445   }
00446 
00447 
00448 private:
00449 
00450   vector_type data_;
00451 
00452 };
00453 
00455 template <class T>
00456 struct BasePropHandleT : public BaseHandle
00457 {
00458   typedef T                                       Value;
00459   typedef std::vector<T>                          vector_type;
00460   typedef T                                       value_type;
00461   typedef typename vector_type::reference         reference;
00462   typedef typename vector_type::const_reference   const_reference;
00463 
00464   explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
00465 };
00466 
00467 
00471 template <class T>
00472 struct VPropHandleT : public BasePropHandleT<T>
00473 {
00474   typedef T                       Value;
00475   typedef T                       value_type;
00476 
00477   explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00478   explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00479 };
00480 
00481 
00485 template <class T>
00486 struct HPropHandleT : public BasePropHandleT<T>
00487 {
00488   typedef T                       Value;
00489   typedef T                       value_type;
00490 
00491   explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00492   explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00493 };
00494 
00495 
00499 template <class T>
00500 struct EPropHandleT : public BasePropHandleT<T>
00501 {
00502   typedef T                       Value;
00503   typedef T                       value_type;
00504 
00505   explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00506   explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00507 };
00508 
00509 
00513 template <class T>
00514 struct FPropHandleT : public BasePropHandleT<T>
00515 {
00516   typedef T                       Value;
00517   typedef T                       value_type;
00518 
00519   explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00520   explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00521 };
00522 
00523 
00527 template <class T>
00528 struct MPropHandleT : public BasePropHandleT<T>
00529 {
00530   typedef T                       Value;
00531   typedef T                       value_type;
00532 
00533   explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00534   explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00535 };
00536 
00537 } // namespace OpenMesh
00538 //=============================================================================
00539 #endif // OPENMESH_PROPERTY_HH defined
00540 //=============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines