OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Property.hh
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
5 * www.openmesh.org *
6 * *
7 *---------------------------------------------------------------------------*
8 * This file is part of OpenMesh. *
9 * *
10 * OpenMesh is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenMesh is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenMesh. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34
35 /*===========================================================================*\
36 * *
37 * $Revision: 736 $ *
38 * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08 Okt 2012) $ *
39 * *
40 \*===========================================================================*/
41
42 #ifndef OPENMESH_PROPERTY_HH
43 #define OPENMESH_PROPERTY_HH
44
45
46 //== INCLUDES =================================================================
47
48
49 #include <OpenMesh/Core/System/config.h>
50 #include <OpenMesh/Core/Mesh/Handles.hh>
51 #include <OpenMesh/Core/Utils/BaseProperty.hh>
52 #include <vector>
53 #include <string>
54 #include <algorithm>
55
56
57 //== NAMESPACES ===============================================================
58
59 namespace OpenMesh {
60
61 //== CLASS DEFINITION =========================================================
62
81 // TODO: it might be possible to define Property using kind of a runtime info
82 // structure holding the size of T. Then reserve, swap, resize, etc can be written
83 // in pure malloc() style w/o virtual overhead. Template member function proved per
84 // element access to the properties, asserting dynamic_casts in debug
85
86 template <class T>
87 class PropertyT : public BaseProperty
88 {
89 public:
90
91 typedef T Value;
92 typedef std::vector<T> vector_type;
93 typedef T value_type;
94 typedef typename vector_type::reference reference;
95 typedef typename vector_type::const_reference const_reference;
96
97 public:
98
100 PropertyT(const std::string& _name = "<unknown>")
101 : BaseProperty(_name)
102 {}
103
105 PropertyT(const PropertyT & _rhs)
106 : BaseProperty( _rhs ), data_( _rhs.data_ ) {}
107
108 public: // inherited from BaseProperty
109
110 virtual void reserve(size_t _n) { data_.reserve(_n); }
111 virtual void resize(size_t _n) { data_.resize(_n); }
112 virtual void clear() { data_.clear(); vector_type().swap(data_); }
113 virtual void push_back() { data_.push_back(T()); }
114 virtual void swap(size_t _i0, size_t _i1)
115 { std::swap(data_[_i0], data_[_i1]); }
116 virtual void copy(size_t _i0, size_t _i1)
117 { data_[_i1] = data_[_i0]; }
118
119 public:
120
121 virtual void set_persistent( bool _yn )
122 { check_and_set_persistent<T>( _yn ); }
123
124 virtual size_t n_elements() const { return data_.size(); }
125 virtual size_t element_size() const { return IO::size_of<T>(); }
126
127 #ifndef DOXY_IGNORE_THIS
128 struct plus {
129 size_t operator () ( size_t _b, const T& _v )
130 { return _b + IO::size_of<T>(_v); }
131 };
132 #endif
133
134 virtual size_t size_of(void) const
135 {
136 if (element_size() != IO::UnknownSize)
137 return this->BaseProperty::size_of(n_elements());
138 return std::accumulate(data_.begin(), data_.end(), 0, plus());
139 }
140
141 virtual size_t size_of(size_t _n_elem) const
142 { return this->BaseProperty::size_of(_n_elem); }
143
144 virtual size_t store( std::ostream& _ostr, bool _swap ) const
145 {
146 if ( IO::is_streamable<vector_type>() )
147 return IO::store(_ostr, data_, _swap );
148 size_t bytes = 0;
149 for (size_t i=0; i<n_elements(); ++i)
150 bytes += IO::store( _ostr, data_[i], _swap );
151 return bytes;
152 }
153
154 virtual size_t restore( std::istream& _istr, bool _swap )
155 {
156 if ( IO::is_streamable<vector_type>() )
157 return IO::restore(_istr, data_, _swap );
158 size_t bytes = 0;
159 for (size_t i=0; i<n_elements(); ++i)
160 bytes += IO::restore( _istr, data_[i], _swap );
161 return bytes;
162 }
163
164 public: // data access interface
165
167 const T* data() const {
168
169 if( data_.empty() )
170 return 0;
171
172 return &data_[0];
173 }
174
176 vector_type& data_vector() {
177
178 return data_;
179 }
180
182 reference operator[](int _idx)
183 {
184 assert( size_t(_idx) < data_.size() );
185 return data_[_idx];
186 }
187
189 const_reference operator[](int _idx) const
190 {
191 assert( size_t(_idx) < data_.size());
192 return data_[_idx];
193 }
194
196 PropertyT<T>* clone() const
197 {
198 PropertyT<T>* p = new PropertyT<T>( *this );
199 return p;
200 }
201
202
203 private:
204
205 vector_type data_;
206 };
207
208 //-----------------------------------------------------------------------------
209
210
215 template <>
216 class PropertyT<bool> : public BaseProperty
217 {
218 public:
219
220 typedef std::vector<bool> vector_type;
221 typedef bool value_type;
222 typedef vector_type::reference reference;
223 typedef vector_type::const_reference const_reference;
224
225 public:
226
227 PropertyT(const std::string& _name = "<unknown>")
228 : BaseProperty(_name)
229 { }
230
231 public: // inherited from BaseProperty
232
233 virtual void reserve(size_t _n) { data_.reserve(_n); }
234 virtual void resize(size_t _n) { data_.resize(_n); }
235 virtual void clear() { data_.clear(); vector_type().swap(data_); }
236 virtual void push_back() { data_.push_back(bool()); }
237 virtual void swap(size_t _i0, size_t _i1)
238 { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
239 virtual void copy(size_t _i0, size_t _i1)
240 { data_[_i1] = data_[_i0]; }
241
242 public:
243
244 virtual void set_persistent( bool _yn )
245 {
246 check_and_set_persistent<bool>( _yn );
247 }
248
249 virtual size_t n_elements() const { return data_.size(); }
250 virtual size_t element_size() const { return UnknownSize; }
251 virtual size_t size_of() const { return size_of( n_elements() ); }
252 virtual size_t size_of(size_t _n_elem) const
253 {
254 return _n_elem / 8 + ((_n_elem % 8)!=0);
255 }
256
257 size_t store( std::ostream& _ostr, bool /* _swap */ ) const
258 {
259 size_t bytes = 0;
260
261 size_t N = data_.size() / 8;
262 size_t R = data_.size() % 8;
263
264 size_t idx; // element index
265 size_t bidx;
266 unsigned char bits; // bitset
267
268 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
269 {
270 bits = !!data_[bidx]
271 | (!!data_[bidx+1] << 1)
272 | (!!data_[bidx+2] << 2)
273 | (!!data_[bidx+3] << 3)
274 | (!!data_[bidx+4] << 4)
275 | (!!data_[bidx+5] << 5)
276 | (!!data_[bidx+6] << 6)
277 | (!!data_[bidx+7] << 7);
278 _ostr << bits;
279 }
280 bytes = N;
281
282 if (R)
283 {
284 bits = 0;
285 for (idx=0; idx < R; ++idx)
286 bits |= !!data_[bidx+idx] << idx;
287 _ostr << bits;
288 ++bytes;
289 }
290
291 std::cout << std::endl;
292
293 assert( bytes == size_of() );
294
295 return bytes;
296 }
297
298 size_t restore( std::istream& _istr, bool /* _swap */ )
299 {
300 size_t bytes = 0;
301
302 size_t N = data_.size() / 8;
303 size_t R = data_.size() % 8;
304
305 size_t idx; // element index
306 size_t bidx; //
307 unsigned char bits; // bitset
308
309 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
310 {
311 _istr >> bits;
312 data_[bidx+0] = !!(bits & 0x01);
313 data_[bidx+1] = !!(bits & 0x02);
314 data_[bidx+2] = !!(bits & 0x04);
315 data_[bidx+3] = !!(bits & 0x08);
316 data_[bidx+4] = !!(bits & 0x10);
317 data_[bidx+5] = !!(bits & 0x20);
318 data_[bidx+6] = !!(bits & 0x40);
319 data_[bidx+7] = !!(bits & 0x80);
320 }
321 bytes = N;
322
323 if (R)
324 {
325 _istr >> bits;
326 for (idx=0; idx < R; ++idx)
327 data_[bidx+idx] = !!(bits & (1<<idx));
328 ++bytes;
329 }
330
331 std::cout << std::endl;
332
333 return bytes;
334 }
335
336
337 public:
338
340 vector_type& data_vector() {
341
342 return data_;
343 }
344
346 reference operator[](int _idx)
347 {
348 assert( size_t(_idx) < data_.size() );
349 return data_[_idx];
350 }
351
353 const_reference operator[](int _idx) const
354 {
355 assert( size_t(_idx) < data_.size());
356 return data_[_idx];
357 }
358
360 PropertyT<bool>* clone() const
361 {
362 PropertyT<bool>* p = new PropertyT<bool>( *this );
363 return p;
364 }
365
366
367 private:
368
369 vector_type data_;
370 };
371
372
373 //-----------------------------------------------------------------------------
374
375
378 template <>
379 class PropertyT<std::string> : public BaseProperty
380 {
381 public:
382
383 typedef std::string Value;
384 typedef std::vector<std::string> vector_type;
385 typedef std::string value_type;
386 typedef vector_type::reference reference;
387 typedef vector_type::const_reference const_reference;
388
389 public:
390
391 PropertyT(const std::string& _name = "<unknown>")
392 : BaseProperty(_name)
393 { }
394
395 public: // inherited from BaseProperty
396
397 virtual void reserve(size_t _n) { data_.reserve(_n); }
398 virtual void resize(size_t _n) { data_.resize(_n); }
399 virtual void clear() { data_.clear(); vector_type().swap(data_); }
400 virtual void push_back() { data_.push_back(std::string()); }
401 virtual void swap(size_t _i0, size_t _i1) {
402 std::swap(data_[_i0], data_[_i1]);
403 }
404 virtual void copy(size_t _i0, size_t _i1)
405 { data_[_i1] = data_[_i0]; }
406
407 public:
408
409 virtual void set_persistent( bool _yn )
410 { check_and_set_persistent<std::string>( _yn ); }
411
412 virtual size_t n_elements() const { return data_.size(); }
413 virtual size_t element_size() const { return UnknownSize; }
414 virtual size_t size_of() const
415 { return IO::size_of( data_ ); }
416
417 virtual size_t size_of(size_t /* _n_elem */) const
418 { return UnknownSize; }
419
421 size_t store( std::ostream& _ostr, bool _swap ) const
422 { return IO::store( _ostr, data_, _swap ); }
423
424 size_t restore( std::istream& _istr, bool _swap )
425 { return IO::restore( _istr, data_, _swap ); }
426
427 public:
428
429 const value_type* data() const {
430 if( data_.empty() )
431 return 0;
432
433 return (value_type*) &data_[0];
434 }
435
437 reference operator[](int _idx) {
438 assert( size_t(_idx) < data_.size());
439 return ((value_type*) &data_[0])[_idx];
440 }
441
443 const_reference operator[](int _idx) const {
444 assert( size_t(_idx) < data_.size());
445 return ((value_type*) &data_[0])[_idx];
446 }
447
448 PropertyT<value_type>* clone() const {
449 PropertyT<value_type>* p = new PropertyT<value_type>( *this );
450 return p;
451 }
452 private:
453
454 vector_type data_;
455
456 };
457
459 template <class T>
460 struct BasePropHandleT : public BaseHandle
461 {
462 typedef T Value;
463 typedef std::vector<T> vector_type;
464 typedef T value_type;
465 typedef typename vector_type::reference reference;
466 typedef typename vector_type::const_reference const_reference;
467
468 explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
469 };
470
471
475 template <class T>
476 struct VPropHandleT : public BasePropHandleT<T>
477 {
478 typedef T Value;
479 typedef T value_type;
480
481 explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
482 explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
483 };
484
485
489 template <class T>
490 struct HPropHandleT : public BasePropHandleT<T>
491 {
492 typedef T Value;
493 typedef T value_type;
494
495 explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
496 explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
497 };
498
499
503 template <class T>
504 struct EPropHandleT : public BasePropHandleT<T>
505 {
506 typedef T Value;
507 typedef T value_type;
508
509 explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
510 explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
511 };
512
513
517 template <class T>
518 struct FPropHandleT : public BasePropHandleT<T>
519 {
520 typedef T Value;
521 typedef T value_type;
522
523 explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
524 explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
525 };
526
527
531 template <class T>
532 struct MPropHandleT : public BasePropHandleT<T>
533 {
534 typedef T Value;
535 typedef T value_type;
536
537 explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
538 explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
539 };
540
541 } // namespace OpenMesh
542 //=============================================================================
543 #endif // OPENMESH_PROPERTY_HH defined
544 //=============================================================================