OpenMesh: OpenMesh/Core/Utils/Property.hh Source File

| OpenMesh

Property.hh
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2022, 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 #pragma once
47
48 //== INCLUDES =================================================================
49
50
51 #include <OpenMesh/Core/System/config.h>
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 #include <OpenMesh/Core/IO/SR_store.hh>
59 #include <iostream>
60
61
62 //== NAMESPACES ===============================================================
63
64 namespace OpenMesh {
65
66 //== CLASS DEFINITION =========================================================
67
86 // TODO: it might be possible to define Property using kind of a runtime info
87 // structure holding the size of T. Then reserve, swap, resize, etc can be written
88 // in pure malloc() style w/o virtual overhead. Template member function proved per
89 // element access to the properties, asserting dynamic_casts in debug
90
91 template <class T>
92 class PropertyT : public BaseProperty
93 {
94 public:
95
96 typedef T Value;
97 typedef std::vector<T> vector_type;
98 typedef T value_type;
99 typedef typename vector_type::reference reference;
100 typedef typename vector_type::const_reference const_reference;
101
102 public:
103
105 explicit PropertyT(
106 const std::string& _name = "<unknown>",
107 const std::string& _internal_type_name = "<unknown>")
108 : BaseProperty(_name, _internal_type_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) override { data_.reserve(_n); }
118 virtual void resize(size_t _n) override { data_.resize(_n); }
119 virtual void clear() override { data_.clear(); vector_type().swap(data_); }
120 virtual void push_back() override { data_.push_back(T()); }
121 virtual void swap(size_t _i0, size_t _i1) override
122 { std::swap(data_[_i0], data_[_i1]); }
123 virtual void copy(size_t _i0, size_t _i1) override
124 { data_[_i1] = data_[_i0]; }
125
126 public:
127
128 virtual void set_persistent( bool _yn ) override
129 { check_and_set_persistent<T>( _yn ); }
130
131 virtual size_t n_elements() const override { return data_.size(); }
132 virtual size_t element_size() const override { 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 override
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 override
149 { return this->BaseProperty::size_of(_n_elem); }
150
151 virtual size_t store( std::ostream& _ostr, bool _swap ) const override
152 {
153 if (IO::is_streamable<vector_type>() && element_size() != IO::UnknownSize)
154 return IO::store(_ostr, data_, _swap, false); //does not need to store its length
155
156 size_t bytes = 0;
157 for (size_t i=0; i<n_elements(); ++i)
158 bytes += IO::store( _ostr, data_[i], _swap);
159 return bytes;
160 }
161
162 virtual size_t restore( std::istream& _istr, bool _swap ) override
163 {
164 if ( IO::is_streamable<vector_type>() && element_size() != IO::UnknownSize)
165 return IO::restore(_istr, data_, _swap, false); //does not need to restore its length
166
167 size_t bytes = 0;
168 for (size_t i=0; i<n_elements(); ++i)
169 bytes += IO::restore( _istr, data_[i], _swap);
170 return bytes;
171 }
172
173 public: // data access interface
174
176 const T* data() const {
177
178 if( data_.empty() )
179 return 0;
180
181 return &data_[0];
182 }
183
185 vector_type& data_vector() {
186 return data_;
187 }
188
190 const vector_type& data_vector() const {
191 return data_;
192 }
193
195 reference operator[](int _idx)
196 {
197 assert( size_t(_idx) < data_.size() );
198 return data_[_idx];
199 }
200
202 const_reference operator[](int _idx) const
203 {
204 assert( size_t(_idx) < data_.size());
205 return data_[_idx];
206 }
207
209 PropertyT<T>* clone() const override
210 {
211 PropertyT<T>* p = new PropertyT<T>( *this );
212 return p;
213 }
214
215 std::string get_storage_name() const override
216 {
217 return OpenMesh::IO::binary<T>::type_identifier();
218 }
219
220 private:
221
222 vector_type data_;
223 };
224
225 //-----------------------------------------------------------------------------
226
227
232 template <>
233 class PropertyT<bool> : public BaseProperty
234 {
235 public:
236
237 typedef std::vector<bool> vector_type;
238 typedef bool value_type;
239 typedef vector_type::reference reference;
240 typedef vector_type::const_reference const_reference;
241
242 public:
243
244 explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
245 : BaseProperty(_name, _internal_type_name)
246 { }
247
248 public: // inherited from BaseProperty
249
250 virtual void reserve(size_t _n) override { data_.reserve(_n); }
251 virtual void resize(size_t _n) override { data_.resize(_n); }
252 virtual void clear() override { data_.clear(); vector_type().swap(data_); }
253 virtual void push_back() override { data_.push_back(bool()); }
254 virtual void swap(size_t _i0, size_t _i1) override
255 { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; }
256 virtual void copy(size_t _i0, size_t _i1) override
257 { data_[_i1] = data_[_i0]; }
258
259 public:
260
261 virtual void set_persistent( bool _yn ) override
262 {
263 check_and_set_persistent<bool>( _yn );
264 }
265
266 virtual size_t n_elements() const override { return data_.size(); }
267 virtual size_t element_size() const override { return UnknownSize; }
268 virtual size_t size_of() const override { return size_of( n_elements() ); }
269 virtual size_t size_of(size_t _n_elem) const override
270 {
271 return _n_elem / 8 + ((_n_elem % 8)!=0);
272 }
273
274 size_t store( std::ostream& _ostr, bool /* _swap */ ) const override
275 {
276 size_t bytes = 0;
277
278 size_t N = data_.size() / 8;
279 size_t R = data_.size() % 8;
280
281 size_t idx; // element index
282 size_t bidx;
283 unsigned char bits; // bitset
284
285 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
286 {
287 bits = static_cast<unsigned char>(data_[bidx])
288 | (static_cast<unsigned char>(data_[bidx+1]) << 1)
289 | (static_cast<unsigned char>(data_[bidx+2]) << 2)
290 | (static_cast<unsigned char>(data_[bidx+3]) << 3)
291 | (static_cast<unsigned char>(data_[bidx+4]) << 4)
292 | (static_cast<unsigned char>(data_[bidx+5]) << 5)
293 | (static_cast<unsigned char>(data_[bidx+6]) << 6)
294 | (static_cast<unsigned char>(data_[bidx+7]) << 7);
295 _ostr << bits;
296 }
297 bytes = N;
298
299 if (R)
300 {
301 bits = 0;
302 for (idx=0; idx < R; ++idx)
303 bits |= static_cast<unsigned char>(data_[bidx+idx]) << idx;
304 _ostr << bits;
305 ++bytes;
306 }
307
308 assert( bytes == size_of() );
309
310 return bytes;
311 }
312
313 size_t restore( std::istream& _istr, bool /* _swap */ ) override
314 {
315 size_t bytes = 0;
316
317 size_t N = data_.size() / 8;
318 size_t R = data_.size() % 8;
319
320 size_t idx; // element index
321 size_t bidx; //
322 unsigned char bits; // bitset
323
324 for (bidx=idx=0; idx < N; ++idx, bidx+=8)
325 {
326 _istr >> bits;
327 data_[bidx+0] = (bits & 0x01) != 0;
328 data_[bidx+1] = (bits & 0x02) != 0;
329 data_[bidx+2] = (bits & 0x04) != 0;
330 data_[bidx+3] = (bits & 0x08) != 0;
331 data_[bidx+4] = (bits & 0x10) != 0;
332 data_[bidx+5] = (bits & 0x20) != 0;
333 data_[bidx+6] = (bits & 0x40) != 0;
334 data_[bidx+7] = (bits & 0x80) != 0;
335 }
336 bytes = N;
337
338 if (R)
339 {
340 _istr >> bits;
341 for (idx=0; idx < R; ++idx)
342 data_[bidx+idx] = (bits & (1<<idx)) != 0;
343 ++bytes;
344 }
345
346 return bytes;
347 }
348
349
350 public:
351
353 vector_type& data_vector() {
354 return data_;
355 }
356
358 const vector_type& data_vector() const {
359 return data_;
360 }
361
363 reference operator[](int _idx)
364 {
365 assert( size_t(_idx) < data_.size() );
366 return data_[_idx];
367 }
368
370 const_reference operator[](int _idx) const
371 {
372 assert( size_t(_idx) < data_.size());
373 return data_[_idx];
374 }
375
377 PropertyT<bool>* clone() const override
378 {
379 PropertyT<bool>* p = new PropertyT<bool>( *this );
380 return p;
381 }
382
383 std::string get_storage_name() const override
384 {
385 return OpenMesh::IO::binary<bool>::type_identifier();
386 }
387
388
389 private:
390
391 vector_type data_;
392 };
393
394
395 //-----------------------------------------------------------------------------
396
397
399 template <class T>
400 struct BasePropHandleT : public BaseHandle
401 {
402 typedef T Value;
403 typedef std::vector<T> vector_type;
404 typedef T value_type;
405 typedef typename vector_type::reference reference;
406 typedef typename vector_type::const_reference const_reference;
407
408 explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {}
409 };
410
411
415 template <class T>
416 struct VPropHandleT : public BasePropHandleT<T>
417 {
418 typedef T Value;
419 typedef T value_type;
420 typedef VertexHandle Handle;
421
422 explicit VPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
423 explicit VPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
424 };
425
426
430 template <class T>
431 struct HPropHandleT : public BasePropHandleT<T>
432 {
433 typedef T Value;
434 typedef T value_type;
435 typedef HalfedgeHandle Handle;
436
437 explicit HPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
438 explicit HPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
439 };
440
441
445 template <class T>
446 struct EPropHandleT : public BasePropHandleT<T>
447 {
448 typedef T Value;
449 typedef T value_type;
450 typedef EdgeHandle Handle;
451
452 explicit EPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
453 explicit EPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
454 };
455
456
460 template <class T>
461 struct FPropHandleT : public BasePropHandleT<T>
462 {
463 typedef T Value;
464 typedef T value_type;
465 typedef FaceHandle Handle;
466
467 explicit FPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
468 explicit FPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
469 };
470
471
475 template <class T>
476 struct MPropHandleT : public BasePropHandleT<T>
477 {
478 typedef T Value;
479 typedef T value_type;
480 typedef MeshHandle Handle;
481
482 explicit MPropHandleT(int _idx=-1) : BasePropHandleT<T>(_idx) {}
483 explicit MPropHandleT(const BasePropHandleT<T>& _b) : BasePropHandleT<T>(_b) {}
484 };
485
486 template <typename HandleT>
487 struct PropHandle;
488
489 template <>
490 struct PropHandle<VertexHandle> {
491 template <typename T>
492 using type = VPropHandleT<T>;
493 };
494
495 template <>
496 struct PropHandle<HalfedgeHandle> {
497 template <typename T>
498 using type = HPropHandleT<T>;
499 };
500
501 template <>
502 struct PropHandle<EdgeHandle> {
503 template <typename T>
504 using type = EPropHandleT<T>;
505 };
506
507 template <>
508 struct PropHandle<FaceHandle> {
509 template <typename T>
510 using type = FPropHandleT<T>;
511 };
512
513 template <>
514 struct PropHandle<MeshHandle> {
515 template <typename T>
516 using type = MPropHandleT<T>;
517 };
518
519 } // namespace OpenMesh
520 //=============================================================================
521 //#endif // OPENMESH_PROPERTY_HH defined
522 //=============================================================================
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::IO::binary::type_identifier
static std::string type_identifier(void)
A string that identifies the type of T.
Definition: SR_binary.hh:114
OpenMesh::BaseHandle
Base class for all handle types.
Definition: Handles.hh:63
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:121
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:128
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:135
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:142
OpenMesh::MeshHandle
Handle type for meshes to simplify some template programming.
Definition: Handles.hh:149
OpenMesh::BaseProperty
Abstract class defining the basic interface of a dynamic property.
Definition: BaseProperty.hh:61
OpenMesh::BaseProperty::BaseProperty
BaseProperty(const std::string &_name="<unknown>", const std::string &_internal_type_name="<unknown>")
Default constructor.
Definition: BaseProperty.hh:84
OpenMesh::BaseProperty::size_of
virtual size_t size_of() const
Return size of property in bytes.
Definition: BaseProperty.hh:147
OpenMesh::BaseProperty::UnknownSize
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:65
OpenMesh::PropertyT
Default property class for any type T.
Definition: Property.hh:93
OpenMesh::PropertyT::data
const T * data() const
Get pointer to array (does not work for T==bool)
Definition: Property.hh:176
OpenMesh::PropertyT::push_back
virtual void push_back() override
Extend the number of elements by one.
Definition: Property.hh:120
OpenMesh::PropertyT::restore
virtual size_t restore(std::istream &_istr, bool _swap) override
Restore self from a binary block.
Definition: Property.hh:162
OpenMesh::PropertyT::copy
virtual void copy(size_t _i0, size_t _i1) override
Copy one element to another.
Definition: Property.hh:123
OpenMesh::PropertyT::set_persistent
virtual void set_persistent(bool _yn) override
Enable or disable persistency.
Definition: Property.hh:128
OpenMesh::PropertyT::operator[]
reference operator[](int _idx)
Access the i'th element. No range check is performed!
Definition: Property.hh:195
OpenMesh::PropertyT::element_size
virtual size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:132
OpenMesh::PropertyT::clear
virtual void clear() override
Clear all elements and free memory.
Definition: Property.hh:119
OpenMesh::PropertyT::reserve
virtual void reserve(size_t _n) override
Reserve memory for n elements.
Definition: Property.hh:117
OpenMesh::PropertyT::clone
PropertyT< T > * clone() const override
Make a copy of self.
Definition: Property.hh:209
OpenMesh::PropertyT::data_vector
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:190
OpenMesh::PropertyT::size_of
virtual size_t size_of(void) const override
Return size of property in bytes.
Definition: Property.hh:141
OpenMesh::PropertyT::resize
virtual void resize(size_t _n) override
Resize storage to hold n elements.
Definition: Property.hh:118
OpenMesh::PropertyT::swap
virtual void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
Definition: Property.hh:121
OpenMesh::PropertyT::PropertyT
PropertyT(const PropertyT &_rhs)
Copy constructor.
Definition: Property.hh:112
OpenMesh::PropertyT::size_of
virtual size_t size_of(size_t _n_elem) const override
Estimated size of property if it has _n_elem elements.
Definition: Property.hh:148
OpenMesh::PropertyT::n_elements
virtual size_t n_elements() const override
Number of elements in property.
Definition: Property.hh:131
OpenMesh::PropertyT::data_vector
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!...
Definition: Property.hh:185
OpenMesh::PropertyT::PropertyT
PropertyT(const std::string &_name="<unknown>", const std::string &_internal_type_name="<unknown>")
Default constructor.
Definition: Property.hh:105
OpenMesh::PropertyT::get_storage_name
std::string get_storage_name() const override
returns a unique string for the type of the elements
Definition: Property.hh:215
OpenMesh::PropertyT::store
virtual size_t store(std::ostream &_ostr, bool _swap) const override
Store self as one binary block.
Definition: Property.hh:151
OpenMesh::PropertyT::operator[]
const_reference operator[](int _idx) const
Const access to the i'th element. No range check is performed!
Definition: Property.hh:202
OpenMesh::PropertyT< bool >
Property specialization for bool type.
Definition: Property.hh:234
OpenMesh::PropertyT< bool >::push_back
virtual void push_back() override
Extend the number of elements by one.
Definition: Property.hh:253
OpenMesh::PropertyT< bool >::set_persistent
virtual void set_persistent(bool _yn) override
Enable or disable persistency.
Definition: Property.hh:261
OpenMesh::PropertyT< bool >::operator[]
reference operator[](int _idx)
Access the i'th element. No range check is performed!
Definition: Property.hh:363
OpenMesh::PropertyT< bool >::data_vector
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!...
Definition: Property.hh:353
OpenMesh::PropertyT< bool >::copy
virtual void copy(size_t _i0, size_t _i1) override
Copy one element to another.
Definition: Property.hh:256
OpenMesh::PropertyT< bool >::operator[]
const_reference operator[](int _idx) const
Const access to the i'th element. No range check is performed!
Definition: Property.hh:370
OpenMesh::PropertyT< bool >::restore
size_t restore(std::istream &_istr, bool) override
Restore self from a binary block.
Definition: Property.hh:313
OpenMesh::PropertyT< bool >::get_storage_name
std::string get_storage_name() const override
returns a unique string for the type of the elements
Definition: Property.hh:383
OpenMesh::PropertyT< bool >::clear
virtual void clear() override
Clear all elements and free memory.
Definition: Property.hh:252
OpenMesh::PropertyT< bool >::size_of
virtual size_t size_of() const override
Return size of property in bytes.
Definition: Property.hh:268
OpenMesh::PropertyT< bool >::clone
PropertyT< bool > * clone() const override
Make a copy of self.
Definition: Property.hh:377
OpenMesh::PropertyT< bool >::n_elements
virtual size_t n_elements() const override
Number of elements in property.
Definition: Property.hh:266
OpenMesh::PropertyT< bool >::size_of
virtual size_t size_of(size_t _n_elem) const override
Estimated size of property if it has _n_elem elements.
Definition: Property.hh:269
OpenMesh::PropertyT< bool >::reserve
virtual void reserve(size_t _n) override
Reserve memory for n elements.
Definition: Property.hh:250
OpenMesh::PropertyT< bool >::resize
virtual void resize(size_t _n) override
Resize storage to hold n elements.
Definition: Property.hh:251
OpenMesh::PropertyT< bool >::swap
virtual void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
Definition: Property.hh:254
OpenMesh::PropertyT< bool >::data_vector
const vector_type & data_vector() const
Const access to property vector.
Definition: Property.hh:358
OpenMesh::PropertyT< bool >::store
size_t store(std::ostream &_ostr, bool) const override
Store self as one binary block.
Definition: Property.hh:274
OpenMesh::PropertyT< bool >::element_size
virtual size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
Definition: Property.hh:267
OpenMesh::BasePropHandleT
Base property handle.
Definition: Property.hh:401
OpenMesh::VPropHandleT
Handle representing a vertex property.
Definition: Property.hh:417
OpenMesh::HPropHandleT
Handle representing a halfedge property.
Definition: Property.hh:432
OpenMesh::EPropHandleT
Handle representing an edge property.
Definition: Property.hh:447
OpenMesh::FPropHandleT
Handle representing a face property.
Definition: Property.hh:462
OpenMesh::MPropHandleT
Handle representing a mesh property.
Definition: Property.hh:477
OpenMesh::PropHandle
Definition: Property.hh:487