Developer Documentation
Iterators.cc
1 /*===========================================================================*\
2  * *
3  * OpenVolumeMesh *
4  * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openvolumemesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenVolumeMesh. *
9  * *
10  * OpenVolumeMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenVolumeMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenVolumeMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision$ *
38  * $Date$ *
39  * $LastChangedBy$ *
40  * *
41 \*===========================================================================*/
42 
43 #include <algorithm>
44 #include <set>
45 
46 #include "Iterators.hh"
47 #include "TopologyKernel.hh"
48 
49 namespace OpenVolumeMesh {
50 
51 //================================================================================================
52 // VertexOHalfEdgeIter
53 //================================================================================================
54 
55 
56 VertexOHalfEdgeIter::VertexOHalfEdgeIter(const VertexHandle& _ref_h,
57  const TopologyKernel* _mesh, int _max_laps) :
58 BaseIter(_mesh, _ref_h, _max_laps),
59 cur_index_(0) {
60 
61  if(!_mesh->has_vertex_bottom_up_incidences()) {
62 #ifndef NDEBUG
63  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
64 #endif
65  BaseIter::valid(false);
66  return;
67  }
68 
69  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
70  BaseIter::valid(false);
71  }
72 
73  if(BaseIter::valid()) {
74  if((unsigned int)cur_index_ >= BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()].size()) {
75  BaseIter::valid(false);
76  }
77  }
78 
79  if(BaseIter::valid()) {
80  BaseIter::cur_handle((
81  BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()])[cur_index_]);
82  }
83 }
84 
85 
86 VertexOHalfEdgeIter& VertexOHalfEdgeIter::operator--() {
87 
88  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
89 
90  if (cur_index_ == 0) {
91  cur_index_ = n_outgoing_halfedges-1;
92  --lap_;
93  if (lap_ < 0)
94  BaseIter::valid(false);
95  }
96  else {
97  --cur_index_;
98  }
99 
100  BaseIter::cur_handle((BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()])[cur_index_]);
101 
102  return *this;
103 }
104 
105 
106 VertexOHalfEdgeIter& VertexOHalfEdgeIter::operator++() {
107 
108  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
109 
110  ++cur_index_;
111 
112  if (cur_index_ == n_outgoing_halfedges) {
113  cur_index_ = 0;
114  ++lap_;
115  if (lap_ >= max_laps_)
116  BaseIter::valid(false);
117  }
118 
119  BaseIter::cur_handle((BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()])[cur_index_]);
120 
121  return *this;
122 }
123 
124 
125 //================================================================================================
126 // VertexVertexIter
127 //================================================================================================
128 
129 
130 VertexVertexIter::VertexVertexIter(const VertexHandle& _ref_h,
131  const TopologyKernel* _mesh, int _max_laps) :
132 BaseIter(_mesh, _ref_h, _max_laps),
133 cur_index_(0) {
134 
135  if(!_mesh->has_vertex_bottom_up_incidences()) {
136 #ifndef NDEBUG
137  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
138 #endif
139  BaseIter::valid(false);
140  return;
141  }
142 
143  if((size_t)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
144  BaseIter::valid(false);
145  }
146 
147  if(BaseIter::valid()) {
148  if((size_t)cur_index_ >= BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()].size()) {
149  BaseIter::valid(false);
150  }
151  }
152 
153  if(BaseIter::valid()) {
154  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()][cur_index_];
155  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
156  }
157 }
158 
159 
160 VertexVertexIter& VertexVertexIter::operator--() {
161 
162  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
163 
164  if (cur_index_ == 0) {
165  cur_index_ = n_outgoing_halfedges-1;
166  --lap_;
167  if (lap_ < 0)
168  BaseIter::valid(false);
169  }
170  else {
171  --cur_index_;
172  }
173 
174  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()][cur_index_];
175  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
176 
177  return *this;
178 }
179 
180 
181 VertexVertexIter& VertexVertexIter::operator++() {
182 
183  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
184 
185  ++cur_index_;
186 
187  if (cur_index_ == n_outgoing_halfedges) {
188  cur_index_ = 0;
189  ++lap_;
190  if (lap_ >= max_laps_)
191  BaseIter::valid(false);
192  }
193 
194 
195  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()][cur_index_];
196  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
197 
198  return *this;
199 }
200 
201 
205 
206 
207 HalfEdgeHalfFaceIter::HalfEdgeHalfFaceIter(const HalfEdgeHandle& _ref_h,
208  const TopologyKernel* _mesh, int _max_laps) :
209 BaseIter(_mesh, _ref_h, _max_laps),
210 cur_index_(0) {
211 
212  if(!_mesh->has_edge_bottom_up_incidences()) {
213 #ifndef NDEBUG
214  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
215 #endif
216  BaseIter::valid(false);
217  return;
218  }
219 
220  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
221  BaseIter::valid(false);
222  }
223 
224  if(BaseIter::valid()) {
225  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
226  BaseIter::valid(false);
227  }
228  }
229 
230  if(BaseIter::valid()) {
231  BaseIter::cur_handle((
232  BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]);
233  }
234 }
235 
236 
237 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator--() {
238 
239  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
240 
241  if (cur_index_ == 0) {
242  cur_index_ = n_outgoing_halffaces-1;
243  --lap_;
244  if (lap_ < 0)
245  BaseIter::valid(false);
246  }
247  else {
248  --cur_index_;
249  }
250 
251  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
252 
253  return *this;
254 }
255 
256 
257 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator++() {
258 
259 
260  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
261 
262  ++cur_index_;
263 
264  if (cur_index_ == n_outgoing_halffaces) {
265  cur_index_ = 0;
266  ++lap_;
267  if (lap_ >= max_laps_)
268  BaseIter::valid(false);
269  }
270 
271  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
272 
273  return *this;
274 }
275 
279 
280 VertexFaceIter::VertexFaceIter(const VertexHandle& _ref_h,
281  const TopologyKernel* _mesh, int _max_laps) :
282 BaseIter(_mesh, _ref_h, _max_laps) {
283 
284  if(!_mesh->has_full_bottom_up_incidences()) {
285 #ifndef NDEBUG
286  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
287 #endif
288  BaseIter::valid(false);
289  return;
290  }
291 
292  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
293  BaseIter::valid(false);
294  return;
295  }
296 
297  // Build up face list
298  const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
299  for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
300 
301  if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
302  const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
303 
304  for (std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
305  hf_it != incidentHalfFaces.end(); ++hf_it) {
306  faces_.push_back(BaseIter::mesh()->face_handle(*hf_it));
307  }
308  }
309  // Remove all duplicate entries
310  std::sort(faces_.begin(), faces_.end());
311  faces_.resize(std::unique(faces_.begin(), faces_.end()) - faces_.begin());
312 
313  // Remove invalid handles
314  if ((faces_.size() > 0) && !faces_.front().is_valid())
315  faces_.erase(faces_.begin());
316 
317  cur_index_ = 0;
318  BaseIter::valid(faces_.size() > 0);
319  if(BaseIter::valid()) {
320  BaseIter::cur_handle(faces_[cur_index_]);
321  }
322 }
323 
324 VertexFaceIter& VertexFaceIter::operator--() {
325 
326  if(cur_index_ == 0) {
327  cur_index_ = faces_.size()-1;
328  --lap_;
329  if (lap_ < 0) {
330  BaseIter::valid(false);
331  }
332  } else {
333  --cur_index_;
334  }
335 
336  BaseIter::cur_handle(faces_[cur_index_]);
337  return *this;
338 }
339 
340 
341 VertexFaceIter& VertexFaceIter::operator++() {
342 
343  ++cur_index_;
344  if(cur_index_ == faces_.size()) {
345  cur_index_ = 0;
346  ++lap_;
347  if (lap_ >= max_laps_) {
348  BaseIter::valid(false);
349  }
350  }
351  BaseIter::cur_handle(faces_[cur_index_]);
352  return *this;
353 }
354 
358 
359 VertexCellIter::VertexCellIter(const VertexHandle& _ref_h,
360  const TopologyKernel* _mesh, int _max_laps) :
361 BaseIter(_mesh, _ref_h, _max_laps) {
362 
363  if(!_mesh->has_full_bottom_up_incidences()) {
364 #ifndef NDEBUG
365  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
366 #endif
367  BaseIter::valid(false);
368  return;
369  }
370 
371  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
372  BaseIter::valid(false);
373  return;
374  }
375 
376  // Build up cell list
377  const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
378  for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
379 
380  if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
381  const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
382 
383  for(std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
384  hf_it != incidentHalfFaces.end(); ++hf_it) {
385  if((unsigned int)hf_it->idx() < BaseIter::mesh()->incident_cell_per_hf_.size()) {
386  CellHandle c_idx = BaseIter::mesh()->incident_cell_per_hf_[hf_it->idx()];
387  if(c_idx != TopologyKernel::InvalidCellHandle)
388  cells_.push_back(c_idx);
389  }
390  }
391  }
392  // Remove all duplicate entries
393  std::sort(cells_.begin(), cells_.end());
394  cells_.resize(std::unique(cells_.begin(), cells_.end()) - cells_.begin());
395 
396  // Remove invalid handles
397  if ((cells_.size() > 0) && !cells_.front().is_valid())
398  cells_.erase(cells_.begin());
399 
400  cur_index_ = 0;
401  BaseIter::valid(cells_.size()>0);
402  if(BaseIter::valid()) {
403  BaseIter::cur_handle(cells_[cur_index_]);
404  }
405 }
406 
407 VertexCellIter& VertexCellIter::operator--() {
408 
409  if(cur_index_ == 0) {
410  cur_index_ = cells_.size()-1;
411  --lap_;
412  if (lap_ < 0) {
413  BaseIter::valid(false);
414  }
415  } else {
416  --cur_index_;
417  }
418 
419  BaseIter::cur_handle(cells_[cur_index_]);
420  return *this;
421 }
422 
423 
424 VertexCellIter& VertexCellIter::operator++() {
425 
426  ++cur_index_;
427  if(cur_index_ == cells_.size()) {
428  cur_index_ = 0;
429  ++lap_;
430  if (lap_ >= max_laps_) {
431  BaseIter::valid(false);
432  }
433  }
434  BaseIter::cur_handle(cells_[cur_index_]);
435  return *this;
436 }
437 
441 
442 
443 HalfEdgeCellIter::HalfEdgeCellIter(const HalfEdgeHandle& _ref_h,
444  const TopologyKernel* _mesh, int _max_laps) :
445 BaseIter(_mesh, _ref_h, _max_laps),
446 cur_index_(0) {
447 
448  if(!_mesh->has_edge_bottom_up_incidences() || !_mesh->has_face_bottom_up_incidences()) {
449 #ifndef NDEBUG
450  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
451 #endif
452  BaseIter::valid(false);
453  return;
454  }
455 
456  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
457 
458  BaseIter::valid(false);
459  return;
460  }
461  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
462 
463  BaseIter::valid(false);
464  return;
465  }
466  if((unsigned int)((BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]).idx() >=
467  BaseIter::mesh()->incident_cell_per_hf_.size()) {
468 
469  BaseIter::valid(false);
470  return;
471  }
472 
473  // collect cell handles
474  const std::vector<HalfFaceHandle>& incidentHalffaces = BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()];
475  std::set<CellHandle> cells;
476  for (unsigned int i = 0; i < incidentHalffaces.size(); ++i)
477  {
478  CellHandle ch = getCellHandle(i);
479  if (ch.is_valid()) {
480  if(cells.count(ch) == 0) {
481  cells_.push_back(ch);
482  }
483  cells.insert(ch);
484  }
485  }
486 
487  BaseIter::valid(cells_.size() > 0);
488 
489  if(BaseIter::valid()) {
490  BaseIter::cur_handle(cells_[cur_index_]);
491  }
492 }
493 
494 
495 HalfEdgeCellIter& HalfEdgeCellIter::operator--() {
496 
497  if (cur_index_ == 0) {
498  cur_index_ = cells_.size()-1;
499  --lap_;
500  if (lap_ < 0)
501  BaseIter::valid(false);
502  }
503  else {
504  --cur_index_;
505  }
506 
507  BaseIter::cur_handle(cells_[cur_index_]);
508  return *this;
509 }
510 
511 
512 HalfEdgeCellIter& HalfEdgeCellIter::operator++() {
513 
514  ++cur_index_;
515 
516  if (cur_index_ == cells_.size()) {
517  cur_index_ = 0;
518  ++lap_;
519  if (lap_ >= max_laps_)
520  BaseIter::valid(false);
521  }
522 
523  BaseIter::cur_handle(cells_[cur_index_]);
524  return *this;
525 }
526 
527 CellHandle HalfEdgeCellIter::getCellHandle(int _cur_index) const
528 {
529  const std::vector<HalfFaceHandle>& halffacehandles = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()];
530  HalfFaceHandle currentHalfface = halffacehandles[_cur_index];
531  if(!currentHalfface.is_valid()) return CellHandle(-1);
532  CellHandle cellhandle = BaseIter::mesh()->incident_cell_per_hf_[currentHalfface.idx()];
533  return cellhandle;
534 }
535 
536 
540 
541 
542 CellVertexIter::CellVertexIter(const CellHandle& _ref_h,
543  const TopologyKernel* _mesh, int _max_laps) :
544 BaseIter(_mesh, _ref_h, _max_laps) {
545 
546  OpenVolumeMeshCell c = BaseIter::mesh()->cell(_ref_h);
547  std::vector<HalfFaceHandle>::const_iterator hf_iter = c.halffaces().begin();
548  for(; hf_iter != c.halffaces().end(); ++hf_iter) {
549  const OpenVolumeMeshFace& halfface = BaseIter::mesh()->halfface(*hf_iter);
550  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
551  for(std::vector<HalfEdgeHandle>::const_iterator he_iter = hes.begin(); he_iter != hes.end(); ++he_iter) {
552  incident_vertices_.push_back(BaseIter::mesh()->halfedge(*he_iter).to_vertex());
553  }
554  }
555 
556  // Remove all duplicate entries
557  std::sort(incident_vertices_.begin(), incident_vertices_.end());
558  incident_vertices_.resize(std::unique(incident_vertices_.begin(), incident_vertices_.end()) - incident_vertices_.begin());
559 
560  cur_index_ = 0;
561  BaseIter::valid(incident_vertices_.size() > 0);
562 
563  if(BaseIter::valid()) {
564  BaseIter::cur_handle(incident_vertices_[cur_index_]);
565  }
566 }
567 
568 
569 CellVertexIter& CellVertexIter::operator--() {
570 
571  if (cur_index_ == 0) {
572  cur_index_ = incident_vertices_.size()-1;
573  --lap_;
574  if (lap_ < 0)
575  BaseIter::valid(false);
576  }
577  else {
578  --cur_index_;
579  }
580 
581  BaseIter::cur_handle(incident_vertices_[cur_index_]);
582  return *this;
583 }
584 
585 
586 CellVertexIter& CellVertexIter::operator++() {
587 
588  ++cur_index_;
589  if (cur_index_ == incident_vertices_.size()){
590  cur_index_ = 0;
591  ++lap_;
592  if (lap_ >= max_laps_)
593  BaseIter::valid(false);
594  }
595 
596  BaseIter::cur_handle(incident_vertices_[cur_index_]);
597  return *this;
598 }
599 
603 
604 
605 CellCellIter::CellCellIter(const CellHandle& _ref_h,
606  const TopologyKernel* _mesh, int _max_laps) :
607 BaseIter(_mesh, _ref_h, _max_laps) {
608 
609  if(!_mesh->has_face_bottom_up_incidences()) {
610 #ifndef NDEBUG
611  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
612 #endif
613  BaseIter::valid(false);
614  return;
615  }
616 
617  std::vector<HalfFaceHandle>::const_iterator hf_iter = BaseIter::mesh()->cell(_ref_h).halffaces().begin();
618  std::vector<HalfFaceHandle>::const_iterator hf_end = BaseIter::mesh()->cell(_ref_h).halffaces().end();
619  for(; hf_iter != hf_end; ++hf_iter) {
620 
621  HalfFaceHandle opp_hf = BaseIter::mesh()->opposite_halfface_handle(*hf_iter);
622  CellHandle ch = BaseIter::mesh()->incident_cell_per_hf_[opp_hf.idx()];
623  if(ch != TopologyKernel::InvalidCellHandle) {
624  adjacent_cells_.push_back(ch);
625  }
626  }
627 
628  // Remove all duplicate entries
629  std::sort(adjacent_cells_.begin(), adjacent_cells_.end());
630  adjacent_cells_.resize(std::unique(adjacent_cells_.begin(), adjacent_cells_.end()) - adjacent_cells_.begin());
631 
632  cur_index_ = 0;
633  BaseIter::valid(adjacent_cells_.size()>0);
634  if(BaseIter::valid()) {
635  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
636  }
637 }
638 
639 
640 CellCellIter& CellCellIter::operator--() {
641 
642  if (cur_index_ == 0) {
643  cur_index_ = adjacent_cells_.size() - 1;
644  --lap_;
645  if (lap_ < 0)
646  BaseIter::valid(false);
647  }
648  else {
649  --cur_index_;
650  }
651 
652  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
653  return *this;
654 }
655 
656 
657 CellCellIter& CellCellIter::operator++() {
658 
659  ++cur_index_;
660  if (cur_index_ == adjacent_cells_.size())
661  {
662  cur_index_ = 0;
663  ++lap_;
664  if (lap_ >= max_laps_)
665  BaseIter::valid(false);
666  }
667  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
668  return *this;
669 }
670 
674 
675 
676 HalfFaceVertexIter::HalfFaceVertexIter(const HalfFaceHandle& _ref_h,
677  const TopologyKernel* _mesh, int _max_laps) :
678 BaseIter(_mesh, _ref_h, _max_laps) {
679 
680  if(!_ref_h.is_valid()) return;
681 
682  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
683  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
684  for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
685  he_it != hes.end(); ++he_it) {
686  vertices_.push_back(_mesh->halfedge(*he_it).from_vertex());
687  }
688 
689  cur_index_ = 0;
690 
691  BaseIter::valid(vertices_.size() > 0);
692  if(BaseIter::valid()) {
693  BaseIter::cur_handle(vertices_[cur_index_]);
694  }
695 }
696 
697 
698 HalfFaceVertexIter& HalfFaceVertexIter::operator--() {
699 
700  if (cur_index_ == 0) {
701  cur_index_ = vertices_.size() - 1;
702  --lap_;
703  if (lap_ < 0)
704  BaseIter::valid(false);
705  }
706  else {
707  --cur_index_;
708  }
709 
710  BaseIter::cur_handle(vertices_[cur_index_]);
711  return *this;
712 }
713 
714 
715 HalfFaceVertexIter& HalfFaceVertexIter::operator++() {
716 
717  ++cur_index_;
718  if (cur_index_ == vertices_.size())
719  {
720  cur_index_ = 0;
721  ++lap_;
722  if (lap_ >= max_laps_)
723  BaseIter::valid(false);
724  }
725  BaseIter::cur_handle(vertices_[cur_index_]);
726  return *this;
727 }
728 
729 //================================================================================================
730 // BoundaryHalfFaceHalfFaceIter
731 //================================================================================================
732 
733 BoundaryHalfFaceHalfFaceIter::BoundaryHalfFaceHalfFaceIter(const HalfFaceHandle& _ref_h,
734  const TopologyKernel* _mesh, int _max_laps) :
735 BaseIter(_mesh, _ref_h, _max_laps) {
736 
737  if(!_mesh->has_face_bottom_up_incidences()) {
738 #ifndef NDEBUG
739  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
740 #endif
741  BaseIter::valid(false);
742  return;
743  }
744 
745  // Go over all incident halfedges
746 // const std::vector<HalfEdgeHandle> halfedges = _mesh->halfface(_ref_h).halfedges();
747  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
748  const std::vector<HalfEdgeHandle>& halfedges = halfface.halfedges();
749  for(std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();
750  he_it != halfedges.end(); ++he_it) {
751 
752  // Get outside halffaces
753  OpenVolumeMesh::HalfEdgeHalfFaceIter hehf_it = _mesh->hehf_iter(_mesh->opposite_halfedge_handle(*he_it));
754  for(; hehf_it.valid(); ++hehf_it) {
755 
756  if(_mesh->is_boundary(*hehf_it)) {
757  neighbor_halffaces_.push_back(*hehf_it);
758  common_edges_.push_back(_mesh->edge_handle(*he_it));
759  }
760  }
761  }
762 
763  cur_index_ = 0;
764  BaseIter::valid(neighbor_halffaces_.size() > 0);
765  if(BaseIter::valid()) {
766  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
767  }
768 }
769 
770 
771 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator--() {
772 
773  if (cur_index_ == 0)
774  {
775  cur_index_ = neighbor_halffaces_.size() - 1;
776  --lap_;
777  if (lap_ < 0)
778  BaseIter::valid(false);
779  }
780  else{
781  --cur_index_;
782  }
783 
784  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
785  return *this;
786 }
787 
788 
789 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator++() {
790 
791  ++cur_index_;
792  if (cur_index_ == neighbor_halffaces_.size())
793  {
794  cur_index_ = 0;
795  ++lap_;
796  if (lap_ >= max_laps_)
797  BaseIter::valid(false);
798  }
799 
800  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
801  return *this;
802 }
803 
807 
808 
809 VertexIter::VertexIter(const TopologyKernel* _mesh, const VertexHandle& _vh) :
810 BaseIter(_mesh, _vh),
811 cur_index_(_vh.idx()) {
812 
813  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
814  ++cur_index_;
815  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
816  BaseIter::valid(false);
817  }
818  BaseIter::cur_handle(VertexHandle(cur_index_));
819 }
820 
821 
822 VertexIter& VertexIter::operator--() {
823 
824  --cur_index_;
825  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
826  --cur_index_;
827  if(cur_index_ < 0) {
828  BaseIter::valid(false);
829  }
830  BaseIter::cur_handle(VertexHandle(cur_index_));
831  return *this;
832 }
833 
834 
835 VertexIter& VertexIter::operator++() {
836 
837  ++cur_index_;
838  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
839  ++cur_index_;
840  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
841  BaseIter::valid(false);
842  }
843  BaseIter::cur_handle(VertexHandle(cur_index_));
844  return *this;
845 }
846 
850 
851 
852 EdgeIter::EdgeIter(const TopologyKernel* _mesh, const EdgeHandle& _eh) :
853 BaseIter(_mesh, _eh),
854 cur_index_(_eh.idx()) {
855 
856  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
857  ++cur_index_;
858  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
859  BaseIter::valid(false);
860  }
861  BaseIter::cur_handle(EdgeHandle(cur_index_));
862 }
863 
864 
865 EdgeIter& EdgeIter::operator--() {
866 
867  --cur_index_;
868  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
869  --cur_index_;
870  if(cur_index_ < 0) {
871  BaseIter::valid(false);
872  }
873  BaseIter::cur_handle(EdgeHandle(cur_index_));
874  return *this;
875 }
876 
877 
878 EdgeIter& EdgeIter::operator++() {
879 
880  ++cur_index_;
881  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
882  ++cur_index_;
883  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
884  BaseIter::valid(false);
885  }
886  BaseIter::cur_handle(EdgeHandle(cur_index_));
887  return *this;
888 }
889 
893 
894 
895 HalfEdgeIter::HalfEdgeIter(const TopologyKernel* _mesh, const HalfEdgeHandle& _heh) :
896 BaseIter(_mesh, _heh),
897 cur_index_(_heh.idx()) {
898 
899  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
900  ++cur_index_;
901  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
902  BaseIter::valid(false);
903  }
904  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
905 }
906 
907 
908 HalfEdgeIter& HalfEdgeIter::operator--() {
909 
910  --cur_index_;
911  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
912  --cur_index_;
913  if(cur_index_ < 0) {
914  BaseIter::valid(false);
915  }
916  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
917  return *this;
918 }
919 
920 
921 HalfEdgeIter& HalfEdgeIter::operator++() {
922 
923  ++cur_index_;
924  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
925  ++cur_index_;
926  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
927  BaseIter::valid(false);
928  }
929  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
930  return *this;
931 }
932 
936 
937 
938 FaceIter::FaceIter(const TopologyKernel* _mesh, const FaceHandle& _fh) :
939 BaseIter(_mesh, _fh),
940 cur_index_(_fh.idx()) {
941 
942  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
943  ++cur_index_;
944  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
945  BaseIter::valid(false);
946  }
947  BaseIter::cur_handle(FaceHandle(cur_index_));
948 }
949 
950 
951 FaceIter& FaceIter::operator--() {
952 
953  --cur_index_;
954  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
955  --cur_index_;
956  if(cur_index_ < 0) {
957  BaseIter::valid(false);
958  }
959  BaseIter::cur_handle(FaceHandle(cur_index_));
960  return *this;
961 }
962 
963 
964 FaceIter& FaceIter::operator++() {
965 
966  ++cur_index_;
967  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
968  ++cur_index_;
969  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
970  BaseIter::valid(false);
971  }
972  BaseIter::cur_handle(FaceHandle(cur_index_));
973  return *this;
974 }
975 
979 
980 
981 HalfFaceIter::HalfFaceIter(const TopologyKernel* _mesh, const HalfFaceHandle& _hfh) :
982 BaseIter(_mesh, _hfh),
983 cur_index_(_hfh.idx()) {
984 
985  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
986  ++cur_index_;
987  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
988  BaseIter::valid(false);
989  }
990  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
991 }
992 
993 
994 HalfFaceIter& HalfFaceIter::operator--() {
995 
996  --cur_index_;
997  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
998  --cur_index_;
999  if(cur_index_ < 0) {
1000  BaseIter::valid(false);
1001  }
1002  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
1003  return *this;
1004 }
1005 
1006 
1007 HalfFaceIter& HalfFaceIter::operator++() {
1008 
1009  ++cur_index_;
1010  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
1011  ++cur_index_;
1012  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
1013  BaseIter::valid(false);
1014  }
1015  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
1016  return *this;
1017 }
1018 
1022 
1023 
1024 CellIter::CellIter(const TopologyKernel* _mesh, const CellHandle& _ch) :
1025 BaseIter(_mesh, _ch),
1026 cur_index_(_ch.idx()) {
1027 
1028  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1029  ++cur_index_;
1030  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
1031  BaseIter::valid(false);
1032  }
1033  BaseIter::cur_handle(CellHandle(cur_index_));
1034 }
1035 
1036 
1037 CellIter& CellIter::operator--() {
1038 
1039  --cur_index_;
1040  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1041  --cur_index_;
1042  if(cur_index_ < 0) {
1043  BaseIter::valid(false);
1044  }
1045  BaseIter::cur_handle(CellHandle(cur_index_));
1046  return *this;
1047 }
1048 
1049 
1050 CellIter& CellIter::operator++() {
1051 
1052  ++cur_index_;
1053  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1054  ++cur_index_;
1055  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
1056  BaseIter::valid(false);
1057  }
1058  BaseIter::cur_handle(CellHandle(cur_index_));
1059  return *this;
1060 }
1061 
1062 namespace Internal {
1063 
1067 
1068 VertexIHalfEdgeIterImpl::VertexIHalfEdgeIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1069  BaseIter(_mesh, _ref_h, _max_laps),
1070  voh_iter_(_mesh->voh_iter(_ref_h, _max_laps))
1071 {
1072  BaseIter::valid(voh_iter_.valid());
1073  if (BaseIter::valid()) {
1074  BaseIter::cur_handle(mesh()->opposite_halfedge_handle(*voh_iter_));
1075  }
1076 }
1077 
1078 VertexIHalfEdgeIterImpl& VertexIHalfEdgeIterImpl::operator--() {
1079  --voh_iter_;
1080  BaseIter::lap(voh_iter_.lap());
1081  BaseIter::valid(voh_iter_.valid());
1082  BaseIter::cur_handle(mesh()->opposite_halfedge_handle(*voh_iter_));
1083  return *this;
1084 }
1085 
1086 VertexIHalfEdgeIterImpl& VertexIHalfEdgeIterImpl::operator++() {
1087  ++voh_iter_;
1088  BaseIter::lap(voh_iter_.lap());
1089  BaseIter::valid(voh_iter_.valid());
1090  BaseIter::cur_handle(mesh()->opposite_halfedge_handle(*voh_iter_));
1091  return *this;
1092 }
1093 
1097 
1098 VertexEdgeIterImpl::VertexEdgeIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1099  BaseIter(_mesh, _ref_h, _max_laps),
1100  voh_iter_(_mesh->voh_iter(_ref_h, _max_laps))
1101 {
1102  BaseIter::valid(voh_iter_.valid());
1103  if (BaseIter::valid()) {
1104  BaseIter::cur_handle(mesh()->edge_handle(*voh_iter_));
1105  }
1106 }
1107 
1108 VertexEdgeIterImpl& VertexEdgeIterImpl::operator--() {
1109  --voh_iter_;
1110  BaseIter::lap(voh_iter_.lap());
1111  BaseIter::valid(voh_iter_.valid());
1112  BaseIter::cur_handle(mesh()->edge_handle(*voh_iter_));
1113  return *this;
1114 }
1115 
1116 VertexEdgeIterImpl& VertexEdgeIterImpl::operator++() {
1117  ++voh_iter_;
1118  BaseIter::lap(voh_iter_.lap());
1119  BaseIter::valid(voh_iter_.valid());
1120  BaseIter::cur_handle(mesh()->edge_handle(*voh_iter_));
1121  return *this;
1122 }
1123 
1127 
1128 VertexHalfFaceIterImpl::VertexHalfFaceIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1129  BaseIter(_mesh, _ref_h, _max_laps),
1130  cur_index_(0)
1131 {
1132  for (VertexEdgeIter ve_iter = _mesh->ve_iter(_ref_h); ve_iter.valid(); ++ve_iter) {
1133  for (EdgeHalfFaceIter ehf_iter = _mesh->ehf_iter(*ve_iter); ehf_iter.valid(); ++ehf_iter) {
1134  halffaces_.push_back(*ehf_iter);
1135  }
1136  }
1137 
1138  // Remove all duplicate entries
1139  std::sort(halffaces_.begin(), halffaces_.end());
1140  halffaces_.resize(std::unique(halffaces_.begin(), halffaces_.end()) - halffaces_.begin());
1141 
1142  BaseIter::valid(halffaces_.size() > 0);
1143  if (BaseIter::valid()) {
1144  BaseIter::cur_handle(halffaces_[cur_index_]);
1145  }
1146 }
1147 
1148 VertexHalfFaceIterImpl& VertexHalfFaceIterImpl::operator--() {
1149  if (cur_index_ == 0) {
1150  cur_index_ = halffaces_.size() - 1;
1151  --lap_;
1152  if (lap_ < 0)
1153  BaseIter::valid(false);
1154  }
1155  else {
1156  --cur_index_;
1157  }
1158  BaseIter::cur_handle(halffaces_[cur_index_]);
1159  return *this;
1160 }
1161 
1162 VertexHalfFaceIterImpl& VertexHalfFaceIterImpl::operator++() {
1163  ++cur_index_;
1164  if (cur_index_ >= halffaces_.size()) {
1165  cur_index_ = 0;
1166  ++lap_;
1167  if (lap_ >= max_laps_)
1168  BaseIter::valid(false);
1169  }
1170  BaseIter::cur_handle(halffaces_[cur_index_]);
1171  return *this;
1172 }
1173 
1174 
1178 
1179 HalfEdgeFaceIterImpl::HalfEdgeFaceIterImpl(const HalfEdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1180  BaseIter(_mesh, _ref_h, _max_laps),
1181  cur_index_(0)
1182 {
1183  for (HalfEdgeHalfFaceIter hehf_iter = _mesh->hehf_iter(_ref_h); hehf_iter.valid(); ++hehf_iter) {
1184  faces_.push_back(_mesh->face_handle(*hehf_iter));
1185  }
1186 
1187  // Remove all duplicate entries
1188  std::sort(faces_.begin(), faces_.end());
1189  faces_.resize(std::unique(faces_.begin(), faces_.end()) - faces_.begin());
1190 
1191  BaseIter::valid(faces_.size() > 0);
1192  if (BaseIter::valid()) {
1193  BaseIter::cur_handle(faces_[cur_index_]);
1194  }
1195 }
1196 
1197 HalfEdgeFaceIterImpl& HalfEdgeFaceIterImpl::operator--() {
1198  if (cur_index_ == 0) {
1199  cur_index_ = faces_.size() - 1;
1200  --lap_;
1201  if (lap_ < 0)
1202  BaseIter::valid(false);
1203  }
1204  else {
1205  --cur_index_;
1206  }
1207  BaseIter::cur_handle(faces_[cur_index_]);
1208  return *this;
1209 }
1210 
1211 HalfEdgeFaceIterImpl& HalfEdgeFaceIterImpl::operator++() {
1212  ++cur_index_;
1213  if (cur_index_ >= faces_.size()) {
1214  cur_index_ = 0;
1215  ++lap_;
1216  if (lap_ >= max_laps_)
1217  BaseIter::valid(false);
1218  }
1219  BaseIter::cur_handle(faces_[cur_index_]);
1220  return *this;
1221 }
1222 
1223 
1227 
1228 EdgeHalfFaceIterImpl::EdgeHalfFaceIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1229  BaseIter(_mesh, _ref_h, _max_laps),
1230  cur_index_(0)
1231 {
1232  const HalfEdgeHandle he = _mesh->halfedge_handle(_ref_h, 0);
1233  for (HalfEdgeHalfFaceIter hehf_iter = _mesh->hehf_iter(he); hehf_iter.valid(); ++hehf_iter) {
1234  halffaces_.push_back(*hehf_iter);
1235  halffaces_.push_back(_mesh->opposite_halfface_handle(*hehf_iter));
1236  }
1237 
1238  BaseIter::valid(halffaces_.size() > 0);
1239  if (BaseIter::valid()) {
1240  BaseIter::cur_handle(halffaces_[cur_index_]);
1241  }
1242 }
1243 
1244 EdgeHalfFaceIterImpl& EdgeHalfFaceIterImpl::operator--() {
1245  if (cur_index_ == 0) {
1246  cur_index_ = halffaces_.size() - 1;
1247  --lap_;
1248  if (lap_ < 0)
1249  BaseIter::valid(false);
1250  }
1251  else {
1252  --cur_index_;
1253  }
1254  BaseIter::cur_handle(halffaces_[cur_index_]);
1255  return *this;
1256 }
1257 
1258 EdgeHalfFaceIterImpl& EdgeHalfFaceIterImpl::operator++() {
1259  ++cur_index_;
1260  if (cur_index_ >= halffaces_.size()) {
1261  cur_index_ = 0;
1262  ++lap_;
1263  if (lap_ >= max_laps_)
1264  BaseIter::valid(false);
1265  }
1266  BaseIter::cur_handle(halffaces_[cur_index_]);
1267  return *this;
1268 }
1269 
1270 
1274 
1275 EdgeFaceIterImpl::EdgeFaceIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1276  HalfEdgeFaceIterImpl(_mesh->halfedge_handle(_ref_h, 0), _mesh, _max_laps) {}
1277 
1278 
1282 
1283 EdgeCellIterImpl::EdgeCellIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1284  HalfEdgeCellIter(_mesh->halfedge_handle(_ref_h, 0), _mesh, _max_laps) {}
1285 
1286 
1290 
1291 HalfFaceHalfEdgeIterImpl::HalfFaceHalfEdgeIterImpl(const HalfFaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1292  BaseIter(_mesh, _ref_h, _max_laps),
1293  cur_index_(0)
1294 {
1295  BaseIter::valid(_ref_h.is_valid() && _mesh->halfface(_ref_h).halfedges().size() > 0);
1296  if (BaseIter::valid()) {
1297  BaseIter::cur_handle(_mesh->halfface(_ref_h).halfedges()[cur_index_]);
1298  }
1299 }
1300 
1301 HalfFaceHalfEdgeIterImpl& HalfFaceHalfEdgeIterImpl::operator--() {
1302  const std::vector<HalfEdgeHandle> halfedges =
1303  mesh()->halfface(ref_handle()).halfedges();
1304  if (cur_index_ == 0) {
1305  cur_index_ = halfedges.size() - 1;
1306  --lap_;
1307  if (lap_ < 0)
1308  BaseIter::valid(false);
1309  }
1310  else {
1311  --cur_index_;
1312  }
1313  BaseIter::cur_handle(halfedges[cur_index_]);
1314  return *this;
1315 }
1316 
1317 HalfFaceHalfEdgeIterImpl& HalfFaceHalfEdgeIterImpl::operator++() {
1318  const std::vector<HalfEdgeHandle> halfedges =
1319  mesh()->halfface(ref_handle()).halfedges();
1320  ++cur_index_;
1321  if (cur_index_ >= halfedges.size()) {
1322  cur_index_ = 0;
1323  ++lap_;
1324  if (lap_ >= max_laps_)
1325  BaseIter::valid(false);
1326  }
1327  BaseIter::cur_handle(halfedges[cur_index_]);
1328  return *this;
1329 }
1330 
1331 
1335 
1336 HalfFaceEdgeIterImpl::HalfFaceEdgeIterImpl(const HalfFaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1337  BaseIter(_mesh, _ref_h, _max_laps),
1338  cur_index_(0)
1339 {
1340  BaseIter::valid(_ref_h.is_valid() && _mesh->halfface(_ref_h).halfedges().size() > 0);
1341  if (BaseIter::valid()) {
1342  HalfEdgeHandle he = _mesh->halfface(_ref_h).halfedges()[cur_index_];
1343  BaseIter::cur_handle(_mesh->edge_handle(he));
1344  }
1345 }
1346 
1347 HalfFaceEdgeIterImpl& HalfFaceEdgeIterImpl::operator--() {
1348  const std::vector<HalfEdgeHandle> halfedges =
1349  mesh()->halfface(ref_handle()).halfedges();
1350  if (cur_index_ == 0) {
1351  cur_index_ = halfedges.size() - 1;
1352  --lap_;
1353  if (lap_ < 0)
1354  BaseIter::valid(false);
1355  }
1356  else {
1357  --cur_index_;
1358  }
1359  BaseIter::cur_handle(mesh()->edge_handle(halfedges[cur_index_]));
1360  return *this;
1361 }
1362 
1363 HalfFaceEdgeIterImpl& HalfFaceEdgeIterImpl::operator++() {
1364  const std::vector<HalfEdgeHandle> halfedges =
1365  mesh()->halfface(ref_handle()).halfedges();
1366  ++cur_index_;
1367  if (cur_index_ >= halfedges.size()) {
1368  cur_index_ = 0;
1369  ++lap_;
1370  if (lap_ >= max_laps_)
1371  BaseIter::valid(false);
1372  }
1373  BaseIter::cur_handle(mesh()->edge_handle(halfedges[cur_index_]));
1374  return *this;
1375 }
1376 
1380 
1381 FaceVertexIterImpl::FaceVertexIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1382  HalfFaceVertexIter(_mesh->halfface_handle(_ref_h, 0), _mesh, _max_laps) {}
1383 
1387 
1388 FaceHalfEdgeIterImpl::FaceHalfEdgeIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1389  HalfFaceHalfEdgeIterImpl(_mesh->halfface_handle(_ref_h, 0), _mesh, _max_laps) {}
1390 
1391 
1395 
1396 FaceEdgeIterImpl::FaceEdgeIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1397  HalfFaceEdgeIterImpl(_mesh->halfface_handle(_ref_h, 0), _mesh, _max_laps) {}
1398 
1399 
1403 
1404 CellHalfEdgeIterImpl::CellHalfEdgeIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1405  BaseIter(_mesh, _ref_h, _max_laps),
1406  cur_index_(0)
1407 {
1408  for (CellHalfFaceIter chf_iter =_mesh->chf_iter(_ref_h); chf_iter.valid(); ++chf_iter) {
1409  for (HalfFaceHalfEdgeIter hfhe_iter =_mesh->hfhe_iter(*chf_iter); hfhe_iter.valid(); ++hfhe_iter) {
1410  halfedges_.push_back(*hfhe_iter);
1411  }
1412  }
1413  BaseIter::valid(halfedges_.size() > 0);
1414  if (BaseIter::valid()) {
1415  BaseIter::cur_handle(halfedges_[cur_index_]);
1416  }
1417 }
1418 
1419 CellHalfEdgeIterImpl& CellHalfEdgeIterImpl::operator--() {
1420  if (cur_index_ == 0) {
1421  cur_index_ = halfedges_.size() - 1;
1422  --lap_;
1423  if (lap_ < 0)
1424  BaseIter::valid(false);
1425  }
1426  else {
1427  --cur_index_;
1428  }
1429  BaseIter::cur_handle(halfedges_[cur_index_]);
1430  return *this;
1431 }
1432 
1433 CellHalfEdgeIterImpl& CellHalfEdgeIterImpl::operator++() {
1434  ++cur_index_;
1435  if (cur_index_ >= halfedges_.size()) {
1436  cur_index_ = 0;
1437  ++lap_;
1438  if (lap_ >= max_laps_)
1439  BaseIter::valid(false);
1440  }
1441  BaseIter::cur_handle(halfedges_[cur_index_]);
1442  return *this;
1443 }
1444 
1445 
1449 
1450 CellEdgeIterImpl::CellEdgeIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1451  BaseIter(_mesh, _ref_h, _max_laps),
1452  cur_index_(0)
1453 {
1454  for (CellHalfEdgeIter che_iter = _mesh->che_iter(_ref_h); che_iter.valid(); ++che_iter) {
1455  edges_.push_back(_mesh->edge_handle(*che_iter));
1456  }
1457 
1458  // Remove all duplicate entries
1459  std::sort(edges_.begin(), edges_.end());
1460  edges_.resize(std::unique(edges_.begin(), edges_.end()) - edges_.begin());
1461 
1462  BaseIter::valid(edges_.size() > 0);
1463  if (BaseIter::valid()) {
1464  BaseIter::cur_handle(edges_[cur_index_]);
1465  }
1466 }
1467 
1468 CellEdgeIterImpl& CellEdgeIterImpl::operator--() {
1469  if (cur_index_ == 0) {
1470  cur_index_ = edges_.size() - 1;
1471  --lap_;
1472  if (lap_ < 0)
1473  BaseIter::valid(false);
1474  }
1475  else {
1476  --cur_index_;
1477  }
1478  BaseIter::cur_handle(edges_[cur_index_]);
1479  return *this;
1480 }
1481 
1482 CellEdgeIterImpl& CellEdgeIterImpl::operator++() {
1483  ++cur_index_;
1484  if (cur_index_ >= edges_.size()) {
1485  cur_index_ = 0;
1486  ++lap_;
1487  if (lap_ >= max_laps_)
1488  BaseIter::valid(false);
1489  }
1490  BaseIter::cur_handle(edges_[cur_index_]);
1491  return *this;
1492 }
1493 
1494 
1498 
1499 CellHalfFaceIterImpl::CellHalfFaceIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1500  BaseIter(_mesh, _ref_h, _max_laps),
1501  hf_iter_(BaseIter::mesh()->cell(_ref_h).halffaces().begin())
1502 {
1503  BaseIter::valid(hf_iter_ != BaseIter::mesh()->cell(_ref_h).halffaces().end());
1504  if (BaseIter::valid()) {
1505  BaseIter::cur_handle(*hf_iter_);
1506  }
1507 }
1508 
1509 CellHalfFaceIterImpl& CellHalfFaceIterImpl::operator--() {
1510  const std::vector<HalfFaceHandle>& halffaces =
1511  BaseIter::mesh()->cell(ref_handle_).halffaces();
1512  if (hf_iter_ == halffaces.begin()) {
1513  hf_iter_ = halffaces.end();
1514  --lap_;
1515  if (lap_ < 0)
1516  BaseIter::valid(false);
1517  }
1518  else {
1519  --hf_iter_;
1520  }
1521  BaseIter::cur_handle(*hf_iter_);
1522  return *this;
1523 }
1524 
1525 CellHalfFaceIterImpl& CellHalfFaceIterImpl::operator++() {
1526  ++hf_iter_;
1527  const std::vector<HalfFaceHandle>& halffaces =
1528  BaseIter::mesh()->cell(ref_handle_).halffaces();
1529  if (hf_iter_ == halffaces.end()) {
1530  hf_iter_ = halffaces.begin();
1531  ++lap_;
1532  if (lap_ >= max_laps_)
1533  BaseIter::valid(false);
1534  }
1535  BaseIter::cur_handle(*hf_iter_);
1536  return *this;
1537 }
1538 
1539 
1543 
1544 CellFaceIterImpl::CellFaceIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps) :
1545  BaseIter(_mesh, _ref_h, _max_laps),
1546  hf_iter_(BaseIter::mesh()->cell(_ref_h).halffaces().begin())
1547 {
1548  BaseIter::valid(hf_iter_ != BaseIter::mesh()->cell(_ref_h).halffaces().end());
1549  if (BaseIter::valid()) {
1550  BaseIter::cur_handle(BaseIter::mesh()->face_handle(*hf_iter_));
1551  }
1552 }
1553 
1554 CellFaceIterImpl& CellFaceIterImpl::operator--() {
1555  const std::vector<HalfFaceHandle>& halffaces =
1556  BaseIter::mesh()->cell(ref_handle_).halffaces();
1557  if (hf_iter_ == halffaces.begin()) {
1558  hf_iter_ = halffaces.end();
1559  --lap_;
1560  if (lap_ < 0)
1561  BaseIter::valid(false);
1562  }
1563  else {
1564  --hf_iter_;
1565  }
1566  BaseIter::cur_handle(BaseIter::mesh()->face_handle(*hf_iter_));
1567  return *this;
1568 }
1569 
1570 CellFaceIterImpl& CellFaceIterImpl::operator++() {
1571  ++hf_iter_;
1572  const std::vector<HalfFaceHandle>& halffaces =
1573  BaseIter::mesh()->cell(ref_handle_).halffaces();
1574  if (hf_iter_ == halffaces.end()) {
1575  hf_iter_ = halffaces.begin();
1576  ++lap_;
1577  if (lap_ >= max_laps_)
1578  BaseIter::valid(false);
1579  }
1580  BaseIter::cur_handle(BaseIter::mesh()->face_handle(*hf_iter_));
1581  return *this;
1582 }
1583 
1584 }
1585 
1586 
1590 
1591 template <>
1592 size_t BoundaryItemIter<VertexIter, VertexHandle>::n_items() const {
1593  return BaseIter::mesh()->n_vertices();
1594 }
1595 
1596 template <>
1597 size_t BoundaryItemIter<HalfEdgeIter, HalfEdgeHandle>::n_items() const {
1598  return BaseIter::mesh()->n_halfedges();
1599 }
1600 
1601 template <>
1602 size_t BoundaryItemIter<EdgeIter, EdgeHandle>::n_items() const {
1603  return BaseIter::mesh()->n_edges();
1604 }
1605 
1606 template <>
1607 size_t BoundaryItemIter<HalfFaceIter, HalfFaceHandle>::n_items() const {
1608  return BaseIter::mesh()->n_halffaces();
1609 }
1610 
1611 template <>
1612 size_t BoundaryItemIter<FaceIter, FaceHandle>::n_items() const {
1613  return BaseIter::mesh()->n_faces();
1614 }
1615 
1616 template <>
1617 size_t BoundaryItemIter<CellIter, CellHandle>::n_items() const {
1618  return BaseIter::mesh()->n_cells();
1619 }
1620 
1621 template <>
1622 bool BoundaryItemIter<VertexIter, VertexHandle>::has_incidences() const {
1623  return BaseIter::mesh()->has_full_bottom_up_incidences();
1624 }
1625 
1626 template <>
1627 bool BoundaryItemIter<HalfEdgeIter, HalfEdgeHandle>::has_incidences() const {
1628  const TopologyKernel *mesh = BaseIter::mesh();
1629  return mesh->has_edge_bottom_up_incidences() && mesh->has_face_bottom_up_incidences();
1630 }
1631 
1632 template <>
1633 bool BoundaryItemIter<EdgeIter, EdgeHandle>::has_incidences() const {
1634  const TopologyKernel *mesh = BaseIter::mesh();
1635  return mesh->has_edge_bottom_up_incidences() && mesh->has_face_bottom_up_incidences();
1636 }
1637 
1638 template <>
1639 bool BoundaryItemIter<HalfFaceIter, HalfFaceHandle>::has_incidences() const {
1640  return BaseIter::mesh()->has_face_bottom_up_incidences();
1641 }
1642 
1643 template <>
1644 bool BoundaryItemIter<FaceIter, FaceHandle>::has_incidences() const {
1645  return BaseIter::mesh()->has_face_bottom_up_incidences();
1646 }
1647 
1648 template <>
1649 bool BoundaryItemIter<CellIter, CellHandle>::has_incidences() const {
1650  return true;
1651 }
1652 
1653 } // Namespace OpenVolumeMesh