Developer Documentation
Property.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
44 #ifndef OPENMESH_PROPERTY_HH
45 #define OPENMESH_PROPERTY_HH
46 
47 
48 //== INCLUDES =================================================================
49 
50 
52 #include <OpenMesh/Core/Mesh/Handles.hh>
53 #include <OpenMesh/Core/Utils/BaseProperty.hh>
54 #include <vector>
55 #include <string>
56 #include <algorithm>
57 
58 
59 //== NAMESPACES ===============================================================
60 
61 namespace OpenMesh {
62 
63 //== CLASS DEFINITION =========================================================
64 
83 // TODO: it might be possible to define Property using kind of a runtime info
84 // structure holding the size of T. Then reserve, swap, resize, etc can be written
85 // in pure malloc() style w/o virtual overhead. Template member function proved per
86 // element access to the properties, asserting dynamic_casts in debug
87 
88 template <class T>
89 class PropertyT : public BaseProperty
90 {
91 public:
92 
93  typedef T Value;
94  typedef std::vector<T> vector_type;
95  typedef T value_type;
96  typedef typename vector_type::reference reference;
97  typedef typename vector_type::const_reference const_reference;
98 
99 public:
100 
102  PropertyT(const std::string& _name = "<unknown>")
103  : BaseProperty(_name)
104  {}
105 
107  PropertyT(const PropertyT & _rhs)
108  : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
109 
110 public: // inherited from BaseProperty
111 
112  virtual void reserve(size_t _n) { data_.reserve(_n); }
113  virtual void resize(size_t _n) { data_.resize(_n); }
114  virtual void clear() { data_.clear(); vector_type().swap(data_); }
115  virtual void push_back() { data_.push_back(T()); }
116  virtual void swap(size_t _i0, size_t _i1)
117  { std::swap(data_[_i0], data_[_i1]); }
118  virtual void copy(size_t _i0, size_t _i1)
119  { data_[_i1] = data_[_i0]; }
120 
121 public:
122 
123  virtual void set_persistent( bool _yn )
124  { check_and_set_persistent<T>( _yn ); }
125 
126  virtual size_t n_elements() const { return data_.size(); }
127  virtual size_t element_size() const { return IO::size_of<T>(); }
128 
129 #ifndef DOXY_IGNORE_THIS
130  struct plus {
131  size_t operator () ( size_t _b, const T& _v )
132  { return _b + IO::size_of<T>(_v); }
133  };
134 #endif
135 
136  virtual size_t size_of(void) const
137  {
138  if (element_size() != IO::UnknownSize)
139  return this->BaseProperty::size_of(n_elements());
140  return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
141  }
142 
143  virtual size_t size_of(size_t _n_elem) const
144  { return this->BaseProperty::size_of(_n_elem); }
145 
146  virtual size_t store( std::ostream& _ostr, bool _swap ) const
147  {
148  if ( IO::is_streamable<vector_type>() )
149  return IO::store(_ostr, data_, _swap );
150  size_t bytes = 0;
151  for (size_t i=0; i<n_elements(); ++i)
152  bytes += IO::store( _ostr, data_[i], _swap );
153  return bytes;
154  }
155 
156  virtual size_t restore( std::istream& _istr, bool _swap )
157  {
158  if ( IO::is_streamable<vector_type>() )
159  return IO::restore(_istr, data_, _swap );
160  size_t bytes = 0;
161  for (size_t i=0; i<n_elements(); ++i)
162  bytes += IO::restore( _istr, data_[i], _swap );
163  return bytes;
164  }
165 
166 public: // data access interface
167 
169  const T* data() const {
170 
171  if( data_.empty() )
172  return 0;
173 
174  return &data_[0];
175  }
176 
178  vector_type& data_vector() {
179  return data_;
180  }
181 
183  const vector_type& data_vector() const {
184  return data_;
185  }
186 
188  reference operator[](int _idx)
189  {
190  assert( size_t(_idx) < data_.size() );
191  return data_[_idx];
192  }
193 
195  const_reference operator[](int _idx) const
196  {
197  assert( size_t(_idx) < data_.size());
198  return data_[_idx];
199  }
200 
203  {
204  PropertyT<T>* p = new PropertyT<T>( *this );
205  return p;
206  }
207 
208 
209 private:
210 
211  vector_type data_;
212 };
213 
214 //-----------------------------------------------------------------------------
215 
216 
221 template <>
222 class PropertyT<bool> : public BaseProperty
223 {
224 public:
225 
226  typedef std::vector<bool> vector_type;
227  typedef bool value_type;
228  typedef vector_type::reference reference;
229  typedef vector_type::const_reference const_reference;
230 
231 public:
232 
233  PropertyT(const std::string& _name = "<unknown>")
234  : BaseProperty(_name)
235  { }
236 
237 public: // inherited from BaseProperty
238 
239  virtual void reserve(size_t _n) { data_.reserve(_n); }
240  virtual void resize(size_t _n) { data_.resize(_n); }
241  virtual void clear() { data_.clear(); vector_type().swap(data_); }
242  virtual void push_back() { data_.push_back(bool()); }
243  virtual void swap(size_t _i0, size_t _i1)
244  { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
245  virtual void copy(size_t _i0, size_t _i1)
246  { data_[_i1] = data_[_i0]; }
247 
248 public:
249 
250  virtual void set_persistent( bool _yn )
251  {
252  check_and_set_persistent<bool>( _yn );
253  }
254 
255  virtual size_t n_elements() const { return data_.size(); }
256  virtual size_t element_size() const { return UnknownSize; }
257  virtual size_t size_of() const { return size_of( n_elements() ); }
258  virtual size_t size_of(size_t _n_elem) const
259  {
260  return _n_elem / 8 + ((_n_elem % 8)!=0);
261  }
262 
263  size_t store( std::ostream& _ostr, bool /* _swap */ ) const
264  {
265  size_t bytes = 0;
266 
267  size_t N = data_.size() / 8;
268  size_t R = data_.size() % 8;
269 
270  size_t idx; // element index
271  size_t bidx;
272  unsigned char bits; // bitset
273 
274  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
275  {
276  bits = static_cast<unsigned char>(data_[bidx])
277  | (static_cast<unsigned char>(data_[bidx+1]) << 1)
278  | (static_cast<unsigned char>(data_[bidx+2]) << 2)
279  | (static_cast<unsigned char>(data_[bidx+3]) << 3)
280  | (static_cast<unsigned char>(data_[bidx+4]) << 4)
281  | (static_cast<unsigned char>(data_[bidx+5]) << 5)
282  | (static_cast<unsigned char>(data_[bidx+6]) << 6)
283  | (static_cast<unsigned char>(data_[bidx+7]) << 7);
284  _ostr << bits;
285  }
286  bytes = N;
287 
288  if (R)
289  {
290  bits = 0;
291  for (idx=0; idx < R; ++idx)
292  bits |= static_cast<unsigned char>(data_[bidx+idx]) << idx;
293  _ostr << bits;
294  ++bytes;
295  }
296 
297  assert( bytes == size_of() );
298 
299  return bytes;
300  }
301 
302  size_t restore( std::istream& _istr, bool /* _swap */ )
303  {
304  size_t bytes = 0;
305 
306  size_t N = data_.size() / 8;
307  size_t R = data_.size() % 8;
308 
309  size_t idx; // element index
310  size_t bidx; //
311  unsigned char bits; // bitset
312 
313  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
314  {
315  _istr >> bits;
316  data_[bidx+0] = (bits & 0x01) != 0;
317  data_[bidx+1] = (bits & 0x02) != 0;
318  data_[bidx+2] = (bits & 0x04) != 0;
319  data_[bidx+3] = (bits & 0x08) != 0;
320  data_[bidx+4] = (bits & 0x10) != 0;
321  data_[bidx+5] = (bits & 0x20) != 0;
322  data_[bidx+6] = (bits & 0x40) != 0;
323  data_[bidx+7] = (bits & 0x80) != 0;
324  }
325  bytes = N;
326 
327  if (R)
328  {
329  _istr >> bits;
330  for (idx=0; idx < R; ++idx)
331  data_[bidx+idx] = (bits & (1<<idx)) != 0;
332  ++bytes;
333  }
334 
335  return bytes;
336  }
337 
338 
339 public:
340 
342  vector_type& data_vector() {
343  return data_;
344  }
345 
347  const vector_type& data_vector() const {
348  return data_;
349  }
350 
352  reference operator[](int _idx)
353  {
354  assert( size_t(_idx) < data_.size() );
355  return data_[_idx];
356  }
357 
359  const_reference operator[](int _idx) const
360  {
361  assert( size_t(_idx) < data_.size());
362  return data_[_idx];
363  }
364 
367  {
368  PropertyT<bool>* p = new PropertyT<bool>( *this );
369  return p;
370  }
371 
372 
373 private:
374 
375  vector_type data_;
376 };
377 
378 
379 //-----------------------------------------------------------------------------
380 
381 
384 template <>
385 class PropertyT<std::string> : public BaseProperty
386 {
387 public:
388 
389  typedef std::string Value;
390  typedef std::vector<std::string> vector_type;
391  typedef std::string value_type;
392  typedef vector_type::reference reference;
393  typedef vector_type::const_reference const_reference;
394 
395 public:
396 
397  PropertyT(const std::string& _name = "<unknown>")
398  : BaseProperty(_name)
399  { }
400 
401 public: // inherited from BaseProperty
402 
403  virtual void reserve(size_t _n) { data_.reserve(_n); }
404  virtual void resize(size_t _n) { data_.resize(_n); }
405  virtual void clear() { data_.clear(); vector_type().swap(data_); }
406  virtual void push_back() { data_.push_back(std::string()); }
407  virtual void swap(size_t _i0, size_t _i1) {
408  std::swap(data_[_i0], data_[_i1]);
409  }
410  virtual void copy(size_t _i0, size_t _i1)
411  { data_[_i1] = data_[_i0]; }
412 
413 public:
414 
415  virtual void set_persistent( bool _yn )
416  { check_and_set_persistent<std::string>( _yn ); }
417 
418  virtual size_t n_elements() const { return data_.size(); }
419  virtual size_t element_size() const { return UnknownSize; }
420  virtual size_t size_of() const
421  { return IO::size_of( data_ ); }
422 
423  virtual size_t size_of(size_t /* _n_elem */) const
424  { return UnknownSize; }
425 
427  size_t store( std::ostream& _ostr, bool _swap ) const
428  { return IO::store( _ostr, data_, _swap ); }
429 
430  size_t restore( std::istream& _istr, bool _swap )
431  { return IO::restore( _istr, data_, _swap ); }
432 
433 public:
434 
435  const value_type* data() const {
436  if( data_.empty() )
437  return 0;
438 
439  return (value_type*) &data_[0];
440  }
441 
443  reference operator[](int _idx) {
444  assert( size_t(_idx) < data_.size());
445  return ((value_type*) &data_[0])[_idx];
446  }
447 
449  const_reference operator[](int _idx) const {
450  assert( size_t(_idx) < data_.size());
451  return ((value_type*) &data_[0])[_idx];
452  }
453 
456  return p;
457  }
458 private:
459 
460  vector_type data_;
461 
462 };
463 
465 template <class T>
467 {
468  typedef T Value;
469  typedef std::vector<T> vector_type;
470  typedef T value_type;
471  typedef typename vector_type::reference reference;
472  typedef typename vector_type::const_reference const_reference;
473 
474  explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
475 };
476 
477 
481 template <class T>
482 struct VPropHandleT : public BasePropHandleT<T>
483 {
484  typedef T Value;
485  typedef T value_type;
486 
487  explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
488  explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
489 };
490 
491 
495 template <class T>
496 struct HPropHandleT : public BasePropHandleT<T>
497 {
498  typedef T Value;
499  typedef T value_type;
500 
501  explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
502  explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
503 };
504 
505 
509 template <class T>
510 struct EPropHandleT : public BasePropHandleT<T>
511 {
512  typedef T Value;
513  typedef T value_type;
514 
515  explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
516  explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
517 };
518 
519 
523 template <class T>
524 struct FPropHandleT : public BasePropHandleT<T>
525 {
526  typedef T Value;
527  typedef T value_type;
528 
529  explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
530  explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
531 };
532 
533 
537 template <class T>
538 struct MPropHandleT : public BasePropHandleT<T>
539 {
540  typedef T Value;
541  typedef T value_type;
542 
543  explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
544  explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
545 };
546 
547 } // namespace OpenMesh
548 //=============================================================================
549 #endif // OPENMESH_PROPERTY_HH defined
550 //=============================================================================
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:405
PropertyT(const PropertyT &_rhs)
Copy constructor.
Definition: Property.hh:107
virtual size_t size_of(void) const
Return size of property in bytes.
Definition: Property.hh:136
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:242
size_t size_of(const T &_v)
Definition: StoreRestore.hh:89
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:342
virtual void resize(size_t _n)
Resize storage to hold n elements.
Definition: Property.hh:113
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:243
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:183
size_t restore(std::istream &_istr, bool)
Definition: Property.hh:302
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:65
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:115
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:116
BaseProperty(const std::string &_name="<unknown>")
Default constructor.
Definition: BaseProperty.hh:83
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:406
size_t store(std::ostream &_ostr, bool) const
Store self as one binary block.
Definition: Property.hh:263
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:419
virtual size_t size_of(size_t) const
Definition: Property.hh:423
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:114
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:407
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:241
PropertyT< bool > * clone() const
Make a copy of self.
Definition: Property.hh:366
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:352
PropertyT< T > * clone() const
Make a copy of self.
Definition: Property.hh:202
virtual size_t size_of() const
Return size of property in bytes.
Definition: Property.hh:420
size_t restore(std::istream &_istr, bool _swap)
Definition: Property.hh:430
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:403
const_reference operator[](int _idx) const
Const access the i&#39;th element. No range check is performed!
Definition: Property.hh:449
virtual void set_persistent(bool _yn)
Definition: Property.hh:250
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:347
virtual size_t size_of() const
Return size of property in bytes.
Definition: Property.hh:257
Base property handle.
Definition: Property.hh:466
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:256
Default property class for any type T.
Definition: Property.hh:89
STL namespace.
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:178
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:126
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:188
PropertyT(const std::string &_name="<unknown>")
Default constructor.
Definition: Property.hh:102
virtual size_t size_of() const
Return size of property in bytes.
PropertyT< value_type > * clone() const
Return a deep copy of self.
Definition: Property.hh:454
const T * data() const
Get pointer to array (does not work for T==bool)
Definition: Property.hh:169
Base class for all handle types.
Definition: Handles.hh:62
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:443
virtual void resize(size_t _n)
Resize storage to hold n elements.
Definition: Property.hh:404
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:127
virtual size_t restore(std::istream &_istr, bool _swap)
Definition: Property.hh:156
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:255
virtual size_t size_of(size_t _n_elem) const
Definition: Property.hh:143
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:418
const_reference operator[](int _idx) const
Const access to the i&#39;th element. No range check is performed!
Definition: Property.hh:195
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:239
virtual void set_persistent(bool _yn)
Definition: Property.hh:123
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:410
size_t store(std::ostream &_ostr, bool _swap) const
Store self as one binary block. Max. length of a string is 65535 bytes.
Definition: Property.hh:427
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:245
virtual size_t size_of(size_t _n_elem) const
Definition: Property.hh:258
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:118
const_reference operator[](int _idx) const
Const access to the i&#39;th element. No range check is performed!
Definition: Property.hh:359
virtual size_t store(std::ostream &_ostr, bool _swap) const
Store self as one binary block.
Definition: Property.hh:146
virtual void resize(size_t _n)
Resize storage to hold n elements.
Definition: Property.hh:240
virtual void set_persistent(bool _yn)
Definition: Property.hh:415
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:112