Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
October 2008
- 14 participants
 - 373 discussions
 
01 Oct '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Some completion work on window and neighborhood.
	* mln/core/neighb.hh (dp): New.
	(operator<<): Move to...
	* mln/core/concept/neighborhood.hh: ...here.
	Generalize it.
	* mln/core/concept/window.hh (todo): Done.
	* mln/win/multiple.hh (delta, sym): New methods.
 core/concept/neighborhood.hh |   17 +++++++++++++++++
 core/concept/window.hh       |    4 +---
 core/neighb.hh               |   31 ++++++++++++++++++++++++-------
 win/multiple.hh              |   31 +++++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+), 10 deletions(-)
Index: mln/core/neighb.hh
--- mln/core/neighb.hh	(revision 2463)
+++ mln/core/neighb.hh	(working copy)
@@ -97,6 +97,12 @@
     /// center and a neighboring point.
     unsigned delta() const;
 
+    /// Give the maximum coordinate gap between the neighborhood
+    /// center and a neighboring point.
+    const mln_dpsite(W)& dp(unsigned i) const;
+
+    // end of Optional methods.
+
 
     /// \internal Hook to the window.
     W& hook_win_();
@@ -106,13 +112,6 @@
   };
 
 
-  template <typename W>
-  inline
-  std::ostream& operator<<(std::ostream&ostr, const neighb<W>& nbh)
-  {
-    return ostr << nbh.win();
-  }
-
 
   namespace convert
   {
@@ -242,6 +241,8 @@
   unsigned
   neighb<W>::size() const
   {
+    mlc_is(mln_trait_window_size(W),
+	   trait::window::size::fixed)::check(); 
     return win_.size();
   }
 
@@ -250,11 +251,27 @@
   unsigned
   neighb<W>::delta() const
   {
+    mlc_is(mln_trait_window_support(W),
+	   trait::window::support::regular)::check();
+    mlc_is_not(mln_trait_window_definition(W),
+	       trait::window::definition::varying)::check();
     return win_.delta();
   }
 
   template <typename W>
   inline
+  const mln_dpsite(W)&
+  neighb<W>::dp(unsigned i) const
+  {
+    mlc_is(mln_trait_window_support(W),
+	   trait::window::support::regular)::check();
+    mlc_is(mln_trait_window_definition(W),
+	   trait::window::definition::unique)::check();
+    return win_.dp(i);
+  }
+
+  template <typename W>
+  inline
   W&
   neighb<W>::hook_win_()
   {
Index: mln/core/concept/neighborhood.hh
--- mln/core/concept/neighborhood.hh	(revision 2463)
+++ mln/core/concept/neighborhood.hh	(working copy)
@@ -78,6 +78,13 @@
 
 
 
+
+  template <typename N>
+  std::ostream&
+  operator<<(std::ostream&ostr, const Neighborhood<N>& nbh);
+
+
+
 # ifndef MLN_INCLUDE_ONLY
 
   template <typename E>
@@ -100,6 +107,16 @@
 # endif
   }
 
+
+
+  template <typename N>
+  inline
+  std::ostream&
+  operator<<(std::ostream&ostr, const Neighborhood<N>& nbh)
+  {
+    return ostr << exact(nbh).win();
+  }
+
 # endif // ! MLN_INCLUDE_ONLY
 
 } // end of namespace mln
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh	(revision 2463)
+++ mln/core/concept/window.hh	(working copy)
@@ -32,8 +32,6 @@
  * \brief Definition of the concept of mln::Window.
  *
  * \todo Operator== should test if the cmp is possible.
- *
- * \todo Activate run_extra() below.
  */
 
 # include <mln/core/concept/object.hh>
@@ -163,7 +161,7 @@
       }
       static void run(mln::trait::window::definition::n_ary)
       {
-	// run_extra();
+	run_extra();
       }
       static void run(mln::trait::window::definition::varying)
       {
Index: mln/win/multiple.hh
--- mln/win/multiple.hh	(revision 2463)
+++ mln/win/multiple.hh	(working copy)
@@ -110,6 +110,10 @@
 
       bool is_symmetric() const;
 
+      void sym();
+
+      unsigned delta() const;
+
     private:
 
       util::array<W> win_;
@@ -250,6 +254,33 @@
       return true;
     }
 
+
+    template <typename W, typename F>
+    inline
+    void
+    multiple<W,F>::sym()
+    {
+      mln_precondition(win_.nelements() >= 1);
+      for (unsigned i = 0; i < win_.nelements(); ++i)
+	win_[i].sym();
+    }
+
+    template <typename W, typename F>
+    inline
+    unsigned
+    multiple<W,F>::delta() const
+    {
+      mln_precondition(win_.nelements() >= 1);
+      unsigned d = win_[0].delta();
+      for (unsigned i = 1; i < win_.nelements(); ++i)
+	{
+	  unsigned d_i = win_[i].delta();
+	  if (d_i > d)
+	    d = d_i;
+	}
+      return d;
+    }
+
 //     template <typename W, typename F>
 //     inline
 //     unsigned
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '08
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
ChangeLog:
2008-10-01  Matthieu Garrigues  <garrigues(a)lrde.epita.fr>
	Add a generic snake browsing with some examples.
	* mln/canvas/browsing/snake_generic.hh: New, generic snake. Works on
	any dimension and follows the dimensions in any order.
	* tests/canvas/browsing/snake_generic_2d_hori.cc: New,
	* tests/canvas/browsing/snake_generic_2d_vert.cc: New,
	* tests/canvas/browsing/snake_generic_3d_hori.cc: New,
	* tests/canvas/browsing/snake_generic_3d_vert.cc: New, examples
	* mln/canvas/browsing/directional.hh: Documentation.
---
 mln/canvas/browsing/directional.hh             |   15 ++
 mln/canvas/browsing/snake_generic.hh           |  163 +++++++++++++++++++++++++
 tests/canvas/browsing/snake_generic_2d_hori.cc |  106 ++++++++++++++++
 tests/canvas/browsing/snake_generic_2d_vert.cc |  106 ++++++++++++++++
 tests/canvas/browsing/snake_generic_3d_hori.cc |  114 +++++++++++++++++
 tests/canvas/browsing/snake_generic_3d_vert.cc |  114 +++++++++++++++++
 6 files changed, 618 insertions(+)
