$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
link_functor_base.hh
1 // Copyright (C) 2009, 2010, 2011, 2013 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 SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH
28 # define SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH
29 
36 
37 # include <mln/core/concept/image.hh>
38 
39 # include <mln/math/abs.hh>
40 
41 # include <mln/util/array.hh>
42 # include <mln/util/couple.hh>
43 
44 # include <mln/labeling/compute.hh>
45 # include <mln/accu/center.hh>
46 
47 # include <scribo/core/tag/anchor.hh>
48 # include <scribo/core/component_set.hh>
49 # include <scribo/core/object_links.hh>
50 # include <scribo/core/concept/link_functor.hh>
51 # include <scribo/primitive/link/internal/compute_anchor.hh>
52 
53 # define scribo_support(T) typename T::support
54 # define scribo_support_(T) T::support
55 
56 namespace scribo
57 {
58 
59  namespace primitive
60  {
61 
62  namespace link
63  {
64 
65  namespace internal
66  {
67 
69  template <typename L, typename E>
70  class link_functor_base : public Link_Functor<E>
71  {
72  public:
73 
75  typedef L support;
76  typedef mln_site(L) P;
78 
80  link_functor_base(const component_set<L>& components);
81 
82 
83  const object_links<L>& links() const;
84 
85  unsigned link(unsigned object) const;
86  const component_set<L>& components() const;
87 
88 
89  void initialize_link(unsigned current_object);
90  couple_t finalize_link(unsigned current_object);
91 
92 
93  bool verify_link_criterion(unsigned current_object,
94  const P& start_point, const P& p,
95  anchor::Type anchor) const;
96 
97  bool is_potential_link(unsigned current_object,
98  const P& start_point, const P& p) const;
99 
100  bool valid_link(unsigned current_object,
101  const P& start_point, const P& p,
102  anchor::Type anchor);
103 
104 
105 
106  //FIXME: there's a probleme here. We may not want to provide
107  //both interfaces (with multiple and single anchors)for
108  //every functors...
109 
110  void validate_link(unsigned current_object,
111  const P& start_point,
112  const P& p,
113  anchor::Type anchor);
114 
117  void validate_link(unsigned current_object,
118  const P& start_point, const P& p);
119 
120  void invalidate_link(unsigned current_object,
121  const P& start_point, const P& p,
122  anchor::Type anchor);
123 
126  void invalidate_link(unsigned current_object,
127  const P& start_point, const P& p);
128 
129 
130  void compute_next_site(P& p);
131 
132 
133  mln_site(L) start_point(unsigned current_object, anchor::Type anchor);
134 
137  mln_site(L) start_point(unsigned current_object);
138 
139 
140  void start_processing_object(unsigned current_object);
141 
142 
143 
144 
145  // Default implementation for possibly not overridden
146  // methods.
147 
148  void initialize_link_(unsigned current_object);
149  couple_t finalize_link_(unsigned current_object);
150 
151  bool is_potential_link_(unsigned current_object,
152  const P& start_point, const P& p) const;
153 
154  bool verify_link_criterion_(unsigned current_object,
155  const P& start_point, const P& p,
156  anchor::Type anchor) const;
157 
158  bool valid_link_(unsigned current_object,
159  const P& start_point, const P& p,
160  anchor::Type anchor);
161 
162  void validate_link_(unsigned current_object,
163  const P& start_point, const P& p,
164  anchor::Type anchor);
165 
166  void invalidate_link_(unsigned current_object,
167  const P& start_point, const P& p,
168  anchor::Type anchor);
169 
170  void compute_next_site_(P& p);
171 
172  void start_processing_object_(unsigned current_object);
173 
174  mln_site(L) start_point_(unsigned current_object,
175  anchor::Type anchor);
176 
177  const L& labeled_image() const;
178 
179  protected:
180  object_links<L> links_;
181  const component_set<L> components_;
182  const L& labeled_image_;
183  };
184 
185 
186 
187 # ifndef MLN_INCLUDE_ONLY
188 
189 
190  template <typename L, typename E>
191  inline
194  : links_(components),
195  components_(components),
196  labeled_image_(this->components_.labeled_image())
197  {
198  links_.init();
199  }
200 
201 
202  template <typename L, typename E>
203  inline
204  const object_links<L>&
205  link_functor_base<L,E>::links() const
206  {
207  return links_;
208  }
209 
210  template <typename L, typename E>
211  inline
212  unsigned
213  link_functor_base<L,E>::link(unsigned object) const
214  {
215  return links_(object);
216  }
217 
218  template <typename L, typename E>
219  inline
220  const component_set<L>&
222  {
223  return components_;
224  }
225 
226 
227 
228 
229  template <typename L, typename E>
230  inline
231  bool
232  link_functor_base<L,E>::is_potential_link(unsigned current_object,
233  const P& start_point,
234  const P& p) const
235  {
236  (void) start_point;
237  mln_value(L) v = this->labeled_image_(p);
238 
239  // We found that we are passing through a separator. We stop
240  // looking up for a neighbor by returning true.
241  //
242  // Since we don't want to link with a separator,
243  // verify_link_criterion will invalidate this link.
244  //
245  if (this->components_.has_separators() && this->components_.separators()(p))
246  return true;
247 
248  return v != literal::zero // Not the background
249  && v != current_object // Not the current component
250  && this->links_(v) != current_object // No loops
251  && this->components_(v).tag() != component::Ignored; // Not ignored
252  }
253 
254 
255  template <typename L, typename E>
256  inline
257  void
258  link_functor_base<L,E>::initialize_link(unsigned current_object)
259  {
260  exact(this)->initialize_link_(current_object);
261  }
262 
263  template <typename L, typename E>
264  inline
266  link_functor_base<L,E>::finalize_link(unsigned current_object)
267  {
268  return exact(this)->finalize_link_(current_object);
269  }
270 
271 
272 
273  template <typename L, typename E>
274  inline
275  bool
276  link_functor_base<L,E>::verify_link_criterion(unsigned current_object,
277  const P& start_point,
278  const P& p,
279  anchor::Type anchor) const
280  {
281  return
282  // Do not link with separators...
283  ! this->components_.separators()(p)
284  // ... and perform custom checks.
285  && exact(this)->verify_link_criterion_(current_object,
286  start_point, p, anchor);
287  }
288 
289  template <typename L, typename E>
290  inline
291  bool
292  link_functor_base<L,E>::valid_link(unsigned current_object,
293  const P& start_point,
294  const P& p,
295  anchor::Type anchor)
296  {
297  return this->labeled_image_.domain().has(p)
298  && exact(this)->valid_link_(current_object, start_point, p, anchor);
299  }
300 
301 
302  template <typename L, typename E>
303  inline
304  void
305  link_functor_base<L,E>::validate_link(unsigned current_object,
306  const P& start_point,
307  const P& p,
308  anchor::Type anchor)
309  {
310  exact(this)->validate_link_(current_object, start_point, p, anchor);
311  }
312 
313 
314 
315  template <typename L, typename E>
316  inline
317  void
318  link_functor_base<L,E>::validate_link(unsigned current_object,
319  const P& start_point,
320  const P& p)
321  {
322  validate_link(current_object, start_point, p, anchor::MassCenter);
323  }
324 
325 
326  template <typename L, typename E>
327  inline
328  void
329  link_functor_base<L,E>::invalidate_link(unsigned current_object,
330  const P& start_point,
331  const P& p,
332  anchor::Type anchor)
333  {
334  exact(this)->invalidate_link_(current_object, start_point, p, anchor);
335  }
336 
337 
338  template <typename L, typename E>
339  inline
340  void
341  link_functor_base<L,E>::invalidate_link(unsigned current_object,
342  const P& start_point,
343  const P& p)
344  {
345  invalidate_link(current_object, start_point, p, anchor::MassCenter);
346  }
347 
348 
349 
350 
351 
352  template <typename L, typename E>
353  inline
354  void
355  link_functor_base<L,E>::compute_next_site(P& p)
356  {
357  // No-op
358  exact(this)->compute_next_site_(p);
359  }
360 
361 
362  template <typename L, typename E>
363  inline
364  mln_site(L)
365  link_functor_base<L,E>::start_point(unsigned current_object,
366  anchor::Type anchor)
367  {
368  return exact(this)->start_point_(current_object, anchor);
369  }
370 
371 
372  template <typename L, typename E>
373  inline
374  mln_site(L)
375  link_functor_base<L,E>::start_point(unsigned current_object)
376  {
377  return start_point(current_object, anchor::MassCenter);
378  }
379 
380 
381  template <typename L, typename E>
382  inline
383  void
384  link_functor_base<L,E>::start_processing_object(
385  unsigned current_object)
386  {
387  (void) current_object;
388  // No-Op
389  exact(this)->start_processing_object_(current_object);
390  }
391 
392 
393  template <typename L, typename E>
394  inline
395  const L&
396  link_functor_base<L,E>::labeled_image() const
397  {
398  return labeled_image_;
399  }
400 
401 
402 
403  // Default implementation for delegated methods.
404 
405  template <typename L, typename E>
406  inline
407  void
408  link_functor_base<L,E>::initialize_link_(unsigned current_object)
409  {
410  (void) current_object;
411  // No-Op
412  }
413 
414 
415  template <typename L, typename E>
416  inline
418  link_functor_base<L,E>::finalize_link_(unsigned current_object)
419  {
420  (void) current_object;
421  // No-Op
422  return mln::make::couple(anchor::Invalid, P());
423  }
424 
425 
426  template <typename L, typename E>
427  inline
428  bool
429  link_functor_base<L,E>::is_potential_link_(unsigned current_object,
430  const P& start_point,
431  const P& p) const
432  {
433  (void) current_object;
434  (void) start_point;
435  (void) p;
436  // No-Op
437  return true;
438  }
439 
440  template <typename L, typename E>
441  inline
442  bool
443  link_functor_base<L,E>::verify_link_criterion_(unsigned current_object,
444  const P& start_point,
445  const P& p,
446  anchor::Type anchor) const
447  {
448  (void) current_object;
449  (void) start_point;
450  (void) p;
451  (void) anchor;
452  // No-Op
453  return true;
454  }
455 
456 
457  template <typename L, typename E>
458  inline
459  bool
460  link_functor_base<L,E>::valid_link_(unsigned current_object,
461  const P& start_point,
462  const P& p,
463  anchor::Type anchor)
464  {
465  return is_potential_link(current_object, start_point, p)
466  && verify_link_criterion(current_object, start_point, p, anchor);
467  }
468 
469 
470  template <typename L, typename E>
471  inline
472  void
473  link_functor_base<L,E>::validate_link_(unsigned current_object,
474  const P& start_point,
475  const P& p,
476  anchor::Type anchor)
477  {
478  (void) start_point;
479  (void) anchor;
480  this->links_.update(current_object, this->labeled_image_(p));
481  }
482 
483 
484  template <typename L, typename E>
485  inline
486  void
487  link_functor_base<L,E>::invalidate_link_(unsigned current_object,
488  const P& start_point,
489  const P& p,
490  anchor::Type anchor)
491  {
492  (void) current_object;
493  (void) start_point;
494  (void) p;
495  (void) anchor;
496  // No-op
497  }
498 
499 
500  template <typename L, typename E>
501  inline
502  mln_site(L)
503  link_functor_base<L,E>::start_point_(unsigned current_object,
504  anchor::Type anchor)
505  {
506  (void) anchor;
507  return internal::compute_anchor(this->components_,
508  current_object, anchor);
509  }
510 
511  template <typename L, typename E>
512  inline
513  void
514  link_functor_base<L,E>::start_processing_object_(
515  unsigned /* current_object */)
516  {
517  // No-Op
518  }
519 
520 
521 # endif // ! MLN_INCLUDE_ONLY
522 
523 
524  } // end of namespace scribo::primitive::link::internal
525 
526  } // end of namespace scribo::primitive::link
527 
528  } // end of namespace scribo::primitive
529 
530 } // end of namespace scribo
531 
532 
533 #endif // ! SCRIBO_CORE_INTERNAL_LINK_FUNCTOR_BASE_HH