Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
adj_lower_dim_connected_n_face_iter.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_TOPO_ADJ_LOWER_DIM_CONNECTED_N_FACE_ITER_HH
27 # define MLN_TOPO_ADJ_LOWER_DIM_CONNECTED_N_FACE_ITER_HH
28 
34 
35 # include <set>
36 
37 # include <mln/topo/internal/complex_relative_iterator_base.hh>
38 # include <mln/topo/algebraic_face.hh>
39 
40 
41 namespace mln
42 {
43 
44  namespace topo
45  {
46 
47  // Forward declarations.
48  template <unsigned D> class complex;
49  namespace internal
50  {
51  template <unsigned D> class adj_lower_dim_connected_n_face_iterator;
52  }
53 
54 
55  /*---------------------------------------------------.
56  | topo::adj_lower_dim_connected_n_face_fwd_iter<D>. |
57  `---------------------------------------------------*/
58 
63  //
64  template <unsigned D>
66  : public internal::forward_complex_relative_iterator_base< topo::face<D>,
67  algebraic_face<D>,
68  adj_lower_dim_connected_n_face_fwd_iter<D> >,
69  private internal::adj_lower_dim_connected_n_face_iterator<D>
70  {
71  // Tech note: we use topo::face to help g++-2.95.
72  private:
74  typedef internal::forward_complex_relative_iterator_base< topo::face<D>,
76  self_ > super_;
77 
78  public:
82  template <typename Fref>
83  adj_lower_dim_connected_n_face_fwd_iter(const Fref& f_ref);
85 
90  void update_adj_faces_();
91  };
92 
93 
94  /*---------------------------------------------------.
95  | topo::adj_lower_dim_connected_n_face_bkd_iter<D>. |
96  `---------------------------------------------------*/
97 
102  //
103  template <unsigned D>
105  : public internal::backward_complex_relative_iterator_base< topo::face<D>,
106  algebraic_face<D>,
107  adj_lower_dim_connected_n_face_bkd_iter<D> >,
108  private internal::adj_lower_dim_connected_n_face_iterator<D>
109  {
110  // Tech note: we use topo::face to help g++-2.95.
111  private:
113  typedef internal::backward_complex_relative_iterator_base< topo::face<D>,
115  self_ > super_;
116 
117  public:
121  template <typename Fref>
122  adj_lower_dim_connected_n_face_bkd_iter(const Fref& f_ref);
124 
129  void update_adj_faces_();
130  };
131 
132 
133  /*-------------------------------------------------------------.
134  | topo::internal::adj_lower_dim_connected_n_face_iterator<D>. |
135  `-------------------------------------------------------------*/
136 
137  namespace internal
138  {
139 
140  template <unsigned D>
141  class adj_lower_dim_connected_n_face_iterator
142  {
143  protected:
146  void update_adj_faces__(const topo::face<D>& center,
147  std::vector< algebraic_face<D> >& adj_faces);
148  };
149 
150  } // end of namespace mln::topo::internal
151 
152 
153 
154 # ifndef MLN_INCLUDE_ONLY
155 
156  /*---------------------------------------------------.
157  | topo::adj_lower_dim_connected_n_face_fwd_iter<D>. |
158  `---------------------------------------------------*/
159 
160  template <unsigned D>
161  inline
163  {
164  }
165 
166  template <unsigned D>
167  template <typename Fref>
168  inline
170  : super_(f_ref)
171  {
172  }
173 
174  /* FIXME: Most of this code is shared by
175  adj_lower_dim_connected_n_face_{fwd,bkd}_iter<D> and
176  adj_higher_dim_connected_n_face_{fwd,bkd}_iter<D>). Find a way
177  to factor this, maybe through a common (implementation) base
178  class. */
179  template <unsigned D>
180  inline
181  void
182  adj_lower_dim_connected_n_face_fwd_iter<D>::update_adj_faces_()
183  {
184  mln_precondition(this->c_);
185  // Delegate computation to base class.
186  this->update_adj_faces__(*this->c_, this->adj_faces_);
187  }
188 
189 
190  /*---------------------------------------------------.
191  | topo::adj_lower_dim_connected_n_face_bkd_iter<D>. |
192  `---------------------------------------------------*/
193 
194  template <unsigned D>
195  inline
197  {
198  }
199 
200  template <unsigned D>
201  template <typename Fref>
202  inline
204  : super_(f_ref)
205  {
206  }
207 
208  template <unsigned D>
209  inline
210  void
211  adj_lower_dim_connected_n_face_bkd_iter<D>::update_adj_faces_()
212  {
213  mln_precondition(this->c_);
214  // Delegate computation to base class.
215  this->update_adj_faces__(*this->c_, this->adj_faces_);
216  }
217 
218 
219  /*-------------------------------------------------------------.
220  | topo::internal::adj_lower_dim_connected_n_face_iterator<D>. |
221  `-------------------------------------------------------------*/
222 
223  namespace internal
224  {
225 
226  /* FIXME: Factor
227  topo::internal::adj_lower_dim_connected_n_face_iterator<D> and
228  topo::internal::adj_higher_dim_connected_n_face_iterator<D>. */
229 
230  template <unsigned D>
231  inline
232  void
233  adj_lower_dim_connected_n_face_iterator<D>::update_adj_faces__(const topo::face<D>& center,
234  std::vector< algebraic_face<D> >& adj_faces)
235  {
236  // Reset the result container.
237  adj_faces.clear();
238 
239  /* A set of faces containing the same values as ADJ_FACES, used
240  to quickly check whether a candidate face has already been
241  added to the pool of adjacent faces. We use an std::set
242  because the lookup is cheaper (O(log(n)) vs O(n) for a
243  vector, where n is the size of the containers. */
244  std::set< algebraic_face<D> > faces_set;
245  typedef std::vector< algebraic_face<D> > faces_t;
246 
247  // The set of (n-1)-faces adjacent to CENTER.
248  faces_t shared_lower_faces = center.lower_dim_adj_faces();
249  for (typename faces_t::const_iterator slf = shared_lower_faces.begin();
250  slf != shared_lower_faces.end(); ++slf)
251  {
252  /* The n-faces sharing an adjacent (n-1)-face with CENTER.
253  Note that this set contains CENTER itself. */
254  faces_t adj_n_faces = slf->higher_dim_adj_faces();
255  for (typename faces_t::const_iterator af = adj_n_faces.begin();
256  af != adj_n_faces.end(); ++af)
257  {
258  /* Ensure that 1. we are not adding CENTER to the result;
259  and 2. that we are not adding an already added
260  processed face. */
261  if (*af != center &&
262  faces_set.find(*af) == faces_set.end())
263  {
264  adj_faces.push_back(*af);
265  faces_set.insert(*af);
266  }
267  }
268  }
269  }
270 
271  } // end of namespace mln::topo::internal
272 
273 # endif // ! MLN_INCLUDE_ONLY
274 
275  } // end of namespace mln::topo
276 
277 } // end of namespace mln
278 
279 #endif // ! MLN_TOPO_ADJ_LOWER_DIM_CONNECTED_N_FACE_ITER_HH