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
OpenVolumeMesh::HalfEdgeHalfFaceIter
Definition: Iterators.hh:365
OpenVolumeMesh
Definition: ColorAttrib.hh:53