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