$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
face.hh
1 // Copyright (C) 2008, 2009, 2010, 2011 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_FACE_HH
28 # define MLN_TOPO_FACE_HH
29 
33 
34 # include <iostream>
35 # include <vector>
36 
37 # include <mln/value/internal/limits.hh>
38 # include <mln/core/contract.hh>
39 # include <mln/metal/bool.hh>
40 
41 
42 namespace mln
43 {
44 
45  namespace topo
46  {
47 
48  // Forward declarations.
49  template <unsigned D> class complex;
50  template <unsigned N, unsigned D> class n_face;
51  template <unsigned N, unsigned D> class face_data;
52  template <unsigned N> class algebraic_face;
53 
54 
55  /*-------.
56  | Face. |
57  `-------*/
58 
63  template <unsigned D>
64  class face
65  {
66  public:
67  // The type of the complex this handle points to.
69 
71  face();
73  face(complex<D>& complex, unsigned n, unsigned face_id);
74 
76  template <unsigned N>
77  face(const n_face<N, D>& f);
78 
80  bool is_valid() const;
82  void invalidate();
83 
87  complex<D> cplx() const;
89  // FIXME: Rename as `dim'?
90  unsigned n() const;
92  // FIXME: Rename as `id'?
93  unsigned face_id() const;
94 
96  void set_cplx(const complex<D>& cplx);
97 
99  void set_n(unsigned n);
101  void inc_n();
103  void dec_n();
104 
106  void set_face_id(unsigned face_id);
108  void inc_face_id();
110  void dec_face_id();
111 
113  template <unsigned N>
114  face_data<N, D>& data() const;
115 
116  // FIXME: To be overhauled.
118  std::vector< algebraic_face<D> > lower_dim_adj_faces() const;
120  std::vector< algebraic_face<D> > higher_dim_adj_faces() const;
122 
123  private:
127  mutable complex<D> cplx_;
129  // FIXME: Rename as `dim_'?
130  unsigned n_;
132  // FIXME: Rename as `id_'?
133  unsigned face_id_;
134  };
135 
136 
139 
144  template <unsigned D>
145  bool operator==(const face<D>& lhs, const face<D>& rhs);
146 
151  template <unsigned D>
152  bool operator!=(const face<D>& lhs, const face<D>& rhs);
153 
161  template <unsigned D>
162  bool operator< (const face<D>& lhs, const face<D>& rhs);
163 
165 
166 
168  template <unsigned D>
169  std::ostream&
170  operator<<(std::ostream& ostr, const face<D>& f);
171 
172 
173 
174 # ifndef MLN_INCLUDE_ONLY
175 
176  template <unsigned D>
177  inline
178  face<D>::face()
179  : cplx_(),
180  n_(value::internal::limits<unsigned>::max()),
181  face_id_(value::internal::limits<unsigned>::max())
182  {
183  }
184 
185  template <unsigned D>
186  inline
187  face<D>::face(complex<D>& c, unsigned n, unsigned face_id)
188  : cplx_(c), n_(n), face_id_(face_id)
189  {
190  // Ensure N is compatible with D.
191  mln_precondition(n <= D);
192  }
193 
194  template <unsigned D>
195  template <unsigned N>
196  inline
197  face<D>::face(const n_face<N, D>& f)
198  : cplx_(f.cplx()), n_(N), face_id_(f.face_id())
199  {
200  // Ensure N is compatible with D.
201  metal::bool_< N <= D >::check();
202  }
203 
204  template <unsigned D>
205  inline
206  bool
207  face<D>::is_valid() const
208  {
209  return n_ <= D && face_id_ < cplx_.nfaces_of_dim(n_);
210  }
211 
212  template <unsigned D>
213  inline
214  void
216  {
219  }
220 
221  template <unsigned D>
222  inline
223  complex<D>
224  face<D>::cplx() const
225  {
226  return cplx_;
227  }
228 
229  template <unsigned D>
230  inline
231  unsigned
232  face<D>::n() const
233  {
234  return n_;
235  }
236 
237  template <unsigned D>
238  inline
239  unsigned
240  face<D>::face_id() const
241  {
242  return face_id_;
243  }
244 
245  template <unsigned D>
246  inline
247  void
248  face<D>::set_cplx(const complex<D>& cplx)
249  {
250  cplx_ = cplx;
251  }
252 
253  template <unsigned D>
254  inline
255  void
256  face<D>::set_n(unsigned n)
257  {
258  n_ = n;
259  }
260 
261  template <unsigned D>
262  inline
263  void
265  {
266  ++n_;
267  }
268 
269  template <unsigned D>
270  inline
271  void
273  {
274  --n_;
275  }
276 
277  template <unsigned D>
278  inline
279  void
280  face<D>::set_face_id(unsigned face_id)
281  {
282  face_id_ = face_id;
283  }
284 
285  template <unsigned D>
286  inline
287  void
289  {
290  ++face_id_;
291  }
292 
293  template <unsigned D>
294  inline
295  void
297  {
298  --face_id_;
299  }
300 
301  template <unsigned D>
302  template <unsigned N>
303  inline
305  face<D>::data() const
306  {
307  mln_precondition(n_ == N);
308  mln_precondition(is_valid());
309  return cplx_.template face_data_<N>(face_id_);
310  }
311 
312 
313  /*-----------------------------------------------.
314  | Helpers for face<D>::lower_dim_adj_faces() and |
315  | face<D>::higher_dim_adj_faces(). |
316  `-----------------------------------------------*/
317 
318  /* FIXME: This is way too complicated; should disappear when the
319  implementation of complexes is simplified (see
320  https://trac.lrde.org/olena/ticket/168). */
321 
322  // Implementation is in mln/topo/algebraic_face.hh.
323 
324  namespace internal
325  {
326 
327  template <unsigned N, unsigned D>
328  struct lower_dim_adj_faces_if_dim_matches_
329  {
330  std::vector< algebraic_face<D> > operator()(const face<D>& face);
331  };
332 
333  template <unsigned D>
334  struct lower_dim_adj_faces_if_dim_matches_<1, D>
335  {
336  std::vector< algebraic_face<D> > operator()(const face<D>& face);
337  };
338 
339  template <unsigned N, unsigned D>
340  struct higher_dim_adj_faces_if_dim_matches_
341  {
342  std::vector< algebraic_face<D> > operator()(const face<D>& face);
343  };
344 
345  template <unsigned D>
346  struct higher_dim_adj_faces_if_dim_matches_<0, D>
347  {
348  std::vector< algebraic_face<D> > operator()(const face<D>& face);
349  };
350 
351  } // end of namespace mln::topo::internal
352 
353 
354  template <unsigned D>
355  inline
356  std::vector< algebraic_face<D> >
358  {
359  // FIXME: Warning: might prevent any attempt to build a complex<0>.
360  metal::bool_<( D != 0 )>::check();
361 
362  return n_ > 0 ?
363  internal::lower_dim_adj_faces_if_dim_matches_<D, D>()(*this) :
364  std::vector< algebraic_face<D> >();
365  }
366 
367  template <unsigned D>
368  inline
369  std::vector< algebraic_face<D> >
371  {
372  // FIXME: Warning: might prevent any attempt to build a complex<0>.
373  metal::bool_<( D != 0 )>::check();
374 
375  return n_ < D ?
376  internal::higher_dim_adj_faces_if_dim_matches_<D - 1, D>()(*this) :
377  std::vector< algebraic_face<D> >();
378  }
379 
380 
381  template <unsigned D>
382  inline
383  bool
384  operator==(const face<D>& lhs, const face<D>& rhs)
385  {
386  // Ensure LHS and RHS belong to the same complex.
387  mln_precondition(lhs.cplx() == rhs.cplx());
388  return lhs.n() == rhs.n() && lhs.face_id() == rhs.face_id();
389  }
390 
391  template <unsigned D>
392  inline
393  bool
394  operator!=(const face<D>& lhs, const face<D>& rhs)
395  {
396  // Ensure LHS and RHS belong to the same complex.
397  mln_precondition(lhs.cplx() == rhs.cplx());
398  return !(lhs == rhs);
399  }
400 
401  template <unsigned D>
402  inline
403  bool
404  operator< (const face<D>& lhs, const face<D>& rhs)
405  {
406  // Ensure LHS and RHS belong to the same complex.
407  mln_precondition(lhs.cplx() == rhs.cplx());
408  return lhs.n() < rhs.n() ||
409  (lhs.n() == rhs.n() && lhs.face_id() < rhs.face_id());
410  }
411 
412 
413  template <unsigned D>
414  inline
415  std::ostream&
416  operator<<(std::ostream& ostr, const face<D>& f)
417  {
418  return ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
419  << ", id = " << f.face_id() << ')';
420  }
421 
422 # endif // ! MLN_INCLUDE_ONLY
423 
424  } // end of namespace mln::topo
425 
426 } // end of namespace mln
427 
428 #endif // ! MLN_TOPO_FACE_HH