[PATCH 7/7] 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. --- 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@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@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
participants (1)
-
Roland Levillain