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: 421 $                                                         *
00038  *   $Date: 2011-10-10 13:14:09 +0200 (Mo, 10 Okt 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 
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   reference operator[](int _idx)
00337   {
00338     assert( size_t(_idx) < data_.size() );
00339     return data_[_idx];
00340   }
00341 
00343   const_reference operator[](int _idx) const
00344   {
00345     assert( size_t(_idx) < data_.size());
00346     return data_[_idx];
00347   }
00348 
00350   PropertyT<bool>* clone() const
00351   {
00352     PropertyT<bool>* p = new PropertyT<bool>( *this );
00353     return p;
00354   }
00355 
00356 
00357 private:
00358 
00359   vector_type data_;
00360 };
00361 
00362 
00363 //-----------------------------------------------------------------------------
00364 
00365 
00368 template <>
00369 class PropertyT<std::string> : public BaseProperty
00370 {
00371 public:
00372 
00373   typedef std::string                             Value;
00374   typedef std::vector<std::string>                vector_type;
00375   typedef std::string                             value_type;
00376   typedef vector_type::reference                  reference;
00377   typedef vector_type::const_reference            const_reference;
00378 
00379 public:
00380 
00381   PropertyT(const std::string& _name = "<unknown>")
00382     : BaseProperty(_name)
00383   { }
00384 
00385 public: // inherited from BaseProperty
00386 
00387   virtual void reserve(size_t _n) { data_.reserve(_n);    }
00388   virtual void resize(size_t _n)  { data_.resize(_n);     }
00389   virtual void clear()  { data_.clear(); vector_type().swap(data_);    }
00390   virtual void push_back()        { data_.push_back(std::string()); }
00391   virtual void swap(size_t _i0, size_t _i1) {
00392     std::swap(data_[_i0], data_[_i1]);
00393   }
00394 
00395 public:
00396 
00397   virtual void set_persistent( bool _yn )
00398   { check_and_set_persistent<std::string>( _yn ); }
00399 
00400   virtual size_t       n_elements()   const { return data_.size();  }
00401   virtual size_t       element_size() const { return UnknownSize;    }
00402   virtual size_t       size_of() const
00403   { return IO::size_of( data_ ); }
00404 
00405   virtual size_t       size_of(size_t /* _n_elem */) const
00406   { return UnknownSize; }
00407 
00409   size_t store( std::ostream& _ostr, bool _swap ) const
00410   { return IO::store( _ostr, data_, _swap ); }
00411 
00412   size_t restore( std::istream& _istr, bool _swap )
00413   { return IO::restore( _istr, data_, _swap ); }
00414 
00415 public:
00416 
00417   const value_type* data() const {
00418       if( data_.empty() )
00419           return 0;
00420 
00421       return (value_type*) &data_[0];
00422   }
00423 
00425   reference operator[](int _idx) {
00426     assert( size_t(_idx) < data_.size());
00427     return ((value_type*) &data_[0])[_idx];
00428   }
00429 
00431   const_reference operator[](int _idx) const {
00432     assert( size_t(_idx) < data_.size());
00433     return ((value_type*) &data_[0])[_idx];
00434   }
00435 
00436   PropertyT<value_type>* clone() const {
00437     PropertyT<value_type>* p = new PropertyT<value_type>( *this );
00438     return p;
00439   }
00440 
00441 
00442 private:
00443 
00444   vector_type data_;
00445 
00446 };
00447 
00449 template <class T>
00450 struct BasePropHandleT : public BaseHandle
00451 {
00452   typedef T                                       Value;
00453   typedef std::vector<T>                          vector_type;
00454   typedef T                                       value_type;
00455   typedef typename vector_type::reference         reference;
00456   typedef typename vector_type::const_reference   const_reference;
00457 
00458   explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
00459 };
00460 
00461 
00465 template <class T>
00466 struct VPropHandleT : public BasePropHandleT<T>
00467 {
00468   typedef T                       Value;
00469   typedef T                       value_type;
00470 
00471   explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00472   explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00473 };
00474 
00475 
00479 template <class T>
00480 struct HPropHandleT : public BasePropHandleT<T>
00481 {
00482   typedef T                       Value;
00483   typedef T                       value_type;
00484 
00485   explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00486   explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00487 };
00488 
00489 
00493 template <class T>
00494 struct EPropHandleT : public BasePropHandleT<T>
00495 {
00496   typedef T                       Value;
00497   typedef T                       value_type;
00498 
00499   explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00500   explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00501 };
00502 
00503 
00507 template <class T>
00508 struct FPropHandleT : public BasePropHandleT<T>
00509 {
00510   typedef T                       Value;
00511   typedef T                       value_type;
00512 
00513   explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00514   explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00515 };
00516 
00517 
00521 template <class T>
00522 struct MPropHandleT : public BasePropHandleT<T>
00523 {
00524   typedef T                       Value;
00525   typedef T                       value_type;
00526 
00527   explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
00528   explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
00529 };
00530 
00531 } // namespace OpenMesh
00532 //=============================================================================
00533 #endif // OPENMESH_PROPERTY_HH defined
00534 //=============================================================================