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  explicit PropertyT(
103  const std::string& _name = "<unknown>",
104  const std::string& _internal_type_name = "<unknown>")
105  : BaseProperty(_name, _internal_type_name)
106  {}
107 
109  PropertyT(const PropertyT & _rhs)
110  : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
111 
112 public: // inherited from BaseProperty
113 
114  virtual void reserve(size_t _n) override { data_.reserve(_n); }
115  virtual void resize(size_t _n) override { data_.resize(_n); }
116  virtual void clear() override { data_.clear(); vector_type().swap(data_); }
117  virtual void push_back() override { data_.push_back(T()); }
118  virtual void swap(size_t _i0, size_t _i1) override
119  { std::swap(data_[_i0], data_[_i1]); }
120  virtual void copy(size_t _i0, size_t _i1) override
121  { data_[_i1] = data_[_i0]; }
122 
123 public:
124 
125  virtual void set_persistent( bool _yn ) override
126  { check_and_set_persistent<T>( _yn ); }
127 
128  virtual size_t n_elements() const override { return data_.size(); }
129  virtual size_t element_size() const override { return IO::size_of<T>(); }
130 
131 #ifndef DOXY_IGNORE_THIS
132  struct plus {
133  size_t operator () ( size_t _b, const T& _v )
134  { return _b + IO::size_of<T>(_v); }
135  };
136 #endif
137 
138  virtual size_t size_of(void) const override
139  {
140  if (element_size() != IO::UnknownSize)
141  return this->BaseProperty::size_of(n_elements());
142  return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
143  }
144 
145  virtual size_t size_of(size_t _n_elem) const override
146  { return this->BaseProperty::size_of(_n_elem); }
147 
148  virtual size_t store( std::ostream& _ostr, bool _swap ) const override
149  {
150  if ( IO::is_streamable<vector_type>() )
151  return IO::store(_ostr, data_, _swap );
152  size_t bytes = 0;
153  for (size_t i=0; i<n_elements(); ++i)
154  bytes += IO::store( _ostr, data_[i], _swap );
155  return bytes;
156  }
157 
158  virtual size_t restore( std::istream& _istr, bool _swap ) override
159  {
160  if ( IO::is_streamable<vector_type>() )
161  return IO::restore(_istr, data_, _swap );
162  size_t bytes = 0;
163  for (size_t i=0; i<n_elements(); ++i)
164  bytes += IO::restore( _istr, data_[i], _swap );
165  return bytes;
166  }
167 
168 public: // data access interface
169 
171  const T* data() const {
172 
173  if( data_.empty() )
174  return 0;
175 
176  return &data_[0];
177  }
178 
180  vector_type& data_vector() {
181  return data_;
182  }
183 
185  const vector_type& data_vector() const {
186  return data_;
187  }
188 
190  reference operator[](int _idx)
191  {
192  assert( size_t(_idx) < data_.size() );
193  return data_[_idx];
194  }
195 
197  const_reference operator[](int _idx) const
198  {
199  assert( size_t(_idx) < data_.size());
200  return data_[_idx];
201  }
202 
204  PropertyT<T>* clone() const override
205  {
206  PropertyT<T>* p = new PropertyT<T>( *this );
207  return p;
208  }
209 
210 
211 private:
212 
213  vector_type data_;
214 };
215 
216 //-----------------------------------------------------------------------------
217 
218 
223 template <>
224 class PropertyT<bool> : public BaseProperty
225 {
226 public:
227 
228  typedef std::vector<bool> vector_type;
229  typedef bool value_type;
230  typedef vector_type::reference reference;
231  typedef vector_type::const_reference const_reference;
232 
233 public:
234 
235  explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
236  : BaseProperty(_name, _internal_type_name)
237  { }
238 
239 public: // inherited from BaseProperty
240 
241  virtual void reserve(size_t _n) override { data_.reserve(_n); }
242  virtual void resize(size_t _n) override { data_.resize(_n); }
243  virtual void clear() override { data_.clear(); vector_type().swap(data_); }
244  virtual void push_back() override { data_.push_back(bool()); }
245  virtual void swap(size_t _i0, size_t _i1) override
246  { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
247  virtual void copy(size_t _i0, size_t _i1) override
248  { data_[_i1] = data_[_i0]; }
249 
250 public:
251 
252  virtual void set_persistent( bool _yn ) override
253  {
254  check_and_set_persistent<bool>( _yn );
255  }
256 
257  virtual size_t n_elements() const override { return data_.size(); }
258  virtual size_t element_size() const override { return UnknownSize; }
259  virtual size_t size_of() const override { return size_of( n_elements() ); }
260  virtual size_t size_of(size_t _n_elem) const override
261  {
262  return _n_elem / 8 + ((_n_elem % 8)!=0);
263  }
264 
265  size_t store( std::ostream& _ostr, bool /* _swap */ ) const override
266  {
267  size_t bytes = 0;
268 
269  size_t N = data_.size() / 8;
270  size_t R = data_.size() % 8;
271 
272  size_t idx; // element index
273  size_t bidx;
274  unsigned char bits; // bitset
275 
276  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
277  {
278  bits = static_cast<unsigned char>(data_[bidx])
279  | (static_cast<unsigned char>(data_[bidx+1]) << 1)
280  | (static_cast<unsigned char>(data_[bidx+2]) << 2)
281  | (static_cast<unsigned char>(data_[bidx+3]) << 3)
282  | (static_cast<unsigned char>(data_[bidx+4]) << 4)
283  | (static_cast<unsigned char>(data_[bidx+5]) << 5)
284  | (static_cast<unsigned char>(data_[bidx+6]) << 6)
285  | (static_cast<unsigned char>(data_[bidx+7]) << 7);
286  _ostr << bits;
287  }
288  bytes = N;
289 
290  if (R)
291  {
292  bits = 0;
293  for (idx=0; idx < R; ++idx)
294  bits |= static_cast<unsigned char>(data_[bidx+idx]) << idx;
295  _ostr << bits;
296  ++bytes;
297  }
298 
299  assert( bytes == size_of() );
300 
301  return bytes;
302  }
303 
304  size_t restore( std::istream& _istr, bool /* _swap */ ) override
305  {
306  size_t bytes = 0;
307 
308  size_t N = data_.size() / 8;
309  size_t R = data_.size() % 8;
310 
311  size_t idx; // element index
312  size_t bidx; //
313  unsigned char bits; // bitset
314 
315  for (bidx=idx=0; idx < N; ++idx, bidx+=8)
316  {
317  _istr >> bits;
318  data_[bidx+0] = (bits & 0x01) != 0;
319  data_[bidx+1] = (bits & 0x02) != 0;
320  data_[bidx+2] = (bits & 0x04) != 0;
321  data_[bidx+3] = (bits & 0x08) != 0;
322  data_[bidx+4] = (bits & 0x10) != 0;
323  data_[bidx+5] = (bits & 0x20) != 0;
324  data_[bidx+6] = (bits & 0x40) != 0;
325  data_[bidx+7] = (bits & 0x80) != 0;
326  }
327  bytes = N;
328 
329  if (R)
330  {
331  _istr >> bits;
332  for (idx=0; idx < R; ++idx)
333  data_[bidx+idx] = (bits & (1<<idx)) != 0;
334  ++bytes;
335  }
336 
337  return bytes;
338  }
339 
340 
341 public:
342 
344  vector_type& data_vector() {
345  return data_;
346  }
347 
349  const vector_type& data_vector() const {
350  return data_;
351  }
352 
354  reference operator[](int _idx)
355  {
356  assert( size_t(_idx) < data_.size() );
357  return data_[_idx];
358  }
359 
361  const_reference operator[](int _idx) const
362  {
363  assert( size_t(_idx) < data_.size());
364  return data_[_idx];
365  }
366 
368  PropertyT<bool>* clone() const override
369  {
370  PropertyT<bool>* p = new PropertyT<bool>( *this );
371  return p;
372  }
373 
374 
375 private:
376 
377  vector_type data_;
378 };
379 
380 
381 //-----------------------------------------------------------------------------
382 
383 
386 template <>
387 class PropertyT<std::string> : public BaseProperty
388 {
389 public:
390 
391  typedef std::string Value;
392  typedef std::vector<std::string> vector_type;
393  typedef std::string value_type;
394  typedef vector_type::reference reference;
395  typedef vector_type::const_reference const_reference;
396 
397 public:
398 
399  explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
400  : BaseProperty(_name, _internal_type_name)
401  { }
402 
403 public: // inherited from BaseProperty
404 
405  virtual void reserve(size_t _n) override { data_.reserve(_n); }
406  virtual void resize(size_t _n) override { data_.resize(_n); }
407  virtual void clear() override { data_.clear(); vector_type().swap(data_); }
408  virtual void push_back() override { data_.push_back(std::string()); }
409  virtual void swap(size_t _i0, size_t _i1) override {
410  std::swap(data_[_i0], data_[_i1]);
411  }
412  virtual void copy(size_t _i0, size_t _i1) override
413  { data_[_i1] = data_[_i0]; }
414 
415 public:
416 
417  virtual void set_persistent( bool _yn ) override
418  { check_and_set_persistent<std::string>( _yn ); }
419 
420  virtual size_t n_elements() const override { return data_.size(); }
421  virtual size_t element_size() const override { return UnknownSize; }
422  virtual size_t size_of() const override
423  { return IO::size_of( data_ ); }
424 
425  virtual size_t size_of(size_t /* _n_elem */) const override
426  { return UnknownSize; }
427 
429  size_t store( std::ostream& _ostr, bool _swap ) const override
430  { return IO::store( _ostr, data_, _swap ); }
431 
432  size_t restore( std::istream& _istr, bool _swap ) override
433  { return IO::restore( _istr, data_, _swap ); }
434 
435 public:
436 
437  const value_type* data() const {
438  if( data_.empty() )
439  return nullptr;
440 
441  return (value_type*) &data_[0];
442  }
443 
445  reference operator[](int _idx) {
446  assert( size_t(_idx) < data_.size());
447  return ((value_type*) &data_[0])[_idx];
448  }
449 
451  const_reference operator[](int _idx) const {
452  assert( size_t(_idx) < data_.size());
453  return ((value_type*) &data_[0])[_idx];
454  }
455 
456  PropertyT<value_type>* clone() const override {
458  return p;
459  }
460 private:
461 
462  vector_type data_;
463 
464 };
465 
467 template <class T>
469 {
470  typedef T Value;
471  typedef std::vector<T> vector_type;
472  typedef T value_type;
473  typedef typename vector_type::reference reference;
474  typedef typename vector_type::const_reference const_reference;
475 
476  explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
477 };
478 
479 
483 template <class T>
484 struct VPropHandleT : public BasePropHandleT<T>
485 {
486  typedef T Value;
487  typedef T value_type;
488  typedef VertexHandle Handle;
489 
490  explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
491  explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
492 };
493 
494 
498 template <class T>
499 struct HPropHandleT : public BasePropHandleT<T>
500 {
501  typedef T Value;
502  typedef T value_type;
503  typedef HalfedgeHandle Handle;
504 
505  explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
506  explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
507 };
508 
509 
513 template <class T>
514 struct EPropHandleT : public BasePropHandleT<T>
515 {
516  typedef T Value;
517  typedef T value_type;
518  typedef EdgeHandle Handle;
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  typedef FaceHandle Handle;
534 
535  explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
536  explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
537 };
538 
539 
543 template <class T>
544 struct MPropHandleT : public BasePropHandleT<T>
545 {
546  typedef T Value;
547  typedef T value_type;
548  typedef MeshHandle Handle;
549 
550  explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
551  explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
552 };
553 
554 template <typename HandleT>
555 struct PropHandle;
556 
557 template <>
559  template <typename T>
560  using type = VPropHandleT<T>;
561 };
562 
563 template <>
565  template <typename T>
566  using type = HPropHandleT<T>;
567 };
568 
569 template <>
571  template <typename T>
572  using type = EPropHandleT<T>;
573 };
574 
575 template <>
577  template <typename T>
578  using type = FPropHandleT<T>;
579 };
580 
581 } // namespace OpenMesh
582 //=============================================================================
583 #endif // OPENMESH_PROPERTY_HH defined
584 //=============================================================================
virtual void push_back() override
Extend the number of elements by one.
Definition: Property.hh:117
Handle for a edge entity.
Definition: Handles.hh:134
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:445
Handle for a face entity.
Definition: Handles.hh:141
size_t store(std::ostream &_ostr, bool _swap) const override
Store self as one binary block. Max. length of a string is 65535 bytes.
Definition: Property.hh:429
virtual size_t size_of() const override
Return size of property in bytes.
Definition: Property.hh:422
PropertyT< T > * clone() const override
Make a copy of self.
Definition: Property.hh:204
Handle type for meshes to simplify some template programming.
Definition: Handles.hh:148
virtual void copy(size_t _i0, size_t _i1) override
Copy one element to another.
Definition: Property.hh:412
size_t size_of(const T &_v)
Definition: StoreRestore.hh:89
virtual size_t size_of(size_t) const override
Definition: Property.hh:425
virtual void copy(size_t _i0, size_t _i1) override
Copy one element to another.
Definition: Property.hh:120
Base property handle.
Definition: Property.hh:468
const_reference operator[](int _idx) const
Const access the i&#39;th element. No range check is performed!
Definition: Property.hh:451
Handle for a halfedge entity.
Definition: Handles.hh:127
BaseProperty(const std::string &_name="<unknown>", const std::string &_internal_type_name="<unknown>")
Default constructor.
Definition: BaseProperty.hh:83
const_reference operator[](int _idx) const
Const access to the i&#39;th element. No range check is performed!
Definition: Property.hh:361
STL namespace.
virtual void resize(size_t _n) override
Resize storage to hold n elements.
Definition: Property.hh:406
virtual void reserve(size_t _n) override
Reserve memory for n elements.
Definition: Property.hh:114
virtual void reserve(size_t _n) override
Reserve memory for n elements.
Definition: Property.hh:241
virtual void resize(size_t _n) override
Resize storage to hold n elements.
Definition: Property.hh:115
virtual size_t size_of(size_t _n_elem) const override
Definition: Property.hh:145
Base class for all handle types.
Definition: Handles.hh:62
Handle for a vertex entity.
Definition: Handles.hh:120
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:190
virtual void resize(size_t _n) override
Resize storage to hold n elements.
Definition: Property.hh:242
virtual void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
Definition: Property.hh:409
virtual void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
Definition: Property.hh:245
size_t restore(std::istream &_istr, bool) override
Definition: Property.hh:304
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:344
virtual size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:129
virtual size_t size_of(size_t _n_elem) const override
Definition: Property.hh:260
virtual void clear() override
Clear all elements and free memory.
Definition: Property.hh:243
virtual void set_persistent(bool _yn) override
Definition: Property.hh:125
Default property class for any type T.
Definition: Property.hh:89
virtual void clear() override
Clear all elements and free memory.
Definition: Property.hh:407
virtual size_t n_elements() const override
Number of elements in property.
Definition: Property.hh:420
virtual void set_persistent(bool _yn) override
Definition: Property.hh:252
virtual size_t size_of() const
Return size of property in bytes.
const T * data() const
Get pointer to array (does not work for T==bool)
Definition: Property.hh:171
const_reference operator[](int _idx) const
Const access to the i&#39;th element. No range check is performed!
Definition: Property.hh:197
virtual void push_back() override
Extend the number of elements by one.
Definition: Property.hh:408
virtual void copy(size_t _i0, size_t _i1) override
Copy one element to another.
Definition: Property.hh:247
virtual size_t size_of() const override
Return size of property in bytes.
Definition: Property.hh:259
size_t restore(std::istream &_istr, bool _swap) override
Definition: Property.hh:432
virtual void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
Definition: Property.hh:118
virtual size_t store(std::ostream &_ostr, bool _swap) const override
Store self as one binary block.
Definition: Property.hh:148
virtual size_t n_elements() const override
Number of elements in property.
Definition: Property.hh:128
virtual void set_persistent(bool _yn) override
Definition: Property.hh:417
virtual size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:258
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:349
virtual size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:421
virtual size_t n_elements() const override
Number of elements in property.
Definition: Property.hh:257
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:65
virtual size_t restore(std::istream &_istr, bool _swap) override
Definition: Property.hh:158
virtual void push_back() override
Extend the number of elements by one.
Definition: Property.hh:244
virtual void reserve(size_t _n) override
Reserve memory for n elements.
Definition: Property.hh:405
PropertyT< value_type > * clone() const override
Return a deep copy of self.
Definition: Property.hh:456
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:180
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:185
virtual size_t size_of(void) const override
Return size of property in bytes.
Definition: Property.hh:138
size_t store(std::ostream &_ostr, bool) const override
Store self as one binary block.
Definition: Property.hh:265
PropertyT(const std::string &_name="<unknown>", const std::string &_internal_type_name="<unknown>")
Default constructor.
Definition: Property.hh:102
PropertyT(const PropertyT &_rhs)
Copy constructor.
Definition: Property.hh:109
PropertyT< bool > * clone() const override
Make a copy of self.
Definition: Property.hh:368
virtual void clear() override
Clear all elements and free memory.
Definition: Property.hh:116
reference operator[](int _idx)
Access the i&#39;th element. No range check is performed!
Definition: Property.hh:354