* mln/core/image/complex_neighborhood_piter.hh New. * tests/core/image/complex_image.cc: Exercise these iterators as well as lower- and higher-dimension complex neighborhoods. --- milena/ChangeLog | 8 + .../mln/core/image/complex_neighborhood_piter.hh | 356 ++++++++++++++++++++ milena/tests/core/image/complex_image.cc | 49 +++ 3 files changed, 413 insertions(+), 0 deletions(-) create mode 100644 milena/mln/core/image/complex_neighborhood_piter.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index be5fc43..ff4f385 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,13 @@ 2008-10-01 Roland Levillain <roland@lrde.epita.fr> + Add iterators on complex neighborhood. + + * mln/core/image/complex_neighborhood_piter.hh New. + * tests/core/image/complex_image.cc: Exercise these iterators as + well as lower- and higher-dimension complex neighborhoods. + +2008-10-01 Roland Levillain <roland@lrde.epita.fr> + Add neighborhoods of lower- and higher-dimension adjacent faces. * mln/core/image/complex_lower_neighborhood.hh, diff --git a/milena/mln/core/image/complex_neighborhood_piter.hh b/milena/mln/core/image/complex_neighborhood_piter.hh new file mode 100644 index 0000000..ff06cd0 --- /dev/null +++ b/milena/mln/core/image/complex_neighborhood_piter.hh @@ -0,0 +1,356 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH +# define MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH + +/// \file mln/core/image/complex_neighborhood_piter.hh +/// \brief Definition of a site iterator on a complex neighborhood. + +# include <mln/core/internal/site_relative_iterator_base.hh> + +// FIXME: These might be factor-able. + +/* FIXME: Do we really want to inherit from + internal::site_relative_iterator_base? I might duplicate things, + since most of the implementation of this iterator is delegated to + the underlying complex iter. Moreover, change_target_() is + useless, and center_at() ``hides'' an existing method in (one of) + the super class(es) which is not sound, IMHO. Think about + introducing base class replacement. */ + + +namespace mln +{ + + /*------------------------------------------. + | complex_neighborhood_fwd_piter<I, P, N>. | + `------------------------------------------*/ + + /// \brief Forward iterator on complex neighborhood. + template <typename I, typename P, typename N> + class complex_neighborhood_fwd_piter + : public internal::site_relative_iterator_base< N, + complex_neighborhood_fwd_piter<I, P, N> > + { + typedef complex_neighborhood_fwd_piter<I, P, N> self_; + typedef internal::site_relative_iterator_base< N, self_ > super_; + + public: + /// The Point_Site type. + typedef mln_psite(N) psite; + + // FIXME: Dummy typedef. +// typedef void dpoint; + // FIXME: Dummy typedef. +// typedef void mesh; + + public: + /// Construction. + /// \{ + complex_neighborhood_fwd_piter(); + template <typename Pref> + complex_neighborhood_fwd_piter(const Neighborhood<N>& nbh, + const Pref& p_ref); + /// \} + + /// Manipulation. + /// \{ + /// Test if the iterator is valid. + bool is_valid_() const; + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void do_start_(); + /// Go to the next point. + void do_next_(); + + /// Set the reference psite. + /* FIXME: Careful, this method overrides the (non virtual) method + internal::site_relative_iterator_base<S, E>::center_at. See + FIXME above. */ + template <typename Pref> + void center_at(const Pref& c); + /// Compute the current psite. + psite compute_p_() const; + /// \} + + private: + /// The type of the underlying complex iterator. + typedef typename N::complex_fwd_iter iter; + /// The underlying complex iterator. + iter iter_; + }; + + + /// Print an mln::complex_neighborhood_fwd_piter. + template <typename I, typename P, typename N> + std::ostream& + operator<<(std::ostream& ostr, + const complex_neighborhood_fwd_piter<I, P, N>& p); + + + /*------------------------------------------. + | complex_neighborhood_bkd_piter<I, P, N>. | + `------------------------------------------*/ + + /// \brief Backward iterator on complex neighborhood. + template <typename I, typename P, typename N> + class complex_neighborhood_bkd_piter + : public internal::site_relative_iterator_base< N, + complex_neighborhood_bkd_piter<I, P, N> > + { + typedef complex_neighborhood_bkd_piter<I, P, N> self_; + typedef internal::site_relative_iterator_base< N, self_ > super_; + + public: + /// The Point_Site type. + typedef mln_psite(N) psite; + + // FIXME: Dummy typedef. +// typedef void dpoint; + // FIXME: Dummy typedef. +// typedef void mesh; + + public: + /// Construction. + /// \{ + complex_neighborhood_bkd_piter(); + template <typename Pref> + complex_neighborhood_bkd_piter(const Neighborhood<N>& nbh, + const Pref& p_ref); + /// \} + + /// Manipulation. + /// \{ + /// Test if the iterator is valid. + bool is_valid_() const; + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void do_start_(); + /// Go to the next point. + void do_next_(); + + /// Set the reference psite. + /* FIXME: Careful, this method overrides the (non virtual) method + internal::site_relative_iterator_base<S, E>::center_at. See + FIXME above. */ + template <typename Pref> + void center_at(const Pref& c); + /// Compute the current psite. + psite compute_p_() const; + /// \} + + private: + /// The type of the underlying complex iterator. + typedef typename N::complex_fwd_iter iter; + /// The underlying complex iterator. + iter iter_; + }; + + + /// Print an mln::complex_neighborhood_bkd_piter. + template <typename I, typename P, typename N> + std::ostream& + operator<<(std::ostream& ostr, + const complex_neighborhood_bkd_piter<I, P, N>& p); + + + +# ifndef MLN_INCLUDE_ONLY + + /*------------------------------------------. + | complex_neighborhood_fwd_piter<I, P, N>. | + `------------------------------------------*/ + + template <typename I, typename P, typename N> + inline + complex_neighborhood_fwd_piter<I, P, N>::complex_neighborhood_fwd_piter() + { + } + + template <typename I, typename P, typename N> + template <typename Pref> + inline + complex_neighborhood_fwd_piter<I, P, N>::complex_neighborhood_fwd_piter(const Neighborhood<N>& nbh, + const Pref& p_ref) + { + this->change_target(exact(nbh)); + center_at(p_ref); + mln_postcondition(!this->is_valid()); + } + + template <typename I, typename P, typename N> + inline + bool + complex_neighborhood_fwd_piter<I, P, N>::is_valid_() const + { + return iter_.is_valid(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_fwd_piter<I, P, N>::invalidate_() + { + iter_.invalidate(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_fwd_piter<I, P, N>::do_start_() + { + iter_.start(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_fwd_piter<I, P, N>::do_next_() + { + iter_.next(); + } + + template <typename I, typename P, typename N> + template <typename Pref> + inline + void + complex_neighborhood_fwd_piter<I, P, N>::center_at(const Pref& c) + { + super_::center_at(c); + iter_.center_at(this->center().face()); + } + + template <typename I, typename P, typename N> + inline + mln_psite(N) + complex_neighborhood_fwd_piter<I, P, N>::compute_p_() const + { + return psite(this->center().site_set(), iter_); + } + + + template <typename I, typename P, typename N> + inline + std::ostream& + operator<<(std::ostream& ostr, + const complex_neighborhood_fwd_piter<I, P, N>& p) + { + return ostr << p.unproxy_(); + } + + + /*------------------------------------------. + | complex_neighborhood_bkd_piter<I, P, N>. | + `------------------------------------------*/ + + template <typename I, typename P, typename N> + inline + complex_neighborhood_bkd_piter<I, P, N>::complex_neighborhood_bkd_piter() + { + } + + template <typename I, typename P, typename N> + template <typename Pref> + inline + complex_neighborhood_bkd_piter<I, P, N>::complex_neighborhood_bkd_piter(const Neighborhood<N>& nbh, + const Pref& p_ref) + { + this->change_target(exact(nbh)); + center_at(p_ref); + mln_postcondition(!this->is_valid()); + } + + template <typename I, typename P, typename N> + inline + bool + complex_neighborhood_bkd_piter<I, P, N>::is_valid_() const + { + return iter_.is_valid(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_bkd_piter<I, P, N>::invalidate_() + { + iter_.invalidate(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_bkd_piter<I, P, N>::do_start_() + { + iter_.start(); + } + + template <typename I, typename P, typename N> + inline + void + complex_neighborhood_bkd_piter<I, P, N>::do_next_() + { + iter_.next(); + } + + template <typename I, typename P, typename N> + template <typename Pref> + inline + void + complex_neighborhood_bkd_piter<I, P, N>::center_at(const Pref& c) + { + super_::center_at(c); + iter_.center_at(this->center().face()); + } + + template <typename I, typename P, typename N> + inline + mln_psite(N) + complex_neighborhood_bkd_piter<I, P, N>::compute_p_() const + { + return psite(this->center().site_set(), iter_); + } + + + template <typename I, typename P, typename N> + inline + std::ostream& + operator<<(std::ostream& ostr, + const complex_neighborhood_bkd_piter<I, P, N>& p) + { + return ostr << p.unproxy_(); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH diff --git a/milena/tests/core/image/complex_image.cc b/milena/tests/core/image/complex_image.cc index 8ac6b4f..76f55db 100644 --- a/milena/tests/core/image/complex_image.cc +++ b/milena/tests/core/image/complex_image.cc @@ -36,6 +36,11 @@ #include <mln/core/site_set/p_faces.hh> #include <mln/core/image/complex_image.hh> +// FIXME: Include these elsewhere? (In complex_image.hh?) +#include <mln/core/image/complex_lower_neighborhood.hh> +#include <mln/core/image/complex_higher_neighborhood.hh> +#include <mln/core/image/complex_neighborhood_piter.hh> + int main() { @@ -196,6 +201,50 @@ int main() // Iterators on windows and neighborhoods. // // ---------------------------------------- // + // FIXME: Factor: these two test cases only differ by their neighborhood. + + // Iterate on the lower-dimension faces of each face. + { + typedef complex_lower_neighborhood<D, P> nbh_t; + nbh_t nbh; + mln_fwd_niter_(nbh_t) fn(nbh, fp); + mln_bkd_niter_(nbh_t) bn(nbh, fp); + for_all(fp) + { + std::cout << "Lower-dimension faces adjacent to " << fp << std::endl; + for_all_2(fn, bn) + { + mln_assertion((fn.center() == + static_cast<const complex_psite<D, P>&>(fp))); + mln_assertion((bn.center() == + static_cast<const complex_psite<D, P>&>(fp))); + std::cout << " " << fn << '\t' << bn << std::endl; + } + } + std::cout << std::endl; + } + + // Iterate on the higher-dimension faces of each face. + { + typedef complex_higher_neighborhood<D, P> nbh_t; + nbh_t nbh; + mln_fwd_niter_(nbh_t) fn(nbh, fp); + mln_bkd_niter_(nbh_t) bn(nbh, fp); + for_all(fp) + { + std::cout << "Higher-dimension faces adjacent to " << fp << std::endl; + for_all_2(fn, bn) + { + mln_assertion((fn.center() == + static_cast<const complex_psite<D, P>&>(fp))); + mln_assertion((bn.center() == + static_cast<const complex_psite<D, P>&>(fp))); + std::cout << " " << fn << '\t' << bn << std::endl; + } + } + std::cout << std::endl; + } + /* FIXME: Implement windows (and neighborhoods) and corresponding iterators for complex-based images. -- 1.6.0.1