Developer Documentation
Iterators.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 ITERATORS_HH_
44 #define ITERATORS_HH_
45 
46 #include <iterator>
47 #include <set>
48 #include <vector>
49 
50 #ifndef NDEBUG
51 #include <iostream>
52 #endif
53 
54 #include "OpenVolumeMeshHandle.hh"
55 
56 namespace OpenVolumeMesh {
57 
58 class TopologyKernel;
59 
60 template <
61 class OH /* Output handle type */>
62 class BaseIterator {
63 public:
64 
65  // STL compliance
66  typedef std::bidirectional_iterator_tag iterator_category;
67  typedef int difference_type;
68  typedef const OH value_type;
69  typedef const OH* pointer;
70  typedef const OH& reference;
71 
72 
73  BaseIterator(const TopologyKernel* _mesh, const OH& _ch) :
74  valid_(true), cur_handle_(_ch), mesh_(_mesh) {}
75 
76  explicit BaseIterator(const TopologyKernel* _mesh) :
77  valid_(true), mesh_(_mesh) {}
78 
79  // STL compliance (needs to have default constructor)
80  BaseIterator() : valid_(false), mesh_(nullptr) {}
81  virtual ~BaseIterator() = default;
82  bool operator== (const BaseIterator& _c) const {
83  return (this->cur_handle_ == _c.cur_handle() &&
84  this->valid_ == _c.valid() &&
85  this->mesh_ == _c.mesh());
86  }
87  bool operator!= (const BaseIterator& _c) const {
88  return !this->operator==(_c);
89  }
90 
91  pointer operator->() const {
92  return &cur_handle_;
93  }
94 
95  reference operator*() const {
96  return cur_handle_;
97  }
98 
99  bool operator< (const BaseIterator& _c) const {
100  return cur_handle_.idx() < _c.cur_handle_.idx();
101  }
102 
103  BaseIterator& operator=(const BaseIterator& _c) {
104  this->valid_ = _c.valid();
105  this->cur_handle_ = _c.cur_handle();
106  this->mesh_ = _c.mesh();
107  return *this;
108  }
109 
110  operator bool() const {
111  return valid_;
112  }
113 
114  void valid(bool _valid) {
115  valid_ = _valid;
116  }
117  bool valid() const {
118  return valid_;
119  }
120  void cur_handle(const OH& _h) {
121  cur_handle_ = _h;
122  }
123  reference cur_handle() const {
124  return cur_handle_;
125  }
126  const TopologyKernel* mesh() const {
127  return mesh_;
128  }
129 
130 private:
131 
132  bool valid_;
133  OH cur_handle_;
134  const TopologyKernel* mesh_;
135 };
136 
137 
138 #if __cplusplus >= 201103L || _MSC_VER >= 1800 // an older MSVC version might be sufficient, didn't test
139 
140 #include <type_traits>
141 
142 template<class I>
143 using is_ovm_iterator = std::is_base_of<BaseIterator<typename std::remove_const<typename I::value_type>::type>, I>;
144 
145 // provide begin() and end() for the iterator pairs provided in TopologyKernel,
146 // so we can use range-for, e.g. for(const auto &vh: mesh.vertices()) works.
147 template<class I>
148 typename std::enable_if<is_ovm_iterator<I>::value, I>::type
149 begin(const std::pair<I, I>& iterpair)
150 {
151  return iterpair.first;
152 }
153 
154 template<class I>
155 typename std::enable_if<is_ovm_iterator<I>::value, I>::type
156 end(const std::pair<I, I>& iterpair)
157 {
158  return iterpair.second;
159 }
160 
161 #endif // C++11
162 
163 template <
164 class IH /* Input handle type */,
165 class OH /* Output handle type */>
166 class BaseCirculator : public BaseIterator<OH> {
167 public:
168 
169  typedef BaseIterator<OH> BaseIter;
170 
171  BaseCirculator(const TopologyKernel* _mesh, const IH& _ih, const OH& _oh, int _max_laps = 1) :
172  BaseIter(_mesh, _oh),
173  lap_(0),
174  max_laps_(_max_laps),
175  ref_handle_(_ih)
176  {}
177 
178  BaseCirculator(const TopologyKernel* _mesh, const IH& _ih, int _max_laps = 1) :
179  BaseIter(_mesh, OH()),
180  lap_(0),
181  max_laps_(_max_laps),
182  ref_handle_(_ih)
183  {}
184 
185  // STL compliance (needs to have default constructor)
186  BaseCirculator() :
187  BaseIter(),
188  lap_(0),
189  max_laps_(1)
190  {}
191 
192  virtual ~BaseCirculator() = default;
193 
194  bool operator== (const BaseCirculator& _c) const {
195  return (BaseIter::operator==(_c) &&
196  this->lap() == _c.lap() &&
197  this->ref_handle() == _c.ref_handle());
198  }
199  bool operator!= (const BaseCirculator& _c) const {
200  return !this->operator==(_c);
201  }
202 
203  bool operator< (const BaseCirculator& _c) const {
204  if (lap_ == _c.lap_)
205  return BaseIter::operator<(_c);
206  else
207  return lap_ < _c.lap_;
208  }
209 
210  BaseCirculator& operator=(const BaseCirculator& _c) {
211  BaseIter::operator=(_c);
212  this->ref_handle_ = _c.ref_handle();
213  this->lap_ = _c.lap_;
214  this->max_laps_ = _c.max_laps_;
215  return *this;
216  }
217 
218  const IH& ref_handle() const {
219  return ref_handle_;
220  }
221 
222  void lap(int _lap) {
223  lap_ = _lap;
224  }
225  int lap() const {
226  return lap_;
227  }
228 
229  void max_laps(int _max_laps) {
230  max_laps_ = _max_laps;
231  }
232  int max_laps() const {
233  return max_laps_;
234  }
235 
236 protected:
237  int lap_;
238  int max_laps_;
239  IH ref_handle_;
240 
241 };
242 
243 //===========================================================================
244 
246  public BaseCirculator<
247  VertexHandle,
248  HalfEdgeHandle> {
249 public:
250  typedef BaseCirculator<
251  VertexHandle,
253 
254 
255  VertexOHalfEdgeIter(const VertexHandle& _vIdx,
256  const TopologyKernel* _mesh, int _max_laps = 1);
257 
258  // Post increment/decrement operator
259  VertexOHalfEdgeIter operator++(int) {
260  VertexOHalfEdgeIter cpy = *this;
261  ++(*this);
262  return cpy;
263  }
264  VertexOHalfEdgeIter operator--(int) {
265  VertexOHalfEdgeIter cpy = *this;
266  --(*this);
267  return cpy;
268  }
269  VertexOHalfEdgeIter operator+(int _n) {
270  VertexOHalfEdgeIter cpy = *this;
271  for(int i = 0; i < _n; ++i) {
272  ++cpy;
273  }
274  return cpy;
275  }
276  VertexOHalfEdgeIter operator-(int _n) {
277  VertexOHalfEdgeIter cpy = *this;
278  for(int i = 0; i < _n; ++i) {
279  --cpy;
280  }
281  return cpy;
282  }
283  VertexOHalfEdgeIter& operator+=(int _n) {
284  for(int i = 0; i < _n; ++i) {
285  ++(*this);
286  }
287  return *this;
288  }
289  VertexOHalfEdgeIter& operator-=(int _n) {
290  for(int i = 0; i < _n; ++i) {
291  --(*this);
292  }
293  return *this;
294  }
295 
296  VertexOHalfEdgeIter& operator++();
297  VertexOHalfEdgeIter& operator--();
298 
299 private:
300 
301  size_t cur_index_;
302 };
303 
304 
305 
306 //===========================================================================
307 
309  public BaseCirculator<
310  VertexHandle,
311  VertexHandle> {
312 public:
313  typedef BaseCirculator<
314  VertexHandle,
315  VertexHandle> BaseIter;
316 
317 
318  VertexVertexIter(const VertexHandle& _vIdx,
319  const TopologyKernel* _mesh, int _max_laps = 1);
320 
321  // Post increment/decrement operator
322  VertexVertexIter operator++(int) {
323  VertexVertexIter cpy = *this;
324  ++(*this);
325  return cpy;
326  }
327  VertexVertexIter operator--(int) {
328  VertexVertexIter cpy = *this;
329  --(*this);
330  return cpy;
331  }
332  VertexVertexIter operator+(int _n) {
333  VertexVertexIter cpy = *this;
334  for(int i = 0; i < _n; ++i) {
335  ++cpy;
336  }
337  return cpy;
338  }
339  VertexVertexIter operator-(int _n) {
340  VertexVertexIter cpy = *this;
341  for(int i = 0; i < _n; ++i) {
342  --cpy;
343  }
344  return cpy;
345  }
346  VertexVertexIter& operator+=(int _n) {
347  for(int i = 0; i < _n; ++i) {
348  ++(*this);
349  }
350  return *this;
351  }
352  VertexVertexIter& operator-=(int _n) {
353  for(int i = 0; i < _n; ++i) {
354  --(*this);
355  }
356  return *this;
357  }
358 
359  VertexVertexIter& operator++();
360  VertexVertexIter& operator--();
361 
362 private:
363 
364  size_t cur_index_;
365 };
366 
367 //===========================================================================
368 
370  HalfEdgeHandle,
371  HalfFaceHandle> {
372 public:
373  typedef BaseCirculator<
376 
377 
378  HalfEdgeHalfFaceIter(const HalfEdgeHandle& _heIdx, const TopologyKernel* _mesh, int _max_laps = 1);
379 
380  // Post increment/decrement operator
381  HalfEdgeHalfFaceIter operator++(int) {
382  HalfEdgeHalfFaceIter cpy = *this;
383  ++(*this);
384  return cpy;
385  }
386  HalfEdgeHalfFaceIter operator--(int) {
387  HalfEdgeHalfFaceIter cpy = *this;
388  --(*this);
389  return cpy;
390  }
391  HalfEdgeHalfFaceIter operator+(int _n) {
392  HalfEdgeHalfFaceIter cpy = *this;
393  for(int i = 0; i < _n; ++i) {
394  ++cpy;
395  }
396  return cpy;
397  }
398  HalfEdgeHalfFaceIter operator-(int _n) {
399  HalfEdgeHalfFaceIter cpy = *this;
400  for(int i = 0; i < _n; ++i) {
401  --cpy;
402  }
403  return cpy;
404  }
405  HalfEdgeHalfFaceIter& operator+=(int _n) {
406  for(int i = 0; i < _n; ++i) {
407  ++(*this);
408  }
409  return *this;
410  }
411  HalfEdgeHalfFaceIter& operator-=(int _n) {
412  for(int i = 0; i < _n; ++i) {
413  --(*this);
414  }
415  return *this;
416  }
417 
418  HalfEdgeHalfFaceIter& operator++();
419  HalfEdgeHalfFaceIter& operator--();
420 
421 private:
422  size_t cur_index_;
423 };
424 
425 //===========================================================================
426 
428  VertexHandle,
429  FaceHandle> {
430 public:
431  typedef BaseCirculator<
432  VertexHandle,
434 
435  VertexFaceIter(const VertexHandle& _vIdx, const TopologyKernel* _mesh, int _max_laps = 1);
436 
437  // Post increment/decrement operator
438  VertexFaceIter operator++(int) {
439  VertexFaceIter cpy = *this;
440  ++(*this);
441  return cpy;
442  }
443  VertexFaceIter operator--(int) {
444  VertexFaceIter cpy = *this;
445  --(*this);
446  return cpy;
447  }
448  VertexFaceIter operator+(int _n) {
449  VertexFaceIter cpy = *this;
450  for(int i = 0; i < _n; ++i) {
451  ++cpy;
452  }
453  return cpy;
454  }
455  VertexFaceIter operator-(int _n) {
456  VertexFaceIter cpy = *this;
457  for(int i = 0; i < _n; ++i) {
458  --cpy;
459  }
460  return cpy;
461  }
462  VertexFaceIter& operator+=(int _n) {
463  for(int i = 0; i < _n; ++i) {
464  ++(*this);
465  }
466  return *this;
467  }
468  VertexFaceIter& operator-=(int _n) {
469  for(int i = 0; i < _n; ++i) {
470  --(*this);
471  }
472  return *this;
473  }
474 
475  VertexFaceIter& operator++();
476  VertexFaceIter& operator--();
477 
478 private:
479  std::vector<FaceHandle> faces_;
480  size_t cur_index_;
481 };
482 
483 //===========================================================================
484 
486  VertexHandle,
487  CellHandle> {
488 public:
489  typedef BaseCirculator<
490  VertexHandle,
492 
493  VertexCellIter(const VertexHandle& _vIdx, const TopologyKernel* _mesh, int _max_laps = 1);
494 
495  // Post increment/decrement operator
496  VertexCellIter operator++(int) {
497  VertexCellIter cpy = *this;
498  ++(*this);
499  return cpy;
500  }
501  VertexCellIter operator--(int) {
502  VertexCellIter cpy = *this;
503  --(*this);
504  return cpy;
505  }
506  VertexCellIter operator+(int _n) {
507  VertexCellIter cpy = *this;
508  for(int i = 0; i < _n; ++i) {
509  ++cpy;
510  }
511  return cpy;
512  }
513  VertexCellIter operator-(int _n) {
514  VertexCellIter cpy = *this;
515  for(int i = 0; i < _n; ++i) {
516  --cpy;
517  }
518  return cpy;
519  }
520  VertexCellIter& operator+=(int _n) {
521  for(int i = 0; i < _n; ++i) {
522  ++(*this);
523  }
524  return *this;
525  }
526  VertexCellIter& operator-=(int _n) {
527  for(int i = 0; i < _n; ++i) {
528  --(*this);
529  }
530  return *this;
531  }
532 
533  VertexCellIter& operator++();
534  VertexCellIter& operator--();
535 
536 private:
537  std::vector<CellHandle> cells_;
538  size_t cur_index_;
539 };
540 
542  HalfEdgeHandle,
543  CellHandle> {
544 public:
545  typedef BaseCirculator<
548 
549 
550  HalfEdgeCellIter(const HalfEdgeHandle& _heIdx, const TopologyKernel* _mesh, int _max_laps = 1);
551 
552  // Post increment/decrement operator
553  HalfEdgeCellIter operator++(int) {
554  HalfEdgeCellIter cpy = *this;
555  ++(*this);
556  return cpy;
557  }
558  HalfEdgeCellIter operator--(int) {
559  HalfEdgeCellIter cpy = *this;
560  --(*this);
561  return cpy;
562  }
563  HalfEdgeCellIter operator+(int _n) {
564  HalfEdgeCellIter cpy = *this;
565  for(int i = 0; i < _n; ++i) {
566  ++cpy;
567  }
568  return cpy;
569  }
570  HalfEdgeCellIter operator-(int _n) {
571  HalfEdgeCellIter cpy = *this;
572  for(int i = 0; i < _n; ++i) {
573  --cpy;
574  }
575  return cpy;
576  }
577  HalfEdgeCellIter& operator+=(int _n) {
578  for(int i = 0; i < _n; ++i) {
579  ++(*this);
580  }
581  return *this;
582  }
583  HalfEdgeCellIter& operator-=(int _n) {
584  for(int i = 0; i < _n; ++i) {
585  --(*this);
586  }
587  return *this;
588  }
589 
590  HalfEdgeCellIter& operator++();
591  HalfEdgeCellIter& operator--();
592 
593 private:
594  CellHandle getCellHandle(int _cur_index) const;
595 
596 private:
597  std::vector<CellHandle> cells_;
598  size_t cur_index_;
599 };
600 
601 //===========================================================================
602 
604  CellHandle,
605  VertexHandle> {
606 public:
607  typedef BaseCirculator<
608  CellHandle,
610 
611  CellVertexIter(const CellHandle& _cIdx, const TopologyKernel* _mesh, int _max_laps = 1);
612 
613  // Post increment/decrement operator
614  CellVertexIter operator++(int) {
615  CellVertexIter cpy = *this;
616  ++(*this);
617  return cpy;
618  }
619  CellVertexIter operator--(int) {
620  CellVertexIter cpy = *this;
621  --(*this);
622  return cpy;
623  }
624  CellVertexIter operator+(int _n) {
625  CellVertexIter cpy = *this;
626  for(int i = 0; i < _n; ++i) {
627  ++cpy;
628  }
629  return cpy;
630  }
631  CellVertexIter operator-(int _n) {
632  CellVertexIter cpy = *this;
633  for(int i = 0; i < _n; ++i) {
634  --cpy;
635  }
636  return cpy;
637  }
638  CellVertexIter& operator+=(int _n) {
639  for(int i = 0; i < _n; ++i) {
640  ++(*this);
641  }
642  return *this;
643  }
644  CellVertexIter& operator-=(int _n) {
645  for(int i = 0; i < _n; ++i) {
646  --(*this);
647  }
648  return *this;
649  }
650 
651  CellVertexIter& operator++();
652  CellVertexIter& operator--();
653 
654 private:
655  std::vector<VertexHandle> incident_vertices_;
656  size_t cur_index_;
657 };
658 
659 //===========================================================================
660 
662  CellHandle,
663  CellHandle> {
664 public:
665  typedef BaseCirculator<
666  CellHandle,
667  CellHandle> BaseIter;
668 
669  CellCellIter(const CellHandle& _cIdx, const TopologyKernel* _mesh, int _max_laps = 1);
670 
671  // Post increment/decrement operator
672  CellCellIter operator++(int) {
673  CellCellIter cpy = *this;
674  ++(*this);
675  return cpy;
676  }
677  CellCellIter operator--(int) {
678  CellCellIter cpy = *this;
679  --(*this);
680  return cpy;
681  }
682  CellCellIter operator+(int _n) {
683  CellCellIter cpy = *this;
684  for(int i = 0; i < _n; ++i) {
685  ++cpy;
686  }
687  return cpy;
688  }
689  CellCellIter operator-(int _n) {
690  CellCellIter cpy = *this;
691  for(int i = 0; i < _n; ++i) {
692  --cpy;
693  }
694  return cpy;
695  }
696  CellCellIter& operator+=(int _n) {
697  for(int i = 0; i < _n; ++i) {
698  ++(*this);
699  }
700  return *this;
701  }
702  CellCellIter& operator-=(int _n) {
703  for(int i = 0; i < _n; ++i) {
704  --(*this);
705  }
706  return *this;
707  }
708 
709  CellCellIter& operator++();
710  CellCellIter& operator--();
711 
712 private:
713  std::vector<CellHandle> adjacent_cells_;
714  size_t cur_index_;
715 };
716 
717 //===========================================================================
718 
720  HalfFaceHandle,
721  VertexHandle> {
722 public:
723  typedef BaseCirculator<
726 
727  HalfFaceVertexIter(const HalfFaceHandle& _hIdx, const TopologyKernel* _mesh, int _max_laps = 1);
728 
729  // Post increment/decrement operator
730  HalfFaceVertexIter operator++(int) {
731  HalfFaceVertexIter cpy = *this;
732  ++(*this);
733  return cpy;
734  }
735  HalfFaceVertexIter operator--(int) {
736  HalfFaceVertexIter cpy = *this;
737  --(*this);
738  return cpy;
739  }
740  HalfFaceVertexIter operator+(int _n) {
741  HalfFaceVertexIter cpy = *this;
742  for(int i = 0; i < _n; ++i) {
743  ++cpy;
744  }
745  return cpy;
746  }
747  HalfFaceVertexIter operator-(int _n) {
748  HalfFaceVertexIter cpy = *this;
749  for(int i = 0; i < _n; ++i) {
750  --cpy;
751  }
752  return cpy;
753  }
754  HalfFaceVertexIter& operator+=(int _n) {
755  for(int i = 0; i < _n; ++i) {
756  ++(*this);
757  }
758  return *this;
759  }
760  HalfFaceVertexIter& operator-=(int _n) {
761  for(int i = 0; i < _n; ++i) {
762  --(*this);
763  }
764  return *this;
765  }
766 
767  HalfFaceVertexIter& operator++();
768  HalfFaceVertexIter& operator--();
769 
770 private:
771  std::vector<VertexHandle> vertices_;
772  size_t cur_index_;
773 };
774 
775 //===========================================================================
776 
777 class BoundaryHalfFaceHalfFaceIter : public BaseCirculator<HalfFaceHandle,
778  HalfFaceHandle> {
779 private:
781  HalfFaceHandle> BaseIter;
782 public:
783  BoundaryHalfFaceHalfFaceIter(const HalfFaceHandle& _ref_h,
784  const TopologyKernel* _mesh, int _max_laps = 1);
785 
786  // Post increment/decrement operator
787  BoundaryHalfFaceHalfFaceIter operator++(int) {
788  BoundaryHalfFaceHalfFaceIter cpy = *this;
789  ++(*this);
790  return cpy;
791  }
792  BoundaryHalfFaceHalfFaceIter operator--(int) {
793  BoundaryHalfFaceHalfFaceIter cpy = *this;
794  --(*this);
795  return cpy;
796  }
797  BoundaryHalfFaceHalfFaceIter operator+(int _n) {
798  BoundaryHalfFaceHalfFaceIter cpy = *this;
799  for(int i = 0; i < _n; ++i) {
800  ++cpy;
801  }
802  return cpy;
803  }
804  BoundaryHalfFaceHalfFaceIter operator-(int _n) {
805  BoundaryHalfFaceHalfFaceIter cpy = *this;
806  for(int i = 0; i < _n; ++i) {
807  --cpy;
808  }
809  return cpy;
810  }
811  BoundaryHalfFaceHalfFaceIter& operator+=(int _n) {
812  for(int i = 0; i < _n; ++i) {
813  ++(*this);
814  }
815  return *this;
816  }
817  BoundaryHalfFaceHalfFaceIter& operator-=(int _n) {
818  for(int i = 0; i < _n; ++i) {
819  --(*this);
820  }
821  return *this;
822  }
823 
824  const EdgeHandle& common_edge() const { return common_edges_[cur_index_]; }
825 
826  BoundaryHalfFaceHalfFaceIter& operator++();
827  BoundaryHalfFaceHalfFaceIter& operator--();
828 
829 private:
830  std::vector<HalfFaceHandle> neighbor_halffaces_;
831  std::vector<EdgeHandle> common_edges_;
832  size_t cur_index_;
833 };
834 
835 //===========================================================================
836 
837 class VertexIter : public BaseIterator<VertexHandle> {
838 public:
840 
841 
842  VertexIter(const TopologyKernel* _mesh, const VertexHandle& _vh = VertexHandle(0));
843 
844  // Post increment/decrement operator
845  VertexIter operator++(int) {
846  VertexIter cpy = *this;
847  ++(*this);
848  return cpy;
849  }
850  VertexIter operator--(int) {
851  VertexIter cpy = *this;
852  --(*this);
853  return cpy;
854  }
855  VertexIter operator+(int _n) {
856  VertexIter cpy = *this;
857  for(int i = 0; i < _n; ++i) {
858  ++cpy;
859  }
860  return cpy;
861  }
862  VertexIter operator-(int _n) {
863  VertexIter cpy = *this;
864  for(int i = 0; i < _n; ++i) {
865  --cpy;
866  }
867  return cpy;
868  }
869  VertexIter& operator+=(int _n) {
870  for(int i = 0; i < _n; ++i) {
871  ++(*this);
872  }
873  return *this;
874  }
875  VertexIter& operator-=(int _n) {
876  for(int i = 0; i < _n; ++i) {
877  --(*this);
878  }
879  return *this;
880  }
881 
882  VertexIter& operator++();
883  VertexIter& operator--();
884 
885 private:
886  int cur_index_;
887 };
888 
889 //===========================================================================
890 
891 class EdgeIter : public BaseIterator<EdgeHandle> {
892 public:
894 
895 
896  EdgeIter(const TopologyKernel* _mesh, const EdgeHandle& _eh = EdgeHandle(0));
897 
898  // Post increment/decrement operator
899  EdgeIter operator++(int) {
900  EdgeIter cpy = *this;
901  ++(*this);
902  return cpy;
903  }
904  EdgeIter operator--(int) {
905  EdgeIter cpy = *this;
906  --(*this);
907  return cpy;
908  }
909  EdgeIter operator+(int _n) {
910  EdgeIter cpy = *this;
911  for(int i = 0; i < _n; ++i) {
912  ++cpy;
913  }
914  return cpy;
915  }
916  EdgeIter operator-(int _n) {
917  EdgeIter cpy = *this;
918  for(int i = 0; i < _n; ++i) {
919  --cpy;
920  }
921  return cpy;
922  }
923  EdgeIter& operator+=(int _n) {
924  for(int i = 0; i < _n; ++i) {
925  ++(*this);
926  }
927  return *this;
928  }
929  EdgeIter& operator-=(int _n) {
930  for(int i = 0; i < _n; ++i) {
931  --(*this);
932  }
933  return *this;
934  }
935 
936  EdgeIter& operator++();
937  EdgeIter& operator--();
938 
939 private:
940  int cur_index_;
941 };
942 
943 //===========================================================================
944 
945 class HalfEdgeIter : public BaseIterator<HalfEdgeHandle> {
946 public:
948 
949 
950  HalfEdgeIter(const TopologyKernel* _mesh, const HalfEdgeHandle& _heh = HalfEdgeHandle(0));
951 
952  // Post increment/decrement operator
953  HalfEdgeIter operator++(int) {
954  HalfEdgeIter cpy = *this;
955  ++(*this);
956  return cpy;
957  }
958  HalfEdgeIter operator--(int) {
959  HalfEdgeIter cpy = *this;
960  --(*this);
961  return cpy;
962  }
963  HalfEdgeIter operator+(int _n) {
964  HalfEdgeIter cpy = *this;
965  for(int i = 0; i < _n; ++i) {
966  ++cpy;
967  }
968  return cpy;
969  }
970  HalfEdgeIter operator-(int _n) {
971  HalfEdgeIter cpy = *this;
972  for(int i = 0; i < _n; ++i) {
973  --cpy;
974  }
975  return cpy;
976  }
977  HalfEdgeIter& operator+=(int _n) {
978  for(int i = 0; i < _n; ++i) {
979  ++(*this);
980  }
981  return *this;
982  }
983  HalfEdgeIter& operator-=(int _n) {
984  for(int i = 0; i < _n; ++i) {
985  --(*this);
986  }
987  return *this;
988  }
989 
990  HalfEdgeIter& operator++();
991  HalfEdgeIter& operator--();
992 
993 private:
994  int cur_index_;
995 };
996 
997 //===========================================================================
998 
999 class FaceIter : public BaseIterator<FaceHandle> {
1000 public:
1002 
1003 
1004  FaceIter(const TopologyKernel* _mesh, const FaceHandle& _fh = FaceHandle(0));
1005 
1006  // Post increment/decrement operator
1007  FaceIter operator++(int) {
1008  FaceIter cpy = *this;
1009  ++(*this);
1010  return cpy;
1011  }
1012  FaceIter operator--(int) {
1013  FaceIter cpy = *this;
1014  --(*this);
1015  return cpy;
1016  }
1017  FaceIter operator+(int _n) {
1018  FaceIter cpy = *this;
1019  for(int i = 0; i < _n; ++i) {
1020  ++cpy;
1021  }
1022  return cpy;
1023  }
1024  FaceIter operator-(int _n) {
1025  FaceIter cpy = *this;
1026  for(int i = 0; i < _n; ++i) {
1027  --cpy;
1028  }
1029  return cpy;
1030  }
1031  FaceIter& operator+=(int _n) {
1032  for(int i = 0; i < _n; ++i) {
1033  ++(*this);
1034  }
1035  return *this;
1036  }
1037  FaceIter& operator-=(int _n) {
1038  for(int i = 0; i < _n; ++i) {
1039  --(*this);
1040  }
1041  return *this;
1042  }
1043 
1044  FaceIter& operator++();
1045  FaceIter& operator--();
1046 
1047 private:
1048  int cur_index_;
1049 };
1050 
1051 //===========================================================================
1052 
1053 class HalfFaceIter : public BaseIterator<HalfFaceHandle> {
1054 public:
1056 
1057 
1058  HalfFaceIter(const TopologyKernel* _mesh, const HalfFaceHandle& _hfh = HalfFaceHandle(0));
1059 
1060  // Post increment/decrement operator
1061  HalfFaceIter operator++(int) {
1062  HalfFaceIter cpy = *this;
1063  ++(*this);
1064  return cpy;
1065  }
1066  HalfFaceIter operator--(int) {
1067  HalfFaceIter cpy = *this;
1068  --(*this);
1069  return cpy;
1070  }
1071  HalfFaceIter operator+(int _n) {
1072  HalfFaceIter cpy = *this;
1073  for(int i = 0; i < _n; ++i) {
1074  ++cpy;
1075  }
1076  return cpy;
1077  }
1078  HalfFaceIter operator-(int _n) {
1079  HalfFaceIter cpy = *this;
1080  for(int i = 0; i < _n; ++i) {
1081  --cpy;
1082  }
1083  return cpy;
1084  }
1085  HalfFaceIter& operator+=(int _n) {
1086  for(int i = 0; i < _n; ++i) {
1087  ++(*this);
1088  }
1089  return *this;
1090  }
1091  HalfFaceIter& operator-=(int _n) {
1092  for(int i = 0; i < _n; ++i) {
1093  --(*this);
1094  }
1095  return *this;
1096  }
1097 
1098  HalfFaceIter& operator++();
1099  HalfFaceIter& operator--();
1100 
1101 private:
1102  int cur_index_;
1103 };
1104 
1105 //===========================================================================
1106 
1107 class CellIter : public BaseIterator<CellHandle> {
1108 public:
1110 
1111 
1112  CellIter(const TopologyKernel* _mesh, const CellHandle& _ch = CellHandle(0));
1113 
1114  // Post increment/decrement operator
1115  CellIter operator++(int) {
1116  CellIter cpy = *this;
1117  ++(*this);
1118  return cpy;
1119  }
1120  CellIter operator--(int) {
1121  CellIter cpy = *this;
1122  --(*this);
1123  return cpy;
1124  }
1125  CellIter operator+(int _n) {
1126  CellIter cpy = *this;
1127  for(int i = 0; i < _n; ++i) {
1128  ++cpy;
1129  }
1130  return cpy;
1131  }
1132  CellIter operator-(int _n) {
1133  CellIter cpy = *this;
1134  for(int i = 0; i < _n; ++i) {
1135  --cpy;
1136  }
1137  return cpy;
1138  }
1139  CellIter& operator+=(int _n) {
1140  for(int i = 0; i < _n; ++i) {
1141  ++(*this);
1142  }
1143  return *this;
1144  }
1145  CellIter& operator-=(int _n) {
1146  for(int i = 0; i < _n; ++i) {
1147  --(*this);
1148  }
1149  return *this;
1150  }
1151 
1152  CellIter& operator++();
1153  CellIter& operator--();
1154 
1155 private:
1156  int cur_index_;
1157 };
1158 
1159 //===========================================================================
1160 
1161 namespace Internal {
1162 
1163 //===========================================================================
1164 
1165 class VertexIHalfEdgeIterImpl : public BaseCirculator<VertexHandle, HalfEdgeHandle> {
1166 public:
1167 
1170 
1171  VertexIHalfEdgeIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1172 
1173  VertexIHalfEdgeIterImpl& operator++();
1174  VertexIHalfEdgeIterImpl& operator--();
1175 
1176 private:
1177  VertexOHalfEdgeIter voh_iter_;
1178 };
1179 
1180 //===========================================================================
1181 
1182 class VertexEdgeIterImpl : public BaseCirculator<VertexHandle, EdgeHandle> {
1183 public:
1184 
1187 
1188  VertexEdgeIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1189 
1190  VertexEdgeIterImpl& operator++();
1191  VertexEdgeIterImpl& operator--();
1192 
1193 private:
1194  VertexOHalfEdgeIter voh_iter_;
1195 };
1196 
1197 //===========================================================================
1198 
1199 class VertexHalfFaceIterImpl : public BaseCirculator<VertexHandle, HalfFaceHandle> {
1200 public:
1201 
1204 
1205  VertexHalfFaceIterImpl(const VertexHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1206 
1207  VertexHalfFaceIterImpl& operator++();
1208  VertexHalfFaceIterImpl& operator--();
1209 
1210 private:
1211  std::vector<HalfFaceHandle> halffaces_;
1212  size_t cur_index_;
1213 };
1214 
1215 //===========================================================================
1216 
1217 class HalfEdgeFaceIterImpl : public BaseCirculator<HalfEdgeHandle, FaceHandle> {
1218 public:
1219 
1222 
1223  HalfEdgeFaceIterImpl(const HalfEdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1224 
1225  HalfEdgeFaceIterImpl& operator++();
1226  HalfEdgeFaceIterImpl& operator--();
1227 
1228 private:
1229  std::vector<FaceHandle> faces_;
1230  size_t cur_index_;
1231 };
1232 
1233 //===========================================================================
1234 
1235 class EdgeHalfFaceIterImpl : public BaseCirculator<EdgeHandle, HalfFaceHandle> {
1236 public:
1237 
1240 
1241  EdgeHalfFaceIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1242 
1243  EdgeHalfFaceIterImpl& operator++();
1244  EdgeHalfFaceIterImpl& operator--();
1245 
1246 private:
1247  std::vector<HalfFaceHandle> halffaces_;
1248  size_t cur_index_;
1249 };
1250 
1251 //===========================================================================
1252 
1254 public:
1255 
1257  EdgeFaceIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1258 
1259 };
1260 
1261 //===========================================================================
1262 
1264 public:
1265 
1267  EdgeCellIterImpl(const EdgeHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1268 
1269 };
1270 
1271 //===========================================================================
1272 
1273 class HalfFaceHalfEdgeIterImpl : public BaseCirculator<HalfFaceHandle, HalfEdgeHandle> {
1274 public:
1275 
1278 
1279  HalfFaceHalfEdgeIterImpl(const HalfFaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1280 
1281  HalfFaceHalfEdgeIterImpl& operator++();
1282  HalfFaceHalfEdgeIterImpl& operator--();
1283 
1284 private:
1285  size_t cur_index_;
1286 };
1287 
1288 //===========================================================================
1289 
1290 class HalfFaceEdgeIterImpl : public BaseCirculator<HalfFaceHandle, EdgeHandle> {
1291 public:
1292 
1295 
1296  HalfFaceEdgeIterImpl(const HalfFaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1297 
1298  HalfFaceEdgeIterImpl& operator++();
1299  HalfFaceEdgeIterImpl& operator--();
1300 
1301 private:
1302  size_t cur_index_;
1303 };
1304 
1305 //===========================================================================
1306 
1308 public:
1309 
1311  FaceVertexIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1312 
1313 };
1314 
1315 //===========================================================================
1316 
1318 public:
1319 
1321  FaceHalfEdgeIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1322 
1323 };
1324 
1325 //===========================================================================
1326 
1328 public:
1329 
1331  FaceEdgeIterImpl(const FaceHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1332 
1333 };
1334 
1335 //===========================================================================
1336 
1337 class CellHalfEdgeIterImpl : public BaseCirculator<CellHandle, HalfEdgeHandle> {
1338 public:
1339 
1342 
1343  CellHalfEdgeIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1344 
1345  CellHalfEdgeIterImpl& operator++();
1346  CellHalfEdgeIterImpl& operator--();
1347 
1348 private:
1349  std::vector<HalfEdgeHandle> halfedges_;
1350  size_t cur_index_;
1351 };
1352 
1353 //===========================================================================
1354 
1355 class CellEdgeIterImpl : public BaseCirculator<CellHandle, EdgeHandle> {
1356 public:
1357 
1360 
1361  CellEdgeIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1362 
1363  CellEdgeIterImpl& operator++();
1364  CellEdgeIterImpl& operator--();
1365 
1366 private:
1367  std::vector<EdgeHandle> edges_;
1368  size_t cur_index_;
1369 };
1370 
1371 //===========================================================================
1372 
1373 class CellHalfFaceIterImpl : public BaseCirculator<CellHandle, HalfFaceHandle> {
1374 public:
1375 
1378 
1379  CellHalfFaceIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1380 
1381  CellHalfFaceIterImpl& operator++();
1382  CellHalfFaceIterImpl& operator--();
1383 
1384 private:
1385  std::vector<HalfFaceHandle>::const_iterator hf_iter_;
1386 };
1387 
1388 //===========================================================================
1389 
1390 class CellFaceIterImpl : public BaseCirculator<CellHandle, FaceHandle> {
1391 public:
1392 
1395 
1396  CellFaceIterImpl(const CellHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1);
1397 
1398  CellFaceIterImpl& operator++();
1399  CellFaceIterImpl& operator--();
1400 
1401 private:
1402  std::vector<HalfFaceHandle>::const_iterator hf_iter_;
1403 };
1404 
1405 //===========================================================================
1406 
1407 } // Namespace Internal
1408 
1409 //===========================================================================
1410 
1411 template <class CirculatorImpl>
1412 class GenericCirculator : public CirculatorImpl {
1413 public:
1414 
1415  GenericCirculator(const typename CirculatorImpl::CenterEntityHandle& _ref_h, const TopologyKernel* _mesh, int _max_laps = 1) :
1416  CirculatorImpl(_ref_h, _mesh, _max_laps) {}
1417 
1418  GenericCirculator& operator++() {
1419  CirculatorImpl::operator++();
1420  return *this;
1421  }
1422 
1423  GenericCirculator& operator--() {
1424  CirculatorImpl::operator--();
1425  return *this;
1426  }
1427 
1428  // Post increment/decrement operator
1429  GenericCirculator operator++(int) {
1430  GenericCirculator cpy = *this;
1431  ++(*this);
1432  return cpy;
1433  }
1434  GenericCirculator operator--(int) {
1435  GenericCirculator cpy = *this;
1436  --(*this);
1437  return cpy;
1438  }
1439  GenericCirculator operator+(int _n) {
1440  GenericCirculator cpy = *this;
1441  for(int i = 0; i < _n; ++i) {
1442  ++cpy;
1443  }
1444  return cpy;
1445  }
1446  GenericCirculator operator-(int _n) {
1447  GenericCirculator cpy = *this;
1448  for(int i = 0; i < _n; ++i) {
1449  --cpy;
1450  }
1451  return cpy;
1452  }
1453  GenericCirculator& operator+=(int _n) {
1454  for(int i = 0; i < _n; ++i) {
1455  ++(*this);
1456  }
1457  return *this;
1458  }
1459  GenericCirculator& operator-=(int _n) {
1460  for(int i = 0; i < _n; ++i) {
1461  --(*this);
1462  }
1463  return *this;
1464  }
1465 
1466 };
1467 
1468 //===========================================================================
1469 
1473 
1475 
1479 
1482 
1486 
1491 
1492 //===========================================================================
1493 
1494 template <class Iter, class Handle>
1495 class BoundaryItemIter : public BaseIterator<Handle> {
1496 public:
1498 
1499 
1500  explicit BoundaryItemIter(const TopologyKernel* _mesh) :
1501  BaseIter(_mesh),
1502  it_(_mesh, Handle(0)),
1503  it_begin_(_mesh, Handle(0)),
1504  it_end_(_mesh, Handle((int)n_items())) {
1505 
1506  if(!has_incidences()) {
1507  #ifndef NDEBUG
1508  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
1509  #endif
1510  BaseIter::valid(false);
1511  return;
1512  }
1513 
1514  while(it_ != it_end_ && !BaseIter::mesh()->is_boundary(*it_)){
1515  ++it_;
1516  }
1517  BaseIter::valid(it_ != it_end_);
1518  if(BaseIter::valid()) {
1519  BaseIter::cur_handle(*it_);
1520  }
1521  }
1522 
1523  // Post increment/decrement operator
1524  BoundaryItemIter operator++(int) {
1525  BoundaryItemIter cpy = *this;
1526  ++(*this);
1527  return cpy;
1528  }
1529  BoundaryItemIter operator--(int) {
1530  BoundaryItemIter cpy = *this;
1531  --(*this);
1532  return cpy;
1533  }
1534  BoundaryItemIter operator+(int _n) {
1535  BoundaryItemIter cpy = *this;
1536  for(int i = 0; i < _n; ++i) {
1537  ++cpy;
1538  }
1539  return cpy;
1540  }
1541  BoundaryItemIter operator-(int _n) {
1542  BoundaryItemIter cpy = *this;
1543  for(int i = 0; i < _n; ++i) {
1544  --cpy;
1545  }
1546  return cpy;
1547  }
1548  BoundaryItemIter& operator+=(int _n) {
1549  for(int i = 0; i < _n; ++i) {
1550  ++(*this);
1551  }
1552  return *this;
1553  }
1554  BoundaryItemIter& operator-=(int _n) {
1555  for(int i = 0; i < _n; ++i) {
1556  --(*this);
1557  }
1558  return *this;
1559  }
1560 
1561  BoundaryItemIter& operator--() {
1562  --it_;
1563  while(it_ >= it_begin_ && !BaseIter::mesh()->is_boundary(*it_)){
1564  --it_;
1565  }
1566  if(it_ >= it_begin_) {
1567  BaseIter::cur_handle(*it_);
1568  } else {
1569  BaseIter::valid(false);
1570  }
1571  return *this;
1572  }
1573 
1574  BoundaryItemIter& operator++() {
1575  ++it_;
1576  while(it_ != it_end_ && !BaseIter::mesh()->is_boundary(*it_)){
1577  ++it_;
1578  }
1579  if(it_ != it_end_) {
1580  BaseIter::cur_handle(*it_);
1581  } else {
1582  BaseIter::valid(false);
1583  }
1584  return *this;
1585  }
1586 
1587 private:
1588  size_t n_items() const;
1589  bool has_incidences() const;
1590 
1591 private:
1592  Iter it_;
1593  const Iter it_begin_;
1594  const Iter it_end_;
1595 };
1596 
1597 //===========================================================================
1598 
1605 
1606 //===========================================================================
1607 
1608 } // Namespace OpenVolumeMesh
1609 
1610 #endif /* ITERATORS_HH_ */