Index: branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_vert.cc
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_vert.cc	(revision 0)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_vert.cc	(revision 2463)
@@ -0,0 +1,106 @@
+// 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
+// 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.
+
+/*! \file tests/canvas/browsing/snake_generic_2d_vert.cc
+ *
+ * \brief Tests on mln::canvas::browsing::snake_generic.
+ */
+
+#include <mln/core/image/image2d.hh>
+#include <mln/canvas/browsing/snake_generic.hh>
+#include <mln/fun/p2v/iota.hh>
+#include <mln/debug/println.hh>
+
+template <typename I, typename F>
+struct assign_browsing_functor
+{
+  enum { dim = I::site::dim };
+
+  typedef assign_browsing_functor<I, F> self;
+  typedef mln_deduce(I, psite, delta) dpsite;
+  typedef void (assign_browsing_functor<I,F>::*move_fun)();
+
+  I input;
+  F f;
+  std::vector<move_fun> moves;
+  std::vector<dpsite> dps;
+
+  assign_browsing_functor(I& input, F f = F())
+    : input(input),
+      f(f),
+      moves(3),
+      dps(3)
+  {
+    dps[0] = dpsite(0, 1);
+    dps[1] = dpsite(1, 0);
+    dps[2] = dpsite(-1, 0);
+    moves[0] = &self::fwd;
+    moves[1] = &self::down;
+    moves[2] = &self::up;
+  }
+
+  mln_psite(I) p;
+
+  void init()  {}
+  void final() {}
+  void next()
+  {
+    input(p) = f(p);
+  }
+  void fwd()  { std::cout << "fwd" << std::endl; next(); }
+  void up()  { std::cout << "up" << std::endl; next(); }
+  void down() { std::cout << "down" << std::endl; next(); }
+};
+
+namespace mln
+{
+
+  template <typename I, typename F, typename B>
+  void my_test(Image<I>& ima_,
+	       const Function_p2v<F>& f_,
+	       const Browsing<B>& browse_)
+  {
+    I& ima = exact(ima_);
+    const F& f = exact(f_);
+    const B& browse = exact(browse_);
+
+    assign_browsing_functor<I, F> fun(ima, f);
+    browse(fun);
+  }
+
+}
+
+
+int main()
+{
+  using namespace mln;
+  image2d<unsigned> ima2(3, 3);
+
+  std::cout << ima2.bbox() << std::endl;
+  my_test(ima2, fun::p2v::iota, canvas::browsing::snake_generic);
+  debug::println(ima2);
+}
Index: branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_hori.cc
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_hori.cc	(revision 0)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_2d_hori.cc	(revision 2463)
@@ -0,0 +1,106 @@
+// 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
+// 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.
+
+/*! \file tests/canvas/browsing/snake_generic_3d_hori.cc
+ *
+ * \brief Tests on mln::canvas::browsing::snake_generic.
+ */
+
+#include <mln/core/image/image2d.hh>
+#include <mln/canvas/browsing/snake_generic.hh>
+#include <mln/fun/p2v/iota.hh>
+#include <mln/debug/println.hh>
+
+template <typename I, typename F>
+struct assign_browsing_functor
+{
+  enum { dim = I::site::dim };
+
+  typedef assign_browsing_functor<I, F> self;
+  typedef mln_deduce(I, psite, delta) dpsite;
+  typedef void (assign_browsing_functor<I,F>::*move_fun)();
+
+  I input;
+  F f;
+  std::vector<move_fun> moves;
+  std::vector<dpsite> dps;
+
+  assign_browsing_functor(I& input, F f = F())
+    : input(input),
+      f(f),
+      moves(3),
+      dps(3)
+  {
+    dps[0] = dpsite(1, 0);
+    dps[1] = dpsite(0, 1);
+    dps[2] = dpsite(0, -1);
+    moves[0] = &self::down;
+    moves[1] = &self::fwd;
+    moves[2] = &self::bkd;
+  }
+
+  mln_psite(I) p;
+
+  void init()  {}
+  void final() {}
+  void next()
+  {
+    input(p) = f(p);
+  }
+  void fwd()  { std::cout << "fwd" << std::endl; next(); }
+  void bkd()  { std::cout << "bkd" << std::endl; next(); }
+  void down() { std::cout << "down" << std::endl; next(); }
+};
+
+namespace mln
+{
+
+  template <typename I, typename F, typename B>
+  void my_test(Image<I>& ima_,
+	       const Function_p2v<F>& f_,
+	       const Browsing<B>& browse_)
+  {
+    I& ima = exact(ima_);
+    const F& f = exact(f_);
+    const B& browse = exact(browse_);
+
+    assign_browsing_functor<I, F> fun(ima, f);
+    browse(fun);
+  }
+
+}
+
+
+int main()
+{
+  using namespace mln;
+  image2d<unsigned> ima2(3, 3);
+
+  std::cout << ima2.bbox() << std::endl;
+  my_test(ima2, fun::p2v::iota, canvas::browsing::snake_generic);
+  debug::println(ima2);
+}
Index: branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_vert.cc
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_vert.cc	(revision 0)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_vert.cc	(revision 2463)
@@ -0,0 +1,114 @@
+// 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
+// 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.
+
+/*! \file tests/canvas/browsing/snake_generic_3d_vert.cc
+ *
+ * \brief Tests on mln::canvas::browsing::snake_generic.
+ */
+
+#include <mln/core/image/image3d.hh>
+#include <mln/canvas/browsing/snake_generic.hh>
+#include <mln/fun/p2v/iota.hh>
+#include <mln/debug/println.hh>
+
+template <typename I, typename F>
+struct assign_browsing_functor
+{
+  enum { dim = I::site::dim };
+
+  typedef assign_browsing_functor<I, F> self;
+  typedef mln_deduce(I, psite, delta) dpsite;
+  typedef void (assign_browsing_functor<I,F>::*move_fun)();
+
+  I input;
+  F f;
+  std::vector<move_fun> moves;
+  std::vector<dpsite> dps;
+
+  assign_browsing_functor(I& input, F f = F())
+    : input(input),
+      f(f),
+      moves(5),
+      dps(5)
+  {
+    dps[0] = dpsite(0, 0, 1);
+    dps[1] = dpsite(0, 1, 0);
+    dps[2] = dpsite(0, -1, 0);
+    dps[3] = dpsite(1, 0, 0);
+    dps[4] = dpsite(-1, 0, 0);
+
+    moves[0] = &self::thr;
+    moves[1] = &self::down;
+    moves[2] = &self::up;
+    moves[3] = &self::fwd;
+    moves[4] = &self::bkd;
+  }
+
+  mln_psite(I) p;
+
+  void init()  {}
+  void final() {}
+  void next()
+  {
+    input(p) = f(p);
+  }
+  void fwd()  { std::cout << "fwd" << std::endl; next(); }
+  void bkd()  { std::cout << "bkd" << std::endl; next(); }
+  void down() { std::cout << "down" << std::endl; next(); }
+  void up() { std::cout << "up" << std::endl; next(); }
+  void thr() { std::cout << "thr" << std::endl; next(); }
+};
+
+namespace mln
+{
+
+  template <typename I, typename F, typename B>
+  void my_test(Image<I>& ima_,
+	       const Function_p2v<F>& f_,
+	       const Browsing<B>& browse_)
+  {
+    I& ima = exact(ima_);
+    const F& f = exact(f_);
+    const B& browse = exact(browse_);
+
+    assign_browsing_functor<I, F> fun(ima, f);
+    browse(fun);
+  }
+
+}
+
+
+int main()
+{
+  using namespace mln;
+  image3d<unsigned> ima(3, 3, 3);
+
+  ima(point3d(0,0,0)) = 42;
+  std::cout << ima.bbox() << std::endl;
+  my_test(ima, fun::p2v::iota, canvas::browsing::snake_generic);
+  debug::println(ima);
+}
Index: branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_hori.cc
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_hori.cc	(revision 0)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/snake_generic_3d_hori.cc	(revision 2463)
@@ -0,0 +1,114 @@
+// 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
+// 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.
+
+/*! \file tests/canvas/browsing/snake_generic_3d_hori.cc
+ *
+ * \brief Tests on mln::canvas::browsing::snake_generic.
+ */
+
+#include <mln/core/image/image3d.hh>
+#include <mln/canvas/browsing/snake_generic.hh>
+#include <mln/fun/p2v/iota.hh>
+#include <mln/debug/println.hh>
+
+template <typename I, typename F>
+struct assign_browsing_functor
+{
+  enum { dim = I::site::dim };
+
+  typedef assign_browsing_functor<I, F> self;
+  typedef mln_deduce(I, psite, delta) dpsite;
+  typedef void (assign_browsing_functor<I,F>::*move_fun)();
+
+  I input;
+  F f;
+  std::vector<move_fun> moves;
+  std::vector<dpsite> dps;
+
+  assign_browsing_functor(I& input, F f = F())
+    : input(input),
+      f(f),
+      moves(5),
+      dps(5)
+  {
+    dps[0] = dpsite(1, 0, 0);
+    dps[1] = dpsite(0, 1, 0);
+    dps[2] = dpsite(0, -1, 0);
+    dps[3] = dpsite(0, 0, 1);
+    dps[4] = dpsite(0, 0, -1);
+
+    moves[0] = &self::thr;
+    moves[1] = &self::down;
+    moves[2] = &self::up;
+    moves[3] = &self::fwd;
+    moves[4] = &self::bkd;
+  }
+
+  mln_psite(I) p;
+
+  void init()  {}
+  void final() {}
+  void next()
+  {
+    input(p) = f(p);
+  }
+  void fwd()  { std::cout << "fwd" << std::endl; next(); }
+  void bkd()  { std::cout << "bkd" << std::endl; next(); }
+  void down() { std::cout << "down" << std::endl; next(); }
+  void up() { std::cout << "up" << std::endl; next(); }
+  void thr() { std::cout << "thr" << std::endl; next(); }
+};
+
+namespace mln
+{
+
+  template <typename I, typename F, typename B>
+  void my_test(Image<I>& ima_,
+	       const Function_p2v<F>& f_,
+	       const Browsing<B>& browse_)
+  {
+    I& ima = exact(ima_);
+    const F& f = exact(f_);
+    const B& browse = exact(browse_);
+
+    assign_browsing_functor<I, F> fun(ima, f);
+    browse(fun);
+  }
+
+}
+
+
+int main()
+{
+  using namespace mln;
+  image3d<unsigned> ima(3, 3, 3);
+
+  ima(point3d(0,0,0)) = 42;
+  std::cout << ima.bbox() << std::endl;
+  my_test(ima, fun::p2v::iota, canvas::browsing::snake_generic);
+  debug::println(ima);
+}
Index: branches/cleanup-2008/milena/mln/canvas/browsing/directional.hh
===================================================================
--- branches/cleanup-2008/milena/mln/canvas/browsing/directional.hh	(revision 2462)
+++ branches/cleanup-2008/milena/mln/canvas/browsing/directional.hh	(revision 2463)
@@ -74,6 +74,21 @@
        *   void final(); \n
        * } \n
        *
