https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Prefer delegation to impl inheritance for neighborhood.
* doc/tutorial/examples/window.cc: Test make.
* mln/core/internal/basic_window_impl.hh: Remove; its contents
is now directly handled by...
* mln/core/window.hh: ...this class.
* mln/core/internal/neighborhood_impl_mixin.hh: Remove.
* mln/core/internal/neighborhood_base.hh
(is_centered, is_symmetric, sym): Remove; meaningless.
* mln/core/pset_if_piter.hh: Use using and update.
* mln/core/neighb2d.hh (neighb2d): Rely on neighborhood.
Clean code.
* mln/core/neighborhood.hh: New; use delegation to window.
* mln/metal/math/sqrt.hh (mlc_sqrt_int): New.
(sqrt_int_): Help compiler.
(sqrt): Fix params.
* mln/make/neighb2d.hh: New.
* mln/make/window2d.hh: New overload.
* mln/morpho/dilation_elementary.hh (todo): New.
doc/tutorial/examples/window.cc | 11 +
mln/core/internal/neighborhood_base.hh | 44 -----
mln/core/neighb2d.hh | 31 ++-
mln/core/neighborhood.hh | 274 +++++++++++++++++++++++++++++++++
mln/core/pset_if_piter.hh | 18 +-
mln/core/window.hh | 202 ++++++++++++++++++++++--
mln/make/neighb2d.hh | 67 +++++---
mln/make/window2d.hh | 42 +++--
mln/metal/math/sqrt.hh | 18 +-
mln/morpho/dilation_elementary.hh | 2
10 files changed, 592 insertions(+), 117 deletions(-)
Index: doc/tutorial/examples/window.cc
--- doc/tutorial/examples/window.cc (revision 2069)
+++ doc/tutorial/examples/window.cc (working copy)
@@ -53,6 +53,17 @@
std::cout << win << std::endl;
{
+ bool b[9] = { 1, 1, 0,
+ 1, 0, 0,
+ 0, 0, 0 };
+ bool b2[3][3] = { { 1, 1, 0 },
+ { 1, 0, 0 },
+ { 0, 0, 0 } };
+ mln_assertion(make::window2d(b) == make::window2d(b2));
+ mln_assertion(make::window2d(b) == win);
+ }
+
+ {
mln_fwd_piter_(I) p(ima.domain());
for_all(p)
picture(ima, win, p);
Index: mln/core/window.hh
--- mln/core/window.hh (revision 2069)
+++ mln/core/window.hh (working copy)
@@ -36,25 +36,33 @@
* point_, neighb_, etc.
*
* \todo Code other comparisons (< and <=).
+ *
+ * \todo Add static checks in insert methods.
*/
# include <mln/core/internal/window_base.hh>
-# include <mln/core/internal/basic_window_impl.hh>
# include <mln/metal/is_a.hh>
+# include <mln/util/set.hh>
+# include <mln/fun/i2v/all_to.hh>
+# include <mln/norm/linfty.hh>
namespace mln
{
+ // Fwd decls.
+ template <typename V> class dpsites_fwd_piter;
+ template <typename V> class dpsites_bkd_piter;
+
+
/*! \brief Generic window class.
*
* This type of window is just like a set of delta-points. The
* parameter is \c D, type of delta-point.
*/
template <typename D>
- class window : public internal::window_base< D, window<D> >,
- public internal::basic_window_impl< D, window<D> >
+ class window : public internal::window_base< D, window<D> >
{
public:
@@ -64,11 +72,6 @@
*/
window();
- window(const util::set<D>& s)
- {
- this->dps_ = s;
- }
-
/*! \brief Test if the window is centered.
*
* \return True if the delta-point 0 belongs to the window.
@@ -82,6 +85,65 @@
/*! Apply a central symmetry to the target window.
*/
void sym();
+
+
+ /*! \brief Site_Iterator type to browse the points of a basic window
+ * w.r.t. the ordering of delta-points.
+ */
+ typedef dpsites_fwd_piter< window<D> > fwd_qiter;
+
+ /*! \brief Site_Iterator type to browse the points of a basic window
+ * w.r.t. the reverse ordering of delta-points.
+ */
+ typedef dpsites_bkd_piter< window<D> > bkd_qiter;
+
+ /*! \brief Site_Iterator type to browse the points of a basic window
+ * whatever the ordering of delta-points.
+ */
+ typedef fwd_qiter qiter;
+
+
+ /// Give the window size, i.e., the number of delta-sites.
+ unsigned size() const;
+
+ /*! \brief Test if the window is empty (null size; no delta-point).
+ */
+ bool is_empty() const;
+
+ /*! \brief Give the maximum coordinate gap between the window
+ center and a window point.
+ */
+ unsigned delta() const;
+
+ // Give the \p i-th delta-point.
+ const D& dp(unsigned i) const;
+
+
+
+ /// Insert a delta-point \p dp.
+ window<D>& insert(const D& dp);
+
+ /// \{ Insertion of a delta-point with different numbers of
+ /// arguments (coordinates) w.r.t. the dimension.
+ window<D>& insert(const mln_coord(D)& dind); // For 1D.
+
+ window<D>& insert(const mln_coord(D)& drow,
+ const mln_coord(D)& dcol); // For 2D.
+
+ window<D>& insert(const mln_coord(D)& dsli,
+ const mln_coord(D)& drow,
+ const mln_coord(D)& dcol); // For 3D.
+ /// \}
+
+ /// Give the vector of delta-points.
+ const std::vector<D>& std_vector() const;
+
+ /// Hook to the set of D.
+ const util::set<D>& dps_hook_() const;
+
+ private:
+
+ util::set<D> dps_;
};
@@ -114,7 +176,8 @@
template <typename D>
inline
- bool window<D>::is_symmetric() const
+ bool
+ window<D>::is_symmetric() const
{
window<D> cpy = *this;
return cpy.sym() == *this;
@@ -122,7 +185,8 @@
template <typename D>
inline
- bool window<D>::is_centered() const
+ bool
+ window<D>::is_centered() const
{
static const D origin = all_to(0);
return this->dps_.has(origin); // FIXME: Use literal::origin.
@@ -134,22 +198,127 @@
window<D>::sym()
{
window<D> tmp;
- const unsigned n = this->ndpoints();
+ const unsigned n = size();
for (unsigned i = 0; i < n; ++i)
tmp.insert(- this->dp(i));
*this = tmp;
}
+
+ template <typename D>
+ inline
+ bool
+ window<D>::is_empty() const
+ {
+ return dps_.is_empty();
+ }
+
template <typename D>
- std::ostream& operator<<(std::ostream& ostr, const window<D>&
win)
+ inline
+ unsigned
+ window<D>::delta() const
+ {
+ // FIXME: Is-it correct?
+ unsigned d = 0;
+ const unsigned n = size();
+ for (unsigned i = 0; i < n; ++i)
{
- return ostr << win.dps_hook();
+ unsigned dd = norm::linfty(dp(i).to_vec());
+ if (dd > d)
+ d = dd;
+ }
+ return d;
}
template <typename D>
- bool operator==(const window<D>& lhs, const window<D>& rhs)
+ inline
+ unsigned
+ window<D>::size() const
{
- return lhs.dps_hook() == rhs.dps_hook();
+ return dps_.nelements();
+ }
+
+ template <typename D>
+ inline
+ const D&
+ window<D>::dp(unsigned i) const
+ {
+ mln_precondition(i < size());
+ return dps_[i];
+ }
+
+ template <typename D>
+ inline
+ const std::vector<D>&
+ window<D>::std_vector() const
+ {
+ return dps_.vect();
+ }
+
+ template <typename D>
+ inline
+ window<D>&
+ window<D>::insert(const D& dp)
+ {
+ dps_.insert(dp);
+ return *this;
+ }
+
+ template <typename D>
+ inline
+ window<D>&
+ window<D>::insert(const mln_coord(D)& dind)
+ {
+ mlc_bool(D::dim == 1)::check();
+ D dp(dind);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ window<D>&
+ window<D>::insert(const mln_coord(D)& drow,
+ const mln_coord(D)& dcol)
+ {
+ mlc_bool(D::dim == 2)::check();
+ D dp(drow, dcol);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ window<D>&
+ window<D>::insert(const mln_coord(D)& dsli,
+ const mln_coord(D)& drow,
+ const mln_coord(D)& dcol)
+ {
+ mlc_bool(D::dim == 3)::check();
+ D dp(dsli, drow, dcol);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ const util::set<D>&
+ window<D>::dps_hook_() const
+ {
+ return dps_;
+ }
+
+ // Operators.
+
+ template <typename D>
+ std::ostream&
+ operator<<(std::ostream& ostr, const window<D>& win)
+ {
+ return ostr << win.dps_hook_();
+ }
+
+ template <typename D>
+ bool
+ operator==(const window<D>& lhs, const window<D>& rhs)
+ {
+ return lhs.dps_hook_() == rhs.dps_hook_();
}
# endif // ! MLN_INCLUDE_ONLY
@@ -157,4 +326,7 @@
} // end of namespace mln
+# include <mln/core/dpsites_piter.hh>
+
+
#endif // ! MLN_CORE_WINDOW_HH
Index: mln/core/internal/neighborhood_base.hh
--- mln/core/internal/neighborhood_base.hh (revision 2069)
+++ mln/core/internal/neighborhood_base.hh (working copy)
@@ -60,26 +60,6 @@
/// Site associated type.
typedef mln_site(D) site;
-
- /*! \brief Test (as a window) if it is centered so (as a
- * neighborhood) return false.
- *
- * \return Always false.
- */
- bool is_centered() const;
-
- /*! \brief Test (as a window) if it is symmetric so (as a
- * neighborhood) return true.
- *
- * \return Always true.
- */
- bool is_symmetric() const;
-
- /*! Apply (as a window) a central symmetry so (as a
- neighborhood) it is a no-op.
- */
- void sym();
-
protected:
neighborhood_base();
};
@@ -93,30 +73,6 @@
{
}
- template <typename D, typename E>
- inline
- bool
- neighborhood_base<D,E>::is_centered() const
- {
- return false;
- }
-
- template <typename D, typename E>
- inline
- bool
- neighborhood_base<D,E>::is_symmetric() const
- {
- return true;
- }
-
- template <typename D, typename E>
- inline
- void
- neighborhood_base<D,E>::sym()
- {
- // No-op.
- }
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
Index: mln/core/pset_if_piter.hh
--- mln/core/pset_if_piter.hh (revision 2069)
+++ mln/core/pset_if_piter.hh (working copy)
@@ -68,6 +68,14 @@
/// The set site targeted by pi_.
const S& pi_set_from_(const pset_if<S,F>& s) const;
+
+ private:
+ typedef pset_if_piter_<Pi,S,F> self_;
+ typedef internal::piter_adaptor_<Pi, pset_if<S,F>, self_> super_;
+
+ protected:
+ using super_::s_;
+ using super_::pi_;
};
@@ -92,9 +100,9 @@
void
pset_if_piter_<Pi,S,F>::start_()
{
- this->pi_.start();
- while (this->pi_.is_valid() && ! this->s_->pred(this->pi_))
- this->pi_.next();
+ pi_.start();
+ while (pi_.is_valid() && ! s_->pred(pi_))
+ pi_.next();
}
template <typename Pi, typename S, typename F>
@@ -103,8 +111,8 @@
pset_if_piter_<Pi,S,F>::next_()
{
do
- this->pi_.next();
- while (this->pi_.is_valid() && ! this->s_->pred(this->pi_));
+ pi_.next();
+ while (pi_.is_valid() && ! s_->pred(pi_));
}
template <typename Pi, typename S, typename F>
Index: mln/core/neighb2d.hh
--- mln/core/neighb2d.hh (revision 2069)
+++ mln/core/neighb2d.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
@@ -35,7 +35,7 @@
*/
# include <cmath>
-# include <mln/core/neighb.hh>
+# include <mln/core/neighborhood.hh>
# include <mln/core/dpoint2d.hh>
@@ -45,9 +45,17 @@
/*! \brief Type alias for a neighborhood defined on the 2D square
* grid with integer coordinates.
*/
- typedef neighb<dpoint2d> neighb2d;
+ typedef neighborhood<dpoint2d> neighb2d;
+
+}
+
+
+# include <mln/make/neighb2d.hh>
+namespace mln
+{
+
/*! \brief 4-connectivity neighborhood on the 2D grid.
*
* - o -
@@ -104,8 +112,8 @@
static neighb2d it;
if (flower)
{
- it.insert(make::dpoint2d(0, 1));
- it.insert(make::dpoint2d(1, 0));
+ it.insert(0, 1)
+ .insert(1, 0);
flower = false;
}
return it;
@@ -118,10 +126,10 @@
static neighb2d it;
if (flower)
{
- it.insert(make::dpoint2d(0, 1));
- it.insert(make::dpoint2d(1,-1));
- it.insert(make::dpoint2d(1, 0));
- it.insert(make::dpoint2d(1, 1));
+ it.insert(0, 1)
+ .insert(1,-1)
+ .insert(1, 0)
+ .insert(1, 1);
flower = false;
}
return it;
@@ -134,7 +142,7 @@
static neighb2d it;
if (flower)
{
- it.insert(make::dpoint2d(0, 1));
+ it.insert(0, 1);
flower = false;
}
return it;
@@ -147,7 +155,7 @@
static neighb2d it;
if (flower)
{
- it.insert(make::dpoint2d(1, 0));
+ it.insert(1, 0);
flower = false;
}
return it;
@@ -158,4 +166,5 @@
} // end of namespace mln
+
#endif // ! MLN_CORE_NEIGHB2D_HH
Index: mln/core/neighborhood.hh
--- mln/core/neighborhood.hh (revision 0)
+++ mln/core/neighborhood.hh (revision 0)
@@ -0,0 +1,274 @@
+// 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_CORE_NEIGHBORHOOD_HH
+# define MLN_CORE_NEIGHBORHOOD_HH
+
+/*! \file mln/core/neighborhood.hh
+ *
+ * \brief Definition of the generic neighborhood class mln::neighborhood.
+ *
+ * \todo Make naming coherent: we have neighborhood (without '_') but
+ * point_, neighb_, etc.
+ *
+ * \todo Code other comparisons (< and <=).
+ *
+ * \todo Add static checks in insert methods.
+ */
+
+# include <mln/core/internal/neighborhood_base.hh>
+# include <mln/core/window.hh>
+# include <mln/literal/zero.hh>
+
+
+namespace mln
+{
+
+ // Fwd decls.
+ template <typename V> class dpsites_fwd_piter;
+ template <typename V> class dpsites_bkd_piter;
+
+
+ /*! \brief Generic neighborhood class.
+ *
+ * This type of neighborhood is just like a set of delta-points. The
+ * parameter is \c D, type of delta-point.
+ */
+ template <typename D>
+ class neighborhood : public internal::neighborhood_base< D, neighborhood<D>
>
+ {
+ public:
+
+ /*! \brief Constructor without argument.
+ *
+ * The constructed neighborhood is empty.
+ */
+ neighborhood();
+
+ /*! \brief Constructor from a window.
+ *
+ * \pre The window has to be symmetrical and not centered.
+ */
+ neighborhood(const mln::window<D>& win);
+
+ /*! \brief Site_Iterator type to browse the points of a basic neighborhood
+ * w.r.t. the ordering of delta-points.
+ */
+ typedef dpsites_fwd_piter< neighborhood<D> > fwd_niter;
+
+ /*! \brief Site_Iterator type to browse the points of a basic neighborhood
+ * w.r.t. the reverse ordering of delta-points.
+ */
+ typedef dpsites_bkd_piter< neighborhood<D> > bkd_niter;
+
+ /*! \brief Site_Iterator type to browse the points of a basic neighborhood
+ * whatever the ordering of delta-points.
+ */
+ typedef fwd_niter niter;
+
+
+ /// Give the neighborhood size, i.e., the number of delta-sites.
+ unsigned size() const;
+
+ /*! \brief Give the maximum coordinate gap between the neighborhood
+ center and a neighborhood point.
+ */
+ unsigned delta() const;
+
+
+ /// Insert a delta-point \p dp.
+ neighborhood<D>& insert(const D& dp);
+
+ /// \{ Insertion of a delta-point with different numbers of
+ /// arguments (coordinates) w.r.t. the dimension.
+ neighborhood<D>& insert(const mln_coord(D)& dind); // For 1D.
+
+ neighborhood<D>& insert(const mln_coord(D)& drow,
+ const mln_coord(D)& dcol); // For 2D.
+
+ neighborhood<D>& insert(const mln_coord(D)& dsli,
+ const mln_coord(D)& drow,
+ const mln_coord(D)& dcol); // For 3D.
+ /// \}
+
+
+
+ typedef window<D> window;
+
+ mln::window<D> to_window() const
+ {
+ mln::window<D> tmp = win_;
+ D zero = literal::zero;
+ tmp.insert(zero);
+ return tmp;
+ }
+
+ /// Give the vector of delta-points.
+ const std::vector<D>& std_vector() const;
+
+ /// Hook to the set of D.
+ const util::set<D>& dps_hook_() const;
+
+ private:
+
+ mln::window<D> win_;
+ };
+
+
+ // FIXME: Doc!
+ template <typename D>
+ std::ostream& operator<<(std::ostream& ostr, const
neighborhood<D>& nbh);
+
+
+
+ /*! \brief Equality comparison between neighborhoods \p lhs and \p rhs.
+ *
+ * \relates mln::neighborhood<D>
+ */
+ template <typename D>
+ bool operator==(const neighborhood<D>& lhs, const neighborhood<D>&
rhs);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // neighborhood<D>
+
+ template <typename D>
+ inline
+ neighborhood<D>::neighborhood()
+ {
+ // FIXME HERE: Was: mln::metal::is_a<D, Dpoint>::check();
+ // mln::metal::is_a<D, Delta_Point_Site>::check();
+ }
+
+ template <typename D>
+ inline
+ neighborhood<D>::neighborhood(const mln::window<D>& win)
+ {
+ mln_precondition(win.is_symmetric() == true);
+ mln_precondition(win.is_centered() == false);
+ win_ = win;
+ }
+
+ template <typename D>
+ inline
+ unsigned
+ neighborhood<D>::delta() const
+ {
+ mln_precondition(size() != 0);
+ return win_.delta();
+ }
+
+ template <typename D>
+ inline
+ unsigned
+ neighborhood<D>::size() const
+ {
+ return win_.size();
+ }
+
+ template <typename D>
+ inline
+ const std::vector<D>&
+ neighborhood<D>::std_vector() const
+ {
+ return win_.std_vector();
+ }
+
+ template <typename D>
+ inline
+ neighborhood<D>&
+ neighborhood<D>::insert(const D& dp)
+ {
+ win_.insert( dp);
+ win_.insert(-dp);
+ return *this;
+ }
+
+ template <typename D>
+ inline
+ neighborhood<D>&
+ neighborhood<D>::insert(const mln_coord(D)& dind)
+ {
+ mlc_bool(D::dim == 1)::check();
+ D dp(dind);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ neighborhood<D>&
+ neighborhood<D>::insert(const mln_coord(D)& drow,
+ const mln_coord(D)& dcol)
+ {
+ mlc_bool(D::dim == 2)::check();
+ D dp(drow, dcol);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ neighborhood<D>&
+ neighborhood<D>::insert(const mln_coord(D)& dsli,
+ const mln_coord(D)& drow,
+ const mln_coord(D)& dcol)
+ {
+ mlc_bool(D::dim == 3)::check();
+ D dp(dsli, drow, dcol);
+ return insert(dp);
+ }
+
+ template <typename D>
+ inline
+ const util::set<D>&
+ neighborhood<D>::dps_hook_() const
+ {
+ return win_.dps_hook_();
+ }
+
+ // Operators.
+
+ template <typename D>
+ std::ostream& operator<<(std::ostream& ostr, const
neighborhood<D>& nbh)
+ {
+ return ostr << nbh.dps_hook_();
+ }
+
+ template <typename D>
+ bool operator==(const neighborhood<D>& lhs, const neighborhood<D>&
rhs)
+ {
+ return lhs.dps_hook_() == rhs.dps_hook_();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_CORE_NEIGHBORHOOD_HH
Index: mln/metal/math/sqrt.hh
--- mln/metal/math/sqrt.hh (revision 2069)
+++ mln/metal/math/sqrt.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
@@ -37,6 +37,9 @@
# include <mln/metal/int.hh>
+# define mlc_sqrt_int(N) mln::metal::math::sqrt_int<( N )>::value
+
+
namespace mln
{
@@ -54,11 +57,12 @@
template <int n, int lo = 1, int hi = n>
struct sqrt_int_
{
- enum { mid = (lo + hi + 1) / 2 };
-
- enum { value = n < mid * mid
- ? sqrt_int_<n, lo, mid-1>::value
- : sqrt_int_<n, mid, hi>::result };
+ enum {
+ mid = (lo + hi + 1) / 2,
+ val_lo = sqrt_int_<n, lo, mid-1>::value,
+ val_hi = sqrt_int_<n, mid, hi>::value
+ };
+ enum { value = n < mid * mid ? val_lo : val_hi };
};
template<int n, int m>
@@ -92,7 +96,7 @@
// sqrt<N>
- template <typename X, typename N>
+ template <typename N>
struct sqrt;
template <int n>
Index: mln/make/neighb2d.hh
--- mln/make/neighb2d.hh (revision 2069)
+++ mln/make/neighb2d.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
@@ -25,17 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MAKE_WINDOW2D_HH
-# define MLN_MAKE_WINDOW2D_HH
+#ifndef MLN_MAKE_NEIGHB2D_HH
+# define MLN_MAKE_NEIGHB2D_HH
-/*! \file mln/make/window2d.hh
+/*! \file mln/make/neighb2d.hh
*
- * \brief Routine to create an mln::window2d.
+ * \brief Routine to create an mln::neighb2d.
*/
-# include <cmath>
-# include <mln/core/window2d.hh>
-# include <mln/make/dpoint2d.hh>
+# include <mln/make/window2d.hh>
namespace mln
@@ -44,32 +42,53 @@
namespace make
{
- /*! \brief Create an mln::window2d.
+ /*! \brief Create a mln::neighb2d.
*
* \param[in] values Array of Booleans.
*
- * \pre The array size, \c M, has to be a square of an odd integer.
+ * \pre The array size, \c S, has to be a square of an odd integer.
*
- * \return A 2D window.
+ * \return A 2D neighborhood.
*/
- template <unsigned M>
- mln::window2d window2d(bool (&values)[M]);
+ template <unsigned S>
+ mln::neighb2d neighb2d(bool (&values)[S]);
+
+
+ /*! \brief Create a mln::neighb2d.
+ *
+ * \param[in] values Double-array of Booleans.
+ *
+ * \pre \c R and \c C, defining the array size, have to be odd.
+ *
+ * \return A 2D neighborhood.
+ */
+ template <unsigned R, unsigned C>
+ mln::neighb2d neighb2d(bool (&values)[R][C]);
# ifndef MLN_INCLUDE_ONLY
- template <unsigned M>
+ template <unsigned S>
+ inline
+ mln::neighb2d
+ neighb2d(bool (&values)[S])
+ {
+ enum { h = mlc_sqrt_int(S) / 2 };
+ mlc_bool((2 * h + 1) * (2 * h + 1) == S)::check();
+ mln::window2d win = make::window2d(values);
+ neighb2d tmp(win);
+ return tmp;
+ }
+
+ template <unsigned R, unsigned C>
inline
- mln::window2d window2d(bool (&values)[M])
+ mln::neighb2d
+ neighb2d(bool (&values)[R][C])
{
- int h = unsigned(std::sqrt(float(M))) / 2;
- assert((2 * h + 1) * (2 * h + 1) == M);
- mln::window2d tmp;
- unsigned i = 0;
- for (int row = - h; row <= h; ++row)
- for (int col = - h; col <= h; ++col)
- if (values[i++])
- tmp.insert(make::dpoint2d(row, col));
+ mlc_bool(R % 2 == 1)::check();
+ mlc_bool(C % 2 == 1)::check();
+ mln::window2d win = make::window2d(values);
+ neighb2d tmp(win);
return tmp;
}
@@ -80,4 +99,4 @@
} // end of namespace mln
-#endif // ! MLN_MAKE_WINDOW2D_HH
+#endif // ! MLN_MAKE_NEIGHB2D_HH
Index: mln/make/window2d.hh
--- mln/make/window2d.hh (revision 2069)
+++ mln/make/window2d.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,9 +33,8 @@
* \brief Routine to create an mln::window2d.
*/
-# include <cmath>
# include <mln/core/window2d.hh>
-# include <mln/make/dpoint2d.hh>
+# include <mln/metal/math/sqrt.hh>
namespace mln
@@ -48,28 +47,49 @@
*
* \param[in] values Array of Booleans.
*
- * \pre The array size, \c M, has to be a square of an odd integer.
+ * \pre The array size, \c S, has to be a square of an odd integer.
*
* \return A 2D window.
*/
- template <unsigned M>
- mln::window2d window2d(bool (&values)[M]);
+ template <unsigned S>
+ mln::window2d window2d(bool (&values)[S]);
+
+
+ template <unsigned R, unsigned C>
+ mln::window2d window2d(bool (&values)[R][C]);
# ifndef MLN_INCLUDE_ONLY
- template <unsigned M>
+ template <unsigned S>
inline
- mln::window2d window2d(bool (&values)[M])
+ mln::window2d
+ window2d(bool (&values)[S])
{
- int h = unsigned(std::sqrt(float(M))) / 2;
- assert((2 * h + 1) * (2 * h + 1) == M);
+ enum { h = mlc_sqrt_int(S) / 2 };
+ mlc_bool((2 * h + 1) * (2 * h + 1) == S)::check();
mln::window2d tmp;
unsigned i = 0;
for (int row = - h; row <= h; ++row)
for (int col = - h; col <= h; ++col)
if (values[i++])
- tmp.insert(make::dpoint2d(row, col));
+ tmp.insert(row, col);
+ return tmp;
+ }
+
+ template <unsigned R, unsigned C>
+ inline
+ mln::window2d
+ window2d(bool (&values)[R][C])
+ {
+ mlc_bool(R % 2 == 1)::check();
+ mlc_bool(C % 2 == 1)::check();
+ const int drow = int(R) / 2, dcol = int(C) / 2;
+ mln::window2d tmp;
+ for (int row = - drow; row <= drow; ++row)
+ for (int col = - dcol; col <= dcol; ++col)
+ if (values[row + drow][col + dcol])
+ tmp.insert(row, col);
return tmp;
}
Index: mln/morpho/dilation_elementary.hh
--- mln/morpho/dilation_elementary.hh (revision 2069)
+++ mln/morpho/dilation_elementary.hh (working copy)
@@ -30,6 +30,8 @@
/// \file mln/morpho/dilation_elementary.hh
/// \brief Morphological elementary dilation.
+///
+/// \todo Write specific code.
# include <mln/morpho/dilation.hh>