
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make neighborhoods based on windows work. * sandbox/geraud/cs2d/tuto_bis.cc: Rename as... * doc/examples/tuto_bis.cc: ...this. De-activate code. Start with new material. * mln/core/window.hh (is_symmetric): Fix the use of sym. * mln/core/neighb.hh (neighb_fwd_niter, neighb_bkd_niter): New. (fwd_niter, bkd_niter, niter): Update. (change_window): New. (from_to_): New overload. * mln/core/concept/window.hh (operator==): Split decl and def. * mln/core/concept/neighborhood.hh (to_window): Relax sig. * mln/make/dual_neighb2d.hh: New. * mln/convert/to_p_set.hh (D): Remove useless typedef. * mln/win/multiple.hh (is_centered, is_symmetrical): New. doc/examples/tuto_bis.cc | 96 ++++++++++++++- mln/convert/to_p_set.hh | 3 mln/core/concept/neighborhood.hh | 5 mln/core/concept/window.hh | 13 +- mln/core/neighb.hh | 237 ++++++++++++++++++++++++++++++++++++++- mln/core/window.hh | 3 mln/make/dual_neighb2d.hh | 80 +++++++++++++ mln/win/multiple.hh | 28 ++++ 8 files changed, 442 insertions(+), 23 deletions(-) Index: doc/examples/tuto_bis.cc --- doc/examples/tuto_bis.cc (revision 2268) +++ doc/examples/tuto_bis.cc (working copy) @@ -1,9 +1,20 @@ # include <vector> +# include <mln/core/var.hh> + +# include <mln/core/alias/point2d.hh> +# include <mln/core/alias/window2d.hh> +# include <mln/make/win_multiple.hh> +# include <mln/convert/to.hh> +# include <mln/make/dual_neighb2d.hh> +# include <mln/literal/origin.hh> +# include <mln/core/site_set/p_set.hh> + + +/* # include <mln/core/image/image2d.hh> # include <mln/core/image/sub_image.hh> # include <mln/core/image/image_if.hh> -# include <mln/core/image_if_value.hh> # include <mln/core/alias/neighb2d.hh> # include <mln/core/alias/window2d.hh> @@ -21,13 +32,14 @@ # include <mln/level/transform.hh> # include <mln/accu/mean.hh> -# include "dbl_neighb.hh" +*/ +/* + namespace mln { - namespace level { @@ -117,19 +129,50 @@ } is_point; +*/ + - struct is_row_odd_t +namespace mln { - bool operator()(const mln::point2d& p) const + + template <typename W, typename S> + void convert_to_site_set(const Window<W>& win, + const mln_psite(W)& p, + Site_Set<S>& s_) { - return p.row() % 2; + std::cout << "win -> pset" << std::endl; + + S& s = exact(s_); + s.clear(); + + mln_qiter(W) q(exact(win), p); + for_all(q) + exact(s).insert(q); } - } is_row_odd; -#define mln_VAR(Var, Expr) \ -typeof(Expr) Var = Expr; + template <typename N, typename S> + void convert_to_site_set(const Neighborhood<N>& nbh, + const mln_psite(N)& p, + Site_Set<S>& s_) + { + S& s = exact(s_); + s.clear(); + + mln_niter(N) n(exact(nbh), p); + for_all(n) + exact(s).insert(n); + } + +} + + + + bool is_row_odd(const mln::point2d& p) + { + return p.row() % 2; + } @@ -137,6 +180,39 @@ { using namespace mln; + // e2c + + bool e2c_h[] = { 0, 1, 0, + 0, 0, 0, + 0, 1, 0 }; + + bool e2c_v[] = { 0, 0, 0, + 1, 0, 1, + 0, 0, 0 }; + + mln_VAR( e2c, make::dual_neighb2d(is_row_odd, e2c_h, e2c_v) ); + +// p_set<point2d> s; +// convert_to_site_set(e2c, literal::origin, s); +// std::cout << s << std::endl; + + bool e2e_h[] = { 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0 }; + + bool e2e_v[] = { 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0 }; + + mln_VAR( e2e, make::dual_neighb2d(is_row_odd, e2e_h, e2e_v) ); + + + /* + window2d c4 = convert::to_window(mln::c4()); @@ -274,4 +350,6 @@ // 5 5 5 // DONE! + + */ } Index: mln/core/window.hh --- mln/core/window.hh (revision 2277) +++ mln/core/window.hh (working copy) @@ -186,7 +186,8 @@ window<D>::is_symmetric() const { window<D> cpy = *this; - return cpy.sym() == *this; + cpy.sym(); + return cpy == *this; } template <typename D> Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2277) +++ mln/core/neighb.hh (working copy) @@ -39,24 +39,30 @@ namespace mln { + // Forward declaration. + template <typename W> class neighb_fwd_niter; + template <typename W> class neighb_bkd_niter; /*! \brief Adapter class from window to neighborhood. */ template <typename W> - class neighb : public internal::neighborhood_base< mln_dpsite(W), neighb<D> >, + class neighb : public internal::neighborhood_base< mln_dpsite(W), neighb<W> >, private mlc_is_a(W, Window)::check_t { public: + typedef W window; + const W& to_window() const { return win_; } + /// Forward site iterator associated type. - typedef mln_fwd_qiter(W) fwd_niter; + typedef neighb_fwd_niter<W> fwd_niter; /// Backward site iterator associated type. - typedef mln_bkd_qiter(W) bkd_niter; + typedef neighb_bkd_niter<W> bkd_niter; /// Site iterator associated type. - typedef mln_qiter(W) niter; + typedef fwd_niter niter; /// Constructor without argument. @@ -68,6 +74,9 @@ /// Get the corresponding window. const W& win() const; + /// Change the corresponding window. + void change_window(const W& new_win); + private: W win_; }; @@ -83,14 +92,94 @@ void from_to_(const mln::neighb<W>& from, W& to); + template <typename W> + void + from_to_(const W& from, mln::neighb<W>& to); + } // end of namespace convert::impl } // end of namespace convert + // neighb_fwd_niter<W> + + template <typename W> + class neighb_fwd_niter + : public internal::site_relative_iterator_base< neighb<W>, + neighb_fwd_niter<W> > + { + public: + + /// Constructor without argument. + neighb_fwd_niter(); + + template <typename P> + neighb_fwd_niter(const neighb<W>& nbh, const P& c); + + /// Test the iterator validity. + bool is_valid_() const; + + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void do_start_(); + + /// Go to the next point. + void do_next_(); + + /// Compute the current psite. + mln_psite(W) compute_p_() const; + + protected: + + mln_fwd_qiter(W) i_; + }; + + + + // neighb_bkd_niter<W> + + template <typename W> + class neighb_bkd_niter + : public internal::site_relative_iterator_base< neighb<W>, + neighb_bkd_niter<W> > + { + public: + + /// Constructor without argument. + neighb_bkd_niter(); + + template <typename P> + neighb_bkd_niter(const neighb<W>& nbh, const P& c); + + /// Test the iterator validity. + bool is_valid_() const; + + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void do_start_(); + + /// Go to the next point. + void do_next_(); + + /// Compute the current psite. + mln_psite(W) compute_p_() const; + + protected: + + mln_bkd_qiter(W) i_; + }; + + + # ifndef MLN_INCLUDE_ONLY + // neighb<W> + template <typename W> inline neighb<W>::neighb() @@ -101,8 +190,7 @@ inline neighb<W>::neighb(const W& win) { - mln_precondition(win.is_neighbable_()); - win_ = win; + change_window(win); } template <typename W> @@ -113,6 +201,17 @@ return win_; } + template <typename W> + inline + void + neighb<W>::change_window(const W& new_win) + { + mln_precondition(new_win.is_neighbable_()); + win_ = new_win; + } + + + // convert::impl::from_to_ namespace convert { @@ -126,11 +225,137 @@ to = from.win(); } + template <typename W> + void + from_to_(const W& from, mln::neighb<W>& to) + { + to.change_window(from); + } + } // end of namespace convert::impl } // end of namespace convert + // neighb_fwd_niter<W> + + template <typename W> + inline + neighb_fwd_niter<W>::neighb_fwd_niter() + { + } + + template <typename W> + template <typename P> + inline + neighb_fwd_niter<W>::neighb_fwd_niter(const neighb<W>& nbh, const P& c) + { + this->change_target(nbh); + this->center_at(c); + i_.center_at(c); // Always before change_target for this kind of iter. + i_.change_target(nbh.to_window()); + } + + template <typename W> + inline + bool + neighb_fwd_niter<W>::is_valid_() const + { + return i_.is_valid(); + } + + template <typename W> + inline + void + neighb_fwd_niter<W>::invalidate_() + { + i_.invalidate(); + } + + template <typename W> + inline + void + neighb_fwd_niter<W>::do_start_() + { + i_.start(); + } + + template <typename W> + inline + void + neighb_fwd_niter<W>::do_next_() + { + i_.next(); + } + + template <typename W> + inline + mln_psite(W) + neighb_fwd_niter<W>::compute_p_() const + { + return i_.compute_p_(); + } + + + // neighb_bkd_niter<W> + + template <typename W> + inline + neighb_bkd_niter<W>::neighb_bkd_niter() + { + } + + template <typename W> + template <typename P> + inline + neighb_bkd_niter<W>::neighb_bkd_niter(const neighb<W>& nbh, const P& c) + { + this->change_target(nbh); + this->center_at(c); + i_.center_at(c); // Always before change_target for this kind of iter. + i_.change_target(nbh.to_window()); + } + + template <typename W> + inline + bool + neighb_bkd_niter<W>::is_valid_() const + { + return i_.is_valid(); + } + + template <typename W> + inline + void + neighb_bkd_niter<W>::invalidate_() + { + i_.invalidate(); + } + + template <typename W> + inline + void + neighb_bkd_niter<W>::do_start_() + { + i_.start(); + } + + template <typename W> + inline + void + neighb_bkd_niter<W>::do_next_() + { + i_.next(); + } + + template <typename W> + inline + mln_psite(W) + neighb_bkd_niter<W>::compute_p_() const + { + return i_.compute_p_(); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/window.hh --- mln/core/concept/window.hh (revision 2277) +++ mln/core/concept/window.hh (working copy) @@ -79,10 +79,8 @@ template <typename Wl, typename Wr> - bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs) - { - return exact(lhs).std_vector() == exact(rhs).std_vector(); - } + bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs); + # ifndef MLN_INCLUDE_ONLY @@ -100,6 +98,13 @@ typedef mln_bkd_qiter(E) bkd_qiter; } + template <typename Wl, typename Wr> + inline + bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs) + { + return exact(lhs).std_vector() == exact(rhs).std_vector(); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/neighborhood.hh --- mln/core/concept/neighborhood.hh (revision 2277) +++ mln/core/concept/neighborhood.hh (working copy) @@ -73,6 +73,7 @@ }; + # ifndef MLN_INCLUDE_ONLY template <typename E> @@ -84,8 +85,10 @@ typedef mln_bkd_niter(E) bkd_niter; typedef mln_window(E) window; - window (E::*m)() const = & E::to_window; + bool m = (& E::to_window) == (& E::to_window); m = 0; +// const window& (E::*m)() const = & E::to_window; +// m = 0; } # endif // ! MLN_INCLUDE_ONLY Index: mln/make/dual_neighb2d.hh --- mln/make/dual_neighb2d.hh (revision 0) +++ mln/make/dual_neighb2d.hh (revision 0) @@ -0,0 +1,80 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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_MAKE_DUAL_NEIGHB2D_HH +# define MLN_MAKE_DUAL_NEIGHB2D_HH + +/*! \file mln/make/dual_neighb2d.hh + * + * \brief Routine to create a dual neighborhood. + */ + +# include <mln/core/alias/window2d.hh> +# include <mln/win/multiple.hh> +# include <mln/core/neighb.hh> + + +namespace mln +{ + + namespace make + { + + template <typename A, unsigned St, unsigned Sf> + neighb< win::multiple<window2d, bool(*)(A)> > + dual_neighb2d(bool (*test)(A), + bool const (&when_true) [St], + bool const (&when_false)[Sf]); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename A, unsigned St, unsigned Sf> + inline + neighb< win::multiple<window2d, bool(*)(A)> > + dual_neighb2d(bool (*test)(A), + bool const (&when_true) [St], + bool const (&when_false)[Sf]) + { + typedef win::multiple<window2d, bool(*)(A)> W; + W wm(test); + wm.set_window(false, convert::to<window2d>(when_false)); // 0 + wm.set_window(true, convert::to<window2d>(when_true) ); // 1 + neighb<W> tmp(wm); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::make + +} // end of namespace mln + + +#endif // ! MLN_MAKE_DUAL_NEIGHB2D_HH Index: mln/convert/to_p_set.hh --- mln/convert/to_p_set.hh (revision 2277) +++ mln/convert/to_p_set.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -112,7 +112,6 @@ inline p_set<mln_site(W)> to_p_set(const Window<W>& win) { - typedef mln_dpsite(W) D; typedef mln_site(W) P; p_set<P> pset; mln_qiter(W) q(exact(win), P::origin); Index: mln/win/multiple.hh --- mln/win/multiple.hh (revision 2277) +++ mln/win/multiple.hh (working copy) @@ -78,6 +78,10 @@ const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const; + bool is_centered() const; + + bool is_symmetric() const; + private: util::array<W> win_; @@ -179,6 +183,30 @@ template <typename W, typename F> inline + bool + multiple<W,F>::is_centered() const + { + mln_precondition(win_.nelements() >= 1); + for (unsigned i = 0; i < win_.nelements(); ++i) + if (! win_[i].is_centered()) + return false; + return true; + } + + template <typename W, typename F> + inline + bool + multiple<W,F>::is_symmetric() const + { + mln_precondition(win_.nelements() >= 1); + for (unsigned i = 0; i < win_.nelements(); ++i) + if (! win_[i].is_symmetric()) + return false; + return true; + } + + template <typename W, typename F> + inline unsigned multiple<W,F>::size_around(const mln_psite(W)& p) const {