* mln/topo/skeleton/breadth_first_thinning.hh
(mln::topo::skeleton::breadth_first_thinning): Add a parameter I.
Take an Image<I> as argument instead of a bin_2complex_image3df.
Adjust return type.
Pass the `detach' function as an additional argument.
Adjust and complete the documentation.
* apps/statues/mesh-complex-skel.cc (main): Adjust caller.
* mln/topo/detach.hh (mln::topo::detach<D, G, V>): Get rid of
parameter V (replace it by `bool'), and turn the signature of
the function into...
(mln::topo::detach<D, G>): ...this.
Remove a (now) useless precondition.
---
milena/ChangeLog | 17 +++++
milena/apps/statues/mesh-complex-skel.cc | 5 +-
milena/mln/topo/detach.hh | 9 +--
milena/mln/topo/skeleton/breadth_first_thinning.hh | 71 +++++++++++---------
4 files changed, 65 insertions(+), 37 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 8b483cf..6ca5470 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,22 @@
2009-04-07 Roland Levillain <roland(a)lrde.epita.fr>
+ Make mln::topo::skeleton::breadth_first_thinning more generic.
+
+ * mln/topo/skeleton/breadth_first_thinning.hh
+ (mln::topo::skeleton::breadth_first_thinning): Add a parameter I.
+ Take an Image<I> as argument instead of a bin_2complex_image3df.
+ Adjust return type.
+ Pass the `detach' function as an additional argument.
+ Adjust and complete the documentation.
+ * apps/statues/mesh-complex-skel.cc (main): Adjust caller.
+ * mln/topo/detach.hh (mln::topo::detach<D, G, V>): Get rid of
+ parameter V (replace it by `bool'), and turn the signature of
+ the function into...
+ (mln::topo::detach<D, G>): ...this.
+ Remove a (now) useless precondition.
+
+2009-04-07 Roland Levillain <roland(a)lrde.epita.fr>
+
Split apps/statues/mesh-complex-skel.
* apps/statues/mesh-complex-skel.cc: Split reusable parts into...
diff --git a/milena/apps/statues/mesh-complex-skel.cc
b/milena/apps/statues/mesh-complex-skel.cc
index 85a1581..77a11cf 100644
--- a/milena/apps/statues/mesh-complex-skel.cc
+++ b/milena/apps/statues/mesh-complex-skel.cc
@@ -44,6 +44,7 @@
#include <mln/topo/is_n_face.hh>
#include <mln/topo/is_simple_cell.hh>
+#include <mln/topo/detach.hh>
#include <mln/topo/skeleton/breadth_first_thinning.hh>
#include <mln/io/off/load.hh>
@@ -198,7 +199,9 @@ main(int argc, char* argv[])
skeleton routine to restrict the iteration to 2-cells. */
mln::topo::is_n_face<bin_ima_t::dim> constraint_p;
bin_ima_t skel =
- mln::topo::skeleton::breadth_first_thinning(surface, nbh, is_simple_p,
+ mln::topo::skeleton::breadth_first_thinning(surface, nbh,
+ is_simple_p,
+ mln::topo::detach<D, G>,
constraint_p);
/*---------.
diff --git a/milena/mln/topo/detach.hh b/milena/mln/topo/detach.hh
index e80a8a9..daae5b2 100644
--- a/milena/mln/topo/detach.hh
+++ b/milena/mln/topo/detach.hh
@@ -47,20 +47,19 @@ namespace mln
\pre \a f is a facet (it does not belong to any face of higher
dimension).
\pre \a ima is an image of Boolean values. */
- template <unsigned D, typename G, typename V>
+ template <unsigned D, typename G>
void
- detach(const complex_psite<D, G>& f, complex_image<D, G, V>&
ima);
+ detach(const complex_psite<D, G>& f, complex_image<D, G, bool>&
ima);
# ifndef MLN_INCLUDE_ONLY
- template <unsigned D, typename G, typename V>
+ template <unsigned D, typename G>
inline
void
- detach(const complex_psite<D, G>& f, complex_image<D, G, V>&
ima)
+ detach(const complex_psite<D, G>& f, complex_image<D, G, bool>&
ima)
{
mln_precondition(topo::is_facet(f));
- mlc_equal(V, bool)::check();
typedef complex_psite<D, G> psite;
typedef p_set<psite> faces_t;
diff --git a/milena/mln/topo/skeleton/breadth_first_thinning.hh
b/milena/mln/topo/skeleton/breadth_first_thinning.hh
index ee4c5f2..6c28410 100644
--- a/milena/mln/topo/skeleton/breadth_first_thinning.hh
+++ b/milena/mln/topo/skeleton/breadth_first_thinning.hh
@@ -36,9 +36,10 @@
# include <mln/core/routine/duplicate.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+
# include <mln/core/site_set/p_set.hh>
-# include <mln/core/alias/complex_image.hh>
-# include <mln/topo/detach.hh>
# include <mln/fun/p2b/tautology.hh>
@@ -51,49 +52,46 @@ namespace mln
namespace skeleton
{
- /* FIXME: Use a generic `I' instead of
- `mln::bin_2complex_image3df', and adjust the
- documentation. */
-
- /* FIXME: Rename `constraint' to a verb or adjective?
- (validate_constraint? satisfy_constraint? pass_constraint?
- is_satisfying?) */
-
- /** \brief Breadth-First Thinning.
+ /** \brief Skeleton by Breadth-First Thinning.
- A semi-generic implementation of a binary skeleton on a triangle
- surface (mesh).
+ A generic implementation of the computation of a skeleton
+ using a breadth-first thinning on a binary.
\param input The input image.
\param nbh The adjacency relation between triangles.
- \param is_simple The predicate on the simplicity of points (sites).
+ \param is_simple The predicate on the simplicity of points
+ (sites). This functor must provide a method
+ <tt>void set_image(const
Image<I>&)</tt>.
+ \param detach A function used to detach a cell from \a input.
\param constraint A constraint on point (site); if it
returns \c false for a point, this point
will not be removed. */
- template <typename N, typename F, typename G>
- bin_2complex_image3df
- breadth_first_thinning(const bin_2complex_image3df& input,
+ template <typename I, typename N, typename F, typename G, typename H>
+ mln_concrete(I)
+ breadth_first_thinning(const Image<I>& input,
const Neighborhood<N>& nbh,
Function_p2b<F>& is_simple,
- const Function_p2b<G>& constraint =
+ G detach,
+ const Function_p2b<H>& constraint =
fun::p2b::tautology());
# ifndef MLN_INCLUDE_ONLY
- template <typename N, typename F, typename G>
+ template <typename I, typename N, typename F, typename G, typename H>
inline
- bin_2complex_image3df
- breadth_first_thinning(const bin_2complex_image3df& input,
+ mln_concrete(I)
+ breadth_first_thinning(const Image<I>& input_,
const Neighborhood<N>& nbh_,
Function_p2b<F>& is_simple_,
- const Function_p2b<G>& constraint_)
+ G detach,
+ const Function_p2b<H>& constraint_)
{
+ const I& input = exact(input_);
const N& nbh = exact(nbh_);
F& is_simple = exact(is_simple_);
- const G& constraint = exact(constraint_);
+ const H& constraint = exact(constraint_);
- typedef bin_2complex_image3df I;
typedef mln_psite(I) psite;
I output = duplicate(input);
@@ -120,18 +118,29 @@ namespace mln
while (!set.is_empty())
{
set_t next_set;
- // FIXME: Use a piter on SET instead of this hand-made iteration.
+
+ /* FIXME: Using the following code does not work (it does
+ compiles, but does not behave like the code using a
+ hand-made loop). There must be a bug somewhere in
+ p_set or p_indexed_psite. */
+# if 0
+ mln_piter(set_t) ps(set);
+ for_all(ps);
+ {
+ // Same remark as above.
+ psite p = p_;
+# endif
for (unsigned i = 0; i < set.nsites(); ++i)
{
psite p = set[i];
- /* FIXME: We compute the cell and attachment of P
- twice: within is_simple and within detach. How
- could we reuse this elegantly, without breaking the
- genericity of the skeleton algorithm? */
+
+ /* FIXME: We compute the cell and attachment of P twice:
+ during the call to is_simple() and within detach().
+ How could we reuse this elegantly, without breaking
+ the genericity of the skeleton algorithm? */
if (constraint(p) && is_simple(p))
{
- // FIXME: `detach' could be a functor, as is `is_simple'.
- topo::detach(p, output);
+ detach(p, output);
mln_niter(N) n(nbh, p);
for_all(n)
if (output.domain().has(n)
--
1.6.1.2