Gudhi  1.2.0
 All Classes Functions Variables Typedefs Friends Groups Pages
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 Sophia Antipolis-Mediterranee (France)
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 #ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
23 #define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
24 
25 #include <boost/iterator/iterator_facade.hpp>
26 #include <memory>
27 
28 namespace Gudhi {
29 
30 namespace skbl {
31 
37 template<typename Complex, typename LinkType>
38 class Triangle_around_vertex_iterator : public boost::iterator_facade
39 < Triangle_around_vertex_iterator <Complex, LinkType>
40 , typename Complex::Simplex_handle const
41 , boost::forward_traversal_tag
42 , typename Complex::Simplex_handle const> {
43  friend class boost::iterator_core_access;
44  template<typename T> friend class Triangle_iterator;
45  private:
46  typedef typename LinkType::Vertex_handle Vertex_handle;
47  typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
48  typedef typename LinkType::Simplex_handle Simplex_handle;
50 
51  const Complex* complex_;
52  Vertex_handle v_;
53  std::shared_ptr<LinkType> link_;
54  Complex_edge_iterator_ current_edge_;
55  bool is_end_;
56 
57  public:
58  Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v) :
59  complex_(complex), v_(v), link_(new LinkType(*complex, v_)),
60  current_edge_(link_->edge_range().begin()),
61  is_end_(current_edge_ == link_->edge_range().end()) { }
62 
66  Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v, bool is_end) :
67  complex_(complex), v_(v), link_(0), is_end_(true) { }
68 
73  complex_(0), v_(-1), link_(0), is_end_(true) { }
74 
76  v_ = other.v_;
77  complex_ = other.complex_;
78  is_end_ = other.is_end_;
79 
80  if (!is_end_) {
81  link_ = other.link_;
82  current_edge_ = other.current_edge_;
83  }
84  }
85 
86  bool equal(const Triangle_around_vertex_iterator& other) const {
87  return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_);
88  }
89 
90  Simplex_handle dereference() const {
91  Root_vertex_handle v1 = (*link_)[*current_edge_].first();
92  Root_vertex_handle v2 = (*link_)[*current_edge_].second();
93  return Simplex_handle(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2)));
94  }
95 
96  void increment() {
97  ++current_edge_;
98  }
99 
100  private:
101  bool finished() const {
102  return is_end_ || (current_edge_ == link_->edge_range().end());
103  }
104 };
105 
112 template<typename SkeletonBlockerComplex>
113 class Triangle_iterator : public boost::iterator_facade<
114 Triangle_iterator <SkeletonBlockerComplex>,
115 typename SkeletonBlockerComplex::Simplex_handle const
116 , boost::forward_traversal_tag
117 , typename SkeletonBlockerComplex::Simplex_handle const> {
118  friend class boost::iterator_core_access;
119  private:
120  typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
121  typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
122  typedef typename SkeletonBlockerComplex::Simplex_handle Simplex_handle;
123  typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
124  typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
125 
126  const SkeletonBlockerComplex* complex_;
127  Complex_vertex_iterator current_vertex_;
128  STAVI current_triangle_;
129  bool is_end_;
130 
131  public:
132  /*
133  * @remark assume that the complex is non-empty
134  */
135  Triangle_iterator(const SkeletonBlockerComplex* complex) :
136  complex_(complex),
137  current_vertex_(complex->vertex_range().begin()),
138  current_triangle_(complex, *current_vertex_), // xxx this line is problematic is the complex is empty
139  is_end_(false) {
140  assert(!complex->empty());
141  gotoFirstTriangle();
142  }
143 
144  private:
145  // goto to the first triangle or to the end if none
146  void gotoFirstTriangle() {
147  if (!is_finished() && current_triangle_.finished()) {
148  goto_next_vertex();
149  }
150  }
151 
152  public:
157  Triangle_iterator(const SkeletonBlockerComplex* complex, bool is_end) :
158  complex_(complex),
159  current_vertex_(complex->vertex_range().end()),
160  current_triangle_(), // xxx this line is problematic is the complex is empty
161  is_end_(true) { }
162 
163  Triangle_iterator& operator=(const Triangle_iterator & other) {
164  complex_ = other.complex_;
165  Complex_vertex_iterator current_vertex_;
166  STAVI current_triangle_;
167  return *this;
168  }
169 
170  bool equal(const Triangle_iterator& other) const {
171  bool both_are_finished = is_finished() && other.is_finished();
172  bool both_arent_finished = !is_finished() && !other.is_finished();
173  // if the two iterators are not finished, they must have the same state
174  return (complex_ == other.complex_) && (both_are_finished || ((both_arent_finished) &&
175  current_vertex_ == other.current_vertex_ && current_triangle_ == other.current_triangle_));
176  }
177 
178  Simplex_handle dereference() const {
179  return *current_triangle_;
180  }
181 
182  private:
183  // goto the next vertex that has a triangle pending or the
184  // end vertex iterator if none exists
185  void goto_next_vertex() {
186  assert(current_triangle_.finished()); // we mush have consume all triangles passing through the vertex
187  assert(!is_finished()); // we must not be done
188 
189  ++current_vertex_;
190 
191  if (!is_finished()) {
192  current_triangle_ = STAVI(complex_, *current_vertex_);
193  if (current_triangle_.finished())
194  goto_next_vertex();
195  }
196  }
197 
198  public:
199  void increment() {
200  if (!current_triangle_.finished()) {
201  ++current_triangle_; // problem here
202  if (current_triangle_.finished())
203  goto_next_vertex();
204  } else {
205  assert(!is_finished());
206  goto_next_vertex();
207  }
208  }
209 
210  private:
211  bool is_finished() const {
212  return is_end_ || current_vertex_ == complex_->vertex_range().end();
213  }
214 };
215 
216 } // namespace skbl
217 
218 } // namespace Gudhi
219 
220 #endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
Triangle_iterator(const SkeletonBlockerComplex *complex, bool is_end)
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:157
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:66
Triangle_around_vertex_iterator()
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:72
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:441
Iterator over the triangles that are adjacent to a vertex of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:38
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:50
Iterator on the edges of a simplicial complex.
Definition: Skeleton_blockers_edges_iterators.h:96
Root_vertex_handle and Vertex_handle are similar to global and local vertex descriptor used in boost ...
Definition: SkeletonBlockerDS.h:50
Iterator over the triangles of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:113