$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
adj_m_face_iter.hh
1 // Copyright (C) 2008, 2009, 2012 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_TOPO_ADJ_M_FACE_ITER_HH
28 # define MLN_TOPO_ADJ_M_FACE_ITER_HH
29 
35 
36 # include <set>
37 # include <vector>
38 
39 # include <mln/topo/internal/complex_relative_iterator_base.hh>
40 # include <mln/topo/face.hh>
41 
42 
43 namespace mln
44 {
45 
46  namespace topo
47  {
48 
49  // Forward declarations.
50  template <unsigned D> class complex;
51  namespace internal
52  {
53  template <unsigned D> class adj_m_face_iterator;
54  }
55 
56 
57  /*-------------------------------.
58  | topo::adj_m_face_fwd_iter<D>. |
59  `-------------------------------*/
60 
73  template <unsigned D>
76  algebraic_face<D>,
77  adj_m_face_fwd_iter<D> >,
79  {
80  // Tech note: we use topo::face to help g++-2.95.
81  private:
85  self_ > super_;
87 
88  public:
96  template <typename Fref>
97  adj_m_face_fwd_iter(const Fref& f_ref, unsigned m);
99 
104  void update_adj_faces_();
105  };
106 
107 
108  /*-------------------------------.
109  | topo::adj_m_face_bkd_iter<D>. |
110  `-------------------------------*/
111 
124  template <unsigned D>
127  algebraic_face<D>,
128  adj_m_face_bkd_iter<D> >,
130  {
131  // Tech note: we use topo::face to help g++-2.95.
132  private:
136  self_ > super_;
138 
139  public:
147  template <typename Fref>
148  adj_m_face_bkd_iter(const Fref& f_ref, unsigned m);
150 
155  void update_adj_faces_();
156  };
157 
158 
159  /*-----------------------------------------.
160  | topo::internal::adj_m_face_iterator<D>. |
161  `-----------------------------------------*/
162 
163  namespace internal
164  {
165 
166  template <unsigned D>
168  {
169  protected:
171  adj_m_face_iterator(unsigned m);
172 
173  public:
175  unsigned m() const;
177  void set_m(unsigned m);
178 
179  protected:
182  void update_adj_faces__(const topo::face<D>& center,
183  std::vector< algebraic_face<D> >& adj_faces);
184 
186  unsigned m_;
187  };
188 
189  } // end of namespace mln::topo::internal
190 
191 
192 
193 # ifndef MLN_INCLUDE_ONLY
194 
195  /*-------------------------------.
196  | topo::adj_m_face_fwd_iter<D>. |
197  `-------------------------------*/
198 
199  template <unsigned D>
200  inline
202  {
203  }
204 
205  template <unsigned D>
206  template <typename Fref>
207  inline
208  adj_m_face_fwd_iter<D>::adj_m_face_fwd_iter(const Fref& f_ref, unsigned m)
209  : super_(f_ref), impl_(m)
210  {
211  }
212 
213  template <unsigned D>
214  inline
215  void
216  adj_m_face_fwd_iter<D>::update_adj_faces_()
217  {
218  mln_precondition(this->c_);
219  // Delegate computation to base class.
220  this->update_adj_faces__(*this->c_, this->adj_faces_);
221  }
222 
223 
224  /*-------------------------------.
225  | topo::adj_m_face_bkd_iter<D>. |
226  `-------------------------------*/
227 
228  template <unsigned D>
229  inline
230  adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter()
231  {
232  }
233 
234  template <unsigned D>
235  template <typename Fref>
236  inline
237  adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter(const Fref& f_ref, unsigned m)
238  : super_(f_ref), impl_(m)
239  {
240  }
241 
242  template <unsigned D>
243  inline
244  void
245  adj_m_face_bkd_iter<D>::update_adj_faces_()
246  {
247  mln_precondition(this->c_);
248  // Delegate computation to base class.
249  this->update_adj_faces__(*this->c_, this->adj_faces_);
250  }
251 
252 
253  /*-----------------------------------------.
254  | topo::internal::adj_m_face_iterator<D>. |
255  `-----------------------------------------*/
256 
257  namespace internal
258  {
259 
260  template <unsigned D>
261  inline
262  adj_m_face_iterator<D>::adj_m_face_iterator()
263  : m_(0)
264  {
265  }
266 
267  template <unsigned D>
268  inline
270  : m_(m)
271  {
272  mln_precondition(m <= D);
273  }
274 
275  template <unsigned D>
276  unsigned
278  {
279  return m_;
280  }
281 
282  template <unsigned D>
283  void
285  {
286  m_ = m;
287  }
288 
289  template <unsigned D>
290  inline
291  void
292  adj_m_face_iterator<D>::update_adj_faces__(const topo::face<D>& center,
293  std::vector< algebraic_face<D> >& adj_faces)
294  {
295  adj_faces.clear();
296 
297  if (center.n() == m_)
298  return;
299 
300  typedef std::vector < topo::algebraic_face<D> > faces_t;
301  typedef std::set < topo::algebraic_face<D> > faces_set_t;
302 
303  /* FIXME: p_faces is redundant; we could use adj_faces
304  directly. */
305  /* The adjacent p-faces being built; initialized with CENTER,
306  and filled with q-faces at each step, until q reaches
307  m_. */
308  faces_t p_faces(1,
309  make_algebraic_face(center, true));
310  // The set of faces being built.
311  /* FIXME: This pattern is recurring in Milena---using an
312  std::set (or any fast associative container) to improve
313  the lookup speed of an std::vector; we should create a
314  class for this, a bit like mln::util::set, but with a
315  garantee on the order of insertion. */
316  faces_t work_faces;
317  faces_set_t work_faces_set;
318 
319  // Iteratively compute the set of locations.
320  for (unsigned p = center.n(); p != m_; (p < m_ ? ++p : --p) )
321  {
322  mln_invariant (p != m_);
323  for (typename faces_t::const_iterator g = p_faces.begin();
324  g != p_faces.end(); ++g)
325  {
326  mln_invariant (g->n() != m_);
327  faces_t q_faces = g->n() < m_ ?
328  g->higher_dim_adj_faces() :
329  g->lower_dim_adj_faces();
330  /* Traverse the higher- or lower-dimension adjacent
331  faces of G in the natural order if G's sign is
332  positive, or in the reverse order if G's sign is
333  negative. */
334  /* FIXME: Factor; the code if the two branches is the
335  same, except for the iteration order. */
336  if (g->sign())
337  {
338  for (typename faces_t::const_iterator h = q_faces.begin();
339  h != q_faces.end(); ++h)
340  // Don't insert a face twice.
341  if (work_faces_set.find(*h) == work_faces_set.end())
342  {
343  work_faces.push_back(*h);
344  work_faces_set.insert(*h);
345  }
346  }
347  else
348  {
349  for (typename faces_t::const_reverse_iterator h =
350  q_faces.rbegin();
351  /* This is crazy. With Apple g++ 4.0, this
352  code won't compile without this cast!
353  This is solved in MacPorts g++ 4.3. */
354  h != (typename faces_t::const_reverse_iterator) q_faces.rend();
355  ++h)
356  // Don't insert a face twice.
357  if (work_faces_set.find(*h) == work_faces_set.end())
358  {
359  work_faces.push_back(*h);
360  work_faces_set.insert(*h);
361  }
362  }
363  }
364  work_faces.swap(p_faces);
365  work_faces.clear();
366  work_faces_set.clear();
367  }
368 
369  adj_faces = p_faces;
370  }
371 
372  } // end of namespace mln::topo::internal
373 
374 # endif // ! MLN_INCLUDE_ONLY
375 
376  } // end of namespace mln::topo
377 
378 } // end of namespace mln
379 
380 #endif // ! MLN_TOPO_ADJ_M_FACE_ITER_HH