Developer Documentation
TopologyKernel.hh
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 #ifndef TOPOLOGYKERNEL_HH_
36 #define TOPOLOGYKERNEL_HH_
37 
38 #include <cassert>
39 #include <set>
40 #include <vector>
41 
42 #include "BaseEntities.hh"
43 #include "OpenVolumeMeshHandle.hh"
44 #include "ResourceManager.hh"
45 #include "Iterators.hh"
46 #include "OpenVolumeMesh/Config/Export.hh"
47 
48 namespace OpenVolumeMesh {
49 
50 class OVM_EXPORT TopologyKernel : public ResourceManager {
51 public:
52 
53  TopologyKernel() = default;
54  ~TopologyKernel() override = default;
55 
56  TopologyKernel& operator=(const TopologyKernel&) = default;
57 
58  void assign(const TopologyKernel *other) {
59  assert(other != nullptr);
60  *this = *other;
61  }
62 
63  /*
64  * Defines and constants
65  */
66 
67  static const VertexHandle InvalidVertexHandle;
68  static const EdgeHandle InvalidEdgeHandle;
69  static const FaceHandle InvalidFaceHandle;
70  static const CellHandle InvalidCellHandle;
71  static const HalfEdgeHandle InvalidHalfEdgeHandle;
72  static const HalfFaceHandle InvalidHalfFaceHandle;
73 
74  typedef OpenVolumeMeshEdge Edge;
75  typedef OpenVolumeMeshFace Face;
76  typedef OpenVolumeMeshCell Cell;
77 
78  // Add StatusAttrib to list of friend classes
79  // since it provides a garbage collection
80  // that needs access to some protected methods
81  friend class StatusAttrib;
82 
83  //=====================================================================
84  // Iterators
85  //=====================================================================
86 
87  friend class VertexOHalfEdgeIter;
88  friend class VertexVertexIter;
89  friend class HalfEdgeHalfFaceIter;
90  friend class VertexFaceIter;
91  friend class VertexCellIter;
92  friend class HalfEdgeCellIter;
93  friend class CellVertexIter;
94  friend class CellCellIter;
95  friend class HalfFaceVertexIter;
96  friend class BoundaryHalfFaceHalfFaceIter;
97  friend class VertexIter;
98  friend class EdgeIter;
99  friend class HalfEdgeIter;
100  friend class FaceIter;
101  friend class HalfFaceIter;
102  friend class CellIter;
103 
104  /*
105  * Circulators
106  */
107 
108 protected:
109  template <class Circulator>
110  static Circulator make_end_circulator(const Circulator& _circ)
111  {
112  Circulator end = _circ;
113  if (end.valid()) {
114  end.lap(_circ.max_laps());
115  end.valid(false);
116  }
117  return end;
118  }
119 
120 public:
121 
122  VertexVertexIter vv_iter(const VertexHandle& _h, int _max_laps = 1) const {
123  return VertexVertexIter(_h, this, _max_laps);
124  }
125 
126  std::pair<VertexVertexIter, VertexVertexIter> vertex_vertices(const VertexHandle& _h, int _max_laps = 1) const {
127  VertexVertexIter begin = vv_iter(_h, _max_laps);
128  return std::make_pair(begin, make_end_circulator(begin));
129  }
130 
131  VertexOHalfEdgeIter voh_iter(const VertexHandle& _h, int _max_laps = 1) const {
132  return VertexOHalfEdgeIter(_h, this, _max_laps);
133  }
134 
135  std::pair<VertexOHalfEdgeIter, VertexOHalfEdgeIter> outgoing_halfedges(const VertexHandle& _h, int _max_laps = 1) const {
136  VertexOHalfEdgeIter begin = voh_iter(_h, _max_laps);
137  return std::make_pair(begin, make_end_circulator(begin));
138  }
139 
140  VertexIHalfEdgeIter vih_iter(const VertexHandle& _h, int _max_laps = 1) const {
141  return VertexIHalfEdgeIter(_h, this, _max_laps);
142  }
143 
144  std::pair<VertexIHalfEdgeIter, VertexIHalfEdgeIter> incoming_halfedges(const VertexHandle& _h, int _max_laps = 1) const {
145  VertexIHalfEdgeIter begin = vih_iter(_h, _max_laps);
146  return std::make_pair(begin, make_end_circulator(begin));
147  }
148 
149  VertexEdgeIter ve_iter(const VertexHandle& _h, int _max_laps = 1) const {
150  return VertexEdgeIter(_h, this, _max_laps);
151  }
152 
153  std::pair<VertexEdgeIter, VertexEdgeIter> vertex_edges(const VertexHandle& _h, int _max_laps = 1) const {
154  VertexEdgeIter begin = ve_iter(_h, _max_laps);
155  return std::make_pair(begin, make_end_circulator(begin));
156  }
157 
158  VertexHalfFaceIter vhf_iter(const VertexHandle& _h, int _max_laps = 1) const {
159  return VertexHalfFaceIter(_h, this, _max_laps);
160  }
161 
162  std::pair<VertexHalfFaceIter, VertexHalfFaceIter> vertex_halffaces(const VertexHandle& _h, int _max_laps = 1) const {
163  VertexHalfFaceIter begin = vhf_iter(_h, _max_laps);
164  return std::make_pair(begin, make_end_circulator(begin));
165  }
166 
167  VertexFaceIter vf_iter(const VertexHandle& _h, int _max_laps = 1) const {
168  return VertexFaceIter(_h, this, _max_laps);
169  }
170 
171  std::pair<VertexFaceIter, VertexFaceIter> vertex_faces(const VertexHandle& _h, int _max_laps = 1) const {
172  VertexFaceIter begin = vf_iter(_h, _max_laps);
173  return std::make_pair(begin, make_end_circulator(begin));
174  }
175 
176  VertexCellIter vc_iter(const VertexHandle& _h, int _max_laps = 1) const {
177  return VertexCellIter(_h, this, _max_laps);
178  }
179 
180  std::pair<VertexCellIter, VertexCellIter> vertex_cells(const VertexHandle& _h, int _max_laps = 1) const {
181  VertexCellIter begin = vc_iter(_h, _max_laps);
182  return std::make_pair(begin, make_end_circulator(begin));
183  }
184 
185  HalfEdgeHalfFaceIter hehf_iter(const HalfEdgeHandle& _h, int _max_laps = 1) const {
186  return HalfEdgeHalfFaceIter(_h, this, _max_laps);
187  }
188 
189  std::pair<HalfEdgeHalfFaceIter, HalfEdgeHalfFaceIter> halfedge_halffaces(const HalfEdgeHandle& _h, int _max_laps = 1) const {
190  HalfEdgeHalfFaceIter begin = hehf_iter(_h, _max_laps);
191  return std::make_pair(begin, make_end_circulator(begin));
192  }
193 
194  HalfEdgeFaceIter hef_iter(const HalfEdgeHandle& _h, int _max_laps = 1) const {
195  return HalfEdgeFaceIter(_h, this, _max_laps);
196  }
197 
198  std::pair<HalfEdgeFaceIter, HalfEdgeFaceIter> halfedge_faces(const HalfEdgeHandle& _h, int _max_laps = 1) const {
199  HalfEdgeFaceIter begin = hef_iter(_h, _max_laps);
200  return std::make_pair(begin, make_end_circulator(begin));
201  }
202 
203  HalfEdgeCellIter hec_iter(const HalfEdgeHandle& _h, int _max_laps = 1) const {
204  return HalfEdgeCellIter(_h, this, _max_laps);
205  }
206 
207  std::pair<HalfEdgeCellIter, HalfEdgeCellIter> halfedge_cells(const HalfEdgeHandle& _h, int _max_laps = 1) const {
208  HalfEdgeCellIter begin = hec_iter(_h, _max_laps);
209  return std::make_pair(begin, make_end_circulator(begin));
210  }
211 
212  EdgeHalfFaceIter ehf_iter(const EdgeHandle& _h, int _max_laps = 1) const {
213  return EdgeHalfFaceIter(_h, this, _max_laps);
214  }
215 
216  std::pair<EdgeHalfFaceIter, EdgeHalfFaceIter> edge_halffaces(const EdgeHandle& _h, int _max_laps = 1) const {
217  EdgeHalfFaceIter begin = ehf_iter(_h, _max_laps);
218  return std::make_pair(begin, make_end_circulator(begin));
219  }
220 
221  EdgeFaceIter ef_iter(const EdgeHandle& _h, int _max_laps = 1) const {
222  return EdgeFaceIter(_h, this, _max_laps);
223  }
224 
225  std::pair<EdgeFaceIter, EdgeFaceIter> edge_faces(const EdgeHandle& _h, int _max_laps = 1) const {
226  EdgeFaceIter begin = ef_iter(_h, _max_laps);
227  return std::make_pair(begin, make_end_circulator(begin));
228  }
229 
230  EdgeCellIter ec_iter(const EdgeHandle& _h, int _max_laps = 1) const {
231  return EdgeCellIter(_h, this, _max_laps);
232  }
233 
234  std::pair<EdgeCellIter, EdgeCellIter> edge_cells(const EdgeHandle& _h, int _max_laps = 1) const {
235  EdgeCellIter begin = ec_iter(_h, _max_laps);
236  return std::make_pair(begin, make_end_circulator(begin));
237  }
238 
239  HalfFaceHalfEdgeIter hfhe_iter(const HalfFaceHandle& _h, int _max_laps = 1) const {
240  return HalfFaceHalfEdgeIter(_h, this, _max_laps);
241  }
242 
243  std::pair<HalfFaceHalfEdgeIter, HalfFaceHalfEdgeIter> halfface_halfedges(const HalfFaceHandle& _h, int _max_laps = 1) const {
244  HalfFaceHalfEdgeIter begin = hfhe_iter(_h, _max_laps);
245  return std::make_pair(begin, make_end_circulator(begin));
246  }
247 
248  HalfFaceEdgeIter hfe_iter(const HalfFaceHandle& _h, int _max_laps = 1) const {
249  return HalfFaceEdgeIter(_h, this, _max_laps);
250  }
251 
252  std::pair<HalfFaceEdgeIter, HalfFaceEdgeIter> halfface_edges(const HalfFaceHandle& _h, int _max_laps = 1) const {
253  HalfFaceEdgeIter begin = hfe_iter(_h, _max_laps);
254  return std::make_pair(begin, make_end_circulator(begin));
255  }
256 
257  FaceVertexIter fv_iter(const FaceHandle& _h, int _max_laps = 1) const {
258  return FaceVertexIter(_h, this, _max_laps);
259  }
260 
261  std::pair<FaceVertexIter, FaceVertexIter> face_vertices(const FaceHandle& _h, int _max_laps = 1) const {
262  FaceVertexIter begin = fv_iter(_h, _max_laps);
263  return std::make_pair(begin, make_end_circulator(begin));
264  }
265 
266  FaceHalfEdgeIter fhe_iter(const FaceHandle& _h, int _max_laps = 1) const {
267  return FaceHalfEdgeIter(_h, this, _max_laps);
268  }
269 
270  std::pair<FaceHalfEdgeIter, FaceHalfEdgeIter> face_halfedges(const FaceHandle& _h, int _max_laps = 1) const {
271  FaceHalfEdgeIter begin = fhe_iter(_h, _max_laps);
272  return std::make_pair(begin, make_end_circulator(begin));
273  }
274 
275  FaceEdgeIter fe_iter(const FaceHandle& _h, int _max_laps = 1) const {
276  return FaceEdgeIter(_h, this, _max_laps);
277  }
278 
279  std::pair<FaceEdgeIter, FaceEdgeIter> face_edges(const FaceHandle& _h, int _max_laps = 1) const {
280  FaceEdgeIter begin = fe_iter(_h, _max_laps);
281  return std::make_pair(begin, make_end_circulator(begin));
282  }
283 
284  CellVertexIter cv_iter(const CellHandle& _h, int _max_laps = 1) const {
285  return CellVertexIter(_h, this, _max_laps);
286  }
287 
288  std::pair<CellVertexIter, CellVertexIter> cell_vertices(const CellHandle& _h, int _max_laps = 1) const {
289  CellVertexIter begin = cv_iter(_h, _max_laps);
290  return std::make_pair(begin, make_end_circulator(begin));
291  }
292 
293  CellHalfEdgeIter che_iter(const CellHandle& _h, int _max_laps = 1) const {
294  return CellHalfEdgeIter(_h, this, _max_laps);
295  }
296 
297  std::pair<CellHalfEdgeIter, CellHalfEdgeIter> cell_halfedges(const CellHandle& _h, int _max_laps = 1) const {
298  CellHalfEdgeIter begin = che_iter(_h, _max_laps);
299  return std::make_pair(begin, make_end_circulator(begin));
300  }
301 
302  CellEdgeIter ce_iter(const CellHandle& _h, int _max_laps = 1) const {
303  return CellEdgeIter(_h, this, _max_laps);
304  }
305 
306  std::pair<CellEdgeIter, CellEdgeIter> cell_edges(const CellHandle& _h, int _max_laps = 1) const {
307  CellEdgeIter begin = ce_iter(_h, _max_laps);
308  return std::make_pair(begin, make_end_circulator(begin));
309  }
310 
311  CellHalfFaceIter chf_iter(const CellHandle& _h, int _max_laps = 1) const {
312  return CellHalfFaceIter(_h, this, _max_laps);
313  }
314 
315  std::pair<CellHalfFaceIter, CellHalfFaceIter> cell_halffaces(const CellHandle& _h, int _max_laps = 1) const {
316  CellHalfFaceIter begin = chf_iter(_h, _max_laps);
317  return std::make_pair(begin, make_end_circulator(begin));
318  }
319 
320  CellFaceIter cf_iter(const CellHandle& _h, int _max_laps = 1) const {
321  return CellFaceIter(_h, this, _max_laps);
322  }
323 
324  std::pair<CellFaceIter, CellFaceIter> cell_faces(const CellHandle& _h, int _max_laps = 1) const {
325  CellFaceIter begin = cf_iter(_h, _max_laps);
326  return std::make_pair(begin, make_end_circulator(begin));
327  }
328 
329  CellCellIter cc_iter(const CellHandle& _h, int _max_laps = 1) const {
330  return CellCellIter(_h, this, _max_laps);
331  }
332 
333  std::pair<CellCellIter, CellCellIter> cell_cells(const CellHandle& _h, int _max_laps = 1) const {
334  CellCellIter begin = cc_iter(_h, _max_laps);
335  return std::make_pair(begin, make_end_circulator(begin));
336  }
337 
338  HalfFaceVertexIter hfv_iter(const HalfFaceHandle& _h, int _max_laps = 1) const {
339  return HalfFaceVertexIter(_h, this, _max_laps);
340  }
341 
342  std::pair<HalfFaceVertexIter, HalfFaceVertexIter> halfface_vertices(const HalfFaceHandle& _h, int _max_laps = 1) const {
343  HalfFaceVertexIter begin = hfv_iter(_h, _max_laps);
344  return std::make_pair(begin, make_end_circulator(begin));
345  }
346 
347  BoundaryHalfFaceHalfFaceIter bhfhf_iter(const HalfFaceHandle& _ref_h, int _max_laps = 1) const {
348  return BoundaryHalfFaceHalfFaceIter(_ref_h, this, _max_laps);
349  }
350 
351  std::pair<BoundaryHalfFaceHalfFaceIter, BoundaryHalfFaceHalfFaceIter> boundary_halfface_halffaces(const HalfFaceHandle& _h, int _max_laps = 1) const {
352  BoundaryHalfFaceHalfFaceIter begin = bhfhf_iter(_h, _max_laps);
353  return std::make_pair(begin, make_end_circulator(begin));
354  }
355 
356  /*
357  * Iterators
358  */
359 
360  BoundaryVertexIter bv_iter() const {
361  return BoundaryVertexIter(this);
362  }
363 
364  BoundaryHalfEdgeIter bhe_iter() const {
365  return BoundaryHalfEdgeIter(this);
366  }
367 
368  BoundaryEdgeIter be_iter() const {
369  return BoundaryEdgeIter(this);
370  }
371 
372  BoundaryHalfFaceIter bhf_iter() const {
373  return BoundaryHalfFaceIter(this);
374  }
375 
376  BoundaryFaceIter bf_iter() const {
377  return BoundaryFaceIter(this);
378  }
379 
380  BoundaryCellIter bc_iter() const {
381  return BoundaryCellIter(this);
382  }
383 
384  VertexIter v_iter() const {
385  return VertexIter(this);
386  }
387 
388  VertexIter vertices_begin() const {
389  return VertexIter(this, VertexHandle(0));
390  }
391 
392  VertexIter vertices_end() const {
393  return VertexIter(this, VertexHandle((int)n_vertices()));
394  }
395 
396  std::pair<VertexIter, VertexIter> vertices() const {
397  return std::make_pair(vertices_begin(), vertices_end());
398  }
399 
400  EdgeIter e_iter() const {
401  return EdgeIter(this);
402  }
403 
404  EdgeIter edges_begin() const {
405  return EdgeIter(this, EdgeHandle(0));
406  }
407 
408  EdgeIter edges_end() const {
409  return EdgeIter(this, EdgeHandle((int)edges_.size()));
410  }
411 
412  std::pair<EdgeIter, EdgeIter> edges() const {
413  return std::make_pair(edges_begin(), edges_end());
414  }
415 
416  HalfEdgeIter he_iter() const {
417  return HalfEdgeIter(this);
418  }
419 
420  HalfEdgeIter halfedges_begin() const {
421  return HalfEdgeIter(this, HalfEdgeHandle(0));
422  }
423 
424  HalfEdgeIter halfedges_end() const {
425  return HalfEdgeIter(this, HalfEdgeHandle((int)edges_.size() * 2));
426  }
427 
428  std::pair<HalfEdgeIter, HalfEdgeIter> halfedges() const {
429  return std::make_pair(halfedges_begin(), halfedges_end());
430  }
431 
432  FaceIter f_iter() const {
433  return FaceIter(this);
434  }
435 
436  FaceIter faces_begin() const {
437  return FaceIter(this, FaceHandle(0));
438  }
439 
440  FaceIter faces_end() const {
441  return FaceIter(this, FaceHandle((int)faces_.size()));
442  }
443 
444  std::pair<FaceIter, FaceIter> faces() const {
445  return std::make_pair(faces_begin(), faces_end());
446  }
447 
448  HalfFaceIter hf_iter() const {
449  return HalfFaceIter(this);
450  }
451 
452  HalfFaceIter halffaces_begin() const {
453  return HalfFaceIter(this, HalfFaceHandle(0));
454  }
455 
456  HalfFaceIter halffaces_end() const {
457  return HalfFaceIter(this, HalfFaceHandle((int)faces_.size() * 2));
458  }
459 
460  std::pair<HalfFaceIter, HalfFaceIter> halffaces() const {
461  return std::make_pair(halffaces_begin(), halffaces_end());
462  }
463 
464  CellIter c_iter() const {
465  return CellIter(this);
466  }
467 
468  CellIter cells_begin() const {
469  return CellIter(this, CellHandle(0));
470  }
471 
472  CellIter cells_end() const {
473  return CellIter(this, CellHandle((int)cells_.size()));
474  }
475 
476  std::pair<CellIter, CellIter> cells() const {
477  return std::make_pair(cells_begin(), cells_end());
478  }
479 
480  /*
481  * Convenience functions
482  */
483 
484  std::vector<VertexHandle> halfedge_vertices(const HalfEdgeHandle& _h) const {
485  std::vector<VertexHandle> res(2);
486  res[0] = from_vertex_handle(_h);
487  res[1] = to_vertex_handle(_h);
488  return res;
489  }
490 
491  std::vector<VertexHandle> edge_vertices(const EdgeHandle& _h) const {
492  return halfedge_vertices(halfedge_handle(_h, 0));
493  }
494 
495  std::vector<HalfEdgeHandle> edge_halfedges(const EdgeHandle& _h) const {
496  std::vector<HalfEdgeHandle> res(2);
497  res[0] = halfedge_handle(_h, 0);
498  res[1] = halfedge_handle(_h, 1);
499  return res;
500  }
501 
502  std::vector<HalfFaceHandle> face_halffaces(const FaceHandle& _h) const {
503  std::vector<HalfFaceHandle> res(2);
504  res[0] = halfface_handle(_h, 0);
505  res[1] = halfface_handle(_h, 1);
506  return res;
507  }
508 
509  std::vector<CellHandle> face_cells(const FaceHandle& _h) const {
510  std::vector<CellHandle> res(2);
511  res[0] = incident_cell(halfface_handle(_h, 0));
512  res[1] = incident_cell(halfface_handle(_h, 1));
513  return res;
514  }
515 
516  /*
517  * Virtual functions with implementation
518  */
519 
521  size_t n_vertices() const override { return n_vertices_; }
523  size_t n_edges() const override { return edges_.size(); }
525  size_t n_halfedges() const override { return edges_.size() * 2u; }
527  size_t n_faces() const override { return faces_.size(); }
529  size_t n_halffaces() const override { return faces_.size() * 2u; }
531  size_t n_cells() const override { return cells_.size(); }
532 
534  size_t n_logical_vertices() const { return n_vertices_ - n_deleted_vertices_; }
536  size_t n_logical_edges() const { return edges_.size() - n_deleted_edges_; }
538  size_t n_logical_halfedges() const { return n_logical_edges() * 2u; }
540  size_t n_logical_faces() const { return faces_.size() - n_deleted_faces_; }
542  size_t n_logical_halffaces() const { return n_faces() * 2u; }
544  size_t n_logical_cells() const { return cells_.size() - n_deleted_cells_; }
545 
546  int genus() const {
547 
548  int g = (1 - (int)(n_vertices() -
549  n_edges() +
550  n_faces() -
551  n_cells()));
552 
553  if(g % 2 == 0) return (g / 2);
554 
555  // An error occured
556  // The mesh might not be manifold
557  return -1;
558  }
559 
560 private:
561 
562  // Cache total vertex number
563  size_t n_vertices_ = 0u;
564 
565 public:
566 
568  virtual VertexHandle add_vertex();
569 
570  //=======================================================================
571 
573  virtual EdgeHandle add_edge(const VertexHandle& _fromVertex, const VertexHandle& _toHandle, bool _allowDuplicates = false);
574 
582  virtual FaceHandle add_face(const std::vector<HalfEdgeHandle>& _halfedges, bool _topologyCheck = false);
583 
585  virtual FaceHandle add_face(const std::vector<VertexHandle>& _vertices);
586 
594  virtual CellHandle add_cell(const std::vector<HalfFaceHandle>& _halffaces, bool _topologyCheck = false);
595 
597  void set_edge(const EdgeHandle& _eh, const VertexHandle& _fromVertex, const VertexHandle& _toVertex);
598 
600  void set_face(const FaceHandle& _fh, const std::vector<HalfEdgeHandle>& _hes);
601 
603  void set_cell(const CellHandle& _ch, const std::vector<HalfFaceHandle>& _hfs);
604 
605  /*
606  * Non-virtual functions
607  */
608 
610  const Edge& edge(const EdgeHandle& _edgeHandle) const;
611 
613  const Face& face(const FaceHandle& _faceHandle) const;
614 
616  const Cell& cell(const CellHandle& _cellHandle) const;
617 
619  Edge& edge(const EdgeHandle& _edgeHandle);
620 
622  Face& face(const FaceHandle& _faceHandle);
623 
625  Cell& cell(const CellHandle& _cellHandle);
626 
628  Edge halfedge(const HalfEdgeHandle& _halfEdgeHandle) const;
629 
631  Face halfface(const HalfFaceHandle& _halfFaceHandle) const;
632 
634  Edge opposite_halfedge(const HalfEdgeHandle& _halfEdgeHandle) const;
635 
637  Face opposite_halfface(const HalfFaceHandle& _halfFaceHandle) const;
638 
640  HalfEdgeHandle halfedge(const VertexHandle& _vh1, const VertexHandle& _vh2) const;
641 
645  HalfFaceHandle halfface(const std::vector<VertexHandle>& _vs) const;
646 
650  HalfFaceHandle halfface_extensive(const std::vector<VertexHandle>& _vs) const;
651 
655  HalfFaceHandle halfface(const std::vector<HalfEdgeHandle>& _hes) const;
656 
658  HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle& _heh, const HalfFaceHandle& _hfh) const;
659 
661  HalfEdgeHandle prev_halfedge_in_halfface(const HalfEdgeHandle& _heh, const HalfFaceHandle& _hfh) const;
662 
665  return halfedge(_h).from_vertex();
666  }
667 
670  return halfedge(_h).to_vertex();
671  }
672 
674  inline size_t valence(const VertexHandle& _vh) const {
675  assert(has_vertex_bottom_up_incidences());
676  assert(_vh.is_valid() && _vh.uidx() < outgoing_hes_per_vertex_.size());
677 
678  return outgoing_hes_per_vertex_[_vh.uidx()].size();
679  }
680 
682  inline size_t valence(const EdgeHandle& _eh) const {
683  assert(has_edge_bottom_up_incidences());
684  assert(_eh.is_valid() && _eh.uidx() < edges_.size());
685  assert(halfedge_handle(_eh, 0).uidx() < incident_hfs_per_he_.size());
686 
687  return incident_hfs_per_he_[halfedge_handle(_eh, 0).uidx()].size();
688  }
689 
691  inline size_t valence(const FaceHandle& _fh) const {
692  assert(_fh.is_valid() && _fh.uidx() < faces_.size());
693 
694  return face(_fh).halfedges().size();
695  }
696 
698  inline size_t valence(const CellHandle& _ch) const {
699  assert(_ch.is_valid() && _ch.uidx() < cells_.size());
700 
701  return cell(_ch).halffaces().size();
702  }
703 
704  //=====================================================================
705  // Delete entities
706  //=====================================================================
707 
708 public:
709 
710  virtual VertexIter delete_vertex(const VertexHandle& _h);
711 
712  virtual EdgeIter delete_edge(const EdgeHandle& _h);
713 
714  virtual FaceIter delete_face(const FaceHandle& _h);
715 
716  virtual CellIter delete_cell(const CellHandle& _h);
717 
718  virtual void collect_garbage();
719 
720 
721  virtual bool is_deleted(const VertexHandle& _h) const { return vertex_deleted_[_h.uidx()]; }
722  virtual bool is_deleted(const EdgeHandle& _h) const { return edge_deleted_[_h.uidx()]; }
723  virtual bool is_deleted(const HalfEdgeHandle& _h) const { return edge_deleted_[_h.uidx()/2]; }
724  virtual bool is_deleted(const FaceHandle& _h) const { return face_deleted_[_h.uidx()]; }
725  virtual bool is_deleted(const HalfFaceHandle& _h) const { return face_deleted_[_h.uidx()/2]; }
726  virtual bool is_deleted(const CellHandle& _h) const { return cell_deleted_[_h.uidx()]; }
727 
728 private:
729 
730  template <class ContainerT>
731  void get_incident_edges(const ContainerT& _vs, std::set<EdgeHandle>& _es) const;
732 
733  template <class ContainerT>
734  void get_incident_faces(const ContainerT& _es, std::set<FaceHandle>& _fs) const;
735 
736  template <class ContainerT>
737  void get_incident_cells(const ContainerT& _fs, std::set<CellHandle>& _cs) const;
738 
739  VertexIter delete_vertex_core(const VertexHandle& _h);
740 
741  EdgeIter delete_edge_core(const EdgeHandle& _h);
742 
743  FaceIter delete_face_core(const FaceHandle& _h);
744 
745  CellIter delete_cell_core(const CellHandle& _h);
746 
747 public:
748 
750  virtual void swap_cell_indices(CellHandle _h1, CellHandle _h2);
751 
753  virtual void swap_face_indices(FaceHandle _h1, FaceHandle _h2);
754 
756  virtual void swap_edge_indices(EdgeHandle _h1, EdgeHandle _h2);
757 
759  virtual void swap_vertex_indices(VertexHandle _h1, VertexHandle _h2);
760 
761 protected:
762 
763  virtual void delete_multiple_vertices(const std::vector<bool>& _tag);
764 
765  virtual void delete_multiple_edges(const std::vector<bool>& _tag);
766 
767  virtual void delete_multiple_faces(const std::vector<bool>& _tag);
768 
769  virtual void delete_multiple_cells(const std::vector<bool>& _tag);
770 
772  public:
773  explicit EdgeCorrector(const std::vector<int>& _newIndices) :
774  newIndices_(_newIndices) {}
775 
776  void operator()(Edge& _edge) {
777  _edge.set_from_vertex(VertexHandle(newIndices_[_edge.from_vertex().uidx()]));
778  _edge.set_to_vertex(VertexHandle(newIndices_[_edge.to_vertex().uidx()]));
779  }
780  private:
781  const std::vector<int>& newIndices_;
782  };
783 
785  public:
786  explicit FaceCorrector(const std::vector<int>& _newIndices) :
787  newIndices_(_newIndices) {}
788 
789  void operator()(Face& _face) {
790  std::vector<HalfEdgeHandle> hes = _face.halfedges();
791  for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
792  he_end = hes.end(); he_it != he_end; ++he_it) {
793 
794  EdgeHandle eh = edge_handle(*he_it);
795  unsigned char opp = he_it->idx() == halfedge_handle(eh, 1).idx();
796  *he_it = halfedge_handle(EdgeHandle(newIndices_[eh.uidx()]), opp);
797  }
798  _face.set_halfedges(hes);
799  }
800  private:
801  const std::vector<int>& newIndices_;
802  };
803 
805  public:
806  explicit CellCorrector(const std::vector<int>& _newIndices) :
807  newIndices_(_newIndices) {}
808 
809  void operator()(Cell& _cell) {
810  std::vector<HalfFaceHandle> hfs = _cell.halffaces();
811  for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
812  hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
813 
814  FaceHandle fh = face_handle(*hf_it);
815  unsigned char opp = hf_it->idx() == halfface_handle(fh, 1).idx();
816  *hf_it = halfface_handle(FaceHandle(newIndices_[fh.uidx()]), opp);
817  }
818  _cell.set_halffaces(hfs);
819  }
820  private:
821  const std::vector<int>& newIndices_;
822  };
823 
824 public:
825 
834  CellIter delete_cell_range(const CellIter& _first, const CellIter& _last);
835 
836 public:
837 
839  virtual void clear(bool _clearProps = true) {
840 
841  edges_.clear();
842  faces_.clear();
843  cells_.clear();
844  vertex_deleted_.clear();
845  edge_deleted_.clear();
846  face_deleted_.clear();
847  cell_deleted_.clear();
848  n_deleted_vertices_ = 0;
849  n_deleted_edges_ = 0;
850  n_deleted_faces_ = 0;
851  n_deleted_cells_ = 0;
852  outgoing_hes_per_vertex_.clear();
853  incident_hfs_per_he_.clear();
854  incident_cell_per_hf_.clear();
855  n_vertices_ = 0;
856 
857  if(_clearProps) {
858 
859  // Delete all property data
860  clear_vertex_props();
861  clear_edge_props();
862  clear_halfedge_props();
863  clear_face_props();
864  clear_halfface_props();
865  clear_cell_props();
866  clear_mesh_props();
867 
868  } else {
869  // Resize props
870  resize_vprops(0u);
871  resize_eprops(0u);
872  resize_fprops(0u);
873  resize_cprops(0u);
874  }
875  }
876 
877  //=====================================================================
878  // Bottom-up Incidences
879  //=====================================================================
880 
881 public:
882 
883  void enable_bottom_up_incidences(bool _enable = true) {
884 
885  enable_vertex_bottom_up_incidences(_enable);
886  enable_edge_bottom_up_incidences(_enable);
887  enable_face_bottom_up_incidences(_enable);
888  }
889 
890  void enable_vertex_bottom_up_incidences(bool _enable = true) {
891 
892  if(_enable && !v_bottom_up_) {
893  // Vertex bottom-up incidences have to be
894  // recomputed for the whole mesh
895  compute_vertex_bottom_up_incidences();
896  }
897 
898  if(!_enable) {
899  outgoing_hes_per_vertex_.clear();
900  }
901 
902  v_bottom_up_ = _enable;
903  }
904 
905  void enable_edge_bottom_up_incidences(bool _enable = true) {
906 
907  if(_enable && !e_bottom_up_) {
908  // Edge bottom-up incidences have to be
909  // recomputed for the whole mesh
910  compute_edge_bottom_up_incidences();
911 
912  if(f_bottom_up_) {
913 #if defined(__clang_major__) && (__clang_major__ >= 5)
914  for(EdgeIter e_it = edges_begin(), e_end = edges_end();
915  e_it != e_end; ++e_it) {
916  reorder_incident_halffaces(*e_it);
917  }
918 #else
919  std::for_each(edges_begin(), edges_end(),
920  fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1));
921 #endif
922  }
923  }
924 
925  if(!_enable) {
926  incident_hfs_per_he_.clear();
927  }
928 
929  e_bottom_up_ = _enable;
930  }
931 
932  void enable_face_bottom_up_incidences(bool _enable = true) {
933 
934  bool updateOrder = false;
935  if(_enable && !f_bottom_up_) {
936  // Face bottom-up incidences have to be
937  // recomputed for the whole mesh
938  compute_face_bottom_up_incidences();
939 
940  updateOrder = true;
941  }
942 
943  if(!_enable) {
944  incident_cell_per_hf_.clear();
945  }
946 
947  f_bottom_up_ = _enable;
948 
949  if(updateOrder) {
950  if(e_bottom_up_) {
951 #if defined(__clang_major__) && (__clang_major__ >= 5)
952  for(EdgeIter e_it = edges_begin(), e_end = edges_end();
953  e_it != e_end; ++e_it) {
954  reorder_incident_halffaces(*e_it);
955  }
956 #else
957  std::for_each(edges_begin(), edges_end(),
958  fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1));
959 #endif
960  }
961  }
962  }
963 
964  bool has_full_bottom_up_incidences() const {
965  return (has_vertex_bottom_up_incidences() &&
966  has_edge_bottom_up_incidences() &&
967  has_face_bottom_up_incidences());
968  }
969 
970  bool has_vertex_bottom_up_incidences() const { return v_bottom_up_; }
971 
972  bool has_edge_bottom_up_incidences() const { return e_bottom_up_; }
973 
974  bool has_face_bottom_up_incidences() const { return f_bottom_up_; }
975 
976 
977  void enable_deferred_deletion(bool _enable = true);
978  bool deferred_deletion_enabled() const { return deferred_deletion; }
979 
980 
981  void enable_fast_deletion(bool _enable = true) { fast_deletion = _enable; }
982  bool fast_deletion_enabled() const { return fast_deletion; }
983 
984 
985 protected:
986 
987  void compute_vertex_bottom_up_incidences();
988 
989  void compute_edge_bottom_up_incidences();
990 
991  void compute_face_bottom_up_incidences();
992 
993  void reorder_incident_halffaces(const EdgeHandle& _eh);
994 
995  // Outgoing halfedges per vertex
996  std::vector<std::vector<HalfEdgeHandle> > outgoing_hes_per_vertex_;
997 
998  // Incident halffaces per (directed) halfedge
999  std::vector<std::vector<HalfFaceHandle> > incident_hfs_per_he_;
1000 
1001  // Incident cell (at most one) per halfface
1002  std::vector<CellHandle> incident_cell_per_hf_;
1003 
1004 private:
1005  bool v_bottom_up_ = true;
1006 
1007  bool e_bottom_up_ = true;
1008 
1009  bool f_bottom_up_ = true;
1010 
1011  bool deferred_deletion = true;
1012 
1013  bool fast_deletion = true;
1014 
1015  //=====================================================================
1016  // Connectivity
1017  //=====================================================================
1018 
1019 public:
1020 
1027  HalfFaceHandle adjacent_halfface_in_cell(const HalfFaceHandle& _halfFaceHandle, const HalfEdgeHandle& _halfEdgeHandle) const;
1028 
1030  CellHandle incident_cell(const HalfFaceHandle& _halfFaceHandle) const;
1031 
1032  bool is_boundary(const HalfFaceHandle& _halfFaceHandle) const {
1033 
1034  assert(_halfFaceHandle.is_valid() && _halfFaceHandle.uidx() < faces_.size() * 2u);
1035  assert(has_face_bottom_up_incidences());
1036  assert(_halfFaceHandle.uidx() < incident_cell_per_hf_.size());
1037  return incident_cell_per_hf_[_halfFaceHandle.uidx()] == InvalidCellHandle;
1038  }
1039 
1040  bool is_boundary(const FaceHandle& _faceHandle) const {
1041  assert(_faceHandle.is_valid() && _faceHandle.uidx() < faces_.size());
1042  assert(has_face_bottom_up_incidences());
1043  return is_boundary(halfface_handle(_faceHandle, 0)) ||
1044  is_boundary(halfface_handle(_faceHandle, 1));
1045  }
1046 
1047  bool is_boundary(const EdgeHandle& _edgeHandle) const {
1048  assert(has_edge_bottom_up_incidences());
1049  assert(_edgeHandle.is_valid() && _edgeHandle.uidx() < edges_.size());
1050 
1051  for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(halfedge_handle(_edgeHandle, 0));
1052  hehf_it.valid(); ++hehf_it) {
1053  if(is_boundary(face_handle(*hehf_it))) {
1054  return true;
1055  }
1056  }
1057  return false;
1058  }
1059 
1060  bool is_boundary(const HalfEdgeHandle& _halfedgeHandle) const {
1061  assert(has_edge_bottom_up_incidences());
1062  assert(_halfedgeHandle.is_valid() && _halfedgeHandle.uidx() < edges_.size() * 2u);
1063 
1064  for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(_halfedgeHandle);
1065  hehf_it.valid(); ++hehf_it) {
1066  if(is_boundary(face_handle(*hehf_it))) {
1067  return true;
1068  }
1069  }
1070  return false;
1071  }
1072 
1073  bool is_boundary(const VertexHandle& _vertexHandle) const {
1074  assert(has_vertex_bottom_up_incidences());
1075  assert(_vertexHandle.is_valid() && _vertexHandle.uidx() < n_vertices());
1076 
1077  for(VertexOHalfEdgeIter voh_it = voh_iter(_vertexHandle); voh_it.valid(); ++voh_it) {
1078  if(is_boundary(*voh_it)) return true;
1079  }
1080  return false;
1081  }
1082 
1083  bool is_boundary(const CellHandle& _cellHandle) const {
1084  assert(_cellHandle.is_valid() && (size_t)_cellHandle.idx() < n_cells());
1085 
1086  for(CellFaceIter cf_it = cf_iter(_cellHandle); cf_it.valid(); ++cf_it) {
1087  if(is_boundary(*cf_it)) return true;
1088  }
1089  return false;
1090  }
1091 
1092  size_t n_vertices_in_cell(const CellHandle& _ch) const {
1093  assert(_ch.is_valid() && _ch.uidx() < cells_.size());
1094 
1095  std::set<VertexHandle> vhs;
1096  std::vector<HalfFaceHandle> hfs = cell(_ch).halffaces();
1097  for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
1098  hf_it != hfs.end(); ++hf_it) {
1099  std::vector<HalfEdgeHandle> hes = halfface(*hf_it).halfedges();
1100  for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
1101  he_it != hes.end(); ++he_it) {
1102  vhs.insert(halfedge(*he_it).to_vertex());
1103  }
1104  }
1105  return vhs.size();
1106  }
1107 
1108  //=========================================================================
1109 
1110  /*
1111  * Non-virtual functions
1112  */
1113 
1114  Edge opposite_halfedge(const Edge& _edge) const {
1115  return Edge(_edge.to_vertex(), _edge.from_vertex());
1116  }
1117 
1118  Face opposite_halfface(const Face& _face) const {
1119  std::vector<HalfEdgeHandle> opp_halfedges;
1120  for(std::vector<HalfEdgeHandle>::const_iterator it = _face.halfedges().begin(); it
1121  != _face.halfedges().end(); ++it) {
1122  opp_halfedges.insert(opp_halfedges.begin(), opposite_halfedge_handle(*it));
1123  }
1124 
1125  return Face(opp_halfedges);
1126  }
1127 
1128  /*
1129  * Static functions
1130  */
1131 
1133  static inline HalfEdgeHandle halfedge_handle(const EdgeHandle& _h, const unsigned char _subIdx) {
1134  // Is handle in range?
1135  assert(_h.is_valid());
1136  assert(_subIdx < 2);
1137  // if(_h.idx() < 0 || _subIdx > 1) return InvalidHalfEdgeHandle;
1138  return HalfEdgeHandle((2 * _h.idx()) + (_subIdx ? 1 : 0));
1139  }
1140 
1142  static inline HalfFaceHandle halfface_handle(const FaceHandle& _h, const unsigned char _subIdx) {
1143  // Is handle in range?
1144  assert(_h.is_valid());
1145  assert(_subIdx < 2);
1146  // if(_h.idx() < 0 || _subIdx > 1) return InvalidHalfFaceHandle;
1147  return HalfFaceHandle((2 * _h.idx()) + (_subIdx ? 1 : 0));
1148  }
1149 
1151  static inline EdgeHandle edge_handle(const HalfEdgeHandle& _h) {
1152  // Is handle in range?
1153  assert(_h.is_valid());
1154  // if(_h.idx() < 0) return InvalidEdgeHandle;
1155  return EdgeHandle((int)(_h.idx() / 2));
1156  }
1157 
1158  static inline FaceHandle face_handle(const HalfFaceHandle& _h) {
1159  // Is handle in range?
1160  assert(_h.is_valid());
1161  // if(_h.idx() < 0) return InvalidFaceHandle;
1162  return FaceHandle((int)(_h.idx() / 2));
1163  }
1164 
1165  static inline HalfEdgeHandle opposite_halfedge_handle(const HalfEdgeHandle& _h) {
1166  // Is handle in range?
1167  assert(_h.is_valid());
1168  // if(_h.idx() < 0) return InvalidHalfEdgeHandle;
1169 
1170  // Is handle even?
1171  if(_h.idx() % 2 == 0) {
1172  return HalfEdgeHandle(_h.idx() + 1);
1173  }
1174  return HalfEdgeHandle(_h.idx() - 1);
1175  }
1176 
1177  static inline HalfFaceHandle opposite_halfface_handle(const HalfFaceHandle& _h) {
1178  // Is handle in range?
1179  assert(_h.is_valid());
1180  // if(_h.idx() < 0) return InvalidHalfFaceHandle;
1181 
1182  // Is handle even?
1183  if(_h.idx() % 2 == 0) {
1184  return HalfFaceHandle(_h.idx() + 1);
1185  }
1186  return HalfFaceHandle(_h.idx() - 1);
1187  }
1188 
1189  bool inline needs_garbage_collection() const {
1190  return n_deleted_vertices_ > 0 || n_deleted_edges_ > 0 || n_deleted_faces_ > 0 || n_deleted_cells_ > 0;
1191  }
1192 
1193 protected:
1194 
1195  // List of edges
1196  std::vector<Edge> edges_;
1197 
1198  // List of faces
1199  std::vector<Face> faces_;
1200 
1201  // List of cells
1202  std::vector<Cell> cells_;
1203 
1204  std::vector<bool> vertex_deleted_;
1205  std::vector<bool> edge_deleted_;
1206  std::vector<bool> face_deleted_;
1207  std::vector<bool> cell_deleted_;
1208 
1209  // number of elements deleted, but not yet garbage collected
1210  size_t n_deleted_vertices_ = 0;
1211  size_t n_deleted_edges_ = 0;
1212  size_t n_deleted_faces_ = 0;
1213  size_t n_deleted_cells_ = 0;
1214 
1215 };
1216 
1217 }
1218 
1219 #endif /* TOPOLOGYKERNEL_HH_ */
size_t n_edges() const override
Get number of edges in mesh.
size_t valence(const VertexHandle &_vh) const
Get valence of vertex (number of incident edges)
virtual void clear(bool _clearProps=true)
Clear whole mesh.
size_t n_logical_halffaces() const
Get number of undeleted halffaces in mesh.
size_t n_cells() const override
Get number of cells in mesh.
size_t n_logical_cells() const
Get number of undeleted cells in mesh.
size_t uidx() const
return unsigned idx - handle must be valid
VertexHandle to_vertex_handle(const HalfEdgeHandle &_h) const
Get the vertex the halfedge points to.
size_t n_logical_vertices() const
Get number of undeleted vertices in mesh.
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
size_t valence(const EdgeHandle &_eh) const
Get valence of edge (number of incident faces)
static HalfFaceHandle halfface_handle(const FaceHandle &_h, const unsigned char _subIdx)
Conversion function.
size_t n_faces() const override
Get number of faces in mesh.
size_t n_vertices() const override
Get number of vertices in mesh.
size_t valence(const CellHandle &_ch) const
Get valence of cell (number of incident faces)
size_t valence(const FaceHandle &_fh) const
Get valence of face (number of incident edges)
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:101
VertexHandle from_vertex_handle(const HalfEdgeHandle &_h) const
Get the vertex the halfedge starts from.
size_t n_logical_faces() const
Get number of undeleted faces in mesh.
size_t n_halffaces() const override
Get number of halffaces in mesh.
size_t n_logical_edges() const
Get number of undeleted edges in mesh.
size_t n_logical_halfedges() const
Get number of undeleted halfedges in mesh.
static HalfEdgeHandle halfedge_handle(const EdgeHandle &_h, const unsigned char _subIdx)
Conversion function.
size_t n_halfedges() const override
Get number of halfedges in mesh.