Loading...
Searching...
No Matches
Skeleton_blockers_triangles_iterators.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): David Salinas
4 *
5 * Copyright (C) 2014 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
11#ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
12#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
13
14#include <boost/iterator/iterator_facade.hpp>
15#include <memory>
16
17namespace Gudhi {
18
19namespace skeleton_blocker {
20
26template<typename Complex, typename LinkType>
27class Triangle_around_vertex_iterator : public boost::iterator_facade
28< Triangle_around_vertex_iterator <Complex, LinkType>
29, typename Complex::Simplex const
30, boost::forward_traversal_tag
31, typename Complex::Simplex const> {
32 friend class boost::iterator_core_access;
33 template<typename T> friend class Triangle_iterator;
34 private:
35 typedef typename LinkType::Vertex_handle Vertex_handle;
36 typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
37 typedef typename LinkType::Simplex Simplex;
39
40 const Complex* complex_;
41 Vertex_handle v_;
42 std::shared_ptr<LinkType> link_;
43 Complex_edge_iterator_ current_edge_;
44 bool is_end_;
45
46 public:
47 Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v) :
48 complex_(complex), v_(v), link_(new LinkType(*complex, v_)),
49 current_edge_(link_->edge_range().begin()),
50 is_end_(current_edge_ == link_->edge_range().end()) { }
51
55 Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v, bool is_end) :
56 complex_(complex), v_(v), link_(0), is_end_(true) { }
57
62 complex_(0), v_(-1), link_(0), is_end_(true) { }
63
65 v_ = other.v_;
66 complex_ = other.complex_;
67 is_end_ = other.is_end_;
68
69 if (!is_end_) {
70 link_ = other.link_;
71 current_edge_ = other.current_edge_;
72 }
73 }
74
75 bool equal(const Triangle_around_vertex_iterator& other) const {
76 return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_);
77 }
78
79 Simplex dereference() const {
80 Root_vertex_handle v1 = (*link_)[*current_edge_].first();
81 Root_vertex_handle v2 = (*link_)[*current_edge_].second();
82 return Simplex(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2)));
83 }
84
85 void increment() {
86 ++current_edge_;
87 }
88
89 private:
90 bool finished() const {
91 return is_end_ || (current_edge_ == link_->edge_range().end());
92 }
93};
94
101template<typename SkeletonBlockerComplex>
102class Triangle_iterator : public boost::iterator_facade<
103Triangle_iterator <SkeletonBlockerComplex>,
104typename SkeletonBlockerComplex::Simplex const
105, boost::forward_traversal_tag
106, typename SkeletonBlockerComplex::Simplex const> {
107 friend class boost::iterator_core_access;
108 private:
109 typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
110 typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
111 typedef typename SkeletonBlockerComplex::Simplex Simplex;
112 typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
113 typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
114
115 const SkeletonBlockerComplex* complex_;
116 Complex_vertex_iterator current_vertex_;
117 STAVI current_triangle_;
118 bool is_end_;
119
120 public:
121 /*
122 * @remark assume that the complex is non-empty
123 */
124 Triangle_iterator(const SkeletonBlockerComplex* complex) :
125 complex_(complex),
126 current_vertex_(complex->vertex_range().begin()),
127 current_triangle_(complex, *current_vertex_), // this line is problematic is the complex is empty
128 is_end_(false) {
129 assert(!complex->empty());
130 gotoFirstTriangle();
131 }
132
133 private:
134 // goto to the first triangle or to the end if none
135 void gotoFirstTriangle() {
136 if (!is_finished() && current_triangle_.finished()) {
137 goto_next_vertex();
138 }
139 }
140
141 public:
146 Triangle_iterator(const SkeletonBlockerComplex* complex, bool is_end) :
147 complex_(complex),
148 current_vertex_(complex->vertex_range().end()),
149 current_triangle_(), // xxx this line is problematic is the complex is empty
150 is_end_(true) { }
151
152 Triangle_iterator& operator=(const Triangle_iterator & other) {
153 complex_ = other.complex_;
154 Complex_vertex_iterator current_vertex_;
155 STAVI current_triangle_;
156 return *this;
157 }
158
159 bool equal(const Triangle_iterator& other) const {
160 bool both_are_finished = is_finished() && other.is_finished();
161 bool both_arent_finished = !is_finished() && !other.is_finished();
162 // if the two iterators are not finished, they must have the same state
163 return (complex_ == other.complex_) && (both_are_finished || ((both_arent_finished) &&
164 current_vertex_ == other.current_vertex_ &&
165 current_triangle_ == other.current_triangle_));
166 }
167
168 Simplex dereference() const {
169 return *current_triangle_;
170 }
171
172 private:
173 // goto the next vertex that has a triangle pending or the
174 // end vertex iterator if none exists
175 void goto_next_vertex() {
176 // we must have consume all triangles passing through the vertex
177 assert(current_triangle_.finished());
178 // we must not be done
179 assert(!is_finished());
180
181 ++current_vertex_;
182
183 if (!is_finished()) {
184 current_triangle_ = STAVI(complex_, *current_vertex_);
185 if (current_triangle_.finished())
186 goto_next_vertex();
187 }
188 }
189
190 public:
191 void increment() {
192 if (!current_triangle_.finished()) {
193 ++current_triangle_; // problem here
194 if (current_triangle_.finished())
195 goto_next_vertex();
196 } else {
197 assert(!is_finished());
198 goto_next_vertex();
199 }
200 }
201
202 private:
203 bool is_finished() const {
204 return is_end_ || current_vertex_ == complex_->vertex_range().end();
205 }
206};
207
208} // namespace skeleton_blocker
209
210namespace skbl = skeleton_blocker;
211
212} // namespace Gudhi
213
214#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
Iterator on the edges of a simplicial complex.
Definition: Skeleton_blockers_edges_iterators.h:88
virtual boost::optional< Vertex_handle > get_address(Root_vertex_handle id) const
Given an Id return the address of the vertex having this Id in the complex.
Definition: Skeleton_blocker_complex.h:432
Class that represents a geometric complex that can be simplified. The class allows access to points o...
Definition: Skeleton_blocker_geometric_complex.h:29
Iterator over the triangles that are adjacent to a vertex of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:31
Triangle_around_vertex_iterator(const Complex *complex, Vertex_handle v, bool is_end)
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:55
Triangle_around_vertex_iterator()
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:61
Iterator over the triangles of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:106
Triangle_iterator(const SkeletonBlockerComplex *complex, bool is_end)
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:146
Root_vertex_handle and Vertex_handle are similar to global and local vertex descriptor used in boost ...
Definition: SkeletonBlockerDS.h:47