⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 property.hh

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 HH
📖 第 1 页 / 共 2 页
字号:
/*===========================================================================*\ *                                                                           * *                               OpenMesh                                    * *      Copyright (C) 2001-2003 by Computer Graphics Group, RWTH Aachen      * *                           www.openmesh.org                                * *                                                                           * *---------------------------------------------------------------------------* *                                                                           * *                                License                                    * *                                                                           * *  This library is free software; you can redistribute it and/or modify it  * *  under the terms of the GNU Library General Public License as published   * *  by the Free Software Foundation, version 2.                              * *                                                                           * *  This library is distributed in the hope that it will be useful, but      * *  WITHOUT ANY WARRANTY; without even the implied warranty of               * *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        * *  Library General Public License for more details.                         * *                                                                           * *  You should have received a copy of the GNU Library General Public        * *  License along with this library; if not, write to the Free Software      * *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                * *                                                                           *\*===========================================================================*/#ifndef OPENMESH_PROPERTY_HH#define OPENMESH_PROPERTY_HH//== INCLUDES =================================================================#include <OpenMesh/Core/System/config.hh>#include <OpenMesh/Core/System/omstream.hh>#include <OpenMesh/Core/Mesh/Kernels/Common/Handles.hh>#include <OpenMesh/Core/IO/StoreRestore.hh>#include <vector>#include <string>#include <algorithm>//== FORWARDDECLARATIONS ======================================================namespace OpenMesh {  class BaseKernel;}//== NAMESPACES ===============================================================namespace OpenMesh {//== CLASS DEFINITION =========================================================/** \class BaseProperty Property.hh <OpenMesh/Core/Utils/PropertyT.hh>    Abstract class defining the basic interface of a dynamic property.**/class BaseProperty{public:  /// Indicates an error when a size is returned by a member.  static const size_t UnknownSize = size_t(-1);public:  /// \brief Default constructor.  ///  /// In %OpenMesh all mesh data is stored in so-called properties.  /// We distinuish between standard properties, which can be defined at  /// compile time using the Attributes in the traits definition and  /// at runtime using the request property functions defined in one of  /// the kernels.  ///  /// If the property should be stored along with the default properties  /// in the OM-format one must name the property and enable the persistant  /// flag with set_persistent().  ///  /// \param _name Optional textual name for the property.  ///  BaseProperty(const std::string& _name = "<unknown>")    : name_(_name), persistent_(false) {}  /// \brief Copy constructor  BaseProperty(const BaseProperty & _rhs)      : name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {}  /// Destructor.  virtual ~BaseProperty() {}public: // synchronized array interface  /// Reserve memory for n elements.  virtual void reserve(size_t _n) = 0;  /// Resize storage to hold n elements.  virtual void resize(size_t _n) = 0;  /// Free unused memory.  virtual void free_mem() = 0;  /// Extend the number of elements by one.  virtual void push_back() = 0;  /// Let two elements swap their storage place.  virtual void swap(size_t _i0, size_t _i1) = 0;  /// Return a deep copy of self.  virtual BaseProperty* clone () const = 0;public: // named property interface  /// Return the name of the property  const std::string& name() const { return name_; }  virtual void stats(std::ostream& _ostr) const;public: // I/O support  /// Returns true if the persistent flag is enabled else false.  bool persistent(void) const { return persistent_; }  /// Enable or disable persistency. Self must be a named property to enable  /// persistency.  virtual void set_persistent( bool _yn ) = 0;  /// Number of elements in property  virtual size_t       n_elements() const = 0;  /// Size of one element in bytes or UnknownSize if not known.  virtual size_t       element_size() const = 0;  /// Return size of property in bytes  virtual size_t       size_of() const  {    return size_of( n_elements() );  }  /// Estimated size of property if it has _n_elem elements.  /// The member returns UnknownSize if the size cannot be estimated.  virtual size_t       size_of(size_t _n_elem) const  {    return (element_size()!=UnknownSize)      ? (_n_elem*element_size())      : UnknownSize;  }  /// Store self as one binary block  virtual size_t store( std::ostream& _ostr, bool _swap ) const = 0;  /** Restore self from a binary block. Uses reserve() to set the      size of self before restoring.  **/  virtual size_t restore( std::istream& _istr, bool _swap ) = 0;protected:  // To be used in a derived class, when overloading set_persistent()  template < typename T >  void check_and_set_persistent( bool _yn )  {    if ( _yn && !IO::is_streamable<T>() )      omerr() << "Warning! Type of property value is not binary storable!\n";    persistent_ = IO::is_streamable<T>() && _yn;  }private:  std::string name_;  bool        persistent_;};//-----------------------------------------------------------------------------/** \class PropertyT Property.hh <OpenMesh/Core/Utils/PropertyT.hh> * *  \brief Default property class for any type T. * *  The default property class for any type T. * *  The property supports persistency if T is a "fundamental" type: *  - integer fundamental types except bool: *    char, short, int, long, long long (__int64 for MS VC++) and *    their unsigned companions. *  - float fundamentals except <tt>long double</tt>: *    float, double *  - %OpenMesh vector types * *  Persistency of non-fundamental types is supported if and only if a *  specialization of struct IO::binary<> exists for the wanted type. */template <class T>class PropertyT : public BaseProperty{public:  typedef T                                       Value;  typedef std::vector<T>                          vector_type;  typedef T                                       value_type;  typedef typename vector_type::reference         reference;  typedef typename vector_type::const_reference   const_reference;public:  /// Default constructor  PropertyT(const std::string& _name = "<unknown>")  : BaseProperty(_name)  {}  /// Copy constructor  PropertyT(const PropertyT & _rhs)      : BaseProperty( _rhs ), data_( _rhs.data_ ) {}public: // inherited from BaseProperty  virtual void reserve(size_t _n) { data_.reserve(_n);    }  virtual void resize(size_t _n)  { data_.resize(_n);     }  virtual void push_back()        { data_.push_back(T()); }  virtual void free_mem()         { vector_type(data_).swap(data_); }  virtual void swap(size_t _i0, size_t _i1)  { std::swap(data_[_i0], data_[_i1]); }public:  virtual void set_persistent( bool _yn )  { check_and_set_persistent<T>( _yn ); }  virtual size_t       n_elements()   const { return data_.size(); }  virtual size_t       element_size() const { return IO::size_of<T>(); }#ifndef DOXY_IGNORE_THIS  struct plus {    size_t operator () ( size_t _b, const T& _v )    { return _b + IO::size_of<T>(_v); }  };#endif  virtual size_t size_of(void) const  {    if (element_size() != IO::UnknownSize)      return this->BaseProperty::size_of(n_elements());    return std::accumulate(data_.begin(), data_.end(), 0, plus());  }  virtual size_t size_of(size_t _n_elem) const  { return this->BaseProperty::size_of(_n_elem); }  virtual size_t store( std::ostream& _ostr, bool _swap ) const  {    if ( IO::is_streamable<vector_type>() )      return IO::store(_ostr, data_, _swap );    size_t bytes = 0;    for (size_t i=0; i<n_elements(); ++i)      bytes += IO::store( _ostr, data_[i], _swap );    return bytes;  }  virtual size_t restore( std::istream& _istr, bool _swap )  {    if ( IO::is_streamable<vector_type>() )      return IO::restore(_istr, data_, _swap );    size_t bytes = 0;    for (size_t i=0; i<n_elements(); ++i)      bytes += IO::restore( _istr, data_[i], _swap );    return bytes;  }public: // data access interface  /// Get pointer to array (does not work for T==bool)  const T* data() const { return &data_[0]; }  /// Access the i'th element. No range check is performed!  reference operator[](int _idx)  {    assert( size_t(_idx) < data_.size() );    return data_[_idx];  }  /// Const access to the i'th element. No range check is performed!  const_reference operator[](int _idx) const  {    assert( size_t(_idx) < data_.size());    return data_[_idx];  }  /// Make a copy of self.  PropertyT<T>* clone() const  {    PropertyT<T>* p = new PropertyT<T>( *this );    return p;  }private:  vector_type data_;};//-----------------------------------------------------------------------------/** \class PropertyT<bool> Property.hh <OpenMesh/Core/Utils/PropertyT.hh>  Property specialization for bool type. The data will be stored as  a bitset. */template <>class PropertyT<bool> : public BaseProperty{public:  typedef std::vector<bool>                       vector_type;  typedef bool                                    value_type;  typedef vector_type::reference                  reference;  typedef vector_type::const_reference            const_reference;public:  PropertyT(const std::string& _name = "<unknown>")    : BaseProperty(_name)  { }  PropertyT(const PropertyT & _rhs)      : BaseProperty( _rhs ), data_( _rhs.data_ ) {}public: // inherited from BaseProperty  virtual void reserve(size_t _n) { data_.reserve(_n);    }  virtual void resize(size_t _n)  { data_.resize(_n);     }  virtual void push_back()        { data_.push_back(bool()); }  virtual void free_mem()         { vector_type(data_).swap(data_); }  virtual void swap(size_t _i0, size_t _i1)  { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }public:  virtual void set_persistent( bool _yn )  {    check_and_set_persistent<bool>( _yn );  }  virtual size_t       n_elements()   const { return data_.size();  }  virtual size_t       element_size() const { return UnknownSize;    }  virtual size_t       size_of() const      { return size_of( n_elements() ); }  virtual size_t       size_of(size_t _n_elem) const  {    return _n_elem / 8 + ((_n_elem % 8)!=0);  }  size_t store( std::ostream& _ostr, bool _swap ) const  {    size_t bytes = 0;    size_t N = data_.size() / 8;    size_t R = data_.size() % 8;    size_t        idx;  // element index    size_t        bidx;    unsigned char bits; // bitset    for (bidx=idx=0; idx < N; ++idx, bidx+=8)    {      bits = !!data_[bidx]        | (!!data_[bidx+1] << 1)        | (!!data_[bidx+2] << 2)        | (!!data_[bidx+3] << 3)        | (!!data_[bidx+4] << 4)        | (!!data_[bidx+5] << 5)        | (!!data_[bidx+6] << 6)        | (!!data_[bidx+7] << 7);      _ostr << bits;    }    bytes = N;    if (R)    {      bits = 0;      for (idx=0; idx < R; ++idx)        bits |= !!data_[bidx+idx] << idx;      _ostr << bits;      ++bytes;    }    std::cout << std::endl;    assert( bytes == size_of() );    return bytes;  }  size_t restore( std::istream& _istr, bool _swap )  {    size_t bytes = 0;    size_t N = data_.size() / 8;    size_t R = data_.size() % 8;    size_t        idx;  // element index    size_t        bidx; //    unsigned char bits; // bitset    for (bidx=idx=0; idx < N; ++idx, bidx+=8)    {      _istr >> bits;      data_[bidx+0] = !!(bits & 0x01);      data_[bidx+1] = !!(bits & 0x02);      data_[bidx+2] = !!(bits & 0x04);      data_[bidx+3] = !!(bits & 0x08);      data_[bidx+4] = !!(bits & 0x10);      data_[bidx+5] = !!(bits & 0x20);      data_[bidx+6] = !!(bits & 0x40);      data_[bidx+7] = !!(bits & 0x80);    }    bytes = N;    if (R)    {      _istr >> bits;      for (idx=0; idx < R; ++idx)        data_[bidx+idx] = !!(bits & (1<<idx));      ++bytes;    }    std::cout << std::endl;    return bytes;  }public:  /// Access the i'th element. No range check is performed!

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -