Developer Documentation
ResourceManager.cc
1 /*===========================================================================*\
2  * *
3  * OpenVolumeMesh *
4  * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openvolumemesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenVolumeMesh. *
9  * *
10  * OpenVolumeMesh 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  * OpenVolumeMesh 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 OpenVolumeMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 #include "ResourceManager.hh"
36 #include "BaseProperty.hh"
37 
38 namespace OpenVolumeMesh {
39 
40 ResourceManager::ResourceManager(const ResourceManager &other)
41 {
42  *this = other;
43 }
44 
45 ResourceManager::ResourceManager(ResourceManager &&other)
46 {
47  *this = std::move(other);
48 }
49 
50 ResourceManager& ResourceManager::operator=(const ResourceManager &other)
51 {
52  if (this == &other)
53  return *this;
54 
55  assignAllPropertiesFrom<false>(&other);
56 
57  return *this;
58 }
59 
60 ResourceManager& ResourceManager::operator=(ResourceManager &&other)
61 {
62  if (this == &other)
63  return *this;
64 
65  assignAllPropertiesFrom<true>(&other);
66 
67  return *this;
68 }
69 
70 ResourceManager::~ResourceManager() {
71 
72  // Delete persistent props
73  clearVec(vertex_props_);
74  clearVec(edge_props_);
75  clearVec(halfedge_props_);
76  clearVec(face_props_);
77  clearVec(halfface_props_);
78  clearVec(cell_props_);
79  clearVec(mesh_props_);
80 }
81 
83 
84  resize_props(vertex_props_, _nv);
85 }
86 
88 
89  resize_props(edge_props_, _ne);
90  resize_props(halfedge_props_, _ne*2u);
91 }
92 
94 
95  resize_props(face_props_, _nf);
96  resize_props(halfface_props_, _nf*2u);
97 }
98 
100 
101  resize_props(cell_props_, _nc);
102 }
103 
104 void ResourceManager::vertex_deleted(const VertexHandle& _h) {
105 
106  entity_deleted(vertex_props_, _h);
107 }
108 
109 void ResourceManager::edge_deleted(const EdgeHandle& _h) {
110 
111  entity_deleted(edge_props_, _h);
112  entity_deleted(halfedge_props_, OpenVolumeMeshHandle(_h.idx()*2 + 1));
113  entity_deleted(halfedge_props_, OpenVolumeMeshHandle(_h.idx()*2));
114 }
115 
116 void ResourceManager::face_deleted(const FaceHandle& _h) {
117 
118  entity_deleted(face_props_, _h);
119  entity_deleted(halfface_props_, OpenVolumeMeshHandle(_h.idx()*2 + 1));
120  entity_deleted(halfface_props_, OpenVolumeMeshHandle(_h.idx()*2));
121 }
122 
123 void ResourceManager::cell_deleted(const CellHandle& _h) {
124 
125  entity_deleted(cell_props_, _h);
126 }
127 
128 void ResourceManager::swap_cell_properties(CellHandle _h1, CellHandle _h2){
129 
130  swap_property_elements(cell_props_begin(), cell_props_end(), _h1, _h2);
131 }
132 
133 void ResourceManager::swap_face_properties(FaceHandle _h1, FaceHandle _h2){
134 
135  swap_property_elements(face_props_begin(), face_props_end(), _h1, _h2);
136 }
137 
138 void ResourceManager::swap_halfface_properties(HalfFaceHandle _h1, HalfFaceHandle _h2){
139 
140  swap_property_elements(halfface_props_begin(), halfface_props_end(), _h1, _h2);
141 }
142 
143 void ResourceManager::swap_edge_properties(EdgeHandle _h1, EdgeHandle _h2){
144 
145  swap_property_elements(edge_props_begin(), edge_props_end(), _h1, _h2);
146 }
147 
148 void ResourceManager::swap_halfedge_properties(HalfEdgeHandle _h1, HalfEdgeHandle _h2){
149 
150  swap_property_elements(halfedge_props_begin(), halfedge_props_end(), _h1, _h2);
151 }
152 
153 void ResourceManager::swap_vertex_properties(VertexHandle _h1, VertexHandle _h2){
154 
155  swap_property_elements(vertex_props_begin(), vertex_props_end(), _h1, _h2);
156 }
157 
158 void ResourceManager::release_property(VertexPropHandle _handle) {
159 
160  remove_property(vertex_props_, _handle.uidx());
161 }
162 
163 void ResourceManager::release_property(EdgePropHandle _handle) {
164 
165  remove_property(edge_props_, _handle.uidx());
166 }
167 
168 void ResourceManager::release_property(HalfEdgePropHandle _handle) {
169 
170  remove_property(halfedge_props_, _handle.uidx());
171 }
172 
173 void ResourceManager::release_property(FacePropHandle _handle) {
174 
175  remove_property(face_props_, _handle.uidx());
176 }
177 
178 void ResourceManager::release_property(HalfFacePropHandle _handle) {
179 
180  remove_property(halfface_props_, _handle.uidx());
181 }
182 
183 void ResourceManager::release_property(CellPropHandle _handle) {
184 
185  remove_property(cell_props_, _handle.uidx());
186 }
187 
188 void ResourceManager::release_property(MeshPropHandle _handle) {
189 
190  remove_property(mesh_props_, _handle.idx());
191 }
192 
193 void ResourceManager::delete_multiple_vertex_props(const std::vector<bool>& _tags) {
194 
195  Properties::iterator vp_it = vertex_props_.begin();
196  Properties::iterator vp_end = vertex_props_.end();
197  for(; vp_it != vp_end; ++vp_it) {
198  (*vp_it)->delete_multiple_entries(_tags);
199  }
200 }
201 
202 void ResourceManager::delete_multiple_edge_props(const std::vector<bool>& _tags) {
203 
204  Properties::iterator ep_it = edge_props_.begin();
205  Properties::iterator ep_end = edge_props_.end();
206  for(; ep_it != ep_end; ++ep_it) {
207  (*ep_it)->delete_multiple_entries(_tags);
208  }
209  // Create tags vector for halfedges
210  std::vector<bool> hetags;
211  for(std::vector<bool>::const_iterator t_it = _tags.begin(),
212  t_end = _tags.end(); t_it != t_end; ++t_it) {
213  hetags.push_back(*t_it);
214  hetags.push_back(*t_it);
215  }
216  Properties::iterator hep_it = halfedge_props_.begin();
217  Properties::iterator hep_end = halfedge_props_.end();
218  for(; hep_it != hep_end; ++hep_it) {
219  (*hep_it)->delete_multiple_entries(hetags);
220  }
221 }
222 
223 void ResourceManager::delete_multiple_face_props(const std::vector<bool>& _tags) {
224 
225  Properties::iterator fp_it = face_props_.begin();
226  Properties::iterator fp_end = face_props_.end();
227  for(; fp_it != fp_end; ++fp_it) {
228  (*fp_it)->delete_multiple_entries(_tags);
229  }
230  // Create tags vector for halffaces
231  std::vector<bool> hftags;
232  for(std::vector<bool>::const_iterator t_it = _tags.begin(),
233  t_end = _tags.end(); t_it != t_end; ++t_it) {
234  hftags.push_back(*t_it);
235  hftags.push_back(*t_it);
236  }
237  Properties::iterator hfp_it = halfface_props_.begin();
238  Properties::iterator hfp_end = halfface_props_.end();
239  for(; hfp_it != hfp_end; ++hfp_it) {
240  (*hfp_it)->delete_multiple_entries(hftags);
241  }
242 }
243 
244 void ResourceManager::delete_multiple_cell_props(const std::vector<bool>& _tags) {
245 
246  Properties::iterator cp_it = cell_props_.begin();
247  Properties::iterator cp_end = cell_props_.end();
248  for(; cp_it != cp_end; ++cp_it) {
249  (*cp_it)->delete_multiple_entries(_tags);
250  }
251 }
252 
253 template<bool Move>
254 void ResourceManager::assignProperties(typename std::conditional<Move, Properties&, const Properties&>::type src,
255  Properties &dest)
256 {
257  // If possible, re-use existing properties instead of copying
258  // everything blindly.
259  Properties out;
260  out.reserve(src.size());
261  for (BaseProperty *srcprop: src) {
262  bool found = false;
263  for (auto it = dest.begin(); it != dest.end(); ++it) {
264  auto dstprop = *it;
265  if (dstprop->name() == srcprop->name()
266  && dstprop->internal_type_name() == srcprop->internal_type_name())
267  {
268  out.push_back(dstprop);
269  dest.erase(it);
270  if (Move) {
271  dstprop->move_values_from(srcprop);
272  } else {
273  dstprop->assign_values_from(srcprop);
274  }
275  found = true;
276  break;
277  }
278  }
279  if (!found) {
280  if (Move) {
281  out.push_back(srcprop);
282  } else {
283  out.push_back(srcprop->clone(*this, OpenVolumeMeshHandle(-1)));
284  }
285  }
286  }
287  updatePropHandles(out);
288  dest = std::move(out);
289 }
290 
291 template<bool Move>
292 void ResourceManager::assignAllPropertiesFrom(typename std::conditional<Move, ResourceManager*, const ResourceManager*>::type other)
293 {
294  assignProperties<Move>(other->vertex_props_, vertex_props_);
295  assignProperties<Move>(other->edge_props_, edge_props_);
296  assignProperties<Move>(other->halfedge_props_, halfedge_props_);
297  assignProperties<Move>(other->face_props_, face_props_);
298  assignProperties<Move>(other->halfface_props_, halfface_props_);
299  assignProperties<Move>(other->cell_props_, cell_props_);
300  assignProperties<Move>(other->mesh_props_, mesh_props_);
301 }
302 
303 template<>
304 ResourceManager::Properties&
305 ResourceManager::entity_props<Entity::Vertex>()
306 {
307  return vertex_props_;
308 }
309 template<>
310 ResourceManager::Properties&
311 ResourceManager::entity_props<Entity::Edge>()
312 {
313  return edge_props_;
314 }
315 template<>
316 ResourceManager::Properties&
317 ResourceManager::entity_props<Entity::HalfEdge>()
318 {
319  return halfedge_props_;
320 }
321 template<>
322 ResourceManager::Properties&
323 ResourceManager::entity_props<Entity::Face>()
324 {
325  return face_props_;
326 }
327 template<>
328 ResourceManager::Properties&
329 ResourceManager::entity_props<Entity::HalfFace>()
330 {
331  return halfface_props_;
332 }
333 template<>
334 ResourceManager::Properties&
335 ResourceManager::entity_props<Entity::Cell>()
336 {
337  return cell_props_;
338 }
339 template<>
340 ResourceManager::Properties&
341 ResourceManager::entity_props<Entity::Mesh>()
342 {
343  return mesh_props_;
344 }
345 
346 template<>
347 size_t ResourceManager::n<Entity::Vertex>()
348 {
349  return n_vertices();
350 }
351 template<>
352 size_t ResourceManager::n<Entity::Edge>()
353 {
354  return n_edges();
355 }
356 template<>
357 size_t ResourceManager::n<Entity::HalfEdge>()
358 {
359  return n_halfedges();
360 }
361 template<>
362 size_t ResourceManager::n<Entity::Face>()
363 {
364  return n_faces();
365 }
366 template<>
367 size_t ResourceManager::n<Entity::HalfFace>()
368 {
369  return n_halffaces();
370 }
371 
372 template<>
373 size_t ResourceManager::n<Entity::Cell>()
374 {
375  return n_cells();
376 }
377 
378 template<>
379 size_t ResourceManager::n<Entity::Mesh>()
380 {
381  return 1;
382 }
383 
384 
385 
386 } // Namespace OpenVolumeMesh
void resize_cprops(size_t _nc)
Change size of stored cell properties.
virtual size_t n_edges() const =0
Get number of edges in mesh.
void resize_eprops(size_t _ne)
Change size of stored edge properties.
virtual size_t n_cells() const =0
Get number of cells in mesh.
size_t uidx() const
return unsigned idx - handle must be valid
virtual size_t n_halfedges() const =0
Get number of halfedges in mesh.
void resize_fprops(size_t _nf)
Change size of stored face properties.
virtual size_t n_halffaces() const =0
Get number of halffaces in mesh.
virtual size_t n_vertices() const =0
Get number of vertices in mesh.
virtual size_t n_faces() const =0
Get number of faces in mesh.
void resize_vprops(size_t _nv)
Change size of stored vertex properties.