Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 _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 
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 _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
171 
173  typedef PropertyManager<PROPTYPE, MeshT> Proxy;
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 
211 
212  PropertyManager duplicate(const char *clone_name) {
213  PropertyManager pm(*mesh_, clone_name, false);
214  pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
215  return pm;
216  }
217 
221  PropertyManager move() {
222  return std::move(*this);
223  }
224 
225 #else
226  class Proxy {
227  private:
228  Proxy(MeshT *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) :
229  mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {}
230  MeshT *mesh_;
231  PROPTYPE prop_;
232  bool retain_;
233  std::string name_;
234 
235  friend class PropertyManager;
236  };
237 
238  operator Proxy() {
239  Proxy p(mesh_, prop_, retain_, name_);
240  mesh_ = 0;
241  retain_ = true;
242  return p;
243  }
244 
245  Proxy move() {
246  return (Proxy)*this;
247  }
248 
249  PropertyManager(Proxy p) : mesh_(p.mesh_), prop_(p.prop_), retain_(p.retain_), name_(p.name_) {}
250 
251  PropertyManager &operator=(Proxy p) {
252  PropertyManager(p).swap(*this);
253  return *this;
254  }
255 
263  static Proxy createIfNotExists(MeshT &mesh, const char *propname) {
264  PROPTYPE dummy_prop;
265  PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname));
266  pm.retain();
267  return (Proxy)pm;
268  }
269 
270  Proxy duplicate(const char *clone_name) {
271  PropertyManager pm(*mesh_, clone_name, false);
272  pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
273  return (Proxy)pm;
274  }
275 #endif
276 
283  inline void retain(bool doRetain = true) {
284  retain_ = doRetain;
285  }
286 
290  inline PROPTYPE &operator* () {
291  return prop_;
292  }
293 
297  inline const PROPTYPE &operator* () const {
298  return prop_;
299  }
300 
308  template<typename HandleType>
309  inline typename PROPTYPE::reference operator[] (const HandleType &handle) {
310  return mesh_->property(prop_, handle);
311  }
312 
320  template<typename HandleType>
321  inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const {
322  return mesh_->property(prop_, handle);
323  }
324 
349  template<typename HandleTypeIterator, typename PROP_VALUE>
350  void set_range(HandleTypeIterator begin, HandleTypeIterator end,
351  const PROP_VALUE &value) {
352  for (; begin != end; ++begin)
353  (*this)[*begin] = value;
354  }
355 
370  template<typename HandleTypeIterator, typename PROPTYPE_2,
371  typename MeshT_2, typename HandleTypeIterator_2>
372  void copy_to(HandleTypeIterator begin, HandleTypeIterator end,
373  PropertyManager<PROPTYPE_2, MeshT_2> &dst_propmanager,
374  HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const {
375 
376  for (; begin != end && dst_begin != dst_end; ++begin, ++dst_begin) {
377  dst_propmanager[*dst_begin] = (*this)[*begin];
378  }
379  }
380 
381  template<typename RangeType, typename PROPTYPE_2,
382  typename MeshT_2, typename RangeType_2>
383  void copy_to(const RangeType &range,
384  PropertyManager<PROPTYPE_2, MeshT_2> &dst_propmanager,
385  const RangeType_2 &dst_range) const {
386  copy_to(range.begin(), range.end(), dst_propmanager,
387  dst_range.begin(), dst_range.end());
388  }
389 
404  template<typename RangeType, typename MeshT_2, typename RangeType_2>
405  static void copy(const char *prop_name,
406  MeshT &src_mesh, const RangeType &src_range,
407  MeshT_2 &dst_mesh, const RangeType_2 &dst_range) {
408 
410  DstPM dst(DstPM::createIfNotExists(dst_mesh, prop_name));
411 
413  SrcPM src(src_mesh, prop_name, true);
414 
415  src.copy_to(src_range, dst, dst_range);
416  }
417 
418  private:
419  void deleteProperty() {
420  if (!retain_)
421  mesh_->remove_property(prop_);
422  }
423 
424  private:
425  MeshT *mesh_;
426  PROPTYPE prop_;
427  bool retain_;
428  std::string name_;
429 };
430 
438 template<typename PROPTYPE, typename MeshT>
440  return PropertyManager<PROPTYPE, MeshT>(mesh, propname, false);
441 }
442 
453 template<typename PROPTYPE, typename MeshT>
455  return PropertyManager<PROPTYPE, MeshT>(mesh, propname, true);
456 }
457 
464 template<typename PROPTYPE, typename MeshT>
467 }
468 
469 } /* namespace OpenMesh */
470 #endif /* PROPERTYMANAGER_HH_ */
void retain(bool doRetain=true)
Disable lifecycle management for this property.
static Proxy createIfNotExists(MeshT &mesh, const char *propname)
PropertyManager & operator=(const PropertyManager &)
void set_range(HandleTypeIterator begin, HandleTypeIterator end, const PROP_VALUE &value)
PROPTYPE::reference operator[](const HandleType &handle)
PropertyManager(MeshT &mesh, const char *propname, bool existing=false)
static void copy(const char *prop_name, MeshT &src_mesh, const RangeType &src_range, MeshT_2 &dst_mesh, const RangeType_2 &dst_range)
PropertyManager(const PropertyManager &)
void copy_to(HandleTypeIterator begin, HandleTypeIterator end, PropertyManager< PROPTYPE_2, MeshT_2 > &dst_propmanager, HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname)
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromNew(MeshT &mesh, const char *propname)
PropertyManager< PROPTYPE, MeshT > makePropertyManagerFromExisting(MeshT &mesh, const char *propname)