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