OpenMesh
PropertyContainer.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2014 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: 990 $ *
38  * $Date: 2014-02-05 10:01:07 +0100 (Mi, 05 Feb 2014) $ *
39  * *
40 \*===========================================================================*/
41 
42 #ifndef OPENMESH_PROPERTYCONTAINER
43 #define OPENMESH_PROPERTYCONTAINER
44 
45 // Use static casts when not debugging
46 #ifdef NDEBUG
47 #define OM_FORCE_STATIC_CAST
48 #endif
49 
50 #include <OpenMesh/Core/Utils/Property.hh>
51 
52 //-----------------------------------------------------------------------------
53 namespace OpenMesh
54 {
55 //== FORWARDDECLARATIONS ======================================================
56  class BaseKernel;
57 
58 //== CLASS DEFINITION =========================================================
61 {
62 public:
63 
64  //-------------------------------------------------- constructor / destructor
65 
67  virtual ~PropertyContainer() { std::for_each(properties_.begin(), properties_.end(), Delete()); }
68 
69 
70  //------------------------------------------------------------- info / access
71 
72  typedef std::vector<BaseProperty*> Properties;
73  const Properties& properties() const { return properties_; }
74  size_t size() const { return properties_.size(); }
75 
76 
77 
78  //--------------------------------------------------------- copy / assignment
79 
80  PropertyContainer(const PropertyContainer& _rhs) { operator=(_rhs); }
81 
82  PropertyContainer& operator=(const PropertyContainer& _rhs)
83  {
84  // The assignment below relies on all previous BaseProperty* elements having been deleted
85  std::for_each(properties_.begin(), properties_.end(), Delete());
86  properties_ = _rhs.properties_;
87  Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
88  for (; p_it!=p_end; ++p_it)
89  if (*p_it)
90  *p_it = (*p_it)->clone();
91  return *this;
92  }
93 
94 
95 
96  //--------------------------------------------------------- manage properties
97 
98  template <class T>
99  BasePropHandleT<T> add(const T&, const std::string& _name="<unknown>")
100  {
101  Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
102  int idx=0;
103  for ( ; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx ) {};
104  if (p_it==p_end) properties_.push_back(NULL);
105  properties_[idx] = new PropertyT<T>(_name);
106  return BasePropHandleT<T>(idx);
107  }
108 
109 
110  template <class T>
111  BasePropHandleT<T> handle(const T&, const std::string& _name) const
112  {
113  Properties::const_iterator p_it = properties_.begin();
114  for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
115  {
116  if (*p_it != NULL &&
117  (*p_it)->name() == _name //skip deleted properties
118 // Skip type check
119 #ifndef OM_FORCE_STATIC_CAST
120  && dynamic_cast<PropertyT<T>*>(properties_[idx]) != NULL //check type
121 #endif
122  )
123  {
124  return BasePropHandleT<T>(idx);
125  }
126  }
127  return BasePropHandleT<T>();
128  }
129 
130  BaseProperty* property( const std::string& _name ) const
131  {
132  Properties::const_iterator p_it = properties_.begin();
133  for (int idx=0; p_it != properties_.end(); ++p_it, ++idx)
134  {
135  if (*p_it != NULL && (*p_it)->name() == _name) //skip deleted properties
136  {
137  return *p_it;
138  }
139  }
140  return NULL;
141  }
142 
143  template <class T> PropertyT<T>& property(BasePropHandleT<T> _h)
144  {
145  assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
146  assert(properties_[_h.idx()] != NULL);
147 #ifdef OM_FORCE_STATIC_CAST
148  return *static_cast <PropertyT<T>*> (properties_[_h.idx()]);
149 #else
150  PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
151  assert(p != NULL);
152  return *p;
153 #endif
154  }
155 
156 
157  template <class T> const PropertyT<T>& property(BasePropHandleT<T> _h) const
158  {
159  assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
160  assert(properties_[_h.idx()] != NULL);
161 #ifdef OM_FORCE_STATIC_CAST
162  return *static_cast<PropertyT<T>*>(properties_[_h.idx()]);
163 #else
164  PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
165  assert(p != NULL);
166  return *p;
167 #endif
168  }
169 
170 
171  template <class T> void remove(BasePropHandleT<T> _h)
172  {
173  assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
174  delete properties_[_h.idx()];
175  properties_[_h.idx()] = NULL;
176  }
177 
178 
179  void clear()
180  {
181  // Clear properties vector:
182  // Replaced the old version with new one
183  // which performs a swap to clear values and
184  // deallocate memory.
185 
186  // Old version (changed 22.07.09) {
187  // std::for_each(properties_.begin(), properties_.end(), Delete());
188  // }
189 
190  std::for_each(properties_.begin(), properties_.end(), ClearAll());
191  }
192 
193 
194  //---------------------------------------------------- synchronize properties
195 
196  void reserve(size_t _n) const {
197  std::for_each(properties_.begin(), properties_.end(), Reserve(_n));
198  }
199 
200  void resize(size_t _n) const {
201  std::for_each(properties_.begin(), properties_.end(), Resize(_n));
202  }
203 
204  void swap(size_t _i0, size_t _i1) const {
205  std::for_each(properties_.begin(), properties_.end(), Swap(_i0, _i1));
206  }
207 
208 
209 
210 protected: // generic add/get
211 
212  size_t _add( BaseProperty* _bp )
213  {
214  Properties::iterator p_it=properties_.begin(), p_end=properties_.end();
215  size_t idx=0;
216  for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx) {};
217  if (p_it==p_end) properties_.push_back(NULL);
218  properties_[idx] = _bp;
219  return idx;
220  }
221 
222  BaseProperty& _property( size_t _idx )
223  {
224  assert( _idx < properties_.size());
225  assert( properties_[_idx] != NULL);
226  BaseProperty *p = properties_[_idx];
227  assert( p != NULL );
228  return *p;
229  }
230 
231  const BaseProperty& _property( size_t _idx ) const
232  {
233  assert( _idx < properties_.size());
234  assert( properties_[_idx] != NULL);
235  BaseProperty *p = properties_[_idx];
236  assert( p != NULL );
237  return *p;
238  }
239 
240 
241  typedef Properties::iterator iterator;
242  typedef Properties::const_iterator const_iterator;
243  iterator begin() { return properties_.begin(); }
244  iterator end() { return properties_.end(); }
245  const_iterator begin() const { return properties_.begin(); }
246  const_iterator end() const { return properties_.end(); }
247 
248  friend class BaseKernel;
249 
250 private:
251 
252  //-------------------------------------------------- synchronization functors
253 
254 #ifndef DOXY_IGNORE_THIS
255  struct Reserve
256  {
257  Reserve(size_t _n) : n_(_n) {}
258  void operator()(BaseProperty* _p) const { if (_p) _p->reserve(n_); }
259  size_t n_;
260  };
261 
262  struct Resize
263  {
264  Resize(size_t _n) : n_(_n) {}
265  void operator()(BaseProperty* _p) const { if (_p) _p->resize(n_); }
266  size_t n_;
267  };
268 
269  struct ClearAll
270  {
271  ClearAll() {}
272  void operator()(BaseProperty* _p) const { if (_p) _p->clear(); }
273  };
274 
275  struct Swap
276  {
277  Swap(size_t _i0, size_t _i1) : i0_(_i0), i1_(_i1) {}
278  void operator()(BaseProperty* _p) const { if (_p) _p->swap(i0_, i1_); }
279  size_t i0_, i1_;
280  };
281 
282  struct Delete
283  {
284  Delete() {}
285  void operator()(BaseProperty* _p) const { if (_p) delete _p; _p=NULL; }
286  };
287 #endif
288 
289  Properties properties_;
290 };
291 
292 }//namespace OpenMesh
293 
294 #endif//OPENMESH_PROPERTYCONTAINER
295 
virtual void swap(size_t _i0, size_t _i1)=0
Let two elements swap their storage place.
Abstract class defining the basic interface of a dynamic property.
Definition: BaseProperty.hh:58
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:67
virtual void resize(size_t _n)=0
Resize storage to hold n elements.
virtual void clear()=0
Clear all elements and free memory.
virtual void reserve(size_t _n)=0
Reserve memory for n elements.
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
Default property class for any type T.
Definition: Property.hh:87
A a container for properties.
Definition: PropertyContainer.hh:60
This class provides the basic property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:91
Base property handle.
Definition: Property.hh:460

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