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 #ifndef NDEBUG
45 #include <iostream>
46 #endif
47 #include <set>
48 
49 #include "Iterators.hh"
50 #include "TopologyKernel.hh"
51 
52 namespace OpenVolumeMesh {
53 
54 //================================================================================================
55 // VertexOHalfEdgeIter
56 //================================================================================================
57 
58 
59 VertexOHalfEdgeIter::VertexOHalfEdgeIter(const VertexHandle& _ref_h,
60  const TopologyKernel* _mesh, int _max_laps) :
61 BaseIter(_mesh, _ref_h, _max_laps),
62 cur_index_(0) {
63 
64  if(!_mesh->has_vertex_bottom_up_incidences()) {
65 #ifndef NDEBUG
66  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
67 #endif
68  BaseIter::valid(false);
69  return;
70  }
71 
72  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
73  BaseIter::valid(false);
74  }
75 
76  if(BaseIter::valid()) {
77  if((unsigned int)cur_index_ >= BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()].size()) {
78  BaseIter::valid(false);
79  }
80  }
81 
82  if(BaseIter::valid()) {
83  BaseIter::cur_handle((
84  BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()])[cur_index_]);
85  }
86 }
87 
88 
89 VertexOHalfEdgeIter& VertexOHalfEdgeIter::operator--() {
90 
91  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
92 
93  if (cur_index_ == 0) {
94  cur_index_ = n_outgoing_halfedges-1;
95  --lap_;
96  if (lap_ < 0)
97  BaseIter::valid(false);
98  }
99  else {
100  --cur_index_;
101  }
102 
103  BaseIter::cur_handle((BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()])[cur_index_]);
104 
105  return *this;
106 }
107 
108 
109 VertexOHalfEdgeIter& VertexOHalfEdgeIter::operator++() {
110 
111  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
112 
113  ++cur_index_;
114 
115  if (cur_index_ == n_outgoing_halfedges) {
116  cur_index_ = 0;
117  ++lap_;
118  if (lap_ >= max_laps_)
119  BaseIter::valid(false);
120  }
121 
122  BaseIter::cur_handle((BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()])[cur_index_]);
123 
124  return *this;
125 }
126 
127 
128 //================================================================================================
129 // VertexVertexIter
130 //================================================================================================
131 
132 
133 VertexVertexIter::VertexVertexIter(const VertexHandle& _ref_h,
134  const TopologyKernel* _mesh, int _max_laps) :
135 BaseIter(_mesh, _ref_h, _max_laps),
136 cur_index_(0) {
137 
138  if(!_mesh->has_vertex_bottom_up_incidences()) {
139 #ifndef NDEBUG
140  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
141 #endif
142  BaseIter::valid(false);
143  return;
144  }
145 
146  if((size_t)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
147  BaseIter::valid(false);
148  }
149 
150  if(BaseIter::valid()) {
151  if((size_t)cur_index_ >= BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()].size()) {
152  BaseIter::valid(false);
153  }
154  }
155 
156  if(BaseIter::valid()) {
157  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()][cur_index_];
158  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
159  }
160 }
161 
162 
163 VertexVertexIter& VertexVertexIter::operator--() {
164 
165  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
166 
167  if (cur_index_ == 0) {
168  cur_index_ = n_outgoing_halfedges-1;
169  --lap_;
170  if (lap_ < 0)
171  BaseIter::valid(false);
172  }
173  else {
174  --cur_index_;
175  }
176 
177  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()][cur_index_];
178  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
179 
180  return *this;
181 }
182 
183 
184 VertexVertexIter& VertexVertexIter::operator++() {
185 
186  size_t n_outgoing_halfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()].size();
187 
188  ++cur_index_;
189 
190  if (cur_index_ == n_outgoing_halfedges) {
191  cur_index_ = 0;
192  ++lap_;
193  if (lap_ >= max_laps_)
194  BaseIter::valid(false);
195  }
196 
197 
198  HalfEdgeHandle heh = BaseIter::mesh()->outgoing_hes_per_vertex_[BaseIter::ref_handle().idx()][cur_index_];
199  BaseIter::cur_handle(BaseIter::mesh()->halfedge(heh).to_vertex());
200 
201  return *this;
202 }
203 
204 
208 
209 
210 HalfEdgeHalfFaceIter::HalfEdgeHalfFaceIter(const HalfEdgeHandle& _ref_h,
211  const TopologyKernel* _mesh, int _max_laps) :
212 BaseIter(_mesh, _ref_h, _max_laps),
213 cur_index_(0) {
214 
215  if(!_mesh->has_edge_bottom_up_incidences()) {
216 #ifndef NDEBUG
217  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
218 #endif
219  BaseIter::valid(false);
220  return;
221  }
222 
223  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
224  BaseIter::valid(false);
225  }
226 
227  if(BaseIter::valid()) {
228  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
229  BaseIter::valid(false);
230  }
231  }
232 
233  if(BaseIter::valid()) {
234  BaseIter::cur_handle((
235  BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]);
236  }
237 }
238 
239 
240 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator--() {
241 
242  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
243 
244  if (cur_index_ == 0) {
245  cur_index_ = n_outgoing_halffaces-1;
246  --lap_;
247  if (lap_ < 0)
248  BaseIter::valid(false);
249  }
250  else {
251  --cur_index_;
252  }
253 
254  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
255 
256  return *this;
257 }
258 
259 
260 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator++() {
261 
262 
263  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
264 
265  ++cur_index_;
266 
267  if (cur_index_ == n_outgoing_halffaces) {
268  cur_index_ = 0;
269  ++lap_;
270  if (lap_ >= max_laps_)
271  BaseIter::valid(false);
272  }
273 
274  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
275 
276  return *this;
277 }
278 
282 
283 VertexFaceIter::VertexFaceIter(const VertexHandle& _ref_h,
284  const TopologyKernel* _mesh, int _max_laps) :
285 BaseIter(_mesh, _ref_h, _max_laps) {
286 
287  if(!_mesh->has_full_bottom_up_incidences()) {
288 #ifndef NDEBUG
289  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
290 #endif
291  BaseIter::valid(false);
292  return;
293  }
294 
295  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
296  BaseIter::valid(false);
297  return;
298  }
299 
300  // Build up face list
301  const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
302  for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
303 
304  if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
305  const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
306 
307  for (std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
308  hf_it != incidentHalfFaces.end(); ++hf_it) {
309  faces_.push_back(BaseIter::mesh()->face_handle(*hf_it));
310  }
311  }
312  // Remove all duplicate entries
313  std::sort(faces_.begin(), faces_.end());
314  faces_.resize(std::unique(faces_.begin(), faces_.end()) - faces_.begin());
315 
316  // Remove invalid handles
317  if ((faces_.size() > 0) && !faces_.front().is_valid())
318  faces_.erase(faces_.begin());
319 
320  cur_index_ = 0;
321  BaseIter::valid(faces_.size() > 0);
322  if(BaseIter::valid()) {
323  BaseIter::cur_handle(faces_[cur_index_]);
324  }
325 }
326 
327 VertexFaceIter& VertexFaceIter::operator--() {
328 
329  if(cur_index_ == 0) {
330  cur_index_ = faces_.size()-1;
331  --lap_;
332  if (lap_ < 0) {
333  BaseIter::valid(false);
334  }
335  } else {
336  --cur_index_;
337  }
338 
339  BaseIter::cur_handle(faces_[cur_index_]);
340  return *this;
341 }
342 
343 
344 VertexFaceIter& VertexFaceIter::operator++() {
345 
346  ++cur_index_;
347  if(cur_index_ == faces_.size()) {
348  cur_index_ = 0;
349  ++lap_;
350  if (lap_ >= max_laps_) {
351  BaseIter::valid(false);
352  }
353  }
354  BaseIter::cur_handle(faces_[cur_index_]);
355  return *this;
356 }
357 
361 
362 VertexCellIter::VertexCellIter(const VertexHandle& _ref_h,
363  const TopologyKernel* _mesh, int _max_laps) :
364 BaseIter(_mesh, _ref_h, _max_laps) {
365 
366  if(!_mesh->has_full_bottom_up_incidences()) {
367 #ifndef NDEBUG
368  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
369 #endif
370  BaseIter::valid(false);
371  return;
372  }
373 
374  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
375  BaseIter::valid(false);
376  return;
377  }
378 
379  // Build up cell list
380  const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
381  for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
382 
383  if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
384  const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
385 
386  for(std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
387  hf_it != incidentHalfFaces.end(); ++hf_it) {
388  if((unsigned int)hf_it->idx() < BaseIter::mesh()->incident_cell_per_hf_.size()) {
389  CellHandle c_idx = BaseIter::mesh()->incident_cell_per_hf_[hf_it->idx()];
390  if(c_idx != TopologyKernel::InvalidCellHandle)
391  cells_.push_back(c_idx);
392  }
393  }
394  }
395  // Remove all duplicate entries
396  std::sort(cells_.begin(), cells_.end());
397  cells_.resize(std::unique(cells_.begin(), cells_.end()) - cells_.begin());
398 
399  // Remove invalid handles
400  if ((cells_.size() > 0) && !cells_.front().is_valid())
401  cells_.erase(cells_.begin());
402 
403  cur_index_ = 0;
404  BaseIter::valid(cells_.size()>0);
405  if(BaseIter::valid()) {
406  BaseIter::cur_handle(cells_[cur_index_]);
407  }
408 }
409 
410 VertexCellIter& VertexCellIter::operator--() {
411 
412  if(cur_index_ == 0) {
413  cur_index_ = cells_.size()-1;
414  --lap_;
415  if (lap_ < 0) {
416  BaseIter::valid(false);
417  }
418  } else {
419  --cur_index_;
420  }
421 
422  BaseIter::cur_handle(cells_[cur_index_]);
423  return *this;
424 }
425 
426 
427 VertexCellIter& VertexCellIter::operator++() {
428 
429  ++cur_index_;
430  if(cur_index_ == cells_.size()) {
431  cur_index_ = 0;
432  ++lap_;
433  if (lap_ >= max_laps_) {
434  BaseIter::valid(false);
435  }
436  }
437  BaseIter::cur_handle(cells_[cur_index_]);
438  return *this;
439 }
440 
444 
445 
446 HalfEdgeCellIter::HalfEdgeCellIter(const HalfEdgeHandle& _ref_h,
447  const TopologyKernel* _mesh, int _max_laps) :
448 BaseIter(_mesh, _ref_h, _max_laps),
449 cur_index_(0) {
450 
451  if(!_mesh->has_edge_bottom_up_incidences() || !_mesh->has_face_bottom_up_incidences()) {
452 #ifndef NDEBUG
453  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
454 #endif
455  BaseIter::valid(false);
456  return;
457  }
458 
459  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
460 
461  BaseIter::valid(false);
462  return;
463  }
464  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
465 
466  BaseIter::valid(false);
467  return;
468  }
469  if((unsigned int)((BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]).idx() >=
470  BaseIter::mesh()->incident_cell_per_hf_.size()) {
471 
472  BaseIter::valid(false);
473  return;
474  }
475 
476  // collect cell handles
477  const std::vector<HalfFaceHandle>& incidentHalffaces = BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()];
478  std::set<CellHandle> cells;
479  for (unsigned int i = 0; i < incidentHalffaces.size(); ++i)
480  {
481  CellHandle ch = getCellHandle(i);
482  if (ch.is_valid()) {
483  if(cells.count(ch) == 0) {
484  cells_.push_back(ch);
485  }
486  cells.insert(ch);
487  }
488  }
489 
490  BaseIter::valid(cells_.size() > 0);
491 
492  if(BaseIter::valid()) {
493  BaseIter::cur_handle(cells_[cur_index_]);
494  }
495 }
496 
497 
498 HalfEdgeCellIter& HalfEdgeCellIter::operator--() {
499 
500  if (cur_index_ == 0) {
501  cur_index_ = cells_.size()-1;
502  --lap_;
503  if (lap_ < 0)
504  BaseIter::valid(false);
505  }
506  else {
507  --cur_index_;
508  }
509 
510  BaseIter::cur_handle(cells_[cur_index_]);
511  return *this;
512 }
513 
514 
515 HalfEdgeCellIter& HalfEdgeCellIter::operator++() {
516 
517  ++cur_index_;
518 
519  if (cur_index_ == cells_.size()) {
520  cur_index_ = 0;
521  ++lap_;
522  if (lap_ >= max_laps_)
523  BaseIter::valid(false);
524  }
525 
526  BaseIter::cur_handle(cells_[cur_index_]);
527  return *this;
528 }
529 
530 CellHandle HalfEdgeCellIter::getCellHandle(int _cur_index) const
531 {
532  const std::vector<HalfFaceHandle>& halffacehandles = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()];
533  HalfFaceHandle currentHalfface = halffacehandles[_cur_index];
534  if(!currentHalfface.is_valid()) return CellHandle(-1);
535  CellHandle cellhandle = BaseIter::mesh()->incident_cell_per_hf_[currentHalfface.idx()];
536  return cellhandle;
537 }
538 
539 
543 
544 
545 CellVertexIter::CellVertexIter(const CellHandle& _ref_h,
546  const TopologyKernel* _mesh, int _max_laps) :
547 BaseIter(_mesh, _ref_h, _max_laps) {
548 
549  OpenVolumeMeshCell c = BaseIter::mesh()->cell(_ref_h);
550  std::vector<HalfFaceHandle>::const_iterator hf_iter = c.halffaces().begin();
551  for(; hf_iter != c.halffaces().end(); ++hf_iter) {
552  const OpenVolumeMeshFace& halfface = BaseIter::mesh()->halfface(*hf_iter);
553  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
554  for(std::vector<HalfEdgeHandle>::const_iterator he_iter = hes.begin(); he_iter != hes.end(); ++he_iter) {
555  incident_vertices_.push_back(BaseIter::mesh()->halfedge(*he_iter).to_vertex());
556  }
557  }
558 
559  // Remove all duplicate entries
560  std::sort(incident_vertices_.begin(), incident_vertices_.end());
561  incident_vertices_.resize(std::unique(incident_vertices_.begin(), incident_vertices_.end()) - incident_vertices_.begin());
562 
563  cur_index_ = 0;
564  BaseIter::valid(incident_vertices_.size() > 0);
565 
566  if(BaseIter::valid()) {
567  BaseIter::cur_handle(incident_vertices_[cur_index_]);
568  }
569 }
570 
571 
572 CellVertexIter& CellVertexIter::operator--() {
573 
574  if (cur_index_ == 0) {
575  cur_index_ = incident_vertices_.size()-1;
576  --lap_;
577  if (lap_ < 0)
578  BaseIter::valid(false);
579  }
580  else {
581  --cur_index_;
582  }
583 
584  BaseIter::cur_handle(incident_vertices_[cur_index_]);
585  return *this;
586 }
587 
588 
589 CellVertexIter& CellVertexIter::operator++() {
590 
591  ++cur_index_;
592  if (cur_index_ == incident_vertices_.size()){
593  cur_index_ = 0;
594  ++lap_;
595  if (lap_ >= max_laps_)
596  BaseIter::valid(false);
597  }
598 
599  BaseIter::cur_handle(incident_vertices_[cur_index_]);
600  return *this;
601 }
602 
606 
607 
608 CellCellIter::CellCellIter(const CellHandle& _ref_h,
609  const TopologyKernel* _mesh, int _max_laps) :
610 BaseIter(_mesh, _ref_h, _max_laps) {
611 
612  if(!_mesh->has_face_bottom_up_incidences()) {
613 #ifndef NDEBUG
614  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
615 #endif
616  BaseIter::valid(false);
617  return;
618  }
619 
620  std::vector<HalfFaceHandle>::const_iterator hf_iter = BaseIter::mesh()->cell(_ref_h).halffaces().begin();
621  std::vector<HalfFaceHandle>::const_iterator hf_end = BaseIter::mesh()->cell(_ref_h).halffaces().end();
622  for(; hf_iter != hf_end; ++hf_iter) {
623 
624  HalfFaceHandle opp_hf = BaseIter::mesh()->opposite_halfface_handle(*hf_iter);
625  CellHandle ch = BaseIter::mesh()->incident_cell_per_hf_[opp_hf.idx()];
626  if(ch != TopologyKernel::InvalidCellHandle) {
627  adjacent_cells_.push_back(ch);
628  }
629  }
630 
631  // Remove all duplicate entries
632  std::sort(adjacent_cells_.begin(), adjacent_cells_.end());
633  adjacent_cells_.resize(std::unique(adjacent_cells_.begin(), adjacent_cells_.end()) - adjacent_cells_.begin());
634 
635  cur_index_ = 0;
636  BaseIter::valid(adjacent_cells_.size()>0);
637  if(BaseIter::valid()) {
638  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
639  }
640 }
641 
642 
643 CellCellIter& CellCellIter::operator--() {
644 
645  if (cur_index_ == 0) {
646  cur_index_ = adjacent_cells_.size() - 1;
647  --lap_;
648  if (lap_ < 0)
649  BaseIter::valid(false);
650  }
651  else {
652  --cur_index_;
653  }
654 
655  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
656  return *this;
657 }
658 
659 
660 CellCellIter& CellCellIter::operator++() {
661 
662  ++cur_index_;
663  if (cur_index_ == adjacent_cells_.size())
664  {
665  cur_index_ = 0;
666  ++lap_;
667  if (lap_ >= max_laps_)
668  BaseIter::valid(false);
669  }
670  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
671  return *this;
672 }
673 
677 
678 
679 HalfFaceVertexIter::HalfFaceVertexIter(const HalfFaceHandle& _ref_h,
680  const TopologyKernel* _mesh, int _max_laps) :
681 BaseIter(_mesh, _ref_h, _max_laps) {
682 
683  if(!_ref_h.is_valid()) return;
684 
685  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
686  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
687  for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
688  he_it != hes.end(); ++he_it) {
689  vertices_.push_back(_mesh->halfedge(*he_it).from_vertex());
690  }
691 
692  cur_index_ = 0;
693 
694  BaseIter::valid(vertices_.size() > 0);
695  if(BaseIter::valid()) {
696  BaseIter::cur_handle(vertices_[cur_index_]);
697  }
698 }
699 
700 
701 HalfFaceVertexIter& HalfFaceVertexIter::operator--() {
702 
703  if (cur_index_ == 0) {
704  cur_index_ = vertices_.size() - 1;
705  --lap_;
706  if (lap_ < 0)
707  BaseIter::valid(false);
708  }
709  else {
710  --cur_index_;
711  }
712 
713  BaseIter::cur_handle(vertices_[cur_index_]);
714  return *this;
715 }
716 
717 
718 HalfFaceVertexIter& HalfFaceVertexIter::operator++() {
719 
720  ++cur_index_;
721  if (cur_index_ == vertices_.size())
722  {
723  cur_index_ = 0;
724  ++lap_;
725  if (lap_ >= max_laps_)
726  BaseIter::valid(false);
727  }
728  BaseIter::cur_handle(vertices_[cur_index_]);
729  return *this;
730 }
731 
732 //================================================================================================
733 // BoundaryHalfFaceHalfFaceIter
734 //================================================================================================
735 
736 BoundaryHalfFaceHalfFaceIter::BoundaryHalfFaceHalfFaceIter(const HalfFaceHandle& _ref_h,
737  const TopologyKernel* _mesh, int _max_laps) :
738 BaseIter(_mesh, _ref_h, _max_laps) {
739 
740  if(!_mesh->has_face_bottom_up_incidences()) {
741 #ifndef NDEBUG
742  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
743 #endif
744  BaseIter::valid(false);
745  return;
746  }
747 
748  // Go over all incident halfedges
749 // const std::vector<HalfEdgeHandle> halfedges = _mesh->halfface(_ref_h).halfedges();
750  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
751  const std::vector<HalfEdgeHandle>& halfedges = halfface.halfedges();
752  for(std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();
753  he_it != halfedges.end(); ++he_it) {
754 
755  // Get outside halffaces
756  OpenVolumeMesh::HalfEdgeHalfFaceIter hehf_it = _mesh->hehf_iter(_mesh->opposite_halfedge_handle(*he_it));
757  for(; hehf_it.valid(); ++hehf_it) {
758 
759  if(_mesh->is_boundary(*hehf_it)) {
760  neighbor_halffaces_.push_back(*hehf_it);
761  common_edges_.push_back(_mesh->edge_handle(*he_it));
762  }
763  }
764  }
765 
766  cur_index_ = 0;
767  BaseIter::valid(neighbor_halffaces_.size() > 0);
768  if(BaseIter::valid()) {
769  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
770  }
771 }
772 
773 
774 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator--() {
775 
776  if (cur_index_ == 0)
777  {
778  cur_index_ = neighbor_halffaces_.size() - 1;
779  --lap_;
780  if (lap_ < 0)
781  BaseIter::valid(false);
782  }
783  else{
784  --cur_index_;
785  }
786 
787  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
788  return *this;
789 }
790 
791 
792 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator++() {
793 
794  ++cur_index_;
795  if (cur_index_ == neighbor_halffaces_.size())
796  {
797  cur_index_ = 0;
798  ++lap_;
799  if (lap_ >= max_laps_)
800  BaseIter::valid(false);
801  }
802 
803  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
804  return *this;
805 }
806 
810 
811 
812 BoundaryFaceIter::BoundaryFaceIter(const TopologyKernel* _mesh) :
813 BaseIter(_mesh),
814 bf_it_(_mesh->faces_begin()) {
815 
816  if(!_mesh->has_face_bottom_up_incidences()) {
817 #ifndef NDEBUG
818  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
819 #endif
820  BaseIter::valid(false);
821  return;
822  }
823 
824  while(bf_it_ != BaseIter::mesh()->faces_end() &&
825  !BaseIter::mesh()->is_boundary(*bf_it_) &&
826  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
827  ++bf_it_;
828  }
829  BaseIter::valid(bf_it_ != BaseIter::mesh()->faces_end());
830  if(BaseIter::valid()) {
831  BaseIter::cur_handle(*bf_it_);
832  }
833 }
834 
835 
836 BoundaryFaceIter& BoundaryFaceIter::operator--() {
837 
838  --bf_it_;
839  while(bf_it_ >= BaseIter::mesh()->faces_begin() &&
840  !BaseIter::mesh()->is_boundary(*bf_it_) &&
841  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
842  --bf_it_;
843  }
844  if(bf_it_ >= BaseIter::mesh()->faces_begin()) {
845  BaseIter::cur_handle(*bf_it_);
846  } else {
847  BaseIter::valid(false);
848  }
849  return *this;
850 }
851 
852 
853 BoundaryFaceIter& BoundaryFaceIter::operator++() {
854 
855  ++bf_it_;
856  while(bf_it_ != BaseIter::mesh()->faces_end() &&
857  !BaseIter::mesh()->is_boundary(*bf_it_) &&
858  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
859  ++bf_it_;
860  }
861  if(bf_it_ != BaseIter::mesh()->faces_end()) {
862  BaseIter::cur_handle(*bf_it_);
863  } else {
864  BaseIter::valid(false);
865  }
866  return *this;
867 }
868 
872 
873 
874 VertexIter::VertexIter(const TopologyKernel* _mesh, const VertexHandle& _vh) :
875 BaseIter(_mesh, _vh),
876 cur_index_(_vh.idx()) {
877 
878  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
879  ++cur_index_;
880  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
881  BaseIter::valid(false);
882  }
883  BaseIter::cur_handle(VertexHandle(cur_index_));
884 }
885 
886 
887 VertexIter& VertexIter::operator--() {
888 
889  --cur_index_;
890  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
891  --cur_index_;
892  if(cur_index_ < 0) {
893  BaseIter::valid(false);
894  }
895  BaseIter::cur_handle(VertexHandle(cur_index_));
896  return *this;
897 }
898 
899 
900 VertexIter& VertexIter::operator++() {
901 
902  ++cur_index_;
903  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
904  ++cur_index_;
905  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
906  BaseIter::valid(false);
907  }
908  BaseIter::cur_handle(VertexHandle(cur_index_));
909  return *this;
910 }
911 
915 
916 
917 EdgeIter::EdgeIter(const TopologyKernel* _mesh, const EdgeHandle& _eh) :
918 BaseIter(_mesh, _eh),
919 cur_index_(_eh.idx()) {
920 
921  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
922  ++cur_index_;
923  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
924  BaseIter::valid(false);
925  }
926  BaseIter::cur_handle(EdgeHandle(cur_index_));
927 }
928 
929 
930 EdgeIter& EdgeIter::operator--() {
931 
932  --cur_index_;
933  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
934  --cur_index_;
935  if(cur_index_ < 0) {
936  BaseIter::valid(false);
937  }
938  BaseIter::cur_handle(EdgeHandle(cur_index_));
939  return *this;
940 }
941 
942 
943 EdgeIter& EdgeIter::operator++() {
944 
945  ++cur_index_;
946  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
947  ++cur_index_;
948  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
949  BaseIter::valid(false);
950  }
951  BaseIter::cur_handle(EdgeHandle(cur_index_));
952  return *this;
953 }
954 
958 
959 
960 HalfEdgeIter::HalfEdgeIter(const TopologyKernel* _mesh, const HalfEdgeHandle& _heh) :
961 BaseIter(_mesh, _heh),
962 cur_index_(_heh.idx()) {
963 
964  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
965  ++cur_index_;
966  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
967  BaseIter::valid(false);
968  }
969  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
970 }
971 
972 
973 HalfEdgeIter& HalfEdgeIter::operator--() {
974 
975  --cur_index_;
976  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
977  --cur_index_;
978  if(cur_index_ < 0) {
979  BaseIter::valid(false);
980  }
981  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
982  return *this;
983 }
984 
985 
986 HalfEdgeIter& HalfEdgeIter::operator++() {
987 
988  ++cur_index_;
989  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
990  ++cur_index_;
991  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
992  BaseIter::valid(false);
993  }
994  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
995  return *this;
996 }
997 
1001 
1002 
1003 FaceIter::FaceIter(const TopologyKernel* _mesh, const FaceHandle& _fh) :
1004 BaseIter(_mesh, _fh),
1005 cur_index_(_fh.idx()) {
1006 
1007  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
1008  ++cur_index_;
1009  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
1010  BaseIter::valid(false);
1011  }
1012  BaseIter::cur_handle(FaceHandle(cur_index_));
1013 }
1014 
1015 
1016 FaceIter& FaceIter::operator--() {
1017 
1018  --cur_index_;
1019  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
1020  --cur_index_;
1021  if(cur_index_ < 0) {
1022  BaseIter::valid(false);
1023  }
1024  BaseIter::cur_handle(FaceHandle(cur_index_));
1025  return *this;
1026 }
1027 
1028 
1029 FaceIter& FaceIter::operator++() {
1030 
1031  ++cur_index_;
1032  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
1033  ++cur_index_;
1034  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
1035  BaseIter::valid(false);
1036  }
1037  BaseIter::cur_handle(FaceHandle(cur_index_));
1038  return *this;
1039 }
1040 
1044 
1045 
1046 HalfFaceIter::HalfFaceIter(const TopologyKernel* _mesh, const HalfFaceHandle& _hfh) :
1047 BaseIter(_mesh, _hfh),
1048 cur_index_(_hfh.idx()) {
1049 
1050  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
1051  ++cur_index_;
1052  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
1053  BaseIter::valid(false);
1054  }
1055  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
1056 }
1057 
1058 
1059 HalfFaceIter& HalfFaceIter::operator--() {
1060 
1061  --cur_index_;
1062  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
1063  --cur_index_;
1064  if(cur_index_ < 0) {
1065  BaseIter::valid(false);
1066  }
1067  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
1068  return *this;
1069 }
1070 
1071 
1072 HalfFaceIter& HalfFaceIter::operator++() {
1073 
1074  ++cur_index_;
1075  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
1076  ++cur_index_;
1077  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
1078  BaseIter::valid(false);
1079  }
1080  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
1081  return *this;
1082 }
1083 
1087 
1088 
1089 CellIter::CellIter(const TopologyKernel* _mesh, const CellHandle& _ch) :
1090 BaseIter(_mesh, _ch),
1091 cur_index_(_ch.idx()) {
1092 
1093  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1094  ++cur_index_;
1095  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
1096  BaseIter::valid(false);
1097  }
1098  BaseIter::cur_handle(CellHandle(cur_index_));
1099 }
1100 
1101 
1102 CellIter& CellIter::operator--() {
1103 
1104  --cur_index_;
1105  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1106  --cur_index_;
1107  if(cur_index_ < 0) {
1108  BaseIter::valid(false);
1109  }
1110  BaseIter::cur_handle(CellHandle(cur_index_));
1111  return *this;
1112 }
1113 
1114 
1115 CellIter& CellIter::operator++() {
1116 
1117  ++cur_index_;
1118  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
1119  ++cur_index_;
1120  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
1121  BaseIter::valid(false);
1122  }
1123  BaseIter::cur_handle(CellHandle(cur_index_));
1124  return *this;
1125 }
1126 
1127 } // Namespace OpenVolumeMesh