
* headers.mk: update distributed file list. * mln/core/image/all.hh, * mln/core/image/graph_elt_neighborhood_if.hh, * mln/core/image/graph_elt_window_if.hh, * mln/core/image/graph_window_if_piter.hh: add a new custom window/neighborhood type for graphes. * mln/core/image/edge_image.hh: add missing operator(). * mln/core/site_set/p_edges.hh, * mln/core/image/vertex_image.hh: update doc. * mln/core/internal/is_masked_impl_selector.hh: new implementation selector for graph_elt_window_if_piter. * mln/core/internal/neighb_niter_impl.hh: add support for graph_elt_neighborhood_if. * mln/core/macros.hh: add mln_graph. * mln/util/vertex.hh, * mln/core/site_set/p_graph_piter.hh: add edge_with member. * mln/graph/all.hh, * mln/graph/labeling.hh, * mln/graph/to_neighb.hh, * mln/graph/to_win.hh: new routines. * mln/make/edge_image.hh: add a new overload to handle p_edges with no sites. * mln/util/graph.hh: add a new edge() member. * mln/util/internal/graph_nbh_iter_base.hh: add element(). * tests/core/other/Makefile.am, * tests/core/other/graph_elt_neighborhood_if.cc, * tests/core/other/graph_elt_window_if.cc, * tests/graph/Makefile.am, * tests/graph/labeling.cc, * tests/unit_test/unit-tests.mk: add new tests for new routines. --- milena/ChangeLog | 47 ++++ milena/headers.mk | 5 + milena/mln/core/image/all.hh | 4 + milena/mln/core/image/edge_image.hh | 26 +++ milena/mln/core/image/graph_elt_neighborhood_if.hh | 97 +++++++++ milena/mln/core/image/graph_elt_window_if.hh | 222 ++++++++++++++++++++ milena/mln/core/image/graph_window_if_piter.hh | 219 +++++++++++++++++++ milena/mln/core/image/vertex_image.hh | 8 +- .../mln/core/internal/is_masked_impl_selector.hh | 145 +++++++++++++ milena/mln/core/internal/neighb_niter_impl.hh | 22 ++- milena/mln/core/macros.hh | 6 + milena/mln/core/site_set/p_edges.hh | 2 +- milena/mln/core/site_set/p_graph_piter.hh | 19 ++- milena/mln/graph/all.hh | 3 + milena/mln/graph/labeling.hh | 106 ++++++++++ milena/mln/graph/to_neighb.hh | 84 ++++++++ milena/mln/graph/to_win.hh | 84 ++++++++ milena/mln/make/edge_image.hh | 55 +++++- milena/mln/util/graph.hh | 27 +++ milena/mln/util/internal/graph_nbh_iter_base.hh | 11 + milena/mln/util/vertex.hh | 26 +++- milena/tests/core/other/Makefile.am | 4 + .../tests/core/other/graph_elt_neighborhood_if.cc | 199 ++++++++++++++++++ milena/tests/core/other/graph_elt_window_if.cc | 200 ++++++++++++++++++ milena/tests/graph/Makefile.am | 6 + milena/tests/graph/labeling.cc | 122 +++++++++++ milena/tests/unit_test/unit-tests.mk | 10 + 27 files changed, 1740 insertions(+), 19 deletions(-) create mode 100644 milena/mln/core/image/graph_elt_neighborhood_if.hh create mode 100644 milena/mln/core/image/graph_elt_window_if.hh create mode 100644 milena/mln/core/image/graph_window_if_piter.hh create mode 100644 milena/mln/core/internal/is_masked_impl_selector.hh create mode 100644 milena/mln/graph/labeling.hh create mode 100644 milena/mln/graph/to_neighb.hh create mode 100644 milena/mln/graph/to_win.hh create mode 100644 milena/tests/core/other/graph_elt_neighborhood_if.cc create mode 100644 milena/tests/core/other/graph_elt_window_if.cc create mode 100644 milena/tests/graph/labeling.cc diff --git a/milena/ChangeLog b/milena/ChangeLog index 443badb..85607ae 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,50 @@ +2009-05-05 Guillaume Lazzara <lazzara@lrde.epita.fr> + + Improve graph support. + + * headers.mk: update distributed file list. + + * mln/core/image/all.hh, + * mln/core/image/graph_elt_neighborhood_if.hh, + * mln/core/image/graph_elt_window_if.hh, + * mln/core/image/graph_window_if_piter.hh: add a new + custom window/neighborhood type for graphes. + + * mln/core/image/edge_image.hh: add missing operator(). + + * mln/core/site_set/p_edges.hh, + * mln/core/image/vertex_image.hh: update doc. + + * mln/core/internal/is_masked_impl_selector.hh: new implementation + selector for graph_elt_window_if_piter. + + * mln/core/internal/neighb_niter_impl.hh: add support for + graph_elt_neighborhood_if. + + * mln/core/macros.hh: add mln_graph. + + * mln/util/vertex.hh, + * mln/core/site_set/p_graph_piter.hh: add edge_with member. + + * mln/graph/all.hh, + * mln/graph/labeling.hh, + * mln/graph/to_neighb.hh, + * mln/graph/to_win.hh: new routines. + + * mln/make/edge_image.hh: add a new overload to handle p_edges with + no sites. + + * mln/util/graph.hh: add a new edge() member. + + * mln/util/internal/graph_nbh_iter_base.hh: add element(). + + * tests/core/other/Makefile.am, + * tests/core/other/graph_elt_neighborhood_if.cc, + * tests/core/other/graph_elt_window_if.cc, + * tests/graph/Makefile.am, + * tests/graph/labeling.cc, + * tests/unit_test/unit-tests.mk: add new tests for new routines. + 2009-05-04 Fabien Freling <fabien.freling@lrde.epita.fr> Add overload for creating 2D neighborhood with a functor. diff --git a/milena/headers.mk b/milena/headers.mk index bc25a88..6631c1d 100644 --- a/milena/headers.mk +++ b/milena/headers.mk @@ -873,6 +873,7 @@ mln/core/internal/graph_psite_base.hh \ mln/core/internal/run_image.hh \ mln/core/internal/pixel_impl.hh \ mln/core/internal/site_set_base.hh \ +mln/core/internal/is_masked_impl_selector.hh \ mln/core/internal/image_value_morpher.hh \ mln/core/internal/site_iterator_base.hh \ mln/core/internal/complex_neighborhood_base.hh \ @@ -1075,6 +1076,7 @@ mln/core/image/image2d.hh \ mln/core/image/ch_piter.hh \ mln/core/image/complex_windows.hh \ mln/core/image/violent_cast_image.hh \ +mln/core/image/graph_elt_neighborhood_if.hh \ mln/core/image/mono_obased_rle_encode.hh \ mln/core/image/value_encode.hh \ mln/core/image/essential.hh \ @@ -1207,6 +1209,9 @@ mln/estim/all.hh \ mln/estim/sum.hh \ mln/estim/mean.hh \ mln/estim/essential.hh \ +mln/graph/labeling.hh \ +mln/graph/to_win.hh \ +mln/graph/to_neighb.hh \ mln/graph/all.hh \ mln/graph/attribute/representative.hh \ mln/graph/attribute/card.hh \ diff --git a/milena/mln/core/image/all.hh b/milena/mln/core/image/all.hh index c4094af..6e04562 100644 --- a/milena/mln/core/image/all.hh +++ b/milena/mln/core/image/all.hh @@ -53,8 +53,12 @@ # include <mln/core/image/extension_ima.hh> # include <mln/core/image/extension_val.hh> # include <mln/core/image/flat_image.hh> +# include <mln/core/image/graph_elt_neighborhood.hh> +# include <mln/core/image/graph_elt_neighborhood_if.hh> # include <mln/core/image/graph_elt_window.hh> +# include <mln/core/image/graph_elt_window_if.hh> # include <mln/core/image/graph_window_piter.hh> +# include <mln/core/image/graph_window_if_piter.hh> # include <mln/core/image/image1d.hh> # include <mln/core/image/image2d.hh> # include <mln/core/image/image3d.hh> diff --git a/milena/mln/core/image/edge_image.hh b/milena/mln/core/image/edge_image.hh index 9b5fb75..76d7fe0 100644 --- a/milena/mln/core/image/edge_image.hh +++ b/milena/mln/core/image/edge_image.hh @@ -132,6 +132,12 @@ namespace mln edge_image<P,V,G> > super_; public: + typedef typename super_::rvalue rvalue; + typedef typename super_::lvalue lvalue; + + /// The type of the underlying graph. + typedef G graph_t; + /// Skeleton type. typedef edge_image< tag::psite_<P>, tag::value_<V>, @@ -167,6 +173,13 @@ namespace mln const Function_i2v<FV>& edge_values); /// @} + /// Value accessors/operators overloads. + /// @{ + using super_::operator(); + rvalue operator()(unsigned e_id) const; + lvalue operator()(unsigned e_id); + /// @} + }; template <typename P, typename V, typename G, typename J> @@ -278,6 +291,19 @@ namespace mln mlc_equal(mln_result(FV),V)::check(); } + template <typename P, typename V, typename G> + typename edge_image<P,V,G>::rvalue + edge_image<P,V,G>::operator()(unsigned e_id) const + { + return this->data_->f_(e_id); + } + + template <typename P, typename V, typename G> + typename edge_image<P,V,G>::lvalue + edge_image<P,V,G>::operator()(unsigned e_id) + { + return this->data_->f_(e_id); + } # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/core/image/graph_elt_neighborhood_if.hh b/milena/mln/core/image/graph_elt_neighborhood_if.hh new file mode 100644 index 0000000..eb2f4fa --- /dev/null +++ b/milena/mln/core/image/graph_elt_neighborhood_if.hh @@ -0,0 +1,97 @@ +// Copyright (C) 2009 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_GRAPH_ELT_NEIGHBORHOOD_IF_HH +# define MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_IF_HH + +/// \file mln/core/image/graph_elt_neighborhood_if.hh +/// +/// Definition of the elementary ``neighborhood_if'' on a graph. + +# include <mln/core/neighb.hh> +# include <mln/core/internal/is_masked_impl_selector.hh> +# include <mln/core/image/graph_elt_window_if.hh> + + +namespace mln +{ + + /// Elementary neighborhood_if on graph class. + template <typename G, typename S, typename I> + struct graph_elt_neighborhood_if + : public neighb< graph_elt_window_if<G,S,I> > + { + typedef neighb< graph_elt_window_if<G,S,I> > super_; + + ///Constructors + /// \@{ + /// Construct an invalid neighborhood. + graph_elt_neighborhood_if(); + /// \param[in] mask A graph image of Boolean. + graph_elt_neighborhood_if(const Image<I>& mask); + /// \@} + + /// Return the graph image used as mask. + const I& mask() const; + + }; + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename G, typename S, typename I> + inline + graph_elt_neighborhood_if<G,S,I>::graph_elt_neighborhood_if() + { + } + + + template <typename G, typename S, typename I> + inline + graph_elt_neighborhood_if<G,S,I>::graph_elt_neighborhood_if(const Image<I>& mask) + { + this->hook_win_().change_mask(mask); + } + + + template <typename G, typename S, typename I> + inline + const I& + graph_elt_neighborhood_if<G,S,I>::mask() const + { + return this->hook_win_().mask(); + } + + +# endif // ! MLN_INCLUDE_ONLY + +} + +#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_IF_HH + diff --git a/milena/mln/core/image/graph_elt_window_if.hh b/milena/mln/core/image/graph_elt_window_if.hh new file mode 100644 index 0000000..dd4f6d9 --- /dev/null +++ b/milena/mln/core/image/graph_elt_window_if.hh @@ -0,0 +1,222 @@ +// Copyright (C) 2009 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_GRAPH_ELT_WINDOW_IF_HH +# define MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_IF_HH + +/// \file mln/core/image/graph_elt_window_if.hh +/// +/// Definition of a custom ``window'' on a graph. +/// +/// \todo Allow to pass a function instead of an image. + +# include <mln/core/concept/window.hh> +# include <mln/core/internal/neighborhood_base.hh> +# include <mln/core/internal/graph_window_base.hh> +# include <mln/core/internal/is_masked_impl_selector.hh> +# include <mln/core/image/graph_window_if_piter.hh> + + +namespace mln +{ + + /// Forward declaration + template <typename G, typename S, typename I> class graph_elt_window_if; + template <typename G, typename F> struct p_edges; + template <typename G, typename F> struct p_vertices; + + + namespace internal + { + + template <typename G, typename S, typename I, typename E> + struct neighborhood_impl<graph_elt_window_if<G,S,I>,E> + : public neighborhood_extra_impl<graph_elt_window_if<G,S,I>,E> + { + }; + + + /// Default + /// The given site set parameter is not supported yet! + template <typename G, typename S> + struct graph_window_if_iter_dispatch; + + template <typename G, typename F> + struct graph_window_if_iter_dispatch<G, p_edges<G,F> > + { + typedef mln_edge_nbh_edge_fwd_iter(G) nbh_fwd_iter_; + typedef mln_edge_nbh_edge_bkd_iter(G) nbh_bkd_iter_; + }; + + template <typename G, typename F> + struct graph_window_if_iter_dispatch<G, p_vertices<G,F> > + { + typedef mln_vertex_nbh_vertex_fwd_iter(G) nbh_fwd_iter_; + typedef mln_vertex_nbh_vertex_bkd_iter(G) nbh_bkd_iter_; + }; + + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename G, typename S, typename I> + struct window_< mln::graph_elt_window_if<G,S,I> > + { + typedef trait::window::size::unknown size; + typedef trait::window::support::irregular support; + typedef trait::window::definition::varying definition; + }; + + } // end of namespace mln::trait + + + /// Custom window on graph class. It is defined thanks to a mask. + /// + /// \p G is the graph type. + /// \p S is the image site set. + /// \p I is the graph image the type used as mask. + /// + template <typename G, typename S, typename I> + class graph_elt_window_if + : public graph_window_base<mln_result(S::fun_t), + graph_elt_window_if<G,S,I> >, + public internal::graph_window_if_iter_dispatch<G,S>, + private mlc_is(mln_value(I), bool)::check_t + { + typedef graph_elt_window_if<G,S,I> self_; + typedef internal::graph_window_if_iter_dispatch<G,S> super_; + + typedef typename super_::nbh_fwd_iter_ nbh_fwd_iter_; + typedef typename super_::nbh_bkd_iter_ nbh_bkd_iter_; + + public: + /// The type of the image used as mask. + typedef I mask_t; + + /// Constructor. + /// \@{ + /// Default. Construct an invalid window. + graph_elt_window_if(); + + /// \param[in] graph_image A graph image. + /// + /// \sa vertex_image, edge_image. + graph_elt_window_if(const Image<I>& mask); + /// \@} + + /// Associated types. + /// \{ + + /// The image domain on which this window iterates on. + typedef S target; + + /// The type of psite corresponding to the window. + typedef mln_psite(target) psite; + + /// Site_Iterator type to browse the psites of the window + /// w.r.t. the ordering of vertices. + typedef graph_window_if_piter<target,self_,nbh_fwd_iter_> fwd_qiter; + + /// Site_Iterator type to browse the psites of the window + /// w.r.t. the reverse ordering of vertices. + typedef graph_window_if_piter<target,self_,nbh_bkd_iter_> bkd_qiter; + + /// The default qiter type. + typedef fwd_qiter qiter; + /// \} + + /// Return the graph image used as mask. + const I& mask() const; + + /// Change mask image. + void change_mask(const Image<I>& mask); + + /// Return true by default. + bool is_valid() const; + + private: + // FIXME: Should be const! + I mask_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename G, typename S, typename I> + inline + graph_elt_window_if<G,S,I>::graph_elt_window_if() + { + } + + + template <typename G, typename S, typename I> + inline + graph_elt_window_if<G,S,I>::graph_elt_window_if(const Image<I>& mask) + : mask_(exact(mask)) + { + } + + + template <typename G, typename S, typename I> + inline + const I& + graph_elt_window_if<G,S,I>::mask() const + { + return mask_; + } + + + template <typename G, typename S, typename I> + inline + void + graph_elt_window_if<G,S,I>::change_mask(const Image<I>& mask) + { + mln_precondition(exact(mask).is_valid()); + mask_ = exact(mask); + } + + template <typename G, typename S, typename I> + inline + bool + graph_elt_window_if<G,S,I>::is_valid() const + { + return mask_.is_valid(); + } + + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + + +#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_IF_HH diff --git a/milena/mln/core/image/graph_window_if_piter.hh b/milena/mln/core/image/graph_window_if_piter.hh new file mode 100644 index 0000000..a3245d1 --- /dev/null +++ b/milena/mln/core/image/graph_window_if_piter.hh @@ -0,0 +1,219 @@ +// Copyright (C) 2009 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_GRAPH_WINDOW_IF_PITER_HH +# define MLN_CORE_IMAGE_GRAPH_WINDOW_IF_PITER_HH + +/// \file mln/core/image/graph_window_if_piter.hh +/// +/// Definition of a site iterator on a custom graph window. + + +# include <mln/core/internal/is_masked_impl_selector.hh> +# include <mln/core/internal/site_relative_iterator_base.hh> + + +namespace mln +{ + + // Forward declaration. + template <typename S, typename I> class p_graph_piter; + + + + /// Forward iterator on line graph window. + template <typename S, typename W, typename I> + class graph_window_if_piter + : public internal::site_relative_iterator_base< W, + graph_window_if_piter<S,W,I> >, + public internal::is_masked_impl_selector<S, + mln_domain(W::mask_t), + graph_window_if_piter<S,W,I> > + { + typedef graph_window_if_piter<S,W,I> self_; + typedef internal::site_relative_iterator_base<W,self_> super_; + + public: + /// Associated types + /// \{ + typedef mln_result(S::fun_t) P; + /// \} + + /// Construction. + /// \{ + graph_window_if_piter(); + template <typename Pref> + graph_window_if_piter(const Window<W>& win, + 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_(); + + /// Do some work while setting the reference site. + template <typename Pref> + void center_at_(const Pref& c); + + /// Do some work while setting the reference site. + template <typename I2> + void center_at_(const p_graph_piter<S, I2>& c); + + /// Return the graph element pointed by this iterator. + const mln_graph_element(S)& element() const; + + /// Compute the current psite. + mln_psite(W) compute_p_() const; + + /// Return the graph element id. + /// FIXME: we do not want to have this member since there is an + /// automatic conversion to the graph element. + /// C++ does not seem to use this conversion operator. + unsigned id() const; + /// \} + + private: + I iter_; + /// The underlying window. + using super_::s_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename S, typename W, typename I> + inline + graph_window_if_piter<S,W,I>::graph_window_if_piter() + { + } + + template <typename S, typename W, typename I> + template <typename Pref> + inline + graph_window_if_piter<S,W,I>::graph_window_if_piter(const Window<W>& win, + const Pref& p_ref) + { + this->center_at(p_ref); + this->change_target(exact(win)); + + mln_postcondition(!this->is_valid()); + } + + template <typename S, typename W, typename I> + inline + bool + graph_window_if_piter<S,W,I>::is_valid_() const + { + return iter_.is_valid(); + } + + template <typename S, typename W, typename I> + inline + void + graph_window_if_piter<S,W,I>::invalidate_() + { + iter_.invalidate(); + } + + template <typename S, typename W, typename I> + inline + void + graph_window_if_piter<S,W,I>::do_start_() + { + iter_.start(); + while (iter_.is_valid() && is_masked(this->c_->element(), iter_)) + iter_.next(); + } + + template <typename S, typename W, typename I> + inline + void + graph_window_if_piter<S,W,I>::do_next_() + { + iter_.next(); + while (iter_.is_valid() && is_masked(this->c_->element(), iter_)) + iter_.next(); + } + + template <typename S, typename W, typename I> + template <typename Pref> + inline + void + graph_window_if_piter<S,W,I>::center_at_(const Pref& c) + { + iter_.center_at(c.p_hook_()); + } + + template <typename S, typename W, typename I> + template <typename I2> + inline + void + graph_window_if_piter<S,W,I>::center_at_(const p_graph_piter<S, I2>& c) + { + iter_.center_at(c.hook_elt_()); + } + + template <typename S, typename W, typename I> + inline + mln_psite(W) + graph_window_if_piter<S,W,I>::compute_p_() const + { + return mln_psite(S)(this->center().site_set(), iter_.id()); + } + + template <typename S, typename W, typename I> + inline + const mln_graph_element(S)& + graph_window_if_piter<S,W,I>::element() const + { + return iter_; + } + + template <typename S, typename W, typename I> + inline + unsigned + graph_window_if_piter<S,W,I>::id() const + { + return iter_.id(); + } + + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_CORE_IMAGE_GRAPH_WINDOW_IF_PITER_HH diff --git a/milena/mln/core/image/vertex_image.hh b/milena/mln/core/image/vertex_image.hh index 8184e3f..3498ec7 100644 --- a/milena/mln/core/image/vertex_image.hh +++ b/milena/mln/core/image/vertex_image.hh @@ -138,6 +138,9 @@ namespace mln typedef typename super_::rvalue rvalue; typedef typename super_::lvalue lvalue; + /// The type of the underlying graph. + typedef G graph_t; + /// Function mapping graph elements to sites. typedef typename internal::vfsite_selector<P,G>::site_function_t site_function_t; @@ -164,12 +167,9 @@ namespace mln const Function_i2v<FV>& vertex_values); /// @} - using super_::operator(); - /// Value accessors/operators overloads. /// @{ -// rvalue operator()(const util::vertex<G>& v) const; -// lvalue operator()(const util::vertex<G>& v); + using super_::operator(); rvalue operator()(unsigned v_id) const; lvalue operator()(unsigned v_id); /// @} diff --git a/milena/mln/core/internal/is_masked_impl_selector.hh b/milena/mln/core/internal/is_masked_impl_selector.hh new file mode 100644 index 0000000..d812e37 --- /dev/null +++ b/milena/mln/core/internal/is_masked_impl_selector.hh @@ -0,0 +1,145 @@ +// Copyright (C) 2009 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_INTERNAL_IS_MASKED_IMPL_SELECTOR +# define MLN_CORE_INTERNAL_IS_MASKED_IMPL_SELECTOR + +/// \file mln/core/internal/is_masked_impl_selector.hh +/// +/// Add a specific member to graph windows/neighborhoods. + +# include <mln/util/edge.hh> + +namespace mln +{ + + // Forward declarations. + template <typename G, typename F> struct p_edges; + template <typename G, typename F> struct p_vertices; + + + + namespace internal + { + + /// Default implementation. D == S. + /// D and S are site sets. + template <typename S, typename D, typename E> + struct is_masked_impl_selector + { + /// Return wheter a graph element must be masked by this window + bool is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const; + }; + + /// Restrict iteration on vertices according to masked edges. + template <typename G1, typename F1, typename G2, typename F2, typename E> + struct is_masked_impl_selector< p_vertices<G1,F1>, p_edges<G2,F2>, E > + { + typedef p_vertices<G1,F1> S; + + /// Return wheter a graph element must be masked by this window + bool is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const; + }; + + /// Restrict iteration on edges according to masked vertices. + template <typename G1, typename F1, typename G2, typename F2, typename E> + struct is_masked_impl_selector< p_edges<G1,F1>, p_vertices<G2,F2>, E > + { + typedef p_edges<G1,F1> S; + + /// Return wheter a graph element must be masked by this window + bool is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const; + }; + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename S, typename I, typename E> + inline + bool + is_masked_impl_selector<S,I,E>::is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const + { + (void) center; + E& iter = internal::force_exact<E>(*this); + return !iter.s_->mask()(element.id()); + } + + + template <typename G1, typename F1, typename G2, typename F2, typename E> + inline + bool + is_masked_impl_selector< p_vertices<G1,F1>, p_edges<G2,F2>, E > + ::is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const + { + E& iter = internal::force_exact<E>(*this); + + util::edge<G1> e = center.edge_with(element); + mln_postcondition(e.is_valid()); + + return !iter.s_->mask()(e.id()); + } + + + /// center element + /// X -------- X ------------ X + /// + /// We try to find the common vertex. + /// Then we test if the other one is masked or not. + /// + template <typename G1, typename F1, typename G2, typename F2, typename E> + inline + bool + is_masked_impl_selector< p_edges<G1,F1>, p_vertices<G2,F2>, E > + ::is_masked(const mln_graph_element(S)& center, + const mln_graph_element(S)& element) const + { + E& iter = internal::force_exact<E>(*this); + + if (center.v1() == element.v2() || center.v2() == element.v2()) + return !iter.s_->mask()(element.v1()); + + //else if (center.v2() == element.v1() || center.v1() == element.v1()) + return !iter.s_->mask()(element.v2()); + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::internal + +} // end of namespace mln + +#endif // ! MLN_CORE_INTERNAL_IS_MASKED_IMPL_SELECTOR diff --git a/milena/mln/core/internal/neighb_niter_impl.hh b/milena/mln/core/internal/neighb_niter_impl.hh index 9079af6..a21f690 100644 --- a/milena/mln/core/internal/neighb_niter_impl.hh +++ b/milena/mln/core/internal/neighb_niter_impl.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 @@ -41,6 +42,7 @@ namespace mln // Forward declaration. template <typename P, typename W> class graph_window_base; template <typename G, typename F> class graph_elt_window; + template <typename G, typename F, typename I> class graph_elt_window_if; template <typename G, typename F> class line_graph_elt_window; @@ -72,11 +74,6 @@ namespace mln return internal::force_exact<E>(*this).compute_p_().id(); } -// operator unsigned() const -// { -// return internal::force_exact<E>(*this).compute_p_().id(); -// } - }; @@ -102,6 +99,19 @@ namespace mln }; + + /// Add more implementation for neighborhoods made from a + /// graph_window_if_piter. + template <typename G, typename S, typename I, typename E> + struct neighb_niter_impl<graph_elt_window_if<G,S,I>, E> + : public neighb_niter_impl< graph_window_base< mln_result(S::fun_t), + graph_elt_window_if<G,S,I> >, + E > + { + + }; + + } // end of namespace mln::internal } // end of namespace mln diff --git a/milena/mln/core/macros.hh b/milena/mln/core/macros.hh index 3eff9be..8aa59ad 100644 --- a/milena/mln/core/macros.hh +++ b/milena/mln/core/macros.hh @@ -124,6 +124,12 @@ # define mln_eiter_(T) T::eiter /// \} +/// Shortcuts to access the graph type associated to T. +/// \{ +# define mln_graph(T) typename T::graph_t +# define mln_graph_(T) T::graph_t +/// \} + /// Shortcuts to access the element type associated to T. /// \{ # define mln_element(T) typename T::element diff --git a/milena/mln/core/site_set/p_edges.hh b/milena/mln/core/site_set/p_edges.hh index f0c60da..a0bf400 100644 --- a/milena/mln/core/site_set/p_edges.hh +++ b/milena/mln/core/site_set/p_edges.hh @@ -96,7 +96,7 @@ namespace mln /// Default constructor. p_edges(); - /// Construct a graph edge psite set from a graph and a function. + /// Construct a graph edge psite set from a graph. /// /// \param gr The graph upon which the graph edge psite set is built. p_edges(const Graph<G>& gr); diff --git a/milena/mln/core/site_set/p_graph_piter.hh b/milena/mln/core/site_set/p_graph_piter.hh index dba2b52..7932ec2 100644 --- a/milena/mln/core/site_set/p_graph_piter.hh +++ b/milena/mln/core/site_set/p_graph_piter.hh @@ -36,12 +36,16 @@ # include <mln/core/internal/site_set_iterator_base.hh> - namespace mln { // Forward declaration. template <typename S, typename I> class graph_psite; + namespace util + { + template <typename G> class edge; + template <typename G> class vertex; + } @@ -115,8 +119,11 @@ namespace mln template <typename S, typename I, typename E> struct subject_impl< const p_graph_piter<S,I>&, E > { - const typename S::graph_t& graph() const; + typedef typename S::graph_t graph_t; + + const graph_t& graph() const; unsigned id() const; + util::edge<graph_t> edge_with(const util::vertex<graph_t>& v) const; private: const E& exact_() const; @@ -269,6 +276,14 @@ namespace mln template <typename S, typename I, typename E> inline + util::edge<typename S::graph_t> + subject_impl< const p_graph_piter<S,I>&, E >::edge_with(const util::vertex<graph_t>& v) const + { + return exact_().get_subject().element().edge_with(v); + }; + + template <typename S, typename I, typename E> + inline E& subject_impl< p_graph_piter<S,I>&, E >::exact_() { diff --git a/milena/mln/graph/all.hh b/milena/mln/graph/all.hh index 35707fe..9d27c3e 100644 --- a/milena/mln/graph/all.hh +++ b/milena/mln/graph/all.hh @@ -43,6 +43,9 @@ namespace mln # include <mln/graph/compute.hh> +# include <mln/graph/labeling.hh> +# include <mln/graph/to_win.hh> +# include <mln/graph/to_neighb.hh> #endif // ! MLN_GRAPH_ALL_HH diff --git a/milena/mln/graph/labeling.hh b/milena/mln/graph/labeling.hh new file mode 100644 index 0000000..8b91847 --- /dev/null +++ b/milena/mln/graph/labeling.hh @@ -0,0 +1,106 @@ +// Copyright (C) 2009 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_GRAPH_LABELING_HH +# define MLN_GRAPH_LABELING_HH + +/// \file mln/graph/labeling.hh +/// +/// Label a graph image. + + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/labeling/blobs.hh> +# include <mln/metal/bexpr.hh> +# include <mln/metal/is_a.hh> + + +namespace mln +{ + + namespace graph + { + + + /// Label graph components. + /// Vertex with id 0, usuallly used to represent the background component, + /// will be labeled with an id different from 0. Therefore, the labeling + /// starts from 1. + /// + /// \param[in] graph_image_ A graph image (\sa vertex_image, + /// edge_image). + /// \param[in] nbh_ A graph neighborhood. + /// \param[in,out] nlabels The number of labels found. + /// + /// \return a Graph image of labels. + // + template <typename I, typename N, typename L> + mln_ch_value(I,L) + labeling(const Image<I>& graph_image_, + const Neighborhood<N>& nbh_, L& nlabels); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I, typename N, typename L> + mln_ch_value(I,L) + labeling(const Image<I>& graph_image_, + const Neighborhood<N>& nbh_, L& nlabels) + { + trace::entering("graph::labeling"); + + const I& graph_image = exact(graph_image_); + const N& nbh = exact(nbh_); + + mln_precondition(graph_image.is_valid()); + mln_precondition(nbh.is_valid()); + // FIXME: Be sure that's a graph image! + // FIXME: Be sure that's a neighborhood on graph! + + mln_ch_value(I,bool) tmp; + initialize(tmp, graph_image); + data::fill(tmp, true); + + mln_ch_value(I,L) output = mln::labeling::blobs(tmp, nbh, nlabels); + + trace::exiting("graph::labeling"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::graph + +} // end of namespace mln + + +#endif // ! MLN_GRAPH_LABELING_HH diff --git a/milena/mln/graph/to_neighb.hh b/milena/mln/graph/to_neighb.hh new file mode 100644 index 0000000..572dec1 --- /dev/null +++ b/milena/mln/graph/to_neighb.hh @@ -0,0 +1,84 @@ +// Copyright (C) 2009 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_GRAPH_TO_NEIGHB_HH +# define MLN_GRAPH_TO_NEIGHB_HH + +/// \file mln/graph/to_neighb.hh +/// +/// Make a custom graph neighborhood from a mask image. + +# include <mln/core/concept/image.hh> +# include <mln/core/image/graph_elt_neighborhood_if.hh> + +namespace mln +{ + + namespace graph + { + + /// Make a custom graph neighborhood from a mask image. + /// + /// \param[in] graph_image_ A graph image (\sa vertex_image and edge_image). + /// \param[in] graph_mask_image_ A graph image of bool used as a mask. + /// + /// \return A masked neighborhood on graph. + template <typename I, typename M> + graph_elt_neighborhood_if<mln_graph(I), mln_domain(I), M> + to_neighb(const Image<I>& graph_image_, const Image<M>& graph_mask_image_); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename M> + graph_elt_neighborhood_if<mln_graph(I), mln_domain(I), M> + to_neighb(const Image<I>& graph_image_, const Image<M>& graph_mask_image_) + { + trace::entering("graph::to_neighb"); + + const I& graph_image = exact(graph_image_); + const M& graph_mask_image = exact(graph_mask_image_); + + mln_precondition(graph_image.is_valid()); + mln_precondition(graph_mask_image.is_valid()); + mlc_equal(mln_value(M),bool)::check(); + + typedef graph_elt_neighborhood_if<mln_graph(I), mln_domain(I), M> nbh_t; + nbh_t nbh(graph_mask_image); + + trace::exiting("graph::to_neighb"); + return nbh; + } + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::graph + +} // end of namespace mln + +#endif // MLN_GRAPH_TO_NEIGHB_HH diff --git a/milena/mln/graph/to_win.hh b/milena/mln/graph/to_win.hh new file mode 100644 index 0000000..af9ecd1 --- /dev/null +++ b/milena/mln/graph/to_win.hh @@ -0,0 +1,84 @@ +// Copyright (C) 2009 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_GRAPH_TO_WIN_HH +# define MLN_GRAPH_TO_WIN_HH + +/// \file mln/graph/to_win.hh +/// +/// Make a custom graph window from a mask image. + +# include <mln/core/concept/image.hh> +# include <mln/core/image/graph_elt_window_if.hh> + +namespace mln +{ + + namespace graph + { + + /// Make a custom graph window from a mask image. + /// + /// \param[in] graph_image_ A graph image (\sa vertex_image and edge_image). + /// \param[in] graph_mask_image_ A graph image of bool used as a mask. + /// + /// \return A masked window on graph. + template <typename I, typename M> + graph_elt_window_if<mln_graph(I), mln_domain(I), M> + to_win(const Image<I>& graph_image_, const Image<M>& graph_mask_image_); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename M> + graph_elt_window_if<mln_graph(I), mln_domain(I), M> + to_win(const Image<I>& graph_image_, const Image<M>& graph_mask_image_) + { + trace::entering("graph::to_win"); + + const I& graph_image = exact(graph_image_); + const M& graph_mask_image = exact(graph_mask_image_); + + mln_precondition(graph_image.is_valid()); + mln_precondition(graph_mask_image.is_valid()); + mlc_equal(mln_value(M),bool)::check(); + + typedef graph_elt_window_if<mln_graph(I), mln_domain(I), M> win_t; + win_t win(graph_mask_image); + + trace::exiting("graph::to_win"); + return win; + } + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace mln::graph + +} // end of namespace mln + +#endif // MLN_GRAPH_TO_WIN_HH diff --git a/milena/mln/make/edge_image.hh b/milena/mln/make/edge_image.hh index 11f9358..d4510c1 100644 --- a/milena/mln/make/edge_image.hh +++ b/milena/mln/make/edge_image.hh @@ -57,6 +57,7 @@ namespace mln edge_image(const Graph<G>& g, const fun::i2v::array<V>& fv); + /// Construct an edge image. /// /// \param[in] g A graph @@ -72,10 +73,11 @@ namespace mln const Function_i2v<FV>& fv); + /// Construct an edge image. /// /// \param[in] v_ima_ A vertex image. - /// \param[in] fp A function mapping edge ids to sites. + /// \param[in] pe A p_edges mapping graph element to sites . /// \param[in] fv A function mapping two vertex ids to a value. /// The result is associated to the corresponding edge. /// @@ -89,9 +91,26 @@ namespace mln + /// Construct an edge image. + /// + /// \param[in] v_ima_ A vertex image. + /// \param[in] pe A p_edges mapping graph element to themselves. + /// \param[in] fv A function mapping two vertex ids to a value. + /// The result is associated to the corresponding edge. + /// + /// \return an edge image. + // + template <typename P, typename V, typename G, typename FV> + mln::edge_image<void,mln_result(FV),G> + edge_image(const vertex_image<P,V,G>& v_ima_, + const p_edges<G,util::internal::id2element<G,util::edge<G> > > pe, + const Function_vv2v<FV>& fv_); + + # ifndef MLN_INCLUDE_ONLY + template <typename V, typename G> mln::edge_image<void,V,G> edge_image(const Graph<G>& g, const fun::i2v::array<V>& fv) @@ -107,6 +126,7 @@ namespace mln } + template <typename FP, typename FV, typename G> mln::edge_image<mln_result(FP),mln_result(FV),G> edge_image(const Graph<G>& g_, @@ -125,6 +145,7 @@ namespace mln } + template <typename P, typename V, typename G, typename FP, typename FV> mln::edge_image<mln_result(FP),mln_result(FV),G> edge_image(const vertex_image<P,V,G>& v_ima_, @@ -137,20 +158,44 @@ namespace mln const vertex_image<P,V,G>& v_ima = exact(v_ima_); mln_precondition(v_ima.is_valid()); - fun::i2v::array<mln_result(FV)> tmp_fv(v_ima.domain().graph().e_nmax()); - typedef mln::edge_image<mln_result(FP),mln_result(FV),G> edge_ima_t; - edge_ima_t ima_e(pe, tmp_fv); + edge_ima_t ima_e(pe); + + mln_piter(edge_ima_t) e(ima_e.domain()); + for_all(e) + ima_e(e) = fv(e.element().v1(), e.element().v2()); + + trace::exiting("make::edge_image"); + return ima_e; + } + + + + template <typename P, typename V, typename G, typename FV> + mln::edge_image<void,mln_result(FV),G> + edge_image(const vertex_image<P,V,G>& v_ima_, + const p_edges<G,util::internal::id2element<G,util::edge<G> > > pe, + const Function_vv2v<FV>& fv_) + { + trace::entering("make::edge_image"); + + const FV& fv = exact(fv_); + const vertex_image<P,V,G>& v_ima = exact(v_ima_); + mln_precondition(v_ima.is_valid()); + + typedef mln::edge_image<void,mln_result(FV),G> edge_ima_t; + edge_ima_t ima_e(pe); mln_piter(edge_ima_t) e(ima_e.domain()); for_all(e) - ima_e(e) = fv(v_ima(e.element().v1()), v_ima(e.element().v2())); + ima_e(e) = fv(e.element().v1(), e.element().v2()); trace::exiting("make::edge_image"); return ima_e; } + # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh index fb0425f..83c0e8c 100644 --- a/milena/mln/util/graph.hh +++ b/milena/mln/util/graph.hh @@ -211,8 +211,13 @@ namespace mln size_t e_nmax() const; /// Return whether \p id_e is in the graph. + /// \@{ bool has_e(const edge_id_t& id_e) const; + /// \@} + /// Return the corresponding edge id if exists. If it is not, returns + /// an invalid edge. + edge_t edge(const vertex_t& v1, const vertex_t& v2) const; /// Return the first vertex associated to the edge \p id_e. vertex_id_t v1(const edge_id_t& id_e) const; @@ -443,6 +448,28 @@ namespace mln } inline + graph::edge_t + graph::edge(const vertex_t& v1, const vertex_t& v2) const + { + mln_precondition(has_v(v1)); + mln_precondition(has_v(v2)); + + vertex_id_t + id_v1 = v1.id(), + id_v2 = v2.id(); + + if (id_v1 > id_v2) + std::swap(id_v1, id_v2); + + for (unsigned i = 0; i < data_->vertices_[id_v1].size(); ++i) + if (data_->edges_[data_->vertices_[id_v1][i]].second() == id_v2) + return edge_t(*this, data_->vertices_[id_v1][i]); + + // Not edges available. Return an invalid edge. + return edge_t(); + } + + inline vertex_id_t graph::v1(const edge_id_t& id_e) const { diff --git a/milena/mln/util/internal/graph_nbh_iter_base.hh b/milena/mln/util/internal/graph_nbh_iter_base.hh index 3e8e958..6598175 100644 --- a/milena/mln/util/internal/graph_nbh_iter_base.hh +++ b/milena/mln/util/internal/graph_nbh_iter_base.hh @@ -90,6 +90,9 @@ namespace mln /// Change the graph targeted by this iterator. void change_target(const G& g); + /// Return the underlying element + const Elt& element() const; + /// Hook to the current location. const Elt& elt_hook_() const; @@ -264,6 +267,14 @@ namespace mln template <typename G, typename C, typename Elt, typename E> inline const Elt& + nbh_iterator_base<G,C,Elt,E>::element() const + { + return elt_; + } + + template <typename G, typename C, typename Elt, typename E> + inline + const Elt& nbh_iterator_base<G,C,Elt,E>::elt_hook_() const { return elt_; diff --git a/milena/mln/util/vertex.hh b/milena/mln/util/vertex.hh index 8c931df..0cde7a1 100644 --- a/milena/mln/util/vertex.hh +++ b/milena/mln/util/vertex.hh @@ -34,6 +34,7 @@ # include <mln/util/internal/vertex_impl.hh> # include <mln/core/concept/proxy.hh> # include <mln/core/concept/site.hh> +# include <mln/util/graph_ids.hh> /// \file mln/util/vertex.hh /// @@ -114,6 +115,9 @@ namespace mln /// Returns the number max of vertices adjacent to this vertex. unsigned nmax_nbh_vertices() const; + /// Returns true if this vertex has an edge with the given vertex. + edge<G> edge_with(const vertex<G>& v_id) const; + /// Change the parent graph of that vertex. void change_graph(const G& g); @@ -180,6 +184,7 @@ namespace mln unsigned nmax_nbh_edges() const; util::vertex_id_t ith_nbh_vertex(unsigned i) const; unsigned nmax_nbh_vertices() const; + util::edge<G> edge_with(const util::vertex<G>& v) const; private: const E& exact_() const; @@ -250,7 +255,7 @@ namespace mln bool vertex<G>::is_valid() const { - return g_.is_valid() && g_.has_v(id_); + return id_ != mln_max(unsigned) && g_.is_valid() && g_.has_v(id_); } template<typename G> @@ -310,6 +315,16 @@ namespace mln template<typename G> inline + edge<G> + vertex<G>::edge_with(const vertex<G>& v) const + { + mln_precondition(g_.has_v(id_)); + mln_precondition(g_.has_v(v)); + return g_.edge(*this, v); + } + + template<typename G> + inline void vertex<G>::change_graph(const G& g) { @@ -446,6 +461,15 @@ namespace mln template <typename G, typename E> inline + util::edge<G> + subject_impl< const util::vertex<G>, E >::edge_with(const util::vertex<G>& v) const + { + return exact_().get_subject().edge_with(v); + } + + + template <typename G, typename E> + inline E& subject_impl< util::vertex<G>, E >::exact_() { diff --git a/milena/tests/core/other/Makefile.am b/milena/tests/core/other/Makefile.am index 0257f27..703c248 100644 --- a/milena/tests/core/other/Makefile.am +++ b/milena/tests/core/other/Makefile.am @@ -10,7 +10,9 @@ check_PROGRAMS = \ ## clock_test \ dpoints_pixter \ graph_elt_neighborhood \ + graph_elt_neighborhood_if \ graph_elt_window \ + graph_elt_window_if \ neighb \ pixel \ pixter1d \ @@ -29,7 +31,9 @@ category_SOURCES = category.cc ##clock_test_SOURCES = clock_test.cc dpoints_pixter_SOURCES = dpoints_pixter.cc graph_elt_neighborhood_SOURCES = graph_elt_neighborhood.cc +graph_elt_neighborhood_if_SOURCES = graph_elt_neighborhood_if.cc graph_elt_window_SOURCES = graph_elt_window.cc +graph_elt_window_if_SOURCES = graph_elt_window_if.cc neighb_SOURCES = neighb.cc pixel_SOURCES = pixel.cc pixter1d_SOURCES = pixter1d.cc diff --git a/milena/tests/core/other/graph_elt_neighborhood_if.cc b/milena/tests/core/other/graph_elt_neighborhood_if.cc new file mode 100644 index 0000000..955889a --- /dev/null +++ b/milena/tests/core/other/graph_elt_neighborhood_if.cc @@ -0,0 +1,199 @@ +// Copyright (C) 2009 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. + +/// \file tests/core/other/graph_elt_neighborhood_if.cc +/// +/// Tests on mln::graph_elt_neighborhood_if. + + +#include <mln/core/image/edge_image.hh> +#include <mln/core/image/vertex_image.hh> + +#include <mln/core/image/graph_elt_neighborhood_if.hh> + +#include <mln/make/dummy_p_vertices.hh> +#include <mln/make/p_vertices_with_mass_centers.hh> +#include <mln/make/dummy_p_edges.hh> +#include <mln/make/p_edges_with_mass_centers.hh> + +#include <mln/data/fill.hh> + +#include <mln/util/graph.hh> +#include <mln/util/site_pair.hh> + +int main() +{ + using namespace mln; + + typedef util::graph G; + + /*--------. + | Graph. | + `--------*/ + + /* The graph is as follows: + + _____ + / \ + 0 1 2 - 3 + \ / \ / + 4 - 5 + + */ + + util::graph gr; + gr.add_vertices(6); + gr.add_edge(1,3); + gr.add_edge(1,4); + gr.add_edge(2,3); + gr.add_edge(2,4); + gr.add_edge(2,5); + gr.add_edge(3,5); + gr.add_edge(4,5); + + /// Mask of vertices while iterating on vertices. + { + static const unsigned result[] = { 3, 3, 5, 1, 5, 1, 5, 3 }; + + // Create a vertex image. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + data::fill(v_ima, 4); + + // Create a mask on vertices. + typedef mln_ch_value_(v_ima_t, bool) v_mask_t; + v_mask_t v_mask(pv); + mln_piter_(v_mask_t) vm(v_mask.domain()); + for_all(vm) + v_mask(vm) = vm.id()%2; + + mln_piter_(v_ima_t) v(v_ima.domain()); + typedef graph_elt_neighborhood_if<util::graph, pv_t, v_mask_t> nbh_t; + nbh_t nbh(v_mask); + mln_niter_(nbh_t) q(nbh, v); + unsigned i = 0; + for_all(v) + for_all(q) + { + mln_assertion(result[i++] == q.id()); + mln_assertion(q.id()%2); + } + } + + /// Mask of edges while iterating on edges. + { + // Create an edge image. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,unsigned> e_ima_t; + e_ima_t e_ima(pe); + data::fill(e_ima, 3); + + // Create a mask on edges. + typedef mln_ch_value_(e_ima_t, bool) e_mask_t; + e_mask_t e_mask(pe); + mln_piter_(e_mask_t) em(e_mask.domain()); + for_all(em) + e_mask(em) = em.id()%2; + + // Iterate on edges neighborhood according to the given mask. + mln_piter_(e_ima_t) e(e_ima.domain()); + typedef graph_elt_neighborhood_if<util::graph, pe_t, e_mask_t> nbh_t; + nbh_t nbh(e_mask); + mln_niter_(nbh_t) q(nbh, e); + for_all(e) + for_all(q) + mln_assertion(q.id()%2); + } + + + /// Mask of vertices while iterating on edges. + { + // Create an edge image. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,unsigned> e_ima_t; + e_ima_t e_ima(pe); + data::fill(e_ima, 3); + + + // Create a mask on vertices. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + typedef mln_ch_value_(v_ima_t, bool) v_mask_t; + v_mask_t v_mask(pv); + mln_piter_(v_mask_t) vm(v_mask.domain()); + for_all(vm) + v_mask(vm) = vm.id()%2; + + mln_piter_(e_ima_t) e(e_ima.domain()); + typedef graph_elt_neighborhood_if<util::graph, pe_t, v_mask_t> nbh_t; + nbh_t nbh(v_mask); + mln_niter_(nbh_t) q(nbh, e); + for_all(e) + for_all(q) + mln_assertion(v_mask(q.v1()) || v_mask(q.v2())); + } + + + /// Mask of edges while iterating on vertices. + { + static const unsigned result[] = { 4, 4, 5, 1, 2, 3 }; + + // Create a vertex image. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + data::fill(v_ima, 4); + + // Create a mask on edges. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,bool> e_mask_t; + e_mask_t e_mask(pe); + mln_piter_(e_mask_t) em(e_mask.domain()); + for_all(em) + e_mask(em) = em.id()%2; + + mln_piter_(v_ima_t) v(v_ima.domain()); + typedef graph_elt_neighborhood_if<util::graph, pv_t, e_mask_t> nbh_t; + nbh_t nbh(e_mask); + mln_niter_(nbh_t) q(nbh, v); + unsigned i = 0; + for_all(v) + for_all(q) + { + mln_assertion(result[i++] == q.id()); + mln_assertion(e_mask(v.edge_with(q).id())); + } + } +} diff --git a/milena/tests/core/other/graph_elt_window_if.cc b/milena/tests/core/other/graph_elt_window_if.cc new file mode 100644 index 0000000..96f0714 --- /dev/null +++ b/milena/tests/core/other/graph_elt_window_if.cc @@ -0,0 +1,200 @@ +// Copyright (C) 2009 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. + +/// \file tests/core/other/graph_elt_window_if.cc +/// +/// Tests on mln::graph_elt_window_if. + + +#include <mln/core/image/edge_image.hh> +#include <mln/core/image/vertex_image.hh> + +#include <mln/core/image/graph_elt_window_if.hh> + +#include <mln/make/dummy_p_vertices.hh> +#include <mln/make/p_vertices_with_mass_centers.hh> +#include <mln/make/dummy_p_edges.hh> +#include <mln/make/p_edges_with_mass_centers.hh> + +#include <mln/data/fill.hh> + +#include <mln/util/graph.hh> +#include <mln/util/site_pair.hh> + +int main() +{ + using namespace mln; + + typedef util::graph G; + + /*--------. + | Graph. | + `--------*/ + + /* The graph is as follows: + + _____ + / \ + 0 1 2 - 3 + \ / \ / + 4 - 5 + + */ + + util::graph gr; + gr.add_vertices(6); + gr.add_edge(1,3); + gr.add_edge(1,4); + gr.add_edge(2,3); + gr.add_edge(2,4); + gr.add_edge(2,5); + gr.add_edge(3,5); + gr.add_edge(4,5); + + /// Mask of vertices while iterating on vertices. + { + static const unsigned result[] = { 3, 3, 5, 1, 5, 1, 5, 3 }; + + // Create a vertex image. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + data::fill(v_ima, 4); + + // Create a mask on vertices. + typedef mln_ch_value_(v_ima_t, bool) v_mask_t; + v_mask_t v_mask(pv); + mln_piter_(v_mask_t) vm(v_mask.domain()); + for_all(vm) + v_mask(vm) = vm.id()%2; + + mln_piter_(v_ima_t) v(v_ima.domain()); + typedef graph_elt_window_if<util::graph, pv_t, v_mask_t> win_t; + win_t win(v_mask); + mln_qiter_(win_t) q(win, v); + unsigned i = 0; + for_all(v) + for_all(q) + { + mln_assertion(result[i++] == q.id()); + mln_assertion(q.id()%2); + } + } + + /// Mask of edges while iterating on edges. + { + // Create an edge image. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,unsigned> e_ima_t; + e_ima_t e_ima(pe); + data::fill(e_ima, 3); + + // Create a mask on edges. + typedef mln_ch_value_(e_ima_t, bool) e_mask_t; + e_mask_t e_mask(pe); + mln_piter_(e_mask_t) em(e_mask.domain()); + for_all(em) + e_mask(em) = em.id()%2; + + // Iterate on edges neighborhood according to the given mask. + mln_piter_(e_ima_t) e(e_ima.domain()); + typedef graph_elt_window_if<util::graph, pe_t, e_mask_t> win_t; + win_t win(e_mask); + mln_qiter_(win_t) q(win, e); + for_all(e) + for_all(q) + mln_assertion(q.id()%2); + } + + + /// Mask of vertices while iterating on edges. + { + // Create an edge image. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,unsigned> e_ima_t; + e_ima_t e_ima(pe); + data::fill(e_ima, 3); + + + // Create a mask on vertices. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + typedef mln_ch_value_(v_ima_t, bool) v_mask_t; + v_mask_t v_mask(pv); + mln_piter_(v_mask_t) vm(v_mask.domain()); + for_all(vm) + v_mask(vm) = vm.id()%2; + + mln_piter_(e_ima_t) e(e_ima.domain()); + typedef graph_elt_window_if<util::graph, pe_t, v_mask_t> win_t; + win_t win(v_mask); + mln_qiter_(win_t) q(win, e); + for_all(e) + for_all(q) + mln_assertion(v_mask(q.v1()) || v_mask(q.v2())); + } + + + /// Mask of edges while iterating on vertices. + { + static const unsigned result[] = { 4, 4, 5, 1, 2, 3 }; + + // Create a vertex image. + typedef p_vertices<G> pv_t; + pv_t pv = make::dummy_p_vertices(gr); + typedef vertex_image<void,unsigned> v_ima_t; + v_ima_t v_ima(pv); + data::fill(v_ima, 4); + + // Create a mask on edges. + typedef p_edges<G> pe_t; + pe_t pe = make::dummy_p_edges(gr); + typedef edge_image<void,bool> e_mask_t; + e_mask_t e_mask(pe); + mln_piter_(e_mask_t) em(e_mask.domain()); + for_all(em) + e_mask(em) = em.id()%2; + + mln_piter_(v_ima_t) v(v_ima.domain()); + typedef graph_elt_window_if<util::graph, pv_t, e_mask_t> win_t; + win_t win(e_mask); + mln_qiter_(win_t) q(win, v); + unsigned i = 0; + for_all(v) + for_all(q) + { + mln_assertion(result[i++] == q.id()); + mln_assertion(e_mask(v.edge_with(q).id())); + } + } +} diff --git a/milena/tests/graph/Makefile.am b/milena/tests/graph/Makefile.am index b663a3f..cca4bcd 100644 --- a/milena/tests/graph/Makefile.am +++ b/milena/tests/graph/Makefile.am @@ -4,3 +4,9 @@ include $(top_srcdir)/milena/tests/tests.mk SUBDIRS = attribute +check_PROGRAMS = \ + labeling + +labeling_SOURCES = labeling.cc + +TESTS = $(check_PROGRAMS) diff --git a/milena/tests/graph/labeling.cc b/milena/tests/graph/labeling.cc new file mode 100644 index 0000000..6c87982 --- /dev/null +++ b/milena/tests/graph/labeling.cc @@ -0,0 +1,122 @@ +// Copyright (C) 2009 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. + +/// \file tests/core/other/graph_elt_neighborhood_if.cc +/// +/// Tests on mln::graph_elt_neighborhood_if. + + +#include <mln/core/image/edge_image.hh> +#include <mln/core/image/vertex_image.hh> + +#include <mln/core/image/graph_elt_neighborhood_if.hh> + +#include <mln/data/fill.hh> + +#include <mln/util/graph.hh> + +#include <mln/value/label_8.hh> + +#include <mln/fun/i2v/array.hh> + +#include <mln/graph/labeling.hh> +#include <mln/graph/to_neighb.hh> + + + +static const unsigned result[] = { 1, 2, 2, 3, 2, 3 }; + + + +int main() +{ + using namespace mln; + + typedef util::graph G; + + /*--------. + | Graph. | + `--------*/ + + /* The graph is as follows: + + _____ + / \ + 0 1 2 - 3 + \ / \ / + 4 - 5 + + */ + + util::graph gr; + gr.add_vertices(6); + gr.add_edge(1,3); + gr.add_edge(1,4); + gr.add_edge(2,3); + gr.add_edge(2,4); + gr.add_edge(2,5); + gr.add_edge(3,5); + gr.add_edge(4,5); + + + typedef fun::i2v::array<point2d> fsite_t; + fsite_t fsite(6); + fsite(0) = point2d(0,0); + fsite(1) = point2d(2,2); + fsite(2) = point2d(4,2); + fsite(3) = point2d(6,2); + fsite(4) = point2d(2,4); + fsite(5) = point2d(2,6); + + // Create a vertex image. + typedef p_vertices<G,fsite_t> pv_t; + pv_t pv(gr, fsite); + typedef vertex_image<point2d,unsigned> v_ima_t; + v_ima_t v_ima(pv); + data::fill(v_ima, 4); + + // Create a mask on edges. + typedef p_edges<G> pe_t; + pe_t pe(gr); + typedef edge_image<void,bool> e_mask_t; + e_mask_t e_mask(pe); + mln_piter_(e_mask_t) em(e_mask.domain()); + for_all(em) + e_mask(em) = em.id()%2; + + typedef graph_elt_neighborhood_if<util::graph, pv_t, e_mask_t> nbh_t; + nbh_t nbh = graph::to_neighb(v_ima, e_mask); + + value::label_8 nlabels; + typedef mln_ch_value_(v_ima_t,value::label_8) lbl_t; + lbl_t lbl = graph::labeling(v_ima, nbh, nlabels); + + unsigned i = 0; + mln_piter_(lbl_t) p(lbl.domain()); + for_all(p) + mln_assertion(result[i++] == lbl(p)); +} diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk index c74cb9a..b276d8b 100644 --- a/milena/tests/unit_test/unit-tests.mk +++ b/milena/tests/unit_test/unit-tests.mk @@ -865,6 +865,7 @@ mln_core_internal_graph_psite_base \ mln_core_internal_run_image \ mln_core_internal_pixel_impl \ mln_core_internal_site_set_base \ +mln_core_internal_is_masked_impl_selector \ mln_core_internal_image_value_morpher \ mln_core_internal_site_iterator_base \ mln_core_internal_complex_neighborhood_base \ @@ -1050,6 +1051,7 @@ mln_core_image_image2d \ mln_core_image_ch_piter \ mln_core_image_complex_windows \ mln_core_image_violent_cast_image \ +mln_core_image_graph_elt_neighborhood_if \ mln_core_image_mono_obased_rle_encode \ mln_core_image_value_encode \ mln_core_image_essential \ @@ -1173,6 +1175,9 @@ mln_estim_all \ mln_estim_sum \ mln_estim_mean \ mln_estim_essential \ +mln_graph_labeling \ +mln_graph_to_win \ +mln_graph_to_neighb \ mln_graph_all \ mln_graph_attribute_representative \ mln_graph_attribute_card \ @@ -2069,6 +2074,7 @@ mln_core_internal_graph_psite_base_SOURCES = mln_core_internal_graph_psite_base. mln_core_internal_run_image_SOURCES = mln_core_internal_run_image.cc mln_core_internal_pixel_impl_SOURCES = mln_core_internal_pixel_impl.cc mln_core_internal_site_set_base_SOURCES = mln_core_internal_site_set_base.cc +mln_core_internal_is_masked_impl_selector_SOURCES = mln_core_internal_is_masked_impl_selector.cc mln_core_internal_image_value_morpher_SOURCES = mln_core_internal_image_value_morpher.cc mln_core_internal_site_iterator_base_SOURCES = mln_core_internal_site_iterator_base.cc mln_core_internal_complex_neighborhood_base_SOURCES = mln_core_internal_complex_neighborhood_base.cc @@ -2254,6 +2260,7 @@ mln_core_image_image2d_SOURCES = mln_core_image_image2d.cc mln_core_image_ch_piter_SOURCES = mln_core_image_ch_piter.cc mln_core_image_complex_windows_SOURCES = mln_core_image_complex_windows.cc mln_core_image_violent_cast_image_SOURCES = mln_core_image_violent_cast_image.cc +mln_core_image_graph_elt_neighborhood_if_SOURCES = mln_core_image_graph_elt_neighborhood_if.cc mln_core_image_mono_obased_rle_encode_SOURCES = mln_core_image_mono_obased_rle_encode.cc mln_core_image_value_encode_SOURCES = mln_core_image_value_encode.cc mln_core_image_essential_SOURCES = mln_core_image_essential.cc @@ -2377,6 +2384,9 @@ mln_estim_all_SOURCES = mln_estim_all.cc mln_estim_sum_SOURCES = mln_estim_sum.cc mln_estim_mean_SOURCES = mln_estim_mean.cc mln_estim_essential_SOURCES = mln_estim_essential.cc +mln_graph_labeling_SOURCES = mln_graph_labeling.cc +mln_graph_to_win_SOURCES = mln_graph_to_win.cc +mln_graph_to_neighb_SOURCES = mln_graph_to_neighb.cc mln_graph_all_SOURCES = mln_graph_all.cc mln_graph_attribute_representative_SOURCES = mln_graph_attribute_representative.cc mln_graph_attribute_card_SOURCES = mln_graph_attribute_card.cc -- 1.5.6.5