+       * Example : \n
+       *
+       *   1 0 0
+       *  2 0 0
+       * 3 0 0
+       *
+       *   4 0 0
+       *  5 0 0
+       * 6 0 0
+       *
+       *   7 0 0
+       *  8 0 0
+       * 9 0 0
+       *
+       *
        */
       struct directional_t : public Browsing< directional_t >
       {
Index: branches/cleanup-2008/milena/mln/canvas/browsing/snake_generic.hh
===================================================================
--- branches/cleanup-2008/milena/mln/canvas/browsing/snake_generic.hh	(revision 0)
+++ branches/cleanup-2008/milena/mln/canvas/browsing/snake_generic.hh	(revision 2463)
@@ -0,0 +1,163 @@
+// Copyright (C) 2007 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_CANVAS_BROWSING_SNAKE_GENERIC_HH
+# define MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
+
+/*! \file mln/canvas/browsing/snake_generic.hh
+ *
+ * \brief Browsing in a snake-way, forward.
+ */
+
+# include <stack>
+# include <mln/core/concept/browsing.hh>
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    namespace browsing
+    {
+
+      /*!
+       * \brief Multidimentional Browsing in a given-way.
+       *
+       * F shall feature: \n
+       * { \n
+       *   --- as attributes: \n
+       *   input; \n
+       *   p; \n
+       *   --- as methods: \n
+       *   void init(); \n
+       *   void *() moves[]; \n
+       *   dpsite dps[]; \n
+       * } \n
+       *
+       * init is called before browsing
+       *
+       * The snake follow dimension using the delta point site of dps.
+       *     dps[0] = delta psite following the global dimension (forward)
+       *     dps[1] = delta psite following the 2nd dimension to follow (forward).
+       *     dps[2] = delta psite following the 2nd dimension to follow (backward).
+       *     dps[3] = delta psite following the 3nd dimension to follow (forward).
+       *     dps[3] = delta psite following the 3nd dimension to follow (backward).
+       *
+       * moves contains pointer to f's members. These merbers will be call in each time
+       * the snake progress in the correct dimension :
+       *
+       *      moves[i] is called at each move following the delta psite dps[i]
+       *
+       */
+
+      struct snake_generic_t : public Browsing< snake_generic_t >
+      {
+
+	template <typename F>
+	void operator()(F& f) const;
+      }
+
+      snake_generic;
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+      template <typename F>
+      inline
+      void
+      snake_generic_t::operator()(F& f) const
+      {
+	trace::entering("canvas::browsing::snake_generic");
+	mln_precondition(f.input.has_data());
+
+	// p init
+ 	f.p = f.input.bbox().pmin();// - f.dps[0];
+
+	std::vector< int > directions(f.moves.size(), 0);
+	unsigned deph = 0;
+	unsigned total_deph = f.moves.size() / 2 + 1;
+
+	// initialization
+	trace::entering("canvas::browsing::snake_generic::init");
+	f.init();
+	trace::exiting("canvas::browsing::snake_generic::init");
+
+	bool first = true;
+	directions[deph] = 1;
+	deph = total_deph - 1;
+
+	// Call the move function (for the first point)
+	(f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
+	while (deph > 0) // If direction is empty, break
+	{
+	  mln_assertion(deph <= total_deph);
+	  mln_assertion(deph > 0);
+	  // If f.p is near the border (we ended a direction) -> next child
+	  if (!f.input.domain().has(f.p +
+				    f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]]))
+	  {
+	    // Go up the tree
+	    deph--;
+	    if  (deph >= 1)
+	      // Change directions
+	      directions[deph] = directions[deph] == 1 ? 0 : 1;
+	    continue;
+	  }
+
+	  if (!first)
+	  {
+	    // Move f.p
+	    f.p += f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]];
+	    // Call the move function
+	    (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
+	  }
+	  else
+	    first = false;
+
+	  if (deph != total_deph)
+	  {
+	    // Go down the tree
+	    deph++;
+	    first = true;
+	  }
+	}
+
+	trace::exiting("canvas::browsing::snake_generic");
+      }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+    } // end of namespace mln::canvas::browsing
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Make the difference between geom and win materials.
	Move window-related routines from mln/geom to mln/win.
	* mln/geom/sym.hh: Move to...
	* mln/win/sym.hh: ...here.
	* mln/geom/shift.hh: Move to...
	* mln/win/shift.hh: ...here.
	* tests/geom/sym.cc: Move to...
	* tests/win/sym.cc: ...here and update.
	* tests/geom/shift.cc: Move to...
	* tests/win/shift.cc: ...here and update.
	* tests/geom/Makefile.am: Update.
	* mln/geom/all.hh: Update.
	* mln/win/all.hh: Update.
	Move window difference into mln/win.
	* mln/set/diff.hh (diff): Move overload on windows into...
	* mln/win/diff.hh: ...this new file.
	(diff): Rename as...
	(operator-): ...this and update.
	* tests/win/diff.cc: New.
	* tests/win/Makefile.am: Update.
	* tests/set/diff.cc: Update.
	Propagate those modifications.
	* tests/win/cuboid3d.cc,
	* tests/win/rectangle2d.cc,
	* tests/morpho/hit_or_miss.cc,
	* mln/core/alias/neighb1d.hh,
	* mln/core/alias/neighb3d.hh,
	* mln/core/neighb.hh,
	* mln/core/concept/window.hh,
	* mln/level/was.median.hh,
	* mln/level/median.hh,
	* mln/level/fast_median.hh,
	* mln/morpho/erosion_fast.hh,
	* mln/morpho/erosion.spe.hh,
	* mln/morpho/hit_or_miss.hh,
	* mln/morpho/closing.hh,
	* mln/morpho/opening.hh,
	* mln/morpho/includes.hh,
	* mln/morpho/dilation_fast.hh,
	* mln/canvas/chamfer.hh,
	* sandbox/duhamel/canvas_chamfer.hh,
	* sandbox/nivault/median.hh: Update.
 mln/canvas/chamfer.hh             |    4 -
 mln/core/alias/neighb1d.hh        |    1 
 mln/core/alias/neighb3d.hh        |    8 +-
 mln/core/concept/window.hh        |   19 ++++++
 mln/core/neighb.hh                |    3 -
 mln/geom/all.hh                   |    4 -
 mln/level/fast_median.hh          |   18 +++---
 mln/level/median.hh               |   17 +++---
 mln/level/was.median.hh           |   22 ++++----
 mln/morpho/closing.hh             |    2 
 mln/morpho/dilation_fast.hh       |   17 +++---
 mln/morpho/erosion.spe.hh         |   26 +++++----
 mln/morpho/erosion_fast.hh        |   19 +++---
 mln/morpho/hit_or_miss.hh         |    4 -
 mln/morpho/includes.hh            |    4 +
 mln/morpho/opening.hh             |    2 
 mln/set/diff.hh                   |   35 ------------
 mln/win/all.hh                    |    9 +++
 mln/win/diff.hh                   |  104 ++++++++++++++++++++++++++++++++++++++
 mln/win/shift.hh                  |    8 +-
 mln/win/sym.hh                    |   12 ++--
 sandbox/duhamel/canvas_chamfer.hh |    2 
 sandbox/nivault/median.hh         |    2 
 tests/geom/Makefile.am            |    6 --
 tests/morpho/hit_or_miss.cc       |    9 +--
 tests/set/diff.cc                 |   36 +------------
 tests/win/Makefile.am             |    6 ++
 tests/win/cuboid3d.cc             |    4 -
 tests/win/diff.cc                 |   66 +++++++-----------------
 tests/win/rectangle2d.cc          |    5 +
 tests/win/shift.cc                |    4 -
 tests/win/sym.cc                  |    4 -
 32 files changed, 272 insertions(+), 210 deletions(-)
Index: tests/geom/Makefile.am
--- tests/geom/Makefile.am	(revision 2461)
+++ tests/geom/Makefile.am	(working copy)
@@ -19,9 +19,7 @@
 pmin_pmax					\
 resize						\
 seed2tiling					\
-seed2tiling_roundness				\
-shift						\
-sym
+seed2tiling_roundness
 
 bbox_SOURCES = bbox.cc
 max_col_SOURCES = max_col.cc
@@ -40,7 +38,5 @@
 resize_SOURCES = resize.cc
 seed2tiling_SOURCES = seed2tiling.cc
 seed2tiling_roundness_SOURCES = seed2tiling_roundness.cc
-shift_SOURCES = shift.cc
-sym_SOURCES = sym.cc
 
 TESTS = $(check_PROGRAMS)
