Gudhi  1.1.0
 All Classes Functions 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 GUDHI_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
23 #define GUDHI_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 
33 
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_handle const
42 , boost::forward_traversal_tag
43 , typename Complex::Simplex_handle const
44 >
45 {
46  friend class boost::iterator_core_access;
47  template<typename T> friend class Triangle_iterator;
48 private:
49  typedef typename LinkType::Vertex_handle Vertex_handle;
50  typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
51  typedef typename LinkType::Simplex_handle Simplex_handle;
53 
54  const Complex* complex_;
55  Vertex_handle v_;
56  std::shared_ptr<LinkType> link_;
57  Complex_edge_iterator_ current_edge_;
58  bool is_end_;
59 public:
60  Triangle_around_vertex_iterator(const Complex* complex,Vertex_handle v):
61  complex_(complex),v_(v),link_(new LinkType(*complex,v_)),
62  current_edge_(link_->edge_range().begin()),
63  is_end_(current_edge_ == link_->edge_range().end()){
64  }
65 
69  Triangle_around_vertex_iterator(const Complex* complex,Vertex_handle v,bool is_end):
70  complex_(complex),v_(v),link_(0),is_end_(true){
71  }
72 
77  complex_(0),v_(-1),link_(0),is_end_(true){
78  }
79 
80 
82  v_ = other.v_;
83  complex_ = other.complex_;
84  is_end_ = other.is_end_;
85 
86  if(!is_end_){
87  link_ = other.link_;
88  current_edge_= other.current_edge_;
89  }
90  }
91 
92  bool equal(const Triangle_around_vertex_iterator& other) const{
93  return (complex_==other.complex_) && ((finished() &&other.finished()) || current_edge_ == other.current_edge_);
94  }
95 
96  Simplex_handle dereference() const{
97  Root_vertex_handle v1 = (*link_)[*current_edge_].first();
98  Root_vertex_handle v2 = (*link_)[*current_edge_].second();
99  return Simplex_handle(v_,*(complex_->get_address(v1)),*(complex_->get_address(v2)));
100  }
101 
102  void increment(){
103  ++current_edge_;
104  }
105 
106 private:
107  bool finished() const{
108  return is_end_ || (current_edge_ == link_->edge_range().end());
109  }
110 
111 };
112 
113 
114 
121 template<typename SkeletonBlockerComplex>
123  public boost::iterator_facade<
124  Triangle_iterator <SkeletonBlockerComplex>,
125  typename SkeletonBlockerComplex::Simplex_handle const
126  , boost::forward_traversal_tag
127  , typename SkeletonBlockerComplex::Simplex_handle const
128  >
129 {
130  friend class boost::iterator_core_access;
131 private:
132  typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
133  typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
134  typedef typename SkeletonBlockerComplex::Simplex_handle Simplex_handle;
135  typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
136 
137  const SkeletonBlockerComplex* complex_;
139  STAVI current_triangle_;
140  bool is_end_;
141 public:
142 
143  /*
144  * @remark assume that the complex is non-empty
145  */
146  Triangle_iterator(const SkeletonBlockerComplex* complex):
147  complex_(complex),
148  current_vertex_(complex->vertex_range().begin()),
149  current_triangle_(complex,*current_vertex_), // xxx this line is problematic is the complex is empty
150  is_end_(false){
151 
152  assert(!complex->empty());
153  gotoFirstTriangle();
154  }
155 
156 private:
157  //goto to the first triangle or to the end if none
158  void gotoFirstTriangle(){
159  if(!is_finished() && current_triangle_.finished()){
160  goto_next_vertex();
161  }
162  }
163 public:
164 
169  Triangle_iterator(const SkeletonBlockerComplex* complex,bool is_end):
170  complex_(complex),
171  current_vertex_(complex->vertex_range().end()),
172  current_triangle_(), // xxx this line is problematic is the complex is empty
173  is_end_(true){
174  }
175 
176 
177  Triangle_iterator& operator=(const Triangle_iterator & other){
178  complex_ = other.complex_;
180  STAVI current_triangle_;
181  return *this;
182  }
183 
184 
185  bool equal(const Triangle_iterator& other) const{
186  bool both_are_finished = is_finished() && other.is_finished();
187  bool both_arent_finished = !is_finished() && !other.is_finished();
188  // if the two iterators are not finished, they must have the same state
189  return (complex_==other.complex_) &&
190  (both_are_finished ||
191  ( (both_arent_finished) && current_vertex_ == other.current_vertex_ && current_triangle_ == other.current_triangle_));
192 
193  }
194 
195  Simplex_handle dereference() const{
196  return *current_triangle_;
197  }
198 
199 private:
200 
201  // goto the next vertex that has a triangle pending or the
202  // end vertex iterator if none exists
203  void goto_next_vertex(){
204  assert(current_triangle_.finished()); //we mush have consume all triangles passing through the vertex
205  assert(!is_finished()); // we must not be done
206 
207  ++current_vertex_;
208 
209  if(!is_finished()){
210  current_triangle_ = STAVI(complex_, *current_vertex_);
211  if(current_triangle_.finished())
212  goto_next_vertex();
213  }
214  }
215 public:
216  void increment(){
217  if(!current_triangle_.finished()){
218  ++current_triangle_; // problem here
219  if(current_triangle_.finished())
220  goto_next_vertex();
221  }
222  else{
223  assert(!is_finished());
224  goto_next_vertex();
225  }
226  }
227 
228 private:
229  bool is_finished() const{
230  return is_end_ || current_vertex_ == complex_->vertex_range().end();
231  }
232 };
233 
234 }
235 
236 } // namespace GUDHI
237 
238 #endif /* GUDHI_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:169
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:69
Triangle_around_vertex_iterator()
ugly hack to get an iterator to the end
Definition: Skeleton_blockers_triangles_iterators.h:76
Iterator over the triangles that are adjacent to a vertex of the simplicial complex.
Definition: Skeleton_blockers_triangles_iterators.h:39
Iterator on the vertices of a simplicial complex.
Definition: Skeleton_blockers_vertices_iterators.h:38
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:122