Skeleton_blockers_triangles_iterators.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): David Salinas
6  *
7  * Copyright (C) 2014 Inria
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
24 #define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
25 
26 #include <boost/iterator/iterator_facade.hpp>
27 #include <memory>
28 
29 namespace Gudhi {
30 
31 namespace skeleton_blocker {
32 
38 template<typename Complex, typename LinkType>
39 class Triangle_around_vertex_iterator : public boost::iterator_facade
40 < Triangle_around_vertex_iterator <Complex, LinkType>
41 , typename Complex::Simplex const
42 , boost::forward_traversal_tag
43 , typename Complex::Simplex const> {
44  friend class boost::iterator_core_access;
45  template<typename T> friend class Triangle_iterator;
46  private:
47  typedef typename LinkType::Vertex_handle Vertex_handle;
48  typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
49  typedef typename LinkType::Simplex Simplex;
50  typedef typename Complex::Complex_edge_iterator Complex_edge_iterator_;
51 
52  const Complex* complex_;
53  Vertex_handle v_;
54  std::shared_ptr<LinkType> link_;
55  Complex_edge_iterator_ current_edge_;
56  bool is_end_;
57 
58  public:
59  Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v) :
60  complex_(complex), v_(v), link_(new LinkType(*complex, v_)),
61  current_edge_(link_->edge_range().begin()),
62  is_end_(current_edge_ == link_->edge_range().end()) { }
63 
67  Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v, bool is_end) :
68  complex_(complex), v_(v), link_(0), is_end_(true) { }
69 
74  complex_(0), v_(-1), link_(0), is_end_(true) { }
75 
77  v_ = other.v_;
78  complex_ = other.complex_;
79  is_end_ = other.is_end_;
80 
81  if (!is_end_) {
82  link_ = other.link_;
83  current_edge_ = other.current_edge_;
84  }
85  }
86 
87  bool equal(const Triangle_around_vertex_iterator& other) const {
88  return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_);
89  }
90 
91  Simplex dereference() const {
92  Root_vertex_handle v1 = (*link_)[*current_edge_].first();
93  Root_vertex_handle v2 = (*link_)[*current_edge_].second();
94  return Simplex(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2)));
95  }
96 
97  void increment() {
98  ++current_edge_;
99  }
100 
101  private:
102  bool finished() const {
103  return is_end_ || (current_edge_ == link_->edge_range().end());
104  }
105 };
106 
113 template<typename SkeletonBlockerComplex>
114 class Triangle_iterator : public boost::iterator_facade<
115 Triangle_iterator <SkeletonBlockerComplex>,
116 typename SkeletonBlockerComplex::Simplex const
117 , boost::forward_traversal_tag
118 , typename SkeletonBlockerComplex::Simplex const> {
119  friend class boost::iterator_core_access;
120  private:
121  typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
122  typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
123  typedef typename SkeletonBlockerComplex::Simplex Simplex;
124  typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
125  typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
126 
127  const SkeletonBlockerComplex* complex_;
128  Complex_vertex_iterator current_vertex_;
129  STAVI current_triangle_;
130  bool is_end_;
131 
132  public:
133  /*
134  * @remark assume that the complex is non-empty
135  */
136  Triangle_iterator(const SkeletonBlockerComplex* complex) :
137  complex_(complex),
138  current_vertex_(complex->vertex_range().begin()),
139  current_triangle_(complex, *current_vertex_), // this line is problematic is the complex is empty
140  is_end_(false) {
141  assert(!complex->empty());
142  gotoFirstTriangle();
143  }
144 
145  private:
146  // goto to the first triangle or to the end if none
147  void gotoFirstTriangle() {
148  if (!is_finished() && current_triangle_.finished()) {
149  goto_next_vertex();
150  }
151  }
152 
153  public:
158  Triangle_iterator(const SkeletonBlockerComplex* complex, bool is_end) :
159  complex_(complex),
160  current_vertex_(complex->vertex_range().end()),
161  current_triangle_(), // xxx this line is problematic is the complex is empty
162  is_end_(true) { }
163 
164  Triangle_iterator& operator=(const Triangle_iterator & other) {
165  complex_ = other.complex_;
166  Complex_vertex_iterator current_vertex_;
167  STAVI current_triangle_;
168  return *this;
169  }
170 
171  bool equal(const Triangle_iterator& other) const {
172  bool both_are_finished = is_finished() && other.is_finished();
173  bool both_arent_finished = !is_finished() && !other.is_finished();
174  // if the two iterators are not finished, they must have the same state
175  return (complex_ == other.complex_) && (both_are_finished || ((both_arent_finished) &&
176  current_vertex_ == other.current_vertex_ &&
177  current_triangle_ == other.current_triangle_));
178  }
179 
180  Simplex dereference() const {
181  return *current_triangle_;
182  }
183 
184  private:
185  // goto the next vertex that has a triangle pending or the
186  // end vertex iterator if none exists
187  void goto_next_vertex() {
188  // we must have consume all triangles passing through the vertex
189  assert(current_triangle_.finished());
190  // we must not be done
191  assert(!is_finished());
192 
193  ++current_vertex_;
194 
195  if (!is_finished()) {
196  current_triangle_ = STAVI(complex_, *current_vertex_);
197  if (current_triangle_.finished())
198  goto_next_vertex();
199  }
200  }
201 
202  public:
203  void increment() {
204  if (!current_triangle_.finished()) {
205  ++current_triangle_; // problem here
206  if (current_triangle_.finished())
207  goto_next_vertex();
208  } else {
209  assert(!is_finished());
210  goto_next_vertex();
211  }
212  }
213 
214  private:
215  bool is_finished() const {
216  return is_end_ || current_vertex_ == complex_->vertex_range().end();
217  }
218 };
219 
220 } // namespace skeleton_blocker
221 
222 namespace skbl = skeleton_blocker;
223 
224 } // namespace Gudhi
225 
226 #endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
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:67
Definition: SimplicialComplexForAlpha.h:26
Triangle_around_vertex_iterator()
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:73
Iterator over the triangles of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:114
Iterator over the triangles that are adjacent to a vertex of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:39
Triangle_iterator(const SkeletonBlockerComplex *complex, bool is_end)
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:158
GUDHI  Version 2.2.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Thu Jun 14 2018 15:00:54 for GUDHI by Doxygen 1.8.13