OpenMesh
PropertyManager.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 PROPERTYMANAGER_HH_
50 #define PROPERTYMANAGER_HH_
51 
52 #include <sstream>
53 #include <stdexcept>
54 #include <string>
55 
56 namespace OpenMesh {
57 
93 template<typename PROPTYPE, typename MeshT>
95 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
96  public:
97  PropertyManager(const PropertyManager&) = delete;
98  PropertyManager& operator=(const PropertyManager&) = delete;
99 #else
100  private:
105 
109  PropertyManager& operator=(const PropertyManager&);
110 #endif
111 
112  public:
130  PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) {
131  if (existing) {
132  if (!mesh_->get_property_handle(prop_, propname)) {
133  std::ostringstream oss;
134  oss << "Requested property handle \"" << propname << "\" does not exist.";
135  throw std::runtime_error(oss.str());
136  }
137  } else {
138  mesh_->add_property(prop_, propname);
139  }
140  }
141 
142  PropertyManager() : mesh_(0), retain_(false) {
143  }
144 
145  ~PropertyManager() {
146  deleteProperty();
147  }
148 
149  void swap(PropertyManager &rhs) {
150  std::swap(mesh_, rhs.mesh_);
151  std::swap(prop_, rhs.prop_);
152  std::swap(retain_, rhs.retain_);
153  std::swap(name_, rhs.name_);
154  }
155 
156  static bool propertyExists(MeshT &mesh, const char *propname) {
157  PROPTYPE dummy;
158  return mesh.get_property_handle(dummy, propname);
159  }
160 
161  bool isValid() const { return mesh_ != 0; }
162  operator bool() const { return isValid(); }
163 
164  const PROPTYPE &getRawProperty() const { return prop_; }
165 
166  const std::string &getName() const { return name_; }
167 
168  MeshT &getMesh() const { return *mesh_; }
169 
170 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
171 
174 
178  PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_), name_(rhs.name_) {
179  rhs.retain_ = true;
180  }
181 
185  PropertyManager &operator=(PropertyManager &&rhs) {
186  if (&rhs != this) {
187  deleteProperty();
188  mesh_ = rhs.mesh_;
189  prop_ = rhs.prop_;
190  retain_ = rhs.retain_;
191  name_ = rhs.name_;
192  rhs.retain_ = true;
193  }
194  return *this;
195  }
196 
204  static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) {
205  PROPTYPE dummy_prop;
206  PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname));
207  pm.retain();
208  return std::move(pm);
209  }
210 
220  template<typename PROP_VALUE, typename ITERATOR_TYPE>
221  static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
222  const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
223  const PROP_VALUE &init_value) {
224  const bool exists = propertyExists(mesh, propname);
225  PropertyManager pm(mesh, propname, exists);
226  pm.retain();
227  if (!exists)
228  pm.set_range(begin, end, init_value);
229  return std::move(pm);
230  }
231 
241  template<typename PROP_VALUE, typename ITERATOR_RANGE>
242  static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
243  const ITERATOR_RANGE &range, const PROP_VALUE &init_value) {
244  return createIfNotExists(
245  mesh, propname, range.begin(), range.end(), init_value);
246  }
247 
248  PropertyManager duplicate(const char *clone_name) {
249  PropertyManager pm(*mesh_, clone_name, false);
250  pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
251  return pm;
252  }
253 
257  PropertyManager move() {
258  return std::move(*this);
259  }
260 
261 #else
262  class Proxy {
263  private:
264  Proxy(MeshT *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) :
265  mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {}
266  MeshT *mesh_;
267  PROPTYPE prop_;
268  bool retain_;
269  std::string name_;
270 
271  friend class PropertyManager;
272  };
273 
274  operator Proxy() {
275  Proxy p(mesh_, prop_, retain_, name_);
276  mesh_ = 0;
277  retain_ = true;
278  return p;
279  }
280 
281  Proxy move() {
282  return (Proxy)*this;
283  }
284 
285  PropertyManager(Proxy p) : mesh_(p.mesh_), prop_(p.prop_), retain_(p.retain_), name_(p.name_) {}
286 
287  PropertyManager &operator=(Proxy p) {
288  PropertyManager(p).swap(*this);
289  return *this;
290  }
291 
299  static Proxy createIfNotExists(MeshT &mesh, const char *propname) {
300  PROPTYPE dummy_prop;
301  PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname));
302  pm.retain();
303  return (Proxy)pm;
304  }
305 
315  template<typename PROP_VALUE, typename ITERATOR_TYPE>
316  static Proxy createIfNotExists(MeshT &mesh, const char *propname,
317  const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
318  const PROP_VALUE &init_value) {
319  const bool exists = propertyExists(mesh, propname);
320  PropertyManager pm(mesh, propname, exists);
321  pm.retain();
322  if (!exists)
323  pm.set_range(begin, end, init_value);
324  return (Proxy)pm;
325  }
326 
327  Proxy duplicate(const char *clone_name) {
328  PropertyManager pm(*mesh_, clone_name, false);
329  pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
330  return (Proxy)pm;
331  }
332 #endif
333 
340  inline void retain(bool doRetain = true) {
341  retain_ = doRetain;
342  }
343 
347  inline PROPTYPE &operator* () {
348  return prop_;
349  }
350 
354  inline const PROPTYPE &operator* () const {
355  return prop_;
356  }
357 
365  template<typename HandleType>
366  inline typename PROPTYPE::reference operator[] (const HandleType &handle) {
367  return mesh_->property(prop_, handle);
368  }
369 
377  template<typename HandleType>
378  inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const {
379  return mesh_->property(prop_, handle);
380  }
381 
406  template<typename HandleTypeIterator, typename PROP_VALUE>
407  void set_range(HandleTypeIterator begin, HandleTypeIterator end,
408  const PROP_VALUE &value) {
409  for (; begin != end; ++begin)
410  (*this)[*begin] = value;
411  }
412 
413 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
414  template<typename HandleTypeIteratorRange, typename PROP_VALUE>
415  void set_range(const HandleTypeIteratorRange &range,
416  const PROP_VALUE &value) {
417  set_range(range.begin(), range.end(), value);
418  }
419 #endif
420 
435  template<typename HandleTypeIterator, typename PROPTYPE_2,
436  typename MeshT_2, typename HandleTypeIterator_2>
437  void copy_to(HandleTypeIterator begin, HandleTypeIterator end,
438  PropertyManager<PROPTYPE_2, MeshT_2> &dst_propmanager,
439  HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const {
440 
441  for (; begin != end && dst_begin != dst_end; ++begin, ++dst_begin) {
442  dst_propmanager[*dst_begin] = (*this)[*begin];
443  }
444  }
445 
446  template<typename RangeType, typename PROPTYPE_2,
447  typename MeshT_2, typename RangeType_2>
448  void copy_to(const RangeType &range,
449  PropertyManager<PROPTYPE_2, MeshT_2> &dst_propmanager,
450  const RangeType_2 &dst_range) const {
451  copy_to(range.begin(), range.end(), dst_propmanager,
452  dst_range.begin(), dst_range.end());
453  }
454 
469  template<typename RangeType, typename MeshT_2, typename RangeType_2>
470  static void copy(const char *prop_name,
471  MeshT &src_mesh, const RangeType &src_range,
472  MeshT_2 &dst_mesh, const RangeType_2 &dst_range) {
473 
475  DstPM dst(DstPM::createIfNotExists(dst_mesh, prop_name));
476 
478  SrcPM src(src_mesh, prop_name, true);
479 
480  src.copy_to(src_range, dst, dst_range);
481  }
482 
483  private:
484  void deleteProperty() {
485  if (!retain_)
486  mesh_->remove_property(prop_);
487  }
488 
489  private:
490  MeshT *mesh_;
491  PROPTYPE prop_;
492  bool retain_;
493  std::string name_;
494 };
495 
503 template<typename PROPTYPE, typename MeshT>
505  return PropertyManager<PROPTYPE, MeshT>(mesh, propname, false);
506 }
507 
518 template<typename PROPTYPE, typename MeshT>
520  return PropertyManager<PROPTYPE, MeshT>(mesh, propname, true);
521 }
522 
529 template<typename PROPTYPE, typename MeshT>
532 }
533 
545 template<typename PROPTYPE, typename MeshT,
546  typename ITERATOR_TYPE, typename PROP_VALUE>
548  MeshT &mesh, const char *propname,
549  const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
550  const PROP_VALUE &init_value) {
552  mesh, propname, begin, end, init_value);
553 }
554 
566 template<typename PROPTYPE, typename MeshT,
567  typename ITERATOR_RANGE, typename PROP_VALUE>
569  MeshT &mesh, const char *propname,
570  const ITERATOR_RANGE &range,
571  const PROP_VALUE &init_value) {
572  return makePropertyManagerFromExistingOrNew<PROPTYPE, MeshT>(
573  mesh, propname, range.begin(), range.end(), init_value);
574 }
575 
576 } /* namespace OpenMesh */
577 #endif /* PROPERTYMANAGER_HH_ */
This class is intended to manage the lifecycle of properties.
Definition: PropertyManager.hh:94
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname, const ITERATOR_RANGE &range, const PROP_VALUE &init_value)
Definition: PropertyManager.hh:568
PropertyManager(MeshT &mesh, const char *propname, bool existing=false)
Constructor.
Definition: PropertyManager.hh:130
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value)
Definition: PropertyManager.hh:547
PROPTYPE & operator*()
Access the encapsulated property.
Definition: PropertyManager.hh:347
Definition: PropertyManager.hh:262
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExisting(MeshT &mesh, const char *propname)
Definition: PropertyManager.hh:519
static Proxy createIfNotExists(MeshT &mesh, const char *propname)
Create a property manager for the supplied property and mesh.
Definition: PropertyManager.hh:299
void copy_to(HandleTypeIterator begin, HandleTypeIterator end, PropertyManager< PROPTYPE_2, MeshT_2 > &dst_propmanager, HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const
Conveniently transfer the values managed by one property manager onto the values managed by a differe...
Definition: PropertyManager.hh:437
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname)
Definition: PropertyManager.hh:530
void set_range(HandleTypeIterator begin, HandleTypeIterator end, const PROP_VALUE &value)
Conveniently set the property for an entire range of values.
Definition: PropertyManager.hh:407
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
static void copy(const char *prop_name, MeshT &src_mesh, const RangeType &src_range, MeshT_2 &dst_mesh, const RangeType_2 &dst_range)
Copy the values of a property from a source range to a target range.
Definition: PropertyManager.hh:470
void retain(bool doRetain=true)
Disable lifecycle management for this property.
Definition: PropertyManager.hh:340
PROPTYPE::reference operator[](const HandleType &handle)
Enables convenient access to the encapsulated property.
Definition: PropertyManager.hh:366
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromNew(MeshT &mesh, const char *propname)
Definition: PropertyManager.hh:504
static Proxy createIfNotExists(MeshT &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value)
Like createIfNotExists() with two parameters except, if the property doesn&#39;t exist, it is initialized with the supplied value over the supplied range after creation.
Definition: PropertyManager.hh:316

Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .