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  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 #ifndef OPENMESH_PROPERTY_HH
50 #define OPENMESH_PROPERTY_HH
51 
52 
53 //== INCLUDES =================================================================
54 
55 
57 #include <OpenMesh/Core/Mesh/Handles.hh>
58 #include <OpenMesh/Core/Utils/BaseProperty.hh>
59 #include <vector>
60 #include <string>
61 #include <algorithm>
62 
63 
64 //== NAMESPACES ===============================================================
65 
66 namespace OpenMesh {
67 
68 //== CLASS DEFINITION =========================================================
69 
88 // TODO: it might be possible to define Property using kind of a runtime info
89 // structure holding the size of T. Then reserve, swap, resize, etc can be written
90 // in pure malloc() style w/o virtual overhead. Template member function proved per
91 // element access to the properties, asserting dynamic_casts in debug
92 
93 template <class T>
94 class PropertyT : public BaseProperty
95 {
96 public:
97 
98  typedef T Value;
99  typedef std::vector<T> vector_type;
100  typedef T value_type;
101  typedef typename vector_type::reference reference;
102  typedef typename vector_type::const_reference const_reference;
103 
104 public:
105 
107  PropertyT(const std::string& _name = "<unknown>")
108  : BaseProperty(_name)
109  {}
110 
112  PropertyT(const PropertyT & _rhs)
113  : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
114 
115 public: // inherited from BaseProperty
116 
117  virtual void reserve(size_t _n) { data_.reserve(_n); }
118  virtual void resize(size_t _n) { data_.resize(_n); }
119  virtual void clear() { data_.clear(); vector_type().swap(data_); }
120  virtual void push_back() { data_.push_back(T()); }
121  virtual void swap(size_t _i0, size_t _i1)
122  { std::swap(data_[_i0], data_[_i1]); }
123  virtual void copy(size_t _i0, size_t _i1)
124  { data_[_i1] = data_[_i0]; }
125 
126 public:
127 
128  virtual void set_persistent( bool _yn )
129  { check_and_set_persistent<T>( _yn ); }
130 
131  virtual size_t n_elements() const { return data_.size(); }
132  virtual size_t element_size() const { return IO::size_of<T>(); }
133 
134 #ifndef DOXY_IGNORE_THIS
135  struct plus {
136  size_t operator () ( size_t _b, const T& _v )
137  { return _b + IO::size_of<T>(_v); }
138  };
139 #endif
140 
141  virtual size_t size_of(void) const
142  {
143  if (element_size() != IO::UnknownSize)
144  return this->BaseProperty::size_of(n_elements());
145  return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
146  }
147 
148  virtual size_t size_of(size_t _n_elem) const
149  { return this->BaseProperty::size_of(_n_elem); }
150 
151  virtual size_t store( std::ostream& _ostr, bool _swap ) const
152  {
153  if ( IO::is_streamable<vector_type>() )
154  return IO::store(_ostr, data_, _swap );
155  size_t bytes = 0;
156  for (size_t i=0; i<n_elements(); ++i)
157  bytes += IO::store( _ostr, data_[i], _swap );
158  return bytes;
159  }
160 
161  virtual size_t restore( std::istream& _istr, bool _swap )
162  {
163  if ( IO::is_streamable<vector_type>() )
164  return IO::restore(_istr, data_, _swap );
165  size_t bytes = 0;
166  for (size_t i=0; i<n_elements(); ++i)
167  bytes += IO::restore( _istr, data_[i], _swap );
168  return bytes;
169  }
170 
171 public: // data access interface
172 
174  const T* data() const {
175 
176  if( data_.empty() )
177  return 0;
178 
179  return &data_[0];
180  }
181 
183  vector_type& data_vector() {
184  return data_;
185  }
186 
188  const vector_type& data_vector() const {
189  return data_;
190  }
191 
193  reference operator[](int _idx)
194  {
195  assert( size_t(_idx) < data_.size() );
196  return data_[_idx];
197  }
198 
200  const_reference operator[](int _idx) const
201  {
202  assert( size_t(_idx) < data_.size());
203  return data_[_idx];
204  }
205 
208  {
209  PropertyT<T>* p = new PropertyT<T>( *this );
210  return p;
211  }
212 
213 
214 private:
215 
216  vector_type data_;
217 };
218 
219 //-----------------------------------------------------------------------------
220 
221 
226 template <>
227 class PropertyT<bool> : public BaseProperty
228 {
229 public:
230 
231  typedef std::vector<bool> vector_type;
232  typedef bool value_type;
233  typedef vector_type::reference reference;
234  typedef vector_type::const_reference const_reference;
235 
236 public:
237 
238  PropertyT(const std::string& _name = "<unknown>")
239  : BaseProperty(_name)
240  { }
241 
242 public: // inherited from BaseProperty
243 
244  virtual void reserve(size_t _n) { data_.reserve(_n); }
245  virtual void resize(size_t _n) { data_.resize(_n); }
246  virtual void clear() { data_.clear(); vector_type().swap(data_); }
247  virtual void push_back() { data_.push_back(bool()); }
248  virtual void swap(size_t _i0, size_t _i1)
249  { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
250  virtual void copy(size_t _i0, size_t _i1)
251  { data_[_i1] = data_[_i0]; }
252 
253 public:
254 
255  virtual void set_persistent( bool _yn )
256  {
257  check_and_set_persistent<bool>( _yn );
258  }
259 
260  virtual size_t n_elements() const { return data_.size(); }
261  virtual size_t element_size() const { return UnknownSize; }
262  virtual size_t size_of() const { return size_of( n_elements() ); }
263  virtual size_t size_of(size_t _n_elem) const
264  {
265  return _n_elem / 8 + ((_n_elem % 8)!=0);
266  }
267 
268  size_t store( std::ostream& _ostr, bool /* _swap */ ) const
269  {
270  size_t bytes = 0;
271 
272  size_t N = data_.size() / 8;
273  size_t R = data_.size() % 8;
274 
275  size_t idx; // element index
276  size_t bidx;
277  unsigned char bits; // bitset
278 
279  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
280  {
281  bits = static_cast<unsigned char>(data_[bidx])
282  | (static_cast<unsigned char>(data_[bidx+1]) << 1)
283  | (static_cast<unsigned char>(data_[bidx+2]) << 2)
284  | (static_cast<unsigned char>(data_[bidx+3]) << 3)
285  | (static_cast<unsigned char>(data_[bidx+4]) << 4)
286  | (static_cast<unsigned char>(data_[bidx+5]) << 5)
287  | (static_cast<unsigned char>(data_[bidx+6]) << 6)
288  | (static_cast<unsigned char>(data_[bidx+7]) << 7);
289  _ostr << bits;
290  }
291  bytes = N;
292 
293  if (R)
294  {
295  bits = 0;
296  for (idx=0; idx < R; ++idx)
297  bits |= static_cast<unsigned char>(data_[bidx+idx]) << idx;
298  _ostr << bits;
299  ++bytes;
300  }
301 
302  assert( bytes == size_of() );
303 
304  return bytes;
305  }
306 
307  size_t restore( std::istream& _istr, bool /* _swap */ )
308  {
309  size_t bytes = 0;
310 
311  size_t N = data_.size() / 8;
312  size_t R = data_.size() % 8;
313 
314  size_t idx; // element index
315  size_t bidx; //
316  unsigned char bits; // bitset
317 
318  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
319  {
320  _istr >> bits;
321  data_[bidx+0] = (bits & 0x01) != 0;
322  data_[bidx+1] = (bits & 0x02) != 0;
323  data_[bidx+2] = (bits & 0x04) != 0;
324  data_[bidx+3] = (bits & 0x08) != 0;
325  data_[bidx+4] = (bits & 0x10) != 0;
326  data_[bidx+5] = (bits & 0x20) != 0;
327  data_[bidx+6] = (bits & 0x40) != 0;
328  data_[bidx+7] = (bits & 0x80) != 0;
329  }
330  bytes = N;
331 
332  if (R)
333  {
334  _istr >> bits;
335  for (idx=0; idx < R; ++idx)
336  data_[bidx+idx] = (bits & (1<<idx)) != 0;
337  ++bytes;
338  }
339 
340  return bytes;
341  }
342 
343 
344 public:
345 
347  vector_type& data_vector() {
348  return data_;
349  }
350 
352  const vector_type& data_vector() const {
353  return data_;
354  }
355 
357  reference operator[](int _idx)
358  {
359  assert( size_t(_idx) < data_.size() );
360  return data_[_idx];
361  }
362 
364  const_reference operator[](int _idx) const
365  {
366  assert( size_t(_idx) < data_.size());
367  return data_[_idx];
368  }
369 
372  {
373  PropertyT<bool>* p = new PropertyT<bool>( *this );
374  return p;
375  }
376 
377 
378 private:
379 
380  vector_type data_;
381 };
382 
383 
384 //-----------------------------------------------------------------------------
385 
386 
389 template <>
390 class PropertyT<std::string> : public BaseProperty
391 {
392 public:
393 
394  typedef std::string Value;
395  typedef std::vector<std::string> vector_type;
396  typedef std::string value_type;
397  typedef vector_type::reference reference;
398  typedef vector_type::const_reference const_reference;
399 
400 public:
401 
402  PropertyT(const std::string& _name = "<unknown>")
403  : BaseProperty(_name)
404  { }
405 
406 public: // inherited from BaseProperty
407 
408  virtual void reserve(size_t _n) { data_.reserve(_n); }
409  virtual void resize(size_t _n) { data_.resize(_n); }
410  virtual void clear() { data_.clear(); vector_type().swap(data_); }
411  virtual void push_back() { data_.push_back(std::string()); }
412  virtual void swap(size_t _i0, size_t _i1) {
413  std::swap(data_[_i0], data_[_i1]);
414  }
415  virtual void copy(size_t _i0, size_t _i1)
416  { data_[_i1] = data_[_i0]; }
417 
418 public:
419 
420  virtual void set_persistent( bool _yn )
421  { check_and_set_persistent<std::string>( _yn ); }
422 
423  virtual size_t n_elements() const { return data_.size(); }
424  virtual size_t element_size() const { return UnknownSize; }
425  virtual size_t size_of() const
426  { return IO::size_of( data_ ); }
427 
428  virtual size_t size_of(size_t /* _n_elem */) const
429  { return UnknownSize; }
430 
432  size_t store( std::ostream& _ostr, bool _swap ) const
433  { return IO::store( _ostr, data_, _swap ); }
434 
435  size_t restore( std::istream& _istr, bool _swap )
436  { return IO::restore( _istr, data_, _swap ); }
437 
438 public:
439 
440  const value_type* data() const {
441  if( data_.empty() )
442  return 0;
443 
444  return (value_type*) &data_[0];
445  }
446 
448  reference operator[](int _idx) {
449  assert( size_t(_idx) < data_.size());
450  return ((value_type*) &data_[0])[_idx];
451  }
452 
454  const_reference operator[](int _idx) const {
455  assert( size_t(_idx) < data_.size());
456  return ((value_type*) &data_[0])[_idx];
457  }
458 
461  return p;
462  }
463 private:
464 
465  vector_type data_;
466 
467 };
468 
470 template <class T>
472 {
473  typedef T Value;
474  typedef std::vector<T> vector_type;
475  typedef T value_type;
476  typedef typename vector_type::reference reference;
477  typedef typename vector_type::const_reference const_reference;
478 
479  explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
480 };
481 
482 
486 template <class T>
487 struct VPropHandleT : public BasePropHandleT<T>
488 {
489  typedef T Value;
490  typedef T value_type;
491 
492  explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
493  explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
494 };
495 
496 
500 template <class T>
501 struct HPropHandleT : public BasePropHandleT<T>
502 {
503  typedef T Value;
504  typedef T value_type;
505 
506  explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
507  explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
508 };
509 
510 
514 template <class T>
515 struct EPropHandleT : public BasePropHandleT<T>
516 {
517  typedef T Value;
518  typedef T value_type;
519 
520  explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
521  explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
522 };
523 
524 
528 template <class T>
529 struct FPropHandleT : public BasePropHandleT<T>
530 {
531  typedef T Value;
532  typedef T value_type;
533 
534  explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
535  explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
536 };
537 
538 
542 template <class T>
543 struct MPropHandleT : public BasePropHandleT<T>
544 {
545  typedef T Value;
546  typedef T value_type;
547 
548  explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
549  explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
550 };
551 
552 } // namespace OpenMesh
553 //=============================================================================
554 #endif // OPENMESH_PROPERTY_HH defined
555 //=============================================================================
PropertyT< value_type > * clone() const
Return a deep copy of self.
Definition: Property.hh:459
virtual size_t size_of(size_t) const
Definition: Property.hh:428
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:193
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:131
const_reference operator[](int _idx) const
Const access to the i&#39;th element. No range check is performed!
Definition: Property.hh:364
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:244
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:183
virtual void resize(size_t _n)
Resize storage to hold n elements.
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:200
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:357
size_t restore(std::istream &_istr, bool _swap)
Definition: Property.hh:435
virtual size_t size_of(size_t _n_elem) const
Definition: Property.hh:148
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:423
PropertyT< T > * clone() const
Make a copy of self.
Definition: Property.hh:207
virtual void resize(size_t _n)
Resize storage to hold n elements.
Definition: Property.hh:409
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:415
PropertyT(const PropertyT &_rhs)
Copy constructor.
Definition: Property.hh:112
Default property class for any type T.
Definition: Property.hh:94
virtual size_t size_of() const
Return size of property in bytes.
Definition: Property.hh:262
PropertyT(const std::string &_name="<unknown>")
Default constructor.
Definition: Property.hh:107
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:411
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:248
virtual size_t size_of() const
Return size of property in bytes.
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:448
size_t size_of(const T &_v)
Definition: StoreRestore.hh:94
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:250
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:352
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:261
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:424
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:246
PropertyT< bool > * clone() const
Make a copy of self.
Definition: Property.hh:371
virtual void copy(size_t _i0, size_t _i1)
Copy one element to another.
Definition: Property.hh:123
virtual size_t store(std::ostream &_ostr, bool _swap) const
Store self as one binary block.
Definition: Property.hh:151
const T * data() const
Get pointer to array (does not work for T==bool)
Definition: Property.hh:174
virtual size_t size_of() const
Return size of property in bytes.
Definition: Property.hh:425
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:247
virtual size_t size_of(size_t _n_elem) const
Definition: Property.hh:263
virtual void set_persistent(bool _yn)
Definition: Property.hh:420
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:70
virtual size_t restore(std::istream &_istr, bool _swap)
Definition: Property.hh:161
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:188
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:119
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:117
virtual size_t n_elements() const
Number of elements in property.
Definition: Property.hh:260
size_t store(std::ostream &_ostr, bool) const
Store self as one binary block.
Definition: Property.hh:268
Base property handle.
Definition: Property.hh:471
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:432
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:132
size_t restore(std::istream &_istr, bool)
Definition: Property.hh:307
STL namespace.
virtual void reserve(size_t _n)
Reserve memory for n elements.
Definition: Property.hh:408
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:121
const_reference operator[](int _idx) const
Const access the i&#39;th element. No range check is performed!
Definition: Property.hh:454
Base class for all handle types.
Definition: Handles.hh:67
virtual void push_back()
Extend the number of elements by one.
Definition: Property.hh:120
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:347
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Definition: Property.hh:412
virtual void set_persistent(bool _yn)
Definition: Property.hh:255
BaseProperty(const std::string &_name="<unknown>")
Default constructor.
Definition: BaseProperty.hh:88
virtual void resize(size_t _n)
Resize storage to hold n elements.
Definition: Property.hh:245
virtual void set_persistent(bool _yn)
Definition: Property.hh:128
virtual size_t size_of(void) const
Return size of property in bytes.
Definition: Property.hh:141
virtual void clear()
Clear all elements and free memory.
Definition: Property.hh:410