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 
130 
131 
132 HalfEdgeHalfFaceIter::HalfEdgeHalfFaceIter(const HalfEdgeHandle& _ref_h,
133  const TopologyKernel* _mesh, int _max_laps) :
134 BaseIter(_mesh, _ref_h, _max_laps),
135 cur_index_(0) {
136 
137  if(!_mesh->has_edge_bottom_up_incidences()) {
138 #ifndef NDEBUG
139  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
140 #endif
141  BaseIter::valid(false);
142  return;
143  }
144 
145  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
146  BaseIter::valid(false);
147  }
148 
149  if(BaseIter::valid()) {
150  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
151  BaseIter::valid(false);
152  }
153  }
154 
155  if(BaseIter::valid()) {
156  BaseIter::cur_handle((
157  BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]);
158  }
159 }
160 
161 
162 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator--() {
163 
164  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
165 
166  if (cur_index_ == 0) {
167  cur_index_ = n_outgoing_halffaces-1;
168  --lap_;
169  if (lap_ < 0)
170  BaseIter::valid(false);
171  }
172  else {
173  --cur_index_;
174  }
175 
176  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
177 
178  return *this;
179 }
180 
181 
182 HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator++() {
183 
184 
185  size_t n_outgoing_halffaces = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()].size();
186 
187  ++cur_index_;
188 
189  if (cur_index_ == n_outgoing_halffaces) {
190  cur_index_ = 0;
191  ++lap_;
192  if (lap_ >= max_laps_)
193  BaseIter::valid(false);
194  }
195 
196  BaseIter::cur_handle((BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()])[cur_index_]);
197 
198  return *this;
199 }
200 
204 
205 VertexCellIter::VertexCellIter(const VertexHandle& _ref_h,
206  const TopologyKernel* _mesh, int _max_laps) :
207 BaseIter(_mesh, _ref_h, _max_laps) {
208 
209  if(!_mesh->has_full_bottom_up_incidences()) {
210 #ifndef NDEBUG
211  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
212 #endif
213  BaseIter::valid(false);
214  return;
215  }
216 
217  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
218  BaseIter::valid(false);
219  return;
220  }
221 
222  // Build up cell list
223  const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
224  for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
225 
226  if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
227  const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
228 
229  for(std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
230  hf_it != incidentHalfFaces.end(); ++hf_it) {
231  if((unsigned int)hf_it->idx() < BaseIter::mesh()->incident_cell_per_hf_.size()) {
232  CellHandle c_idx = BaseIter::mesh()->incident_cell_per_hf_[hf_it->idx()];
233  if(c_idx != TopologyKernel::InvalidCellHandle)
234  cells_.push_back(c_idx);
235  }
236  }
237  }
238  // Remove all duplicate entries
239  std::sort(cells_.begin(), cells_.end());
240  cells_.resize(std::unique(cells_.begin(), cells_.end()) - cells_.begin());
241 
242  // Remove invalid handles
243  if ((cells_.size() > 0) && !cells_.front().is_valid())
244  cells_.erase(cells_.begin());
245 
246  cur_index_ = 0;
247  BaseIter::valid(cells_.size()>0);
248  if(BaseIter::valid()) {
249  BaseIter::cur_handle(cells_[cur_index_]);
250  }
251 }
252 
253 VertexCellIter& VertexCellIter::operator--() {
254 
255  if(cur_index_ == 0) {
256  cur_index_ = cells_.size()-1;
257  --lap_;
258  if (lap_ < 0) {
259  BaseIter::valid(false);
260  }
261  } else {
262  --cur_index_;
263  }
264 
265  BaseIter::cur_handle(cells_[cur_index_]);
266  return *this;
267 }
268 
269 
270 VertexCellIter& VertexCellIter::operator++() {
271 
272  ++cur_index_;
273  if(cur_index_ == cells_.size()) {
274  cur_index_ = 0;
275  ++lap_;
276  if (lap_ >= max_laps_) {
277  BaseIter::valid(false);
278  }
279  }
280  BaseIter::cur_handle(cells_[cur_index_]);
281  return *this;
282 }
283 
287 
288 
289 HalfEdgeCellIter::HalfEdgeCellIter(const HalfEdgeHandle& _ref_h,
290  const TopologyKernel* _mesh, int _max_laps) :
291 BaseIter(_mesh, _ref_h, _max_laps),
292 cur_index_(0) {
293 
294  if(!_mesh->has_edge_bottom_up_incidences() || !_mesh->has_face_bottom_up_incidences()) {
295 #ifndef NDEBUG
296  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
297 #endif
298  BaseIter::valid(false);
299  return;
300  }
301 
302  if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) {
303 
304  BaseIter::valid(false);
305  return;
306  }
307  if((unsigned int)cur_index_ >= BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()].size()) {
308 
309  BaseIter::valid(false);
310  return;
311  }
312  if((unsigned int)((BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()])[cur_index_]).idx() >=
313  BaseIter::mesh()->incident_cell_per_hf_.size()) {
314 
315  BaseIter::valid(false);
316  return;
317  }
318 
319  // collect cell handles
320  const std::vector<HalfFaceHandle>& incidentHalffaces = BaseIter::mesh()->incident_hfs_per_he_[_ref_h.idx()];
321  std::set<CellHandle> cells;
322  for (unsigned int i = 0; i < incidentHalffaces.size(); ++i)
323  {
324  CellHandle ch = getCellHandle(i);
325  if (ch.is_valid()) {
326  if(cells.count(ch) == 0) {
327  cells_.push_back(ch);
328  }
329  cells.insert(ch);
330  }
331  }
332 
333  BaseIter::valid(cells_.size() > 0);
334 
335  if(BaseIter::valid()) {
336  BaseIter::cur_handle(cells_[cur_index_]);
337  }
338 }
339 
340 
341 HalfEdgeCellIter& HalfEdgeCellIter::operator--() {
342 
343  if (cur_index_ == 0) {
344  cur_index_ = cells_.size()-1;
345  --lap_;
346  if (lap_ < 0)
347  BaseIter::valid(false);
348  }
349  else {
350  --cur_index_;
351  }
352 
353  BaseIter::cur_handle(cells_[cur_index_]);
354  return *this;
355 }
356 
357 
358 HalfEdgeCellIter& HalfEdgeCellIter::operator++() {
359 
360  ++cur_index_;
361 
362  if (cur_index_ == cells_.size()) {
363  cur_index_ = 0;
364  ++lap_;
365  if (lap_ >= max_laps_)
366  BaseIter::valid(false);
367  }
368 
369  BaseIter::cur_handle(cells_[cur_index_]);
370  return *this;
371 }
372 
373 CellHandle HalfEdgeCellIter::getCellHandle(int _cur_index) const
374 {
375  const std::vector<HalfFaceHandle>& halffacehandles = BaseIter::mesh()->incident_hfs_per_he_[BaseIter::ref_handle().idx()];
376  HalfFaceHandle currentHalfface = halffacehandles[_cur_index];
377  if(!currentHalfface.is_valid()) return CellHandle(-1);
378  CellHandle cellhandle = BaseIter::mesh()->incident_cell_per_hf_[currentHalfface.idx()];
379  return cellhandle;
380 }
381 
382 
386 
387 
388 CellVertexIter::CellVertexIter(const CellHandle& _ref_h,
389  const TopologyKernel* _mesh, int _max_laps) :
390 BaseIter(_mesh, _ref_h, _max_laps) {
391 
392  OpenVolumeMeshCell c = BaseIter::mesh()->cell(_ref_h);
393  std::vector<HalfFaceHandle>::const_iterator hf_iter = c.halffaces().begin();
394  for(; hf_iter != c.halffaces().end(); ++hf_iter) {
395  const OpenVolumeMeshFace& halfface = BaseIter::mesh()->halfface(*hf_iter);
396  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
397  for(std::vector<HalfEdgeHandle>::const_iterator he_iter = hes.begin(); he_iter != hes.end(); ++he_iter) {
398  incident_vertices_.push_back(BaseIter::mesh()->halfedge(*he_iter).to_vertex());
399  }
400  }
401 
402  // Remove all duplicate entries
403  std::sort(incident_vertices_.begin(), incident_vertices_.end());
404  incident_vertices_.resize(std::unique(incident_vertices_.begin(), incident_vertices_.end()) - incident_vertices_.begin());
405 
406  cur_index_ = 0;
407  BaseIter::valid(incident_vertices_.size() > 0);
408 
409  if(BaseIter::valid()) {
410  BaseIter::cur_handle(incident_vertices_[cur_index_]);
411  }
412 }
413 
414 
415 CellVertexIter& CellVertexIter::operator--() {
416 
417  if (cur_index_ == 0) {
418  cur_index_ = incident_vertices_.size()-1;
419  --lap_;
420  if (lap_ < 0)
421  BaseIter::valid(false);
422  }
423  else {
424  --cur_index_;
425  }
426 
427  BaseIter::cur_handle(incident_vertices_[cur_index_]);
428  return *this;
429 }
430 
431 
432 CellVertexIter& CellVertexIter::operator++() {
433 
434  ++cur_index_;
435  if (cur_index_ == incident_vertices_.size()){
436  cur_index_ = 0;
437  ++lap_;
438  if (lap_ >= max_laps_)
439  BaseIter::valid(false);
440  }
441 
442  BaseIter::cur_handle(incident_vertices_[cur_index_]);
443  return *this;
444 }
445 
449 
450 
451 CellCellIter::CellCellIter(const CellHandle& _ref_h,
452  const TopologyKernel* _mesh, int _max_laps) :
453 BaseIter(_mesh, _ref_h, _max_laps) {
454 
455  if(!_mesh->has_face_bottom_up_incidences()) {
456 #ifndef NDEBUG
457  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
458 #endif
459  BaseIter::valid(false);
460  return;
461  }
462 
463  std::vector<HalfFaceHandle>::const_iterator hf_iter = BaseIter::mesh()->cell(_ref_h).halffaces().begin();
464  std::vector<HalfFaceHandle>::const_iterator hf_end = BaseIter::mesh()->cell(_ref_h).halffaces().end();
465  for(; hf_iter != hf_end; ++hf_iter) {
466 
467  HalfFaceHandle opp_hf = BaseIter::mesh()->opposite_halfface_handle(*hf_iter);
468  CellHandle ch = BaseIter::mesh()->incident_cell_per_hf_[opp_hf.idx()];
469  if(ch != TopologyKernel::InvalidCellHandle) {
470  adjacent_cells_.push_back(ch);
471  }
472  }
473 
474  // Remove all duplicate entries
475  std::sort(adjacent_cells_.begin(), adjacent_cells_.end());
476  adjacent_cells_.resize(std::unique(adjacent_cells_.begin(), adjacent_cells_.end()) - adjacent_cells_.begin());
477 
478  cur_index_ = 0;
479  BaseIter::valid(adjacent_cells_.size()>0);
480  if(BaseIter::valid()) {
481  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
482  }
483 }
484 
485 
486 CellCellIter& CellCellIter::operator--() {
487 
488  if (cur_index_ == 0) {
489  cur_index_ = adjacent_cells_.size() - 1;
490  --lap_;
491  if (lap_ < 0)
492  BaseIter::valid(false);
493  }
494  else {
495  --cur_index_;
496  }
497 
498  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
499  return *this;
500 }
501 
502 
503 CellCellIter& CellCellIter::operator++() {
504 
505  ++cur_index_;
506  if (cur_index_ == adjacent_cells_.size())
507  {
508  cur_index_ = 0;
509  ++lap_;
510  if (lap_ >= max_laps_)
511  BaseIter::valid(false);
512  }
513  BaseIter::cur_handle(adjacent_cells_[cur_index_]);
514  return *this;
515 }
516 
520 
521 
522 HalfFaceVertexIter::HalfFaceVertexIter(const HalfFaceHandle& _ref_h,
523  const TopologyKernel* _mesh, int _max_laps) :
524 BaseIter(_mesh, _ref_h, _max_laps) {
525 
526  if(!_ref_h.is_valid()) return;
527 
528  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
529  const std::vector<HalfEdgeHandle>& hes = halfface.halfedges();
530  for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
531  he_it != hes.end(); ++he_it) {
532  vertices_.push_back(_mesh->halfedge(*he_it).from_vertex());
533  }
534 
535  cur_index_ = 0;
536 
537  BaseIter::valid(vertices_.size() > 0);
538  if(BaseIter::valid()) {
539  BaseIter::cur_handle(vertices_[cur_index_]);
540  }
541 }
542 
543 
544 HalfFaceVertexIter& HalfFaceVertexIter::operator--() {
545 
546  if (cur_index_ == 0) {
547  cur_index_ = vertices_.size() - 1;
548  --lap_;
549  if (lap_ < 0)
550  BaseIter::valid(false);
551  }
552  else {
553  --cur_index_;
554  }
555 
556  BaseIter::cur_handle(vertices_[cur_index_]);
557  return *this;
558 }
559 
560 
561 HalfFaceVertexIter& HalfFaceVertexIter::operator++() {
562 
563  ++cur_index_;
564  if (cur_index_ == vertices_.size())
565  {
566  cur_index_ = 0;
567  ++lap_;
568  if (lap_ >= max_laps_)
569  BaseIter::valid(false);
570  }
571  BaseIter::cur_handle(vertices_[cur_index_]);
572  return *this;
573 }
574 
575 //================================================================================================
576 // BoundaryHalfFaceHalfFaceIter
577 //================================================================================================
578 
579 BoundaryHalfFaceHalfFaceIter::BoundaryHalfFaceHalfFaceIter(const HalfFaceHandle& _ref_h,
580  const TopologyKernel* _mesh, int _max_laps) :
581 BaseIter(_mesh, _ref_h, _max_laps) {
582 
583  if(!_mesh->has_face_bottom_up_incidences()) {
584 #ifndef NDEBUG
585  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
586 #endif
587  BaseIter::valid(false);
588  return;
589  }
590 
591  // Go over all incident halfedges
592 // const std::vector<HalfEdgeHandle> halfedges = _mesh->halfface(_ref_h).halfedges();
593  const OpenVolumeMeshFace& halfface = _mesh->halfface(_ref_h);
594  const std::vector<HalfEdgeHandle>& halfedges = halfface.halfedges();
595  for(std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();
596  he_it != halfedges.end(); ++he_it) {
597 
598  // Get outside halffaces
599  OpenVolumeMesh::HalfEdgeHalfFaceIter hehf_it = _mesh->hehf_iter(_mesh->opposite_halfedge_handle(*he_it));
600  for(; hehf_it.valid(); ++hehf_it) {
601 
602  if(_mesh->is_boundary(*hehf_it)) {
603  neighbor_halffaces_.push_back(*hehf_it);
604  common_edges_.push_back(_mesh->edge_handle(*he_it));
605  }
606  }
607  }
608 
609  cur_index_ = 0;
610  BaseIter::valid(neighbor_halffaces_.size() > 0);
611  if(BaseIter::valid()) {
612  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
613  }
614 }
615 
616 
617 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator--() {
618 
619  if (cur_index_ == 0)
620  {
621  cur_index_ = neighbor_halffaces_.size() - 1;
622  --lap_;
623  if (lap_ < 0)
624  BaseIter::valid(false);
625  }
626  else{
627  --cur_index_;
628  }
629 
630  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
631  return *this;
632 }
633 
634 
635 BoundaryHalfFaceHalfFaceIter& BoundaryHalfFaceHalfFaceIter::operator++() {
636 
637  ++cur_index_;
638  if (cur_index_ == neighbor_halffaces_.size())
639  {
640  cur_index_ = 0;
641  ++lap_;
642  if (lap_ >= max_laps_)
643  BaseIter::valid(false);
644  }
645 
646  BaseIter::cur_handle(neighbor_halffaces_[cur_index_]);
647  return *this;
648 }
649 
653 
654 
655 BoundaryFaceIter::BoundaryFaceIter(const TopologyKernel* _mesh) :
656 BaseIter(_mesh),
657 bf_it_(_mesh->faces_begin()) {
658 
659  if(!_mesh->has_face_bottom_up_incidences()) {
660 #ifndef NDEBUG
661  std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
662 #endif
663  BaseIter::valid(false);
664  return;
665  }
666 
667  while(bf_it_ != BaseIter::mesh()->faces_end() &&
668  !BaseIter::mesh()->is_boundary(*bf_it_) &&
669  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
670  ++bf_it_;
671  }
672  BaseIter::valid(bf_it_ != BaseIter::mesh()->faces_end());
673  if(BaseIter::valid()) {
674  BaseIter::cur_handle(*bf_it_);
675  }
676 }
677 
678 
679 BoundaryFaceIter& BoundaryFaceIter::operator--() {
680 
681  --bf_it_;
682  while(bf_it_ >= BaseIter::mesh()->faces_begin() &&
683  !BaseIter::mesh()->is_boundary(*bf_it_) &&
684  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
685  --bf_it_;
686  }
687  if(bf_it_ >= BaseIter::mesh()->faces_begin()) {
688  BaseIter::cur_handle(*bf_it_);
689  } else {
690  BaseIter::valid(false);
691  }
692  return *this;
693 }
694 
695 
696 BoundaryFaceIter& BoundaryFaceIter::operator++() {
697 
698  ++bf_it_;
699  while(bf_it_ != BaseIter::mesh()->faces_end() &&
700  !BaseIter::mesh()->is_boundary(*bf_it_) &&
701  BaseIter::mesh()->is_deleted(bf_it_.cur_handle())){
702  ++bf_it_;
703  }
704  if(bf_it_ != BaseIter::mesh()->faces_end()) {
705  BaseIter::cur_handle(*bf_it_);
706  } else {
707  BaseIter::valid(false);
708  }
709  return *this;
710 }
711 
715 
716 
717 VertexIter::VertexIter(const TopologyKernel* _mesh, const VertexHandle& _vh) :
718 BaseIter(_mesh, _vh),
719 cur_index_(_vh.idx()) {
720 
721  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
722  ++cur_index_;
723  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
724  BaseIter::valid(false);
725  }
726  BaseIter::cur_handle(VertexHandle(cur_index_));
727 }
728 
729 
730 VertexIter& VertexIter::operator--() {
731 
732  --cur_index_;
733  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
734  --cur_index_;
735  if(cur_index_ < 0) {
736  BaseIter::valid(false);
737  }
738  BaseIter::cur_handle(VertexHandle(cur_index_));
739  return *this;
740 }
741 
742 
743 VertexIter& VertexIter::operator++() {
744 
745  ++cur_index_;
746  while ((unsigned int)cur_index_ < BaseIter::mesh()->n_vertices() && BaseIter::mesh()->is_deleted(VertexHandle(cur_index_)))
747  ++cur_index_;
748  if((unsigned int)cur_index_ >= BaseIter::mesh()->n_vertices()) {
749  BaseIter::valid(false);
750  }
751  BaseIter::cur_handle(VertexHandle(cur_index_));
752  return *this;
753 }
754 
758 
759 
760 EdgeIter::EdgeIter(const TopologyKernel* _mesh, const EdgeHandle& _eh) :
761 BaseIter(_mesh, _eh),
762 cur_index_(_eh.idx()) {
763 
764  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
765  ++cur_index_;
766  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
767  BaseIter::valid(false);
768  }
769  BaseIter::cur_handle(EdgeHandle(cur_index_));
770 }
771 
772 
773 EdgeIter& EdgeIter::operator--() {
774 
775  --cur_index_;
776  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
777  --cur_index_;
778  if(cur_index_ < 0) {
779  BaseIter::valid(false);
780  }
781  BaseIter::cur_handle(EdgeHandle(cur_index_));
782  return *this;
783 }
784 
785 
786 EdgeIter& EdgeIter::operator++() {
787 
788  ++cur_index_;
789  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() && BaseIter::mesh()->is_deleted(EdgeHandle(cur_index_)))
790  ++cur_index_;
791  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size()) {
792  BaseIter::valid(false);
793  }
794  BaseIter::cur_handle(EdgeHandle(cur_index_));
795  return *this;
796 }
797 
801 
802 
803 HalfEdgeIter::HalfEdgeIter(const TopologyKernel* _mesh, const HalfEdgeHandle& _heh) :
804 BaseIter(_mesh, _heh),
805 cur_index_(_heh.idx()) {
806 
807  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
808  ++cur_index_;
809  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
810  BaseIter::valid(false);
811  }
812  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
813 }
814 
815 
816 HalfEdgeIter& HalfEdgeIter::operator--() {
817 
818  --cur_index_;
819  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
820  --cur_index_;
821  if(cur_index_ < 0) {
822  BaseIter::valid(false);
823  }
824  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
825  return *this;
826 }
827 
828 
829 HalfEdgeIter& HalfEdgeIter::operator++() {
830 
831  ++cur_index_;
832  while ((unsigned int)cur_index_ < BaseIter::mesh()->edges_.size() * 2 && BaseIter::mesh()->is_deleted(HalfEdgeHandle(cur_index_)))
833  ++cur_index_;
834  if((unsigned int)cur_index_ >= BaseIter::mesh()->edges_.size() * 2) {
835  BaseIter::valid(false);
836  }
837  BaseIter::cur_handle(HalfEdgeHandle(cur_index_));
838  return *this;
839 }
840 
844 
845 
846 FaceIter::FaceIter(const TopologyKernel* _mesh, const FaceHandle& _fh) :
847 BaseIter(_mesh, _fh),
848 cur_index_(_fh.idx()) {
849 
850  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
851  ++cur_index_;
852  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
853  BaseIter::valid(false);
854  }
855  BaseIter::cur_handle(FaceHandle(cur_index_));
856 }
857 
858 
859 FaceIter& FaceIter::operator--() {
860 
861  --cur_index_;
862  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
863  --cur_index_;
864  if(cur_index_ < 0) {
865  BaseIter::valid(false);
866  }
867  BaseIter::cur_handle(FaceHandle(cur_index_));
868  return *this;
869 }
870 
871 
872 FaceIter& FaceIter::operator++() {
873 
874  ++cur_index_;
875  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() && BaseIter::mesh()->is_deleted(FaceHandle(cur_index_)))
876  ++cur_index_;
877  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size()) {
878  BaseIter::valid(false);
879  }
880  BaseIter::cur_handle(FaceHandle(cur_index_));
881  return *this;
882 }
883 
887 
888 
889 HalfFaceIter::HalfFaceIter(const TopologyKernel* _mesh, const HalfFaceHandle& _hfh) :
890 BaseIter(_mesh, _hfh),
891 cur_index_(_hfh.idx()) {
892 
893  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
894  ++cur_index_;
895  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
896  BaseIter::valid(false);
897  }
898  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
899 }
900 
901 
902 HalfFaceIter& HalfFaceIter::operator--() {
903 
904  --cur_index_;
905  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
906  --cur_index_;
907  if(cur_index_ < 0) {
908  BaseIter::valid(false);
909  }
910  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
911  return *this;
912 }
913 
914 
915 HalfFaceIter& HalfFaceIter::operator++() {
916 
917  ++cur_index_;
918  while ((unsigned int)cur_index_ < BaseIter::mesh()->faces_.size() * 2 && BaseIter::mesh()->is_deleted(HalfFaceHandle(cur_index_)))
919  ++cur_index_;
920  if((unsigned int)cur_index_ >= BaseIter::mesh()->faces_.size() * 2) {
921  BaseIter::valid(false);
922  }
923  BaseIter::cur_handle(HalfFaceHandle(cur_index_));
924  return *this;
925 }
926 
930 
931 
932 CellIter::CellIter(const TopologyKernel* _mesh, const CellHandle& _ch) :
933 BaseIter(_mesh, _ch),
934 cur_index_(_ch.idx()) {
935 
936  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
937  ++cur_index_;
938  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
939  BaseIter::valid(false);
940  }
941  BaseIter::cur_handle(CellHandle(cur_index_));
942 }
943 
944 
945 CellIter& CellIter::operator--() {
946 
947  --cur_index_;
948  while (cur_index_ >= 0 && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
949  --cur_index_;
950  if(cur_index_ < 0) {
951  BaseIter::valid(false);
952  }
953  BaseIter::cur_handle(CellHandle(cur_index_));
954  return *this;
955 }
956 
957 
958 CellIter& CellIter::operator++() {
959 
960  ++cur_index_;
961  while ((unsigned int)cur_index_ < BaseIter::mesh()->cells_.size() && BaseIter::mesh()->is_deleted(CellHandle(cur_index_)))
962  ++cur_index_;
963  if((unsigned int)cur_index_ >= BaseIter::mesh()->cells_.size()) {
964  BaseIter::valid(false);
965  }
966  BaseIter::cur_handle(CellHandle(cur_index_));
967  return *this;
968 }
969 
970 } // Namespace OpenVolumeMesh