2015-04-28 11:54:17 +00:00
|
|
|
/* ========================================================================= *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
|
|
|
|
* OpenMesh *
|
2015-04-28 11:33:32 +00:00
|
|
|
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
2015-04-28 13:07:46 +00:00
|
|
|
* Department of Computer Graphics and Multimedia *
|
2015-04-28 11:33:32 +00:00
|
|
|
* All rights reserved. *
|
|
|
|
|
* www.openmesh.org *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
*---------------------------------------------------------------------------*
|
|
|
|
|
* This file is part of OpenMesh. *
|
|
|
|
|
*---------------------------------------------------------------------------*
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* Redistribution and use in source and binary forms, with or without *
|
|
|
|
|
* modification, are permitted provided that the following conditions *
|
|
|
|
|
* are met: *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* 1. Redistributions of source code must retain the above copyright notice, *
|
|
|
|
|
* this list of conditions and the following disclaimer. *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright *
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the *
|
|
|
|
|
* documentation and/or other materials provided with the distribution. *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* 3. Neither the name of the copyright holder nor the names of its *
|
|
|
|
|
* contributors may be used to endorse or promote products derived from *
|
|
|
|
|
* this software without specific prior written permission. *
|
2009-06-04 08:46:29 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
|
|
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
|
|
|
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
2015-04-28 11:54:17 +00:00
|
|
|
* *
|
|
|
|
|
* ========================================================================= */
|
2009-06-04 08:46:29 +00:00
|
|
|
|
2019-01-15 11:21:12 +01:00
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
#ifndef OPENMESH_PROPERTY_HH
|
|
|
|
|
#define OPENMESH_PROPERTY_HH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//== INCLUDES =================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <OpenMesh/Core/System/config.h>
|
|
|
|
|
#include <OpenMesh/Core/Mesh/Handles.hh>
|
|
|
|
|
#include <OpenMesh/Core/Utils/BaseProperty.hh>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <algorithm>
|
2020-11-26 17:50:48 +01:00
|
|
|
#include <OpenMesh/Core/Utils/typename.hh>
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//== NAMESPACES ===============================================================
|
|
|
|
|
|
|
|
|
|
namespace OpenMesh {
|
|
|
|
|
|
|
|
|
|
//== CLASS DEFINITION =========================================================
|
|
|
|
|
|
|
|
|
|
/** \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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// TODO: it might be possible to define Property using kind of a runtime info
|
|
|
|
|
// structure holding the size of T. Then reserve, swap, resize, etc can be written
|
|
|
|
|
// in pure malloc() style w/o virtual overhead. Template member function proved per
|
|
|
|
|
// element access to the properties, asserting dynamic_casts in debug
|
|
|
|
|
|
|
|
|
|
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
|
2019-08-13 18:24:26 +02:00
|
|
|
explicit PropertyT(
|
|
|
|
|
const std::string& _name = "<unknown>",
|
|
|
|
|
const std::string& _internal_type_name = "<unknown>")
|
|
|
|
|
: BaseProperty(_name, _internal_type_name)
|
2009-02-06 13:37:46 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
/// Copy constructor
|
|
|
|
|
PropertyT(const PropertyT & _rhs)
|
|
|
|
|
: BaseProperty( _rhs ), data_( _rhs.data_ ) {}
|
|
|
|
|
|
|
|
|
|
public: // inherited from BaseProperty
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void reserve(size_t _n) override { data_.reserve(_n); }
|
|
|
|
|
virtual void resize(size_t _n) override { data_.resize(_n); }
|
|
|
|
|
virtual void clear() override { data_.clear(); vector_type().swap(data_); }
|
|
|
|
|
virtual void push_back() override { data_.push_back(T()); }
|
|
|
|
|
virtual void swap(size_t _i0, size_t _i1) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ std::swap(data_[_i0], data_[_i1]); }
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void copy(size_t _i0, size_t _i1) override
|
2012-09-17 08:02:13 +00:00
|
|
|
{ data_[_i1] = data_[_i0]; }
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void set_persistent( bool _yn ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ check_and_set_persistent<T>( _yn ); }
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t n_elements() const override { return data_.size(); }
|
|
|
|
|
virtual size_t element_size() const override { return IO::size_of<T>(); }
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
#ifndef DOXY_IGNORE_THIS
|
|
|
|
|
struct plus {
|
|
|
|
|
size_t operator () ( size_t _b, const T& _v )
|
|
|
|
|
{ return _b + IO::size_of<T>(_v); }
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t size_of(void) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
if (element_size() != IO::UnknownSize)
|
|
|
|
|
return this->BaseProperty::size_of(n_elements());
|
2013-07-22 14:29:52 +00:00
|
|
|
return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t size_of(size_t _n_elem) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ return this->BaseProperty::size_of(_n_elem); }
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t store( std::ostream& _ostr, bool _swap ) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t restore( std::istream& _istr, bool _swap ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
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)
|
2009-08-10 10:50:34 +00:00
|
|
|
const T* data() const {
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
if( data_.empty() )
|
|
|
|
|
return 0;
|
|
|
|
|
|
2009-08-10 10:50:34 +00:00
|
|
|
return &data_[0];
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
2019-08-13 18:24:26 +02:00
|
|
|
|
|
|
|
|
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
|
|
|
|
|
vector_type& data_vector() {
|
|
|
|
|
return data_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Const access to property vector
|
|
|
|
|
const vector_type& data_vector() const {
|
|
|
|
|
return data_;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
/// 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.
|
2019-05-28 11:50:49 +02:00
|
|
|
PropertyT<T>* clone() const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
PropertyT<T>* p = new PropertyT<T>( *this );
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 17:50:48 +01:00
|
|
|
std::string get_storage_name() const override
|
|
|
|
|
{
|
|
|
|
|
return get_string_for_type(T());
|
|
|
|
|
}
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
vector_type data_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
2011-10-10 11:14:09 +00:00
|
|
|
/** Property specialization for bool type.
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2011-10-10 11:14:09 +00:00
|
|
|
The data will be stored as a bitset.
|
2009-02-06 13:37:46 +00:00
|
|
|
*/
|
|
|
|
|
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:
|
|
|
|
|
|
2019-08-14 11:25:36 +02:00
|
|
|
explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
|
|
|
|
|
: BaseProperty(_name, _internal_type_name)
|
2009-02-06 13:37:46 +00:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public: // inherited from BaseProperty
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void reserve(size_t _n) override { data_.reserve(_n); }
|
|
|
|
|
virtual void resize(size_t _n) override { data_.resize(_n); }
|
|
|
|
|
virtual void clear() override { data_.clear(); vector_type().swap(data_); }
|
|
|
|
|
virtual void push_back() override { data_.push_back(bool()); }
|
|
|
|
|
virtual void swap(size_t _i0, size_t _i1) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void copy(size_t _i0, size_t _i1) override
|
2012-09-17 08:02:13 +00:00
|
|
|
{ data_[_i1] = data_[_i0]; }
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void set_persistent( bool _yn ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
check_and_set_persistent<bool>( _yn );
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t n_elements() const override { return data_.size(); }
|
|
|
|
|
virtual size_t element_size() const override { return UnknownSize; }
|
|
|
|
|
virtual size_t size_of() const override { return size_of( n_elements() ); }
|
|
|
|
|
virtual size_t size_of(size_t _n_elem) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
return _n_elem / 8 + ((_n_elem % 8)!=0);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
size_t store( std::ostream& _ostr, bool /* _swap */ ) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2015-06-01 12:09:32 +00:00
|
|
|
bits = static_cast<unsigned char>(data_[bidx])
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+1]) << 1)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+2]) << 2)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+3]) << 3)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+4]) << 4)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+5]) << 5)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+6]) << 6)
|
|
|
|
|
| (static_cast<unsigned char>(data_[bidx+7]) << 7);
|
2009-02-06 13:37:46 +00:00
|
|
|
_ostr << bits;
|
|
|
|
|
}
|
|
|
|
|
bytes = N;
|
|
|
|
|
|
|
|
|
|
if (R)
|
|
|
|
|
{
|
|
|
|
|
bits = 0;
|
|
|
|
|
for (idx=0; idx < R; ++idx)
|
2015-06-03 07:19:08 +00:00
|
|
|
bits |= static_cast<unsigned char>(data_[bidx+idx]) << idx;
|
2009-02-06 13:37:46 +00:00
|
|
|
_ostr << bits;
|
|
|
|
|
++bytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert( bytes == size_of() );
|
|
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
size_t restore( std::istream& _istr, bool /* _swap */ ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
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;
|
2015-06-01 12:09:32 +00:00
|
|
|
data_[bidx+0] = (bits & 0x01) != 0;
|
|
|
|
|
data_[bidx+1] = (bits & 0x02) != 0;
|
|
|
|
|
data_[bidx+2] = (bits & 0x04) != 0;
|
|
|
|
|
data_[bidx+3] = (bits & 0x08) != 0;
|
|
|
|
|
data_[bidx+4] = (bits & 0x10) != 0;
|
|
|
|
|
data_[bidx+5] = (bits & 0x20) != 0;
|
|
|
|
|
data_[bidx+6] = (bits & 0x40) != 0;
|
|
|
|
|
data_[bidx+7] = (bits & 0x80) != 0;
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
bytes = N;
|
|
|
|
|
|
|
|
|
|
if (R)
|
|
|
|
|
{
|
|
|
|
|
_istr >> bits;
|
|
|
|
|
for (idx=0; idx < R; ++idx)
|
2015-06-03 07:19:08 +00:00
|
|
|
data_[bidx+idx] = (bits & (1<<idx)) != 0;
|
2009-02-06 13:37:46 +00:00
|
|
|
++bytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
2019-08-13 18:24:26 +02:00
|
|
|
|
|
|
|
|
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
|
|
|
|
|
vector_type& data_vector() {
|
|
|
|
|
return data_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Const access to property vector
|
|
|
|
|
const vector_type& data_vector() const {
|
|
|
|
|
return data_;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
/// 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.
|
2019-05-29 10:55:52 +02:00
|
|
|
PropertyT<bool>* clone() const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
PropertyT<bool>* p = new PropertyT<bool>( *this );
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 17:50:48 +01:00
|
|
|
std::string get_storage_name() const override
|
|
|
|
|
{
|
|
|
|
|
return get_string_for_type(bool());
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
vector_type data_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
2011-10-10 11:14:09 +00:00
|
|
|
/** Property specialization for std::string type.
|
2009-02-06 13:37:46 +00:00
|
|
|
*/
|
|
|
|
|
template <>
|
|
|
|
|
class PropertyT<std::string> : public BaseProperty
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
typedef std::string Value;
|
|
|
|
|
typedef std::vector<std::string> vector_type;
|
|
|
|
|
typedef std::string value_type;
|
|
|
|
|
typedef vector_type::reference reference;
|
|
|
|
|
typedef vector_type::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2019-08-15 10:47:37 +02:00
|
|
|
explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
|
|
|
|
|
: BaseProperty(_name, _internal_type_name)
|
2009-02-06 13:37:46 +00:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public: // inherited from BaseProperty
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void reserve(size_t _n) override { data_.reserve(_n); }
|
|
|
|
|
virtual void resize(size_t _n) override { data_.resize(_n); }
|
|
|
|
|
virtual void clear() override { data_.clear(); vector_type().swap(data_); }
|
|
|
|
|
virtual void push_back() override { data_.push_back(std::string()); }
|
|
|
|
|
virtual void swap(size_t _i0, size_t _i1) override {
|
2009-02-06 13:37:46 +00:00
|
|
|
std::swap(data_[_i0], data_[_i1]);
|
|
|
|
|
}
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void copy(size_t _i0, size_t _i1) override
|
2012-09-17 08:02:13 +00:00
|
|
|
{ data_[_i1] = data_[_i0]; }
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual void set_persistent( bool _yn ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ check_and_set_persistent<std::string>( _yn ); }
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t n_elements() const override { return data_.size(); }
|
|
|
|
|
virtual size_t element_size() const override { return UnknownSize; }
|
|
|
|
|
virtual size_t size_of() const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ return IO::size_of( data_ ); }
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
virtual size_t size_of(size_t /* _n_elem */) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ return UnknownSize; }
|
|
|
|
|
|
|
|
|
|
/// Store self as one binary block. Max. length of a string is 65535 bytes.
|
2019-05-28 11:50:49 +02:00
|
|
|
size_t store( std::ostream& _ostr, bool _swap ) const override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ return IO::store( _ostr, data_, _swap ); }
|
|
|
|
|
|
2019-05-28 11:50:49 +02:00
|
|
|
size_t restore( std::istream& _istr, bool _swap ) override
|
2009-02-06 13:37:46 +00:00
|
|
|
{ return IO::restore( _istr, data_, _swap ); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
const value_type* data() const {
|
|
|
|
|
if( data_.empty() )
|
2019-05-29 10:11:42 +02:00
|
|
|
return nullptr;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
return (value_type*) &data_[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Access the i'th element. No range check is performed!
|
|
|
|
|
reference operator[](int _idx) {
|
|
|
|
|
assert( size_t(_idx) < data_.size());
|
|
|
|
|
return ((value_type*) &data_[0])[_idx];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Const access the i'th element. No range check is performed!
|
|
|
|
|
const_reference operator[](int _idx) const {
|
|
|
|
|
assert( size_t(_idx) < data_.size());
|
|
|
|
|
return ((value_type*) &data_[0])[_idx];
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-29 10:55:52 +02:00
|
|
|
PropertyT<value_type>* clone() const override {
|
2009-02-06 13:37:46 +00:00
|
|
|
PropertyT<value_type>* p = new PropertyT<value_type>( *this );
|
|
|
|
|
return p;
|
|
|
|
|
}
|
2020-11-26 17:50:48 +01:00
|
|
|
|
|
|
|
|
std::string get_storage_name() const override
|
|
|
|
|
{
|
|
|
|
|
return get_string_for_type(std::string());
|
|
|
|
|
}
|
2009-02-06 13:37:46 +00:00
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
vector_type data_;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// Base property handle.
|
|
|
|
|
template <class T>
|
|
|
|
|
struct BasePropHandleT : public BaseHandle
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \ingroup mesh_property_handle_group
|
|
|
|
|
* Handle representing a vertex property
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
struct VPropHandleT : public BasePropHandleT<T>
|
|
|
|
|
{
|
|
|
|
|
typedef T Value;
|
|
|
|
|
typedef T value_type;
|
2019-10-31 14:02:43 +01:00
|
|
|
typedef VertexHandle Handle;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
|
|
|
|
|
explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \ingroup mesh_property_handle_group
|
|
|
|
|
* Handle representing a halfedge property
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
struct HPropHandleT : public BasePropHandleT<T>
|
|
|
|
|
{
|
|
|
|
|
typedef T Value;
|
|
|
|
|
typedef T value_type;
|
2019-10-31 14:02:43 +01:00
|
|
|
typedef HalfedgeHandle Handle;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
|
|
|
|
|
explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \ingroup mesh_property_handle_group
|
|
|
|
|
* Handle representing an edge property
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
struct EPropHandleT : public BasePropHandleT<T>
|
|
|
|
|
{
|
|
|
|
|
typedef T Value;
|
|
|
|
|
typedef T value_type;
|
2019-10-31 14:02:43 +01:00
|
|
|
typedef EdgeHandle Handle;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
|
|
|
|
|
explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \ingroup mesh_property_handle_group
|
|
|
|
|
* Handle representing a face property
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
struct FPropHandleT : public BasePropHandleT<T>
|
|
|
|
|
{
|
|
|
|
|
typedef T Value;
|
|
|
|
|
typedef T value_type;
|
2019-10-31 14:02:43 +01:00
|
|
|
typedef FaceHandle Handle;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
|
|
|
|
|
explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \ingroup mesh_property_handle_group
|
|
|
|
|
* Handle representing a mesh property
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
struct MPropHandleT : public BasePropHandleT<T>
|
|
|
|
|
{
|
|
|
|
|
typedef T Value;
|
|
|
|
|
typedef T value_type;
|
2019-11-05 15:29:11 +01:00
|
|
|
typedef MeshHandle Handle;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
|
|
|
|
|
explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-31 17:56:37 +01:00
|
|
|
template <typename HandleT>
|
|
|
|
|
struct PropHandle;
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
struct PropHandle<VertexHandle> {
|
|
|
|
|
template <typename T>
|
|
|
|
|
using type = VPropHandleT<T>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
struct PropHandle<HalfedgeHandle> {
|
|
|
|
|
template <typename T>
|
|
|
|
|
using type = HPropHandleT<T>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
struct PropHandle<EdgeHandle> {
|
|
|
|
|
template <typename T>
|
|
|
|
|
using type = EPropHandleT<T>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
struct PropHandle<FaceHandle> {
|
|
|
|
|
template <typename T>
|
|
|
|
|
using type = FPropHandleT<T>;
|
|
|
|
|
};
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
} // namespace OpenMesh
|
|
|
|
|
//=============================================================================
|
|
|
|
|
#endif // OPENMESH_PROPERTY_HH defined
|
|
|
|
|
//=============================================================================
|