Index: tests/set/diff.cc
--- tests/set/diff.cc	(revision 2461)
+++ tests/set/diff.cc	(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
@@ -30,41 +30,15 @@
  * \brief Tests on mln::set::diff.
  */
 
-#include <mln/set/diff.hh>
+#include <mln/core/site_set/p_set.hh>
 #include <mln/core/alias/dpoint2d.hh>
+#include <mln/set/diff.hh>
+
 
 int main()
 {
   using namespace mln;
   
-  {
-    window<dpoint2d> win1;
-    win1.insert( 2, 7);
-    win1.insert( 2, 1);
-    win1.insert(-4, 0);
-    win1.insert( 0, 0);
-    win1.insert( 1, 1);
-    win1.insert( 6, 5);
-
-    window<dpoint2d> win2;
-    win2.insert( 2, 7);
-    win2.insert(-2, 1);
-    win2.insert(-4, 0);
-    win2.insert( 1,-1);
-    win2.insert( 6, 5);
-
-    window<dpoint2d> win3 = set::diff(win1, win2);
-    mln_assertion(win3.has(dpoint2d( 2, 1)));
-    mln_assertion(win3.has(dpoint2d( 0, 0)));
-    mln_assertion(win3.has(dpoint2d( 1, 1)));
-    mln_assertion(!win3.has(dpoint2d( 2, 7)));
-    mln_assertion(!win3.has(dpoint2d(-2, 1)));
-    mln_assertion(!win3.has(dpoint2d(-4, 0)));
-    mln_assertion(!win3.has(dpoint2d( 1,-1)));
-    mln_assertion(!win3.has(dpoint2d( 6, 5)));
-  }
-
-  {
     p_set<point2d> pst1;
     pst1.insert(point2d( 2, 7));
     pst1.insert(point2d( 2, 1));
@@ -81,6 +55,7 @@
     pst2.insert(point2d( 6, 5));
 
     p_set<point2d> pst3 = set::diff(pst1, pst2);
+
     mln_assertion(pst3.has(point2d( 2, 1)));
     mln_assertion(pst3.has(point2d( 0, 0)));
     mln_assertion(pst3.has(point2d( 1, 1)));
@@ -90,4 +65,3 @@
     mln_assertion(!pst3.has(point2d( 1,-1)));
     mln_assertion(!pst3.has(point2d( 6, 5)));
   }
-}
Index: tests/win/cuboid3d.cc
--- tests/win/cuboid3d.cc	(revision 2461)
+++ tests/win/cuboid3d.cc	(working copy)
@@ -32,7 +32,7 @@
 
 #include <cmath>
 #include <mln/win/cuboid3d.hh>
-#include <mln/geom/sym.hh>
+#include <mln/win/sym.hh>
 
 #include <mln/convert/to_image.hh>
 
@@ -47,7 +47,7 @@
 
   mln_assertion(cuboid.is_centered());
   mln_assertion(cuboid.is_symmetric());
-  mln_assertion(cuboid == geom::sym(cuboid));
+  mln_assertion(cuboid == win::sym(cuboid));
   mln_assertion(cuboid.size() == d * h * w);
 
   mln_assertion(cuboid.delta() == 3);
Index: tests/win/shift.cc
--- tests/win/shift.cc	(revision 2451)
+++ tests/win/shift.cc	(working copy)
@@ -28,7 +28,7 @@
 #include <mln/core/alias/window2d.hh>
 #include <mln/core/alias/dpoint2d.hh>
 
-#include <mln/geom/shift.hh>
+#include <mln/win/shift.hh>
 
 int main()
 {
@@ -50,5 +50,5 @@
   win2.insert(dpoint2d(7,8));
   win2.insert(dpoint2d(9,10));
 
-  mln_assertion(geom::shift(win, dp) == win2);
+  mln_assertion(win::shift(win, dp) == win2);
 }
Index: tests/win/Makefile.am
--- tests/win/Makefile.am	(revision 2461)
+++ tests/win/Makefile.am	(working copy)
@@ -7,22 +7,28 @@
   cube3d					\
   cuboid3d					\
   diag2d					\
+  diff						\
   disk2d					\
   hline2d					\
   octagon2d					\
   rectangle2d					\
   segment1d					\
+  shift						\
+  sym						\
   vline2d
 
 backdiag2d_SOURCES = backdiag2d.cc
 cube3d_SOURCES = cube3d.cc
 cuboid3d_SOURCES = cuboid3d.cc
 diag2d_SOURCES = diag2d.cc
+diff_SOURCES = diff.cc
 disk2d_SOURCES = disk2d.cc
 hline2d_SOURCES = hline2d.cc
 octagon2d_SOURCES = octagon2d.cc
 rectangle2d_SOURCES = rectangle2d.cc
 segment1d_SOURCES = segment1d.cc
+shift_SOURCES = shift.cc
+sym_SOURCES = sym.cc
 vline2d_SOURCES = vline2d.cc
 
 TESTS = $(check_PROGRAMS)
Index: tests/win/sym.cc
--- tests/win/sym.cc	(revision 2451)
+++ tests/win/sym.cc	(working copy)
@@ -28,7 +28,7 @@
 #include <mln/core/alias/window2d.hh>
 #include <mln/core/alias/dpoint2d.hh>
 
-#include <mln/geom/sym.hh>
+#include <mln/win/sym.hh>
 
 int main()
 {
@@ -50,5 +50,5 @@
   win2.insert(dpoint2d(-5,-6));
   win2.insert(dpoint2d(-7,-8));
 
-  mln_assertion(geom::sym(win) == win2);
+  mln_assertion(win::sym(win) == win2);
 }
Index: tests/win/diff.cc
--- tests/win/diff.cc	(revision 2451)
+++ tests/win/diff.cc	(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
@@ -25,69 +25,45 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/set/diff.cc
+/*! \file tests/win/diff.cc
  *
- * \brief Tests on mln::set::diff.
+ * \brief Tests on mln::win::diff.
  */
 
-#include <mln/set/diff.hh>
 #include <mln/core/alias/dpoint2d.hh>
+#include <mln/win/diff.hh>
+
 
 int main()
 {
   using namespace mln;
   
-  {
     window<dpoint2d> win1;
-    win1.insert( 2, 7);
-    win1.insert( 2, 1);
-    win1.insert(-4, 0);
-    win1.insert( 0, 0);
-    win1.insert( 1, 1);
-    win1.insert( 6, 5);
+  win1
+    .insert( 2, 7)
+    .insert( 2, 1)
+    .insert(-4, 0)
+    .insert( 0, 0)
+    .insert( 1, 1)
+    .insert( 6, 5);
 
     window<dpoint2d> win2;
-    win2.insert( 2, 7);
-    win2.insert(-2, 1);
-    win2.insert(-4, 0);
-    win2.insert( 1,-1);
-    win2.insert( 6, 5);
+  win2
+    .insert( 2, 7)
+    .insert(-2, 1)
+    .insert(-4, 0)
+    .insert( 1,-1)
+    .insert( 6, 5);
+
+  window<dpoint2d> win3 = win1 - win2;
 
-    window<dpoint2d> win3 = set::diff(win1, win2);
     mln_assertion(win3.has(dpoint2d( 2, 1)));
     mln_assertion(win3.has(dpoint2d( 0, 0)));
     mln_assertion(win3.has(dpoint2d( 1, 1)));
+
     mln_assertion(!win3.has(dpoint2d( 2, 7)));
     mln_assertion(!win3.has(dpoint2d(-2, 1)));
     mln_assertion(!win3.has(dpoint2d(-4, 0)));
     mln_assertion(!win3.has(dpoint2d( 1,-1)));
     mln_assertion(!win3.has(dpoint2d( 6, 5)));
   }
-
-  {
-    p_set<point2d> pst1;
-    pst1.insert(point2d( 2, 7));
-    pst1.insert(point2d( 2, 1));
-    pst1.insert(point2d(-4, 0));
-    pst1.insert(point2d( 0, 0));
-    pst1.insert(point2d( 1, 1));
-    pst1.insert(point2d( 6, 5));
-
-    p_set<point2d> pst2;
-    pst2.insert(point2d( 2, 7));
-    pst2.insert(point2d(-2, 1));
-    pst2.insert(point2d(-4, 0));
-    pst2.insert(point2d( 1,-1));
-    pst2.insert(point2d( 6, 5));
-
-    p_set<point2d> pst3 = set::diff(pst1, pst2);
-    mln_assertion(pst3.has(point2d( 2, 1)));
-    mln_assertion(pst3.has(point2d( 0, 0)));
-    mln_assertion(pst3.has(point2d( 1, 1)));
-    mln_assertion(!pst3.has(point2d( 2, 7)));
-    mln_assertion(!pst3.has(point2d(-2, 1)));
-    mln_assertion(!pst3.has(point2d(-4, 0)));
-    mln_assertion(!pst3.has(point2d( 1,-1)));
-    mln_assertion(!pst3.has(point2d( 6, 5)));
-  }
-}
Index: tests/win/rectangle2d.cc
--- tests/win/rectangle2d.cc	(revision 2461)
+++ tests/win/rectangle2d.cc	(working copy)
@@ -32,12 +32,13 @@
 
 #include <cmath>
 #include <mln/win/rectangle2d.hh>
-#include <mln/geom/sym.hh>
+#include <mln/win/sym.hh>
 
 #include <mln/convert/to_image.hh>
 
 #include <mln/debug/println.hh>
 
+
 int main()
 {
   using namespace mln;
@@ -47,7 +48,7 @@
 
   mln_assertion(rec.is_centered());
   mln_assertion(rec.is_symmetric());
-  mln_assertion(rec == geom::sym(rec));
+  mln_assertion(rec == win::sym(rec));
   mln_assertion(rec.size() == h * w);
 
   mln_assertion(rec.delta() == 2);
Index: tests/morpho/hit_or_miss.cc
--- tests/morpho/hit_or_miss.cc	(revision 2461)
+++ tests/morpho/hit_or_miss.cc	(working copy)
@@ -35,8 +35,9 @@
 
 #include <mln/win/rectangle2d.hh>
 #include <mln/core/alias/window2d.hh>
-#include <mln/geom/shift.hh>
-#include <mln/set/diff.hh>
+
+#include <mln/win/shift.hh>
+#include <mln/win/diff.hh>
 
 #include <mln/io/pbm/load.hh>
 #include <mln/io/pbm/save.hh>
@@ -54,9 +55,9 @@
   using namespace mln;
   using value::int_u8;
 
-  window2d win_hit = geom::shift(win::rectangle2d(3, 3),
+  window2d win_hit = win::shift(win::rectangle2d(3, 3),
 				 dpoint2d(+1, +1));
-  window2d win_miss = mln::set::diff(win::rectangle2d(5, 5), win_hit);
+  window2d win_miss = win::rectangle2d(5, 5) - win_hit;
 
   {
     bool hit[] = { 0, 0, 0, 0, 0,
Index: mln/core/alias/neighb1d.hh
--- mln/core/alias/neighb1d.hh	(revision 2461)
+++ mln/core/alias/neighb1d.hh	(working copy)
@@ -37,7 +37,6 @@
 # include <cmath>
 # include <mln/core/neighb.hh>
 # include <mln/core/alias/window1d.hh>
-# include <mln/geom/sym.hh>
 
 
 namespace mln
Index: mln/core/alias/neighb3d.hh
--- mln/core/alias/neighb3d.hh	(revision 2461)
+++ mln/core/alias/neighb3d.hh	(working copy)
@@ -37,7 +37,7 @@
 # include <cmath>
 # include <mln/core/neighb.hh>
 # include <mln/core/alias/window3d.hh>
-# include <mln/geom/sym.hh>
+# include <mln/win/sym.hh>
 
 
 namespace mln
@@ -119,7 +119,7 @@
 	  .insert(0, 1, 0)
 	  .insert(0, 0, 1);
 	win
-	  .insert(geom::sym(win));
+	  .insert(win::sym(win));
       }
     return it;
   }
@@ -139,7 +139,7 @@
 	  .insert(1,  1,  0)
 	  .insert(1, -1,  0);
 	win
-	  .insert(geom::sym(win))
+	  .insert(win::sym(win))
 	  .insert(c6().win());
       }
     return it;
@@ -158,7 +158,7 @@
 	  .insert(1, -1,  1)
 	  .insert(1, -1, -1);
 	win
-	  .insert(geom::sym(win))
+	  .insert(win::sym(win))
 	  .insert(c18().win());
       }
     return it;
Index: mln/core/neighb.hh
--- mln/core/neighb.hh	(revision 2461)
+++ mln/core/neighb.hh	(working copy)
@@ -47,7 +47,8 @@
 
 namespace mln
 {
-  // Forward declaration.
+
+  // Forward declarations.
   template <typename W> class neighb_fwd_niter;
   template <typename W> class neighb_bkd_niter;
 
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh	(revision 2461)
+++ mln/core/concept/window.hh	(working copy)
@@ -42,6 +42,18 @@
 # include <mln/core/site_set/p_array.hh>
 
 
+
+# define mln_is_simple_window(W)							\
+											\
+mln::metal::and_< mlc_is(mln_trait_window_size(W),					\
+			 mln::trait::window::size::fixed),				\
+		  mln::metal::and_< mlc_is(mln_trait_window_support(W),			\
+					   mln::trait::window::support::regular),	\
+				    mlc_is(mln_trait_window_definition(W),		\
+					   mln::trait::window::definition::unique) > >
+
+
+
 namespace mln
 {
 
@@ -90,8 +102,15 @@
 
 
 
+  template <typename W>
+  void check_simple(const Window<W>& win);
+
+
+
 # ifndef MLN_INCLUDE_ONLY
 
+
+
   namespace internal
   {
 
Index: mln/level/was.median.hh
--- mln/level/was.median.hh	(revision 2461)
+++ mln/level/was.median.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
@@ -33,13 +33,17 @@
  * \brief Obsolete routines for median filtering.
  */
 
-# include <mln/geom/shift.hh>
+# include <mln/win/shift.hh>
 # include <mln/core/alias/window2d.hh>
+
 # include <mln/geom/min_col.hh>
 # include <mln/geom/max_col.hh>
 # include <mln/geom/max_row.hh>
 # include <mln/geom/min_row.hh>
-# include <mln/set/diff.hh>
+
+# include <mln/win/diff.hh>
+# include <mln/win/shift.hh>
+
 # include <mln/level/median.hh>
 # include <mln/win/hline2d.hh>
 
@@ -68,12 +72,12 @@
 	  min_col = geom::min_col(input), max_col = geom::max_col(input);
 
 	window2d
-	  win_fwd_plus  = set::diff(win, geom::shift(win, left)),
-	  win_fwd_minus = set::diff(geom::shift(win, left), win),
-	  win_bkd_plus  = set::diff(win, geom::shift(win, right)),
-	  win_bkd_minus = set::diff(geom::shift(win, right), win),
-	  win_bot  = set::diff(win, geom::shift(win, up)),
-	  win_top = set::diff(geom::shift(win, up), win);
+	  win_fwd_plus  = win - win::shift(win, left),
+	  win_fwd_minus = win::shift(win, left)  - win,
+	  win_bkd_plus  = win - win::shift(win, right),
+	  win_bkd_minus = win::shift(win, right) - win,
+	  win_bot       = win - win::shift(win, up),
+	  win_top       = win::shift(win, up)    - win;
 
 	point2d p;
 	mln_qiter(W)
Index: mln/level/median.hh
--- mln/level/median.hh	(revision 2461)
+++ mln/level/median.hh	(working copy)
@@ -38,8 +38,9 @@
 # include <mln/core/concept/image.hh>
 # include <mln/core/window.hh>
 # include <mln/core/alias/dpoint2d.hh>
-# include <mln/geom/shift.hh>
-# include <mln/set/diff.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
 
 # include <mln/canvas/browsing/snake_fwd.hh>
 # include <mln/canvas/browsing/dir_struct_elt_incr_update.hh>
@@ -125,12 +126,12 @@
 	  // aux data
 	  med(),
 	  p(),
-	  win_fp(set::diff(win, geom::shift(win, left))),
-	  win_fm(set::diff(geom::shift(win, left),  win)),
-	  win_bp(set::diff(win, geom::shift(win, right))),
-	  win_bm(set::diff(geom::shift(win, right), win)),
-	  win_dp(set::diff(win, geom::shift(win, up))),
-	  win_dm(set::diff(geom::shift(win, up),    win)),
+	  win_fp(win - win::shift(win, left)),
+	  win_fm(win::shift(win, left)  - win),
+	  win_bp(win - win::shift(win, right)),
+	  win_bm(win::shift(win, right) - win),
+	  win_dp(win - win::shift(win, up)),
+	  win_dm(win::shift(win, up)    - win),
 	  q_fp(win_fp, p),  q_fm(win_fm, p),
 	  q_bp(win_bp, p),  q_bm(win_bm, p),
 	  q_dp(win_dp, p),  q_dm(win_dm, p)
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh	(revision 2461)
+++ mln/level/fast_median.hh	(working copy)
@@ -38,12 +38,14 @@
 # include <mln/core/concept/image.hh>
 # include <mln/core/alias/window2d.hh>
 # include <mln/accu/median_h.hh>
-# include <mln/geom/shift.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
+
 # include <mln/geom/min_col.hh>
 # include <mln/geom/min_row.hh>
 # include <mln/geom/max_col.hh>
 # include <mln/geom/max_row.hh>
-# include <mln/set/diff.hh>
 
 
 namespace mln
@@ -86,12 +88,12 @@
 	  min_col = geom::min_col(input), max_col = geom::max_col(input);
 
 	window2d
-	  win_fwd_plus  = set::diff(win, geom::shift(win, left)),
-	  win_fwd_minus = set::diff(geom::shift(win, left), win),
-	  win_bkd_plus  = set::diff(win, geom::shift(win, right)),
-	  win_bkd_minus = set::diff(geom::shift(win, right), win),
-	  win_bot  = set::diff(win, geom::shift(win, up)),
-	  win_top = set::diff(geom::shift(win, up), win);
+	  win_fwd_plus  = win - win::shift(win, left),
+	  win_fwd_minus = win::shift(win, left) - win,
+	  win_bkd_plus  = win - win::shift(win, right),
+	  win_bkd_minus = win::shift(win, right) - win,
+	  win_bot       = win - win::shift(win, up),
+	  win_top       = win::shift(win, up) - win;
 
 	accu::median_h<mln_value(I)> med;
 
Index: mln/geom/all.hh
--- mln/geom/all.hh	(revision 2461)
+++ mln/geom/all.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
@@ -51,11 +51,9 @@
 # include <mln/geom/pmin_pmax.hh>
 # include <mln/geom/seeds2tiling.hh>
 # include <mln/geom/seeds2tiling_roundness.hh>
-# include <mln/geom/shift.hh>
 # include <mln/geom/size1d.hh>
 # include <mln/geom/size2d.hh>
 # include <mln/geom/size3d.hh>
-# include <mln/geom/sym.hh>
 
 
 #endif // ! MLN_GEOM_ALL_HH
Index: mln/set/diff.hh
--- mln/set/diff.hh	(revision 2461)
+++ mln/set/diff.hh	(working copy)
@@ -37,7 +37,6 @@
  */
 
 # include <mln/convert/to_std_set.hh>
-# include <mln/convert/to_window.hh>
 # include <mln/convert/to_p_set.hh>
 # include <mln/metal/equal.hh>
 
@@ -51,14 +50,6 @@
 
     /*! \brief Set theoretic difference of \p lhs and \p rhs.
      *
-     * \relates mln::Window
-     */
-    template <typename Wl, typename Wr>
-    window<mln_dpsite(Wl)>
-    diff(const Window<Wl>& lhs, const Window<Wr>& rhs);
-
-    /*! \brief Set theoretic difference of \p lhs and \p rhs.
-     *
      * \relates mln::Site_Set
      */
     template <typename Wl, typename Wr>
@@ -70,32 +61,6 @@
 
     template <typename Wl, typename Wr>
     inline
-    window<mln_dpsite(Wl)>
-    diff(const Window<Wl>& lhs_, const Window<Wr>& rhs_)
-    {
-      trace::entering("set::diff");
-      mlc_is_a(mln_site(Wl), Gpoint)::check();
-      mlc_is_a(mln_site(Wr), Gpoint)::check();
-      mlc_converts_to(mln_dpsite(Wl), mln_dpsite(Wr))::check();
-
-      const Wl& lhs = exact(lhs_);
-      const Wr& rhs = exact(rhs_);
-      window<mln_dpsite(Wl)> tmp;
-
-      const unsigned n = lhs.size();
-      for (unsigned i = 0; i < n; ++i)
-	{
-	  if (rhs.has(lhs.dp(i)))
-	    continue;
-	  tmp.insert(lhs.dp(i));
-	}
-
-      trace::exiting("set::diff");
-      return tmp;
-    }
-
-    template <typename Wl, typename Wr>
-    inline
     p_set<mln_psite(Wl)>
     diff(const Site_Set<Wl>& lhs, const Site_Set<Wr>& rhs)
     {
Index: mln/win/diff.hh
--- mln/win/diff.hh	(revision 0)
+++ mln/win/diff.hh	(revision 0)
@@ -0,0 +1,104 @@
+// 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_WIN_DIFF_HH
+# define MLN_WIN_DIFF_HH
+
+/*! \file mln/win/diff.hh
+ *
+ * \brief Set difference between a couple of windows or neighborhoods.
+ */
+
+# include <mln/core/window.hh>
+# include <mln/core/neighb.hh>
+
+
+
+namespace mln
+{
+
+  namespace win
+  {
+
+    /// Set difference between a couple of windows \p win1 and \p win2.
+    template <typename W1, typename W2>
+    mln_regular(W1)
+    operator-(const Window<W1>& win1, const Window<W2>& win2);
+
+    /// Set difference between a couple of neighborhoods \p nbh1 and \p nbh2.
+    template <typename N1, typename N2>
+    neighb<mln_deduce(N1, window, regular)>
+    operator-(const Neighborhood<N1>& nbh1, const Neighborhood<N2>& nbh2);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename W1, typename W2>
+    inline
+    mln_regular(W1)
+    operator-(const Window<W1>& win1_, const Window<W2>& win2_)
+    {
+      trace::entering("win::diff");
+
+      mln_is_simple_window(W1)::check();
+      mln_is_simple_window(W2)::check();
+
+      const W1& win1 = exact(win1_);
+      const W2& win2 = exact(win2_);
+      mln_regular(W1) tmp;
+
+      const unsigned n = win1.size();
+      for (unsigned i = 0; i < n; ++i)
+	{
+	  if (win2.has(win1.dp(i)))
+	    continue;
+	  tmp.insert(win1.dp(i));
+	}
+
+      trace::exiting("win::diff");
+      return tmp;
+    }
+
+
+    template <typename N1, typename N2>
+    neighb<mln_deduce(N1, window, regular)>
+    operator-(const Neighborhood<N1>& nbh1, const Neighborhood<N2>& nbh2)
+    {
+      typedef mln_deduce(N1, window, regular) W1;
+      W1 win = diff(exact(nbh1).win(), exact(nbh2).win());
+      neighb<W1> tmp(win);
+      return tmp;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::win
+
+} // end of namespace mln
+
+
+#endif // ! MLN_WIN_DIFF_HH
Index: mln/win/sym.hh
--- mln/win/sym.hh	(revision 2451)
+++ mln/win/sym.hh	(working copy)
@@ -25,10 +25,10 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_GEOM_SYM_HH
-# define MLN_GEOM_SYM_HH
+#ifndef MLN_WIN_SYM_HH
+# define MLN_WIN_SYM_HH
 
-/*! \file mln/geom/sym.hh
+/*! \file mln/win/sym.hh
  *
  * \brief Give the symmetrical object.
  */
@@ -41,7 +41,7 @@
 namespace mln
 {
 
-  namespace geom
+  namespace win
   {
 
     /*! \brief Give the symmetrical window of \p win.
@@ -77,9 +77,9 @@
 
 # endif // ! MLN_INCLUDE_ONLY
 
-  } // end of namespace mln::geom
+  } // end of namespace mln::win
 
 } // end of namespace mln
 
 
-#endif // ! MLN_GEOM_SYM_HH
+#endif // ! MLN_WIN_SYM_HH
Index: mln/win/all.hh
--- mln/win/all.hh	(revision 2461)
+++ mln/win/all.hh	(working copy)
@@ -42,6 +42,9 @@
 
 }
 
+
+// Types.
+
 # include <mln/win/backdiag2d.hh>
 # include <mln/win/cube3d.hh>
 # include <mln/win/cuboid3d.hh>
@@ -55,6 +58,12 @@
 # include <mln/win/segment1d.hh>
 # include <mln/win/vline2d.hh>
 
+// Routines.
+
+# include <mln/win/diff.hh>
+# include <mln/win/shift.hh>
+# include <mln/win/sym.hh>
+
 
 
 #endif // ! MLN_WIN_ALL_HH
Index: mln/win/shift.hh
--- mln/win/shift.hh	(revision 2451)
+++ mln/win/shift.hh	(working copy)
@@ -28,7 +28,7 @@
 #ifndef MLN_GEOM_SHIFT_HH
 # define MLN_GEOM_SHIFT_HH
 
-/*! \file mln/geom/shift.hh
+/*! \file mln/win/shift.hh
  *
  * \brief Define a function which shifts a window with a delta-point.
  */
@@ -78,7 +78,7 @@
 	mln_regular(W) tmp(win.function());
 	const unsigned nw = win.nwindows();
 	for (unsigned w = 0; w < nw; ++w)
-	  tmp.set_window(w, geom::shift(win.window(w), dp));
+	  tmp.set_window(w, win::shift(win.window(w), dp));
 	return tmp;
       }
 
@@ -91,7 +91,7 @@
     mln_regular(W)
     shift(const Window<W>& win, const mln_dpsite(W)& dp)
     {
-      trace::entering("geom::shift");
+      trace::entering("win::shift");
 
       mlc_is(mln_trait_window_support(W),
 	     trait::window::support::regular)::check();
@@ -101,7 +101,7 @@
       mln_regular(W) tmp = impl::shift_(mln_trait_window_definition(W)(),
 					exact(win), dp);
 
-      trace::exiting("geom::shift");
+      trace::exiting("win::shift");
       return tmp;
     }
 
Index: mln/morpho/erosion_fast.hh
--- mln/morpho/erosion_fast.hh	(revision 2461)
+++ mln/morpho/erosion_fast.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
@@ -38,8 +38,9 @@
 # include <mln/core/concept/image.hh>
 # include <mln/core/window.hh>
 # include <mln/core/alias/dpoint2d.hh>
-# include <mln/geom/shift.hh>
-# include <mln/set/diff.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
 
 # include <mln/canvas/browsing/snake_fwd.hh>
 # include <mln/accu/min_h.hh>
@@ -107,12 +108,12 @@
 	  // aux data
 	  min(input.values()),
 	  p(),
-	  win_fp(set::diff(win, geom::shift(win, left))),
-	  win_fm(set::diff(geom::shift(win, left),  win)),
-	  win_bp(set::diff(win, geom::shift(win, right))),
-	  win_bm(set::diff(geom::shift(win, right), win)),
-	  win_dp(set::diff(win, geom::shift(win, up))),
-	  win_dm(set::diff(geom::shift(win, up),    win)),
+	  win_fp(win - win::shift(win, left)),
+	  win_fm(win::shift(win, left)  - win),
+	  win_bp(win - win::shift(win, right)),
+	  win_bm(win::shift(win, right) - win),
+	  win_dp(win - win::shift(win, up)),
+	  win_dm(win::shift(win, up)    - win),
 	  q_fp(win_fp, p),  q_fm(win_fm, p),
 	  q_bp(win_bp, p),  q_bm(win_bm, p),
 	  q_dp(win_dp, p),  q_dm(win_dm, p)
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh	(revision 2461)
+++ mln/morpho/erosion.spe.hh	(working copy)
@@ -35,9 +35,11 @@
 # include <mln/core/alias/window2d.hh>
 # include <mln/win/octagon2d.hh>
 # include <mln/win/rectangle2d.hh>
-# include <mln/geom/shift.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
+
 # include <mln/accu/min_h.hh>
-# include <mln/set/diff.hh>
 # include <mln/canvas/browsing/snake_fwd.hh>
 
 
@@ -279,10 +281,10 @@
 	  : input(input),
 	    win(win),
 	    min(),
-	    win_left(set::diff(geom::shift(win, left), win)),
-	    win_right(set::diff(win, geom::shift(win, left))),
-	    win_bot(set::diff(win, geom::shift(win, up))),
-	    win_top(set::diff(geom::shift(win, up), win)),
+	    win_left(win::shift(win, left) - win),
+	    win_right(win - win::shift(win, left)),
+	    win_bot(win - win::shift(win, up)),
+	    win_top(win::shift(win, up) - win),
 	    q_l(input, win_left, p),
 	    q_r(input, win_right, p),
 	    q_top(input, win_top, p),
@@ -376,10 +378,10 @@
 	  : input(input),
 	    win(win),
 	    min(),
-	    win_left(set::diff(geom::shift(win, left), win)),
-	    win_right(set::diff(win, geom::shift(win, left))),
-	    win_bot(set::diff(win, geom::shift(win, up))),
-	    win_top(set::diff(geom::shift(win, up), win)),
+	    win_left(win::shift(win, left) - win),
+	    win_right(win - win::shift(win, left)),
+	    win_bot(win - win::shift(win, up)),
+	    win_top(win::shift(win, up) - win),
 	    q_l(win_left, p),
 	    q_r(win_right, p),
 	    q_top(win_top, p),
@@ -562,8 +564,8 @@
       erosion_dispatch_wrt_win(const I& input, const W& win)
       {
 	// FIXME: De-activate because, when win is multiple,
-	// geom::shift does not work.  We have to introduce
-	// props from windows, then re-write geom::shift.
+	// win::shift does not work.  We have to introduce
+	// props from windows, then re-write win::shift.
 
 // 	if (erosion_chooses_arbitrary(input, win))
 // 	  return erosion_dispatch_for_arbitrary(input, win);
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh	(revision 2461)
+++ mln/morpho/hit_or_miss.hh	(working copy)
@@ -224,7 +224,7 @@
       impl::hit_or_miss_preconditions_(input, win_hit, win_miss);
 
       mln_concrete(I) output = dilation( hit_or_miss(input, win_hit, win_miss),
-					 geom::sym(win_hit) );
+					 win::sym(win_hit) );
 
       trace::exiting("morpho::hit_or_miss_opening");
       return output;
@@ -243,7 +243,7 @@
       mln_concrete(I) output = hit_or_miss_opening(complementation(input), win_miss, win_hit);
 
       mln_postcondition( dilation( hit_or_miss(input, win_hit, win_miss),
-				   geom::sym(win_miss) ) == output);
+				   win::sym(win_miss) ) == output);
       trace::exiting("morpho::hit_or_miss_background_opening");
       return output;
     }
Index: mln/morpho/closing.hh
--- mln/morpho/closing.hh	(revision 2461)
+++ mln/morpho/closing.hh	(working copy)
@@ -60,7 +60,7 @@
       mln_precondition(exact(input).has_data());
       mln_precondition(! exact(win).is_empty());
 
-      mln_concrete(I) output = erosion(dilation(input, win), geom::sym(win));
+      mln_concrete(I) output = erosion(dilation(input, win), win::sym(win));
 
       mln_postcondition(output >= input);
       trace::exiting("morpho::closing");
Index: mln/morpho/opening.hh
--- mln/morpho/opening.hh	(revision 2461)
+++ mln/morpho/opening.hh	(working copy)
@@ -60,7 +60,7 @@
       mln_precondition(exact(input).has_data());
       mln_precondition(! exact(win).is_empty());
 
-      mln_concrete(I) output = dilation(erosion(input, win), geom::sym(win));
+      mln_concrete(I) output = dilation(erosion(input, win), win::sym(win));
 
       // FIXME: Is this postcondition always true, even if the
       // structuring element is not centered?
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh	(revision 2461)
+++ mln/morpho/includes.hh	(working copy)
@@ -57,7 +57,9 @@
 
 # include <mln/extension/all.hh>
 
-# include <mln/geom/sym.hh>
+# include <mln/win/sym.hh>
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
 # include <mln/set/inter.hh>
 
 # include <mln/morpho/dilation.hh>
Index: mln/morpho/dilation_fast.hh
--- mln/morpho/dilation_fast.hh	(revision 2461)
+++ mln/morpho/dilation_fast.hh	(working copy)
@@ -38,8 +38,9 @@
 # include <mln/core/concept/image.hh>
 # include <mln/core/window.hh>
 # include <mln/core/alias/dpoint2d.hh>
-# include <mln/geom/shift.hh>
-# include <mln/set/diff.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
 
 # include <mln/canvas/browsing/snake_fwd.hh>
 # include <mln/accu/max_h.hh>
@@ -107,12 +108,12 @@
 	  // aux data
 	  max(input.values()),
 	  p(),
-	  win_fp(set::diff(win, geom::shift(win, left))),
-	  win_fm(set::diff(geom::shift(win, left),  win)),
-	  win_bp(set::diff(win, geom::shift(win, right))),
-	  win_bm(set::diff(geom::shift(win, right), win)),
-	  win_dp(set::diff(win, geom::shift(win, up))),
-	  win_dm(set::diff(geom::shift(win, up),    win)),
+	  win_fp(win - win::shift(win, left)),
+	  win_fm(win::shift(win, left)  - win),
+	  win_bp(win - win::shift(win, right)),
+	  win_bm(win::shift(win, right) - win),
+	  win_dp(win - win::shift(win, up)),
+	  win_dm(win::shift(win, up)    - win),
 	  q_fp(win_fp, p),  q_fm(win_fm, p),
 	  q_bp(win_bp, p),  q_bm(win_bm, p),
 	  q_dp(win_dp, p),  q_dm(win_dm, p)
Index: mln/canvas/chamfer.hh
--- mln/canvas/chamfer.hh	(revision 2461)
+++ mln/canvas/chamfer.hh	(working copy)
@@ -34,7 +34,7 @@
  */
 
 # include <mln/core/internal/image_morpher.hh>
-# include <mln/geom/sym.hh>
+# include <mln/win/sym.hh>
 
 namespace mln
 {
@@ -94,7 +94,7 @@
 
       /// Bkd pass.
       {
-	W w_win_b = geom::sym(f.win);
+	W w_win_b = win::sym(f.win);
 
 	mln_bkd_piter(I) p(f.input.domain());
 	mln_qiter(W) q(w_win_b, p);
Index: sandbox/duhamel/canvas_chamfer.hh
--- sandbox/duhamel/canvas_chamfer.hh	(revision 2461)
+++ sandbox/duhamel/canvas_chamfer.hh	(working copy)
@@ -75,7 +75,7 @@
 	
 	/// Bkd pass.
 	{
-	  W w_win_b = geom::sym(f.win);
+	  W w_win_b = win::sym(f.win);
 	  
 	  mln_bkd_piter(I) p(f.input.domain());
 	  mln_qiter(W) q(w_win_b, p);
Index: sandbox/nivault/median.hh
--- sandbox/nivault/median.hh	(revision 2461)
+++ sandbox/nivault/median.hh	(working copy)
@@ -45,7 +45,7 @@
 # include <mln/accu/median.hh>
 # include <mln/canvas/browsing/snake_fwd.hh>
 
-# include <mln/geom/shift.hh>
+# include <mln/win/shift.hh>
 # include <mln/set/diff.hh>
 
 # include <mln/border/resize.hh>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            2461: mln/core/concept/neighborhood.hh: Add	documentation on static checks.
                        
                        
by Roland Levillain 01 Oct '08
                    by Roland Levillain 01 Oct '08
01 Oct '08
                    
                        ---
 milena/ChangeLog                        |    5 +++++
 milena/mln/core/concept/neighborhood.hh |    9 +++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index ff4f385..cd39a45 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,10 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	* mln/core/concept/neighborhood.hh: Add documentation on static
+	checks.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	Add iterators on complex neighborhood.
 
 	* mln/core/image/complex_neighborhood_piter.hh New.
diff --git a/milena/mln/core/concept/neighborhood.hh b/milena/mln/core/concept/neighborhood.hh
index 1f96d45..47193c6 100644
--- a/milena/mln/core/concept/neighborhood.hh
+++ b/milena/mln/core/concept/neighborhood.hh
@@ -91,8 +91,13 @@ namespace mln
     typedef mln_window(E) window;
     bool m = (& E::win) == (& E::win);
     m = 0;
-//     const window& (E::*m)() const = & E::to_window;
-//     m = 0;
+# if 0
+    /* FIXME: Disabled, as win() can either return a const reference
+       or a copy of the window (see documentation above).  Hence the
+       simpler, relaxed check above (m0).  */
+    const window& (E::*m1)() const = & E::win;
+    m = m1;
+# endif
   }
 
 # endif // ! MLN_INCLUDE_ONLY
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* 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(a)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(a)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
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            2459: Add neighborhoods of lower- and	higher-dimension adjacent faces.
                        
                        
by Roland Levillain 01 Oct '08
                    by Roland Levillain 01 Oct '08
01 Oct '08
                    
                        	* mln/core/image/complex_lower_neighborhood.hh,
	* mln/core/image/complex_higher_neighborhood.hh:
	New.
---
 milena/ChangeLog                                   |    8 ++
 .../mln/core/image/complex_higher_neighborhood.hh  |  117 ++++++++++++++++++++
 .../mln/core/image/complex_lower_neighborhood.hh   |  117 ++++++++++++++++++++
 3 files changed, 242 insertions(+), 0 deletions(-)
 create mode 100644 milena/mln/core/image/complex_higher_neighborhood.hh
 create mode 100644 milena/mln/core/image/complex_lower_neighborhood.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index e44301f..be5fc43 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	Add neighborhoods of lower- and higher-dimension adjacent faces.
+
+	* mln/core/image/complex_lower_neighborhood.hh,
+	* mln/core/image/complex_higher_neighborhood.hh:
+	New.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	* tests/core/image/complex_image.cc: Alias mln::point2d to P.
 
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
diff --git a/milena/mln/core/image/complex_higher_neighborhood.hh b/milena/mln/core/image/complex_higher_neighborhood.hh
new file mode 100644
index 0000000..2b52c5b
--- /dev/null
+++ b/milena/mln/core/image/complex_higher_neighborhood.hh
@@ -0,0 +1,117 @@
+// 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_COMPLEX_HIGHER_NEIGHBORHOOD_HH
+# define MLN_CORE_COMPLEX_HIGHER_NEIGHBORHOOD_HH
+
+/// \file mln/core/complex_higher_neighborhood.hh
+/// \brief A neighborhood centered on a n-face of complex returning its
+/// adjacent (n+1)-faces.
+
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/core/site_set/complex_psite.hh>
+
+# include <mln/topo/adj_higher_face_iter.hh>
+
+// FIXME: Factor with complex_lower_neighborhood.
+
+
+namespace mln
+{
+  // Fwd decls.
+  template <typename I, typename P, typename N>
+  class complex_neighborhood_fwd_piter;
+  template <typename I, typename P, typename N>
+  class complex_neighborhood_bkd_piter;
+
+
+  /// \brief Neighborhood centered on a n-face of complex returning its
+  /// adjacent (n-1)-faces.
+  template <unsigned D, typename P>
+  class complex_higher_neighborhood
+    : public Neighborhood< complex_higher_neighborhood<D, P> >
+  {
+    typedef complex_higher_neighborhood<D, P> self_;
+
+    // FIXME: The associated complex iterators.
+  public:
+    typedef topo::adj_higher_face_fwd_iter<D> complex_fwd_iter;
+    typedef topo::adj_higher_face_bkd_iter<D> complex_bkd_iter;
+
+  public:
+    /// Associated types.
+    /// \{
+    /// The type of psite corresponding to the neighborhood.
+    typedef complex_psite<D, P> psite;
+    /// The type of site corresponding to the neighborhood.
+    typedef mln_site(psite) site;
+
+    /// \brief Point_Iterator type to browse the psites of the neighborhood
+    /// w.r.t. the ordering of vertices.
+    typedef
+    complex_neighborhood_fwd_piter<complex_fwd_iter, P, self_> fwd_niter;
+
+    /// \brief Point_Iterator type to browse the psites of the neighborhood
+    /// w.r.t. the reverse ordering of vertices.
+    typedef
+    complex_neighborhood_bkd_piter<complex_bkd_iter, P, self_> bkd_niter;
+
+    /// The default niter type.
+    typedef fwd_niter niter;
+    /// \}
+
+    /// Conversions.
+    /// \{
+    /// The window type corresponding to this neighborhood.
+    // FIXME: Dummy.
+    typedef self_ window;
+    /// Create a window corresponding to this neighborhood.
+    const window& win() const;
+    /// \}
+  };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+  // FIXME: Dummy.
+  template <unsigned D, typename P>
+  inline
+  // FIXME: Change (dummy) type.
+  const typename complex_higher_neighborhood<D, P>::window&
+  complex_higher_neighborhood<D, P>::win() const
+  {
+    // FIXME: Dummy.
+    return *this;
+  }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_CORE_COMPLEX_HIGHER_NEIGHBORHOOD_HH
diff --git a/milena/mln/core/image/complex_lower_neighborhood.hh b/milena/mln/core/image/complex_lower_neighborhood.hh
new file mode 100644
index 0000000..7eb8fc4
--- /dev/null
+++ b/milena/mln/core/image/complex_lower_neighborhood.hh
@@ -0,0 +1,117 @@
+// 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_COMPLEX_LOWER_NEIGHBORHOOD_HH
+# define MLN_CORE_COMPLEX_LOWER_NEIGHBORHOOD_HH
+
+/// \file mln/core/complex_lower_neighborhood.hh
+/// \brief A neighborhood centered on a n-face of complex returning its
+/// adjacent (n-1)-faces.
+
+# include <mln/core/concept/neighborhood.hh>
+
+# include <mln/core/site_set/complex_psite.hh>
+
+# include <mln/topo/adj_lower_face_iter.hh>
+
+// FIXME: Factor with complex_higher_neighborhood.
+
+
+namespace mln
+{
+  // Fwd decls.
+  template <typename I, typename P, typename N>
+  class complex_neighborhood_fwd_piter;
+  template <typename I, typename P, typename N>
+  class complex_neighborhood_bkd_piter;
+
+
+  /// \brief Neighborhood centered on a n-face of complex returning its
+  /// adjacent (n-1)-faces.
+  template <unsigned D, typename P>
+  class complex_lower_neighborhood
+    : public Neighborhood< complex_lower_neighborhood<D, P> >
+  {
+    typedef complex_lower_neighborhood<D, P> self_;
+
+    // FIXME: The associated complex iterators.
+  public:
+    typedef topo::adj_lower_face_fwd_iter<D> complex_fwd_iter;
+    typedef topo::adj_lower_face_bkd_iter<D> complex_bkd_iter;
+
+  public:
+    /// Associated types.
+    /// \{
+    /// The type of psite corresponding to the neighborhood.
+    typedef complex_psite<D, P> psite;
+    /// The type of site corresponding to the neighborhood.
+    typedef mln_site(psite) site;
+
+    /// \brief Point_Iterator type to browse the psites of the neighborhood
+    /// w.r.t. the ordering of vertices.
+    typedef
+    complex_neighborhood_fwd_piter<complex_fwd_iter, P, self_> fwd_niter;
+
+    /// \brief Point_Iterator type to browse the psites of the neighborhood
+    /// w.r.t. the reverse ordering of vertices.
+    typedef
+    complex_neighborhood_bkd_piter<complex_bkd_iter, P, self_> bkd_niter;
+
+    /// The default niter type.
+    typedef fwd_niter niter;
+    /// \}
+
+    /// Conversions.
+    /// \{
+    /// The window type corresponding to this neighborhood.
+    // FIXME: Dummy.
+    typedef self_ window;
+    /// Create a window corresponding to this neighborhood.
+    const window& win() const;
+    /// \}
+  };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+  // FIXME: Dummy.
+  template <unsigned D, typename P>
+  inline
+  // FIXME: Change (dummy) type.
+  const typename complex_lower_neighborhood<D, P>::window&
+  complex_lower_neighborhood<D, P>::win() const
+  {
+    // FIXME: Dummy.
+    return *this;
+  }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_CORE_COMPLEX_LOWER_NEIGHBORHOOD_HH
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '08
                    
                        ---
 milena/ChangeLog                         |    4 ++++
 milena/tests/core/image/complex_image.cc |   26 ++++++++++++++------------
 2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index a8e28fd..e44301f 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,9 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	* tests/core/image/complex_image.cc: Alias mln::point2d to P.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	* tests/core/image/complex_image.cc: Fix diagram in documentation.
 
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
diff --git a/milena/tests/core/image/complex_image.cc b/milena/tests/core/image/complex_image.cc
index 9ef09fc..8ac6b4f 100644
--- a/milena/tests/core/image/complex_image.cc
+++ b/milena/tests/core/image/complex_image.cc
@@ -89,11 +89,13 @@ int main()
   | Complex-based pset.  |
   `---------------------*/
 
+  typedef point2d P;
+
   // A pset.
-  p_complex<D, point2d> pc(c);
+  p_complex<D, P> pc(c);
   topo::face<D> af(e0);
   // An associated psite.
-  complex_psite<D, point2d> cs(pc, af);
+  complex_psite<D, P> cs(pc, af);
 
 
   /*--------------------.
@@ -105,16 +107,16 @@ int main()
      of the test?  */
 
   // Pset of 0-faces.
-  p_faces<0, D, point2d> pf0(c);
+  p_faces<0, D, P> pf0(c);
   // Pset of 1-faces.
-  p_faces<1, D, point2d> pf1(c);
+  p_faces<1, D, P> pf1(c);
   // Pset of 2-faces.
-  p_faces<2, D, point2d> pf2(c);
+  p_faces<2, D, P> pf2(c);
 
   // Some psites on faces.
-  faces_psite<0, D, point2d> fs0(pf0, v0);
-  faces_psite<1, D, point2d> fs1(pf1, e0);
-  faces_psite<2, D, point2d> fs2(pf2, t0);
+  faces_psite<0, D, P> fs0(pf0, v0);
+  faces_psite<1, D, P> fs1(pf1, e0);
+  faces_psite<2, D, P> fs2(pf2, t0);
 
 
   /*----------------------.
@@ -125,7 +127,7 @@ int main()
 
   // An image type built on a 2-complex with mln::int_u8 values on
   // each face.
-  typedef complex_image<D, point2d, int_u8> ima_t;
+  typedef complex_image<D, P, int_u8> ima_t;
 
   // Values.
   metal::vec<D + 1, std::vector< int_u8 > > values;
@@ -167,8 +169,8 @@ int main()
   // Dynamic version.
   for (unsigned n = 0; n <= D; ++n)
     {
-      p_n_faces_fwd_piter<D, point2d> fwd_np(ima.domain(), n);
-      p_n_faces_bkd_piter<D, point2d> bkd_np(ima.domain(), n);
+      p_n_faces_fwd_piter<D, P> fwd_np(ima.domain(), n);
+      p_n_faces_bkd_piter<D, P> bkd_np(ima.domain(), n);
       for_all_2(fwd_np, bkd_np)
 	std::cout << "ima(" << fwd_np << ") = " << ima(fwd_np) << '\t'
 		  << "ima(" << bkd_np << ") = " << ima(bkd_np)
@@ -180,7 +182,7 @@ int main()
 // FIXME: Disabled (moved to the attic).
 # if 0
   // FIXME: Sugar the name of the iterator.
-  p_complex_faces_fwd_piter_<0, D, point2d> f0p(ima.domain());
+  p_complex_faces_fwd_piter_<0, D, P> f0p(ima.domain());
   for_all(f0p)
     std::cout << "ima(" << f0p << ") = " << ima(f0p) << std::endl;
 #endif
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            2457: tests/core/image/complex_image.cc: Fix	diagram in documentation.
                        
                        
by Roland Levillain 01 Oct '08
                    by Roland Levillain 01 Oct '08
01 Oct '08
                    
                        ---
 milena/ChangeLog                         |    4 ++++
 milena/tests/core/image/complex_image.cc |    4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 5107bb1..a8e28fd 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,9 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	* tests/core/image/complex_image.cc: Fix diagram in documentation.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	Overhaul conversions of complex_relative_iterator_base<F, E>.
 
 	* mln/topo/internal/complex_relative_iterator_base.hh
diff --git a/milena/tests/core/image/complex_image.cc b/milena/tests/core/image/complex_image.cc
index 59eba87..9ef09fc 100644
--- a/milena/tests/core/image/complex_image.cc
+++ b/milena/tests/core/image/complex_image.cc
@@ -50,9 +50,9 @@ int main()
               v0      e3     v3
                 o-----------o                v0----e3----v3      
                / \ ,-----. /                / \    |    /   
-              / . \ \ t2/ /                /   \   t2  /    
+              / . \ \ t1/ /                /   \   t1  /    
           e0 / / \ e1\ / / e4             e0.  ,e1Ž  `e4  
-            / /t1 \ \ ' /                /   t1  \   /      
+            / /t0 \ \ ' /                /   t0  \   /      
            / `-----' \ /                /    |    \ /       
           o-----------o                v1----e2----v2
        v1      e2      v2
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '08
                    
                        	* mln/topo/internal/complex_relative_iterator_base.hh
	(complex_relative_iterator_base<F, E>::to_face):
	Remove.
	(complex_relative_iterator_base<F, E>::operator face):
	Turn into...
	(complex_relative_iterator_base<F, E>::operator const face&):
	..this.
	Return a const reference to the held face instead of a copy, so
	that its address can be safely taken.
	Remove the precondition, as invalid iterators are allowed to give
	access to the face they hold.
---
 milena/ChangeLog                                   |   16 ++++++++++++++++
 .../internal/complex_relative_iterator_base.hh     |   15 ++-------------
 2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index cf00b66..5107bb1 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,21 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	Overhaul conversions of complex_relative_iterator_base<F, E>.
+
+	* mln/topo/internal/complex_relative_iterator_base.hh
+	(complex_relative_iterator_base<F, E>::to_face):
+	Remove.
+	(complex_relative_iterator_base<F, E>::operator face):
+	Turn into...
+	(complex_relative_iterator_base<F, E>::operator const face&):
+	..this.
+	Return a const reference to the held face instead of a copy, so
+	that its address can be safely taken.
+	Remove the precondition, as invalid iterators are allowed to give
+	access to the face they hold.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	Delegate pretty-printing of complex_psite<D> to topo::face<D>.
 
 	* mln/core/site_set/complex_psite.hh
diff --git a/milena/mln/topo/internal/complex_relative_iterator_base.hh b/milena/mln/topo/internal/complex_relative_iterator_base.hh
index 599727a..43a38ae 100644
--- a/milena/mln/topo/internal/complex_relative_iterator_base.hh
+++ b/milena/mln/topo/internal/complex_relative_iterator_base.hh
@@ -110,10 +110,8 @@ namespace mln
 
 	/// Conversion and accessors.
 	/// \{
-	/// Reference to the corresponding face handle.
-	const face& to_face () const;
 	/// Convert the iterator into an face handle.
-	operator face() const;
+	operator const face&() const;
 	/// \}
 
       protected:
@@ -297,20 +295,11 @@ namespace mln
 
       template <typename F, typename E>
       inline
-      const F&
-      complex_relative_iterator_base<F, E>::to_face() const
+      complex_relative_iterator_base<F, E>::operator const F&() const
       {
 	return f_;
       }
 
-      template <typename F, typename E>
-      inline
-      complex_relative_iterator_base<F, E>::operator F() const
-      {
-	mln_precondition(exact(this)->is_valid());
-	return f_;
-      }
-
 
       template <typename F, typename E>
       inline
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '08
                    
                        	* mln/core/site_set/complex_psite.hh
	(operator<<(std::ostream&, const complex_psite<D, P>&)): Here.
---
 milena/ChangeLog                          |    7 +++++++
 milena/mln/core/site_set/complex_psite.hh |    2 +-
 2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 641ceda..cf00b66 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
 2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
 
+	Delegate pretty-printing of complex_psite<D> to topo::face<D>.
+
+	* mln/core/site_set/complex_psite.hh
+	(operator<<(std::ostream&, const complex_psite<D, P>&)): Here.
+
+2008-10-01  Roland Levillain  <roland(a)lrde.epita.fr>
+
 	Fix mln::topo::complex_psite<D, P> conversion to topo::face<D>.
 
 	* mln/core/site_set/complex_psite.hh
diff --git a/milena/mln/core/site_set/complex_psite.hh b/milena/mln/core/site_set/complex_psite.hh
index fdff939..1fe3ccc 100644
--- a/milena/mln/core/site_set/complex_psite.hh
+++ b/milena/mln/core/site_set/complex_psite.hh
@@ -363,7 +363,7 @@ namespace mln
   std::ostream&
   operator<<(std::ostream& ostr, const complex_psite<D, P>& p)
   {
-    return ostr << "(dim = " << p.n() << ", id = " << p.face_id() << ')';
+    return ostr << p.face();
   }
 
 # endif // ! MLN_INCLUDE_ONLY
-- 
1.6.0.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0