Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 /*===========================================================================*\
36  * *
37  * $Revision$ *
38  * $Date$ *
39  * $LastChangedBy$ *
40  * *
41 \*===========================================================================*/
42 
43 #ifndef TOPOLOGYKERNEL_HH_
44 #define TOPOLOGYKERNEL_HH_
45 
46 #include <cassert>
47 #include <set>
48 #include <vector>
49 
50 #include "BaseEntities.hh"
51 #include "OpenVolumeMeshHandle.hh"
52 #include "ResourceManager.hh"
53 #include "Iterators.hh"
54 
55 namespace OpenVolumeMesh {
56 
58 public:
59 
61  virtual ~TopologyKernel();
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 BoundaryFaceIter;
98  friend class VertexIter;
99  friend class EdgeIter;
100  friend class HalfEdgeIter;
101  friend class FaceIter;
102  friend class HalfFaceIter;
103  friend class CellIter;
104 
105  /*
106  * Circulators
107  */
108 
109 protected:
110  template <class Circulator>
111  static Circulator make_end_circulator(const Circulator& _circ)
112  {
113  Circulator end = _circ;
114  if (end.valid()) {
115  end.lap(_circ.max_laps());
116  end.valid(false);
117  }
118  return end;
119  }
120 
121 public:
122 
123  VertexOHalfEdgeIter voh_iter(const VertexHandle& _h, int _max_laps = 1) const {
124  return VertexOHalfEdgeIter(_h, this, _max_laps);
125  }
126 
127  std::pair<VertexOHalfEdgeIter, VertexOHalfEdgeIter> outgoing_halfedges(const VertexHandle& _h, int _max_laps = 1) const {
128  VertexOHalfEdgeIter begin = voh_iter(_h, _max_laps);
129  return std::make_pair(begin, make_end_circulator(begin));
130  }
131 
132  VertexVertexIter vv_iter(const VertexHandle& _h, int _max_laps = 1) const {
133  return VertexVertexIter(_h, this, _max_laps);
134  }
135 
136  std::pair<VertexVertexIter, VertexVertexIter> vertex_vertices(const VertexHandle& _h, int _max_laps = 1) const {
137  VertexVertexIter begin = vv_iter(_h, _max_laps);
138  return std::make_pair(begin, make_end_circulator(begin));
139  }
140 
141  HalfEdgeHalfFaceIter hehf_iter(const HalfEdgeHandle& _h, int _max_laps = 1) const {
142  return HalfEdgeHalfFaceIter(_h, this, _max_laps);
143  }
144 
145  std::pair<HalfEdgeHalfFaceIter, HalfEdgeHalfFaceIter> halfedge_halffaces(const HalfEdgeHandle& _h, int _max_laps = 1) const {
146  HalfEdgeHalfFaceIter begin = hehf_iter(_h, _max_laps);
147  return std::make_pair(begin, make_end_circulator(begin));
148  }
149 
150  VertexFaceIter vf_iter(const VertexHandle& _h, int _max_laps = 1) const {
151  return VertexFaceIter(_h, this, _max_laps);
152  }
153 
154  std::pair<VertexFaceIter, VertexFaceIter> vertex_faces(const VertexHandle& _h, int _max_laps = 1) const {
155  VertexFaceIter begin = vf_iter(_h, _max_laps);
156  return std::make_pair(begin, make_end_circulator(begin));
157  }
158 
159  VertexCellIter vc_iter(const VertexHandle& _h, int _max_laps = 1) const {
160  return VertexCellIter(_h, this, _max_laps);
161  }
162 
163  std::pair<VertexCellIter, VertexCellIter> vertex_cells(const VertexHandle& _h, int _max_laps = 1) const {
164  VertexCellIter begin = vc_iter(_h, _max_laps);
165  return std::make_pair(begin, make_end_circulator(begin));
166  }
167 
168  HalfEdgeCellIter hec_iter(const HalfEdgeHandle& _h, int _max_laps = 1) const {
169  return HalfEdgeCellIter(_h, this, _max_laps);
170  }
171 
172  std::pair<HalfEdgeCellIter, HalfEdgeCellIter> halfedge_cells(const HalfEdgeHandle& _h, int _max_laps = 1) const {
173  HalfEdgeCellIter begin = hec_iter(_h, _max_laps);
174  return std::make_pair(begin, make_end_circulator(begin));
175  }
176 
177  CellVertexIter cv_iter(const CellHandle& _h, int _max_laps = 1) const {
178  return CellVertexIter(_h, this, _max_laps);
179  }
180 
181  std::pair<CellVertexIter, CellVertexIter> cell_vertices(const CellHandle& _h, int _max_laps = 1) const {
182  CellVertexIter begin = cv_iter(_h, _max_laps);
183  return std::make_pair(begin, make_end_circulator(begin));
184  }
185 
186  CellCellIter cc_iter(const CellHandle& _h, int _max_laps = 1) const {
187  return CellCellIter(_h, this, _max_laps);
188  }
189 
190  std::pair<CellCellIter, CellCellIter> cell_cells(const CellHandle& _h, int _max_laps = 1) const {
191  CellCellIter begin = cc_iter(_h, _max_laps);
192  return std::make_pair(begin, make_end_circulator(begin));
193  }
194 
195  HalfFaceVertexIter hfv_iter(const HalfFaceHandle& _h, int _max_laps = 1) const {
196  return HalfFaceVertexIter(_h, this, _max_laps);
197  }
198 
199  std::pair<HalfFaceVertexIter, HalfFaceVertexIter> halfface_vertices(const HalfFaceHandle& _h, int _max_laps = 1) const {
200  HalfFaceVertexIter begin = hfv_iter(_h, _max_laps);
201  return std::make_pair(begin, make_end_circulator(begin));
202  }
203 
204  BoundaryHalfFaceHalfFaceIter bhfhf_iter(const HalfFaceHandle& _ref_h, int _max_laps = 1) const {
205  return BoundaryHalfFaceHalfFaceIter(_ref_h, this, _max_laps);
206  }
207 
208  std::pair<BoundaryHalfFaceHalfFaceIter, BoundaryHalfFaceHalfFaceIter> boundary_halfface_halffaces(const HalfFaceHandle& _h, int _max_laps = 1) const {
209  BoundaryHalfFaceHalfFaceIter begin = bhfhf_iter(_h, _max_laps);
210  return std::make_pair(begin, make_end_circulator(begin));
211  }
212 
213  /*
214  * Iterators
215  */
216 
217  BoundaryFaceIter bf_iter() const {
218  return BoundaryFaceIter(this);
219  }
220 
221  VertexIter v_iter() const {
222  return VertexIter(this);
223  }
224 
225  VertexIter vertices_begin() const {
226  return VertexIter(this, VertexHandle(0));
227  }
228 
229  VertexIter vertices_end() const {
230  return VertexIter(this, VertexHandle((int)n_vertices()));
231  }
232 
233  std::pair<VertexIter, VertexIter> vertices() const {
234  return std::make_pair(vertices_begin(), vertices_end());
235  }
236 
237  EdgeIter e_iter() const {
238  return EdgeIter(this);
239  }
240 
241  EdgeIter edges_begin() const {
242  return EdgeIter(this, EdgeHandle(0));
243  }
244 
245  EdgeIter edges_end() const {
246  return EdgeIter(this, EdgeHandle((int)edges_.size()));
247  }
248 
249  std::pair<EdgeIter, EdgeIter> edges() const {
250  return std::make_pair(edges_begin(), edges_end());
251  }
252 
253  HalfEdgeIter he_iter() const {
254  return HalfEdgeIter(this);
255  }
256 
257  HalfEdgeIter halfedges_begin() const {
258  return HalfEdgeIter(this, HalfEdgeHandle(0));
259  }
260 
261  HalfEdgeIter halfedges_end() const {
262  return HalfEdgeIter(this, HalfEdgeHandle((int)edges_.size() * 2));
263  }
264 
265  std::pair<HalfEdgeIter, HalfEdgeIter> halfedges() const {
266  return std::make_pair(halfedges_begin(), halfedges_end());
267  }
268 
269  FaceIter f_iter() const {
270  return FaceIter(this);
271  }
272 
273  FaceIter faces_begin() const {
274  return FaceIter(this, FaceHandle(0));
275  }
276 
277  FaceIter faces_end() const {
278  return FaceIter(this, FaceHandle((int)faces_.size()));
279  }
280 
281  std::pair<FaceIter, FaceIter> faces() const {
282  return std::make_pair(faces_begin(), faces_end());
283  }
284 
285  HalfFaceIter hf_iter() const {
286  return HalfFaceIter(this);
287  }
288 
289  HalfFaceIter halffaces_begin() const {
290  return HalfFaceIter(this, HalfFaceHandle(0));
291  }
292 
293  HalfFaceIter halffaces_end() const {
294  return HalfFaceIter(this, HalfFaceHandle((int)faces_.size() * 2));
295  }
296 
297  std::pair<HalfFaceIter, HalfFaceIter> halffaces() const {
298  return std::make_pair(halffaces_begin(), halffaces_end());
299  }
300 
301  CellIter c_iter() const {
302  return CellIter(this);
303  }
304 
305  CellIter cells_begin() const {
306  return CellIter(this, CellHandle(0));
307  }
308 
309  CellIter cells_end() const {
310  return CellIter(this, CellHandle((int)cells_.size()));
311  }
312 
313  std::pair<CellIter, CellIter> cells() const {
314  return std::make_pair(cells_begin(), cells_end());
315  }
316 
317  /*
318  * Virtual functions with implementation
319  */
320 
322  virtual size_t n_vertices() const { return n_vertices_; }
324  virtual size_t n_edges() const { return edges_.size(); }
326  virtual size_t n_halfedges() const { return edges_.size() * 2u; }
328  virtual size_t n_faces() const { return faces_.size(); }
330  virtual size_t n_halffaces() const { return faces_.size() * 2u; }
332  virtual size_t n_cells() const { return cells_.size(); }
333 
334  int genus() const {
335 
336  int g = (1 - (int)(n_vertices() -
337  n_edges() +
338  n_faces() -
339  n_cells()));
340 
341  if(g % 2 == 0) return (g / 2);
342 
343  // An error occured
344  // The mesh might not be manifold
345  return -1;
346  }
347 
348 private:
349 
350  // Cache total vertex number
351  size_t n_vertices_;
352 
353 public:
354 
356  virtual VertexHandle add_vertex();
357 
358  //=======================================================================
359 
361  virtual EdgeHandle add_edge(const VertexHandle& _fromVertex, const VertexHandle& _toHandle, bool _allowDuplicates = false);
362 
370  virtual FaceHandle add_face(const std::vector<HalfEdgeHandle>& _halfedges, bool _topologyCheck = false);
371 
373  virtual FaceHandle add_face(const std::vector<VertexHandle>& _vertices);
374 
382  virtual CellHandle add_cell(const std::vector<HalfFaceHandle>& _halffaces, bool _topologyCheck = false);
383 
385  void set_edge(const EdgeHandle& _eh, const VertexHandle& _fromVertex, const VertexHandle& _toVertex);
386 
388  void set_face(const FaceHandle& _fh, const std::vector<HalfEdgeHandle>& _hes);
389 
391  void set_cell(const CellHandle& _ch, const std::vector<HalfFaceHandle>& _hfs);
392 
393  /*
394  * Non-virtual functions
395  */
396 
398  const Edge& edge(const EdgeHandle& _edgeHandle) const;
399 
401  const Face& face(const FaceHandle& _faceHandle) const;
402 
404  const Cell& cell(const CellHandle& _cellHandle) const;
405 
407  Edge& edge(const EdgeHandle& _edgeHandle);
408 
410  Face& face(const FaceHandle& _faceHandle);
411 
413  Cell& cell(const CellHandle& _cellHandle);
414 
416  Edge halfedge(const HalfEdgeHandle& _halfEdgeHandle) const;
417 
419  Face halfface(const HalfFaceHandle& _halfFaceHandle) const;
420 
422  Edge opposite_halfedge(const HalfEdgeHandle& _halfEdgeHandle) const;
423 
425  Face opposite_halfface(const HalfFaceHandle& _halfFaceHandle) const;
426 
428  HalfEdgeHandle halfedge(const VertexHandle& _vh1, const VertexHandle& _vh2) const;
429 
433  HalfFaceHandle halfface(const std::vector<VertexHandle>& _vs) const;
434 
438  HalfFaceHandle halfface_extensive(const std::vector<VertexHandle>& _vs) const;
439 
443  HalfFaceHandle halfface(const std::vector<HalfEdgeHandle>& _hes) const;
444 
446  HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle& _heh, const HalfFaceHandle& _hfh) const;
447 
449  HalfEdgeHandle prev_halfedge_in_halfface(const HalfEdgeHandle& _heh, const HalfFaceHandle& _hfh) const;
450 
452  inline size_t valence(const VertexHandle& _vh) const {
453  assert(has_vertex_bottom_up_incidences());
454  assert(_vh.is_valid() && (size_t)_vh.idx() < outgoing_hes_per_vertex_.size());
455 
456  return outgoing_hes_per_vertex_[_vh.idx()].size();
457  }
458 
460  inline size_t valence(const EdgeHandle& _eh) const {
461  assert(has_edge_bottom_up_incidences());
462  assert(_eh.is_valid() && (size_t)_eh.idx() < edges_.size());
463  assert((size_t)halfedge_handle(_eh, 0).idx() < incident_hfs_per_he_.size());
464 
465  return incident_hfs_per_he_[halfedge_handle(_eh, 0).idx()].size();
466  }
467 
469  inline size_t valence(const FaceHandle& _fh) const {
470  assert(_fh.is_valid() && (size_t)_fh.idx() < faces_.size());
471 
472  return face(_fh).halfedges().size();
473  }
474 
476  inline size_t valence(const CellHandle& _ch) const {
477  assert(_ch.is_valid() && (size_t)_ch.idx() < cells_.size());
478 
479  return cell(_ch).halffaces().size();
480  }
481 
482  //=====================================================================
483  // Delete entities
484  //=====================================================================
485 
486 public:
487 
488  virtual VertexIter delete_vertex(const VertexHandle& _h);
489 
490  virtual EdgeIter delete_edge(const EdgeHandle& _h);
491 
492  virtual FaceIter delete_face(const FaceHandle& _h);
493 
494  virtual CellIter delete_cell(const CellHandle& _h);
495 
496  virtual void collect_garbage();
497 
498 
499  virtual bool is_deleted(const VertexHandle& _h) const { return vertex_deleted_[_h.idx()]; }
500  virtual bool is_deleted(const EdgeHandle& _h) const { return edge_deleted_[_h.idx()]; }
501  virtual bool is_deleted(const HalfEdgeHandle& _h) const { return edge_deleted_[_h.idx()/2]; }
502  virtual bool is_deleted(const FaceHandle& _h) const { return face_deleted_[_h.idx()]; }
503  virtual bool is_deleted(const HalfFaceHandle& _h) const { return face_deleted_[_h.idx()/2]; }
504  virtual bool is_deleted(const CellHandle& _h) const { return cell_deleted_[_h.idx()]; }
505 
506 private:
507 
508  template <class ContainerT>
509  void get_incident_edges(const ContainerT& _vs, std::set<EdgeHandle>& _es) const;
510 
511  template <class ContainerT>
512  void get_incident_faces(const ContainerT& _es, std::set<FaceHandle>& _fs) const;
513 
514  template <class ContainerT>
515  void get_incident_cells(const ContainerT& _fs, std::set<CellHandle>& _cs) const;
516 
517  VertexIter delete_vertex_core(const VertexHandle& _h);
518 
519  EdgeIter delete_edge_core(const EdgeHandle& _h);
520 
521  FaceIter delete_face_core(const FaceHandle& _h);
522 
523  CellIter delete_cell_core(const CellHandle& _h);
524 
525 protected:
526 
527  virtual void swap_cells(CellHandle _h1, CellHandle _h2);
528 
529  virtual void swap_faces(FaceHandle _h1, FaceHandle _h2);
530 
531  virtual void swap_edges(EdgeHandle _h1, EdgeHandle _h2);
532 
533  virtual void swap_vertices(VertexHandle _h1, VertexHandle _h2);
534 
535  virtual void delete_multiple_vertices(const std::vector<bool>& _tag);
536 
537  virtual void delete_multiple_edges(const std::vector<bool>& _tag);
538 
539  virtual void delete_multiple_faces(const std::vector<bool>& _tag);
540 
541  virtual void delete_multiple_cells(const std::vector<bool>& _tag);
542 
544  public:
545  EdgeCorrector(const std::vector<int>& _newIndices) :
546  newIndices_(_newIndices) {}
547 
548  void operator()(Edge& _edge) {
549  _edge.set_from_vertex(VertexHandle(newIndices_[_edge.from_vertex().idx()]));
550  _edge.set_to_vertex(VertexHandle(newIndices_[_edge.to_vertex().idx()]));
551  }
552  private:
553  const std::vector<int>& newIndices_;
554  };
555 
557  public:
558  FaceCorrector(const std::vector<int>& _newIndices) :
559  newIndices_(_newIndices) {}
560 
561  void operator()(Face& _face) {
562  std::vector<HalfEdgeHandle> hes = _face.halfedges();
563  for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
564  he_end = hes.end(); he_it != he_end; ++he_it) {
565 
566  EdgeHandle eh = edge_handle(*he_it);
567  unsigned char opp = (he_it->idx() - halfedge_handle(eh, 0).idx());
568  *he_it = halfedge_handle(newIndices_[eh.idx()], opp);
569  }
570  _face.set_halfedges(hes);
571  }
572  private:
573  const std::vector<int>& newIndices_;
574  };
575 
577  public:
578  CellCorrector(const std::vector<int>& _newIndices) :
579  newIndices_(_newIndices) {}
580 
581  void operator()(Cell& _cell) {
582  std::vector<HalfFaceHandle> hfs = _cell.halffaces();
583  for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
584  hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
585 
586  FaceHandle fh = face_handle(*hf_it);
587  unsigned char opp = (hf_it->idx() - halfface_handle(fh, 0).idx());
588  *hf_it = halfface_handle(newIndices_[fh.idx()], opp);
589  }
590  _cell.set_halffaces(hfs);
591  }
592  private:
593  const std::vector<int>& newIndices_;
594  };
595 
596 public:
597 
606  CellIter delete_cell_range(const CellIter& _first, const CellIter& _last);
607 
608 public:
609 
611  virtual void clear(bool _clearProps = true) {
612 
613  edges_.clear();
614  faces_.clear();
615  cells_.clear();
616  vertex_deleted_.clear();
617  edge_deleted_.clear();
618  face_deleted_.clear();
619  cell_deleted_.clear();
620  outgoing_hes_per_vertex_.clear();
621  incident_hfs_per_he_.clear();
622  incident_cell_per_hf_.clear();
623  n_vertices_ = 0;
624 
625  if(_clearProps) {
626 
627  // Delete all property data
628  clear_vertex_props();
629  clear_edge_props();
630  clear_halfedge_props();
631  clear_face_props();
632  clear_halfface_props();
633  clear_cell_props();
634  clear_mesh_props();
635 
636  } else {
637  // Resize props
638  resize_vprops(0u);
639  resize_eprops(0u);
640  resize_fprops(0u);
641  resize_cprops(0u);
642  }
643  }
644 
645  //=====================================================================
646  // Bottom-up Incidences
647  //=====================================================================
648 
649 public:
650 
651  void enable_bottom_up_incidences(bool _enable = true) {
652 
653  enable_vertex_bottom_up_incidences(_enable);
654  enable_edge_bottom_up_incidences(_enable);
655  enable_face_bottom_up_incidences(_enable);
656  }
657 
658  void enable_vertex_bottom_up_incidences(bool _enable = true) {
659 
660  if(_enable && !v_bottom_up_) {
661  // Vertex bottom-up incidences have to be
662  // recomputed for the whole mesh
663  compute_vertex_bottom_up_incidences();
664  }
665 
666  if(!_enable) {
667  outgoing_hes_per_vertex_.clear();
668  }
669 
670  v_bottom_up_ = _enable;
671  }
672 
673  void enable_edge_bottom_up_incidences(bool _enable = true) {
674 
675  if(_enable && !e_bottom_up_) {
676  // Edge bottom-up incidences have to be
677  // recomputed for the whole mesh
678  compute_edge_bottom_up_incidences();
679 
680  if(f_bottom_up_) {
681 #if defined(__clang_major__) && (__clang_major__ >= 5)
682  for(EdgeIter e_it = edges_begin(), e_end = edges_end();
683  e_it != e_end; ++e_it) {
684  reorder_incident_halffaces(*e_it);
685  }
686 #else
687  std::for_each(edges_begin(), edges_end(),
688  fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1));
689 #endif
690  }
691  }
692 
693  if(!_enable) {
694  incident_hfs_per_he_.clear();
695  }
696 
697  e_bottom_up_ = _enable;
698  }
699 
700  void enable_face_bottom_up_incidences(bool _enable = true) {
701 
702  bool updateOrder = false;
703  if(_enable && !f_bottom_up_) {
704  // Face bottom-up incidences have to be
705  // recomputed for the whole mesh
706  compute_face_bottom_up_incidences();
707 
708  updateOrder = true;
709  }
710 
711  if(!_enable) {
712  incident_cell_per_hf_.clear();
713  }
714 
715  f_bottom_up_ = _enable;
716 
717  if(updateOrder) {
718  if(e_bottom_up_) {
719 #if defined(__clang_major__) && (__clang_major__ >= 5)
720  for(EdgeIter e_it = edges_begin(), e_end = edges_end();
721  e_it != e_end; ++e_it) {
722  reorder_incident_halffaces(*e_it);
723  }
724 #else
725  std::for_each(edges_begin(), edges_end(),
726  fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1));
727 #endif
728  }
729  }
730  }
731 
732  bool has_full_bottom_up_incidences() const {
733  return (has_vertex_bottom_up_incidences() &&
734  has_edge_bottom_up_incidences() &&
735  has_face_bottom_up_incidences());
736  }
737 
738  bool has_vertex_bottom_up_incidences() const { return v_bottom_up_; }
739 
740  bool has_edge_bottom_up_incidences() const { return e_bottom_up_; }
741 
742  bool has_face_bottom_up_incidences() const { return f_bottom_up_; }
743 
744 
745  void enable_deferred_deletion(bool _enable = true);
746  bool deferred_deletion_enabled() const { return deferred_deletion; }
747 
748 
749  void enable_fast_deletion(bool _enable = true) { fast_deletion = _enable; }
750  bool fast_deletion_enabled() const { return fast_deletion; }
751 
752 
753 protected:
754 
755  void compute_vertex_bottom_up_incidences();
756 
757  void compute_edge_bottom_up_incidences();
758 
759  void compute_face_bottom_up_incidences();
760 
761  void reorder_incident_halffaces(const EdgeHandle& _eh);
762 
763  // Outgoing halfedges per vertex
764  std::vector<std::vector<HalfEdgeHandle> > outgoing_hes_per_vertex_;
765 
766  // Incident halffaces per (directed) halfedge
767  std::vector<std::vector<HalfFaceHandle> > incident_hfs_per_he_;
768 
769  // Incident cell (at most one) per halfface
770  std::vector<CellHandle> incident_cell_per_hf_;
771 
772 private:
773  bool v_bottom_up_;
774 
775  bool e_bottom_up_;
776 
777  bool f_bottom_up_;
778 
779  bool deferred_deletion;
780 
781  bool fast_deletion;
782 
783  //=====================================================================
784  // Connectivity
785  //=====================================================================
786 
787 public:
788 
795  HalfFaceHandle adjacent_halfface_in_cell(const HalfFaceHandle& _halfFaceHandle, const HalfEdgeHandle& _halfEdgeHandle) const;
796 
798  CellHandle incident_cell(const HalfFaceHandle& _halfFaceHandle) const;
799 
800  bool is_boundary(const HalfFaceHandle& _halfFaceHandle) const {
801 
802  assert(_halfFaceHandle.is_valid() && (size_t)_halfFaceHandle.idx() < faces_.size() * 2u);
803  assert(has_face_bottom_up_incidences());
804  assert((size_t)_halfFaceHandle.idx() < incident_cell_per_hf_.size());
805  return incident_cell_per_hf_[_halfFaceHandle.idx()] == InvalidCellHandle;
806  }
807 
808  bool is_boundary(const FaceHandle& _faceHandle) const {
809  assert(_faceHandle.is_valid() && (size_t)_faceHandle.idx() < faces_.size());
810  assert(has_face_bottom_up_incidences());
811  return is_boundary(halfface_handle(_faceHandle, 0)) ||
812  is_boundary(halfface_handle(_faceHandle, 1));
813  }
814 
815  bool is_boundary(const EdgeHandle& _edgeHandle) const {
816  assert(has_edge_bottom_up_incidences());
817  assert(_edgeHandle.is_valid() && (size_t)_edgeHandle.idx() < edges_.size());
818 
819  for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(halfedge_handle(_edgeHandle, 0));
820  hehf_it.valid(); ++hehf_it) {
821  if(is_boundary(face_handle(*hehf_it))) {
822  return true;
823  }
824  }
825  return false;
826  }
827 
828  bool is_boundary(const HalfEdgeHandle& _halfedgeHandle) const {
829  assert(has_edge_bottom_up_incidences());
830  assert(_halfedgeHandle.is_valid() && (size_t)_halfedgeHandle.idx() < edges_.size() * 2u);
831 
832  for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(_halfedgeHandle);
833  hehf_it.valid(); ++hehf_it) {
834  if(is_boundary(face_handle(*hehf_it))) {
835  return true;
836  }
837  }
838  return false;
839  }
840 
841  bool is_boundary(const VertexHandle& _vertexHandle) const {
842  assert(has_vertex_bottom_up_incidences());
843  assert(_vertexHandle.is_valid() && (size_t)_vertexHandle.idx() < n_vertices());
844 
845  for(VertexOHalfEdgeIter voh_it = voh_iter(_vertexHandle); voh_it.valid(); ++voh_it) {
846  if(is_boundary(*voh_it)) return true;
847  }
848  return false;
849  }
850 
851  size_t n_vertices_in_cell(const CellHandle& _ch) const {
852  assert(_ch.is_valid() && (size_t)_ch.idx() < cells_.size());
853 
854  std::set<VertexHandle> vertices;
855  std::vector<HalfFaceHandle> hfs = cell(_ch).halffaces();
856  for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
857  hf_it != hfs.end(); ++hf_it) {
858  std::vector<HalfEdgeHandle> hes = halfface(*hf_it).halfedges();
859  for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
860  he_it != hes.end(); ++he_it) {
861  vertices.insert(halfedge(*he_it).to_vertex());
862  }
863  }
864  return vertices.size();
865  }
866 
867  //=========================================================================
868 
869  /*
870  * Non-virtual functions
871  */
872 
873  Edge opposite_halfedge(const Edge& _edge) const {
874  return Edge(_edge.to_vertex(), _edge.from_vertex());
875  }
876 
877  Face opposite_halfface(const Face& _face) const {
878  std::vector<HalfEdgeHandle> opp_halfedges;
879  for(std::vector<HalfEdgeHandle>::const_iterator it = _face.halfedges().begin(); it
880  != _face.halfedges().end(); ++it) {
881  opp_halfedges.insert(opp_halfedges.begin(), opposite_halfedge_handle(*it));
882  }
883 
884  return Face(opp_halfedges);
885  }
886 
887  /*
888  * Static functions
889  */
890 
892  static inline HalfEdgeHandle halfedge_handle(const EdgeHandle& _h, const unsigned char _subIdx) {
893  // Is handle in range?
894  assert(_h.is_valid());
895  assert(_subIdx < 2);
896  // if(_h.idx() < 0 || _subIdx > 1) return InvalidHalfEdgeHandle;
897  return HalfEdgeHandle((2 * _h.idx()) + (_subIdx ? 1 : 0));
898  }
899 
901  static inline HalfFaceHandle halfface_handle(const FaceHandle& _h, const unsigned char _subIdx) {
902  // Is handle in range?
903  assert(_h.is_valid());
904  assert(_subIdx < 2);
905  // if(_h.idx() < 0 || _subIdx > 1) return InvalidHalfFaceHandle;
906  return HalfFaceHandle((2 * _h.idx()) + (_subIdx ? 1 : 0));
907  }
908 
910  static inline EdgeHandle edge_handle(const HalfEdgeHandle& _h) {
911  // Is handle in range?
912  assert(_h.is_valid());
913  // if(_h.idx() < 0) return InvalidEdgeHandle;
914  return EdgeHandle((int)(_h.idx() / 2));
915  }
916 
917  static inline FaceHandle face_handle(const HalfFaceHandle& _h) {
918  // Is handle in range?
919  assert(_h.is_valid());
920  // if(_h.idx() < 0) return InvalidFaceHandle;
921  return FaceHandle((int)(_h.idx() / 2));
922  }
923 
924  static inline HalfEdgeHandle opposite_halfedge_handle(const HalfEdgeHandle& _h) {
925  // Is handle in range?
926  assert(_h.is_valid());
927  // if(_h.idx() < 0) return InvalidHalfEdgeHandle;
928 
929  // Is handle even?
930  if(_h.idx() % 2 == 0) {
931  return HalfEdgeHandle(_h.idx() + 1);
932  }
933  return HalfEdgeHandle(_h.idx() - 1);
934  }
935 
936  static inline HalfFaceHandle opposite_halfface_handle(const HalfFaceHandle& _h) {
937  // Is handle in range?
938  assert(_h.is_valid());
939  // if(_h.idx() < 0) return InvalidHalfFaceHandle;
940 
941  // Is handle even?
942  if(_h.idx() % 2 == 0) {
943  return HalfFaceHandle(_h.idx() + 1);
944  }
945  return HalfFaceHandle(_h.idx() - 1);
946  }
947 
948  bool inline needs_garbage_collection() const {
949  return needs_garbage_collection_;
950  }
951 
952 protected:
953 
954  // List of edges
955  std::vector<Edge> edges_;
956 
957  // List of faces
958  std::vector<Face> faces_;
959 
960  // List of cells
961  std::vector<Cell> cells_;
962 
963  std::vector<bool> vertex_deleted_;
964  std::vector<bool> edge_deleted_;
965  std::vector<bool> face_deleted_;
966  std::vector<bool> cell_deleted_;
967  bool needs_garbage_collection_;
968 
969 };
970 
971 }
972 
973 #endif /* TOPOLOGYKERNEL_HH_ */
virtual size_t n_halffaces() const
Get number of halffaces in mesh.
virtual void collect_garbage()
Delete all entities that are marked as deleted.
virtual size_t n_cells() const
Get number of cells in mesh.
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
virtual EdgeIter delete_edge(const EdgeHandle &_h)
Delete edge from mesh.
size_t valence(const EdgeHandle &_eh) const
Get valence of edge (number of incident faces)
Edge opposite_halfedge(const HalfEdgeHandle &_halfEdgeHandle) const
Get opposite halfedge that corresponds to halfedge with handle _halfEdgeHandle.
size_t valence(const CellHandle &_ch) const
Get valence of cell (number of incident faces)
void set_cell(const CellHandle &_ch, const std::vector< HalfFaceHandle > &_hfs)
Set the half-faces of a cell.
HalfFaceHandle adjacent_halfface_in_cell(const HalfFaceHandle &_halfFaceHandle, const HalfEdgeHandle &_halfEdgeHandle) const
Get halfface that is adjacent (w.r.t. a common halfedge) within the same cell.
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
static HalfFaceHandle halfface_handle(const FaceHandle &_h, const unsigned char _subIdx)
Conversion function.
Face halfface(const HalfFaceHandle &_halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
void resize_cprops(size_t _nc)
Change size of stored cell properties.
FaceIter delete_face_core(const FaceHandle &_h)
Delete face from mesh.
size_t valence(const FaceHandle &_fh) const
Get valence of face (number of incident edges)
const Edge & edge(const EdgeHandle &_edgeHandle) const
Get edge with handle _edgeHandle.
size_t valence(const VertexHandle &_vh) const
Get valence of vertex (number of incident edges)
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
virtual size_t n_edges() const
Get number of edges in mesh.
virtual size_t n_vertices() const
Get number of vertices in mesh.
HalfEdgeHandle prev_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get previous halfedge within a halfface.
void resize_fprops(size_t _nf)
Change size of stored face properties.
HalfFaceHandle halfface_extensive(const std::vector< VertexHandle > &_vs) const
void resize_vprops(size_t _nv)
Change size of stored vertex properties.
virtual VertexHandle add_vertex()
Add abstract vertex.
void resize_eprops(size_t _ne)
Change size of stored edge properties.
CellHandle incident_cell(const HalfFaceHandle &_halfFaceHandle) const
Get cell that is incident to the given halfface.
void set_face(const FaceHandle &_fh, const std::vector< HalfEdgeHandle > &_hes)
Set the half-edges of a face.
virtual size_t n_halfedges() const
Get number of halfedges in mesh.
const Face & face(const FaceHandle &_faceHandle) const
Get face with handle _faceHandle.
Face opposite_halfface(const HalfFaceHandle &_halfFaceHandle) const
Get opposite halfface that corresponds to halfface with handle _halfFaceHandle.
virtual void clear(bool _clearProps=true)
Clear whole mesh.
static HalfEdgeHandle halfedge_handle(const EdgeHandle &_h, const unsigned char _subIdx)
Conversion function.
virtual CellIter delete_cell(const CellHandle &_h)
Delete cell from mesh.
CellIter delete_cell_range(const CellIter &_first, const CellIter &_last)
Delete range of cells.
EdgeIter delete_edge_core(const EdgeHandle &_h)
Delete edge from mesh.
HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get next halfedge within a halfface.
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:106
virtual size_t n_faces() const
Get number of faces in mesh.
virtual EdgeHandle add_edge(const VertexHandle &_fromVertex, const VertexHandle &_toHandle, bool _allowDuplicates=false)
Add edge.
VertexIter delete_vertex_core(const VertexHandle &_h)
Delete vertex from mesh.
virtual FaceIter delete_face(const FaceHandle &_h)
Delete face from mesh.
virtual VertexIter delete_vertex(const VertexHandle &_h)
Delete vertex from mesh.
const Cell & cell(const CellHandle &_cellHandle) const
Get cell with handle _cellHandle.
Edge halfedge(const HalfEdgeHandle &_halfEdgeHandle) const
Get edge that corresponds to halfedge with handle _halfEdgeHandle.
CellIter delete_cell_core(const CellHandle &_h)
Delete cell from mesh.
void set_edge(const EdgeHandle &_eh, const VertexHandle &_fromVertex, const VertexHandle &_toVertex)
Set the vertices of an edge.