
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> More on general-purpose graph-based images, improperly called mesh-based images. * mln/util/graph.hh: Migrate C-styled constructs to C++ ones. (graph::nodes, graph::edges): New typedefs. Use them... (nodes_, edges_): ...here. * mln/core/mesh_p.hh (graph): New typedef. Use it... (gr_): ...here. Aesthetic changes. * mln/core/mesh_psite.hh (m_ptr_): Turn this non-const pointer on mesh_p<P> into... (mesh_): ...a const reference on mesh_p<P>. (mesh_psite::mesh_psite(unsigned, mesh_p<P>*)): Adjust ctor and swap the arguments of this ctor to get... (mesh_psite::mesh_psite(const mesh_p<P>&, unsigned)): ...this much natural signature. (mesh_psite::mesh_psite(const self_& rhs)): New copy ctor. (operator= (const self_& rhs)): New assignment operator. * mln/core/mesh_p_piter.hh: Adjust forward declarations. (psite, point): New typedefs. (update_, to_psite, operator psite): New methods. (loc_): Remove attribute. (psite_set_, psite_): New attributes. (mesh_p_piter_::mesh_p_piter_): Adjust ctor. (is_valid invalidate, start, next_): Adjust methods. * mln/core/mesh_image.hh (mln::trait::image_< mesh_image<P, V> >): New traits. (operator()(const mesh_psite<P>& p) const) (operator()(const mesh_psite<P>& p)): Catch up with the new interface of mln::mesh_psite. * mln/trait/image/props.hh (mln::trait::image::space_from_point): New function on types mapping points types to the corresponding images space trait. * mln/core/mesh_elt_window.hh, * mln/core/mesh_window_piter.hh: New files. * mln/draw/mesh.hh, * mln/trait/images.hh: Add a FIXME. * mln/core/box_piter.hh, * tests/value/Makefile.am: Typos. * tests/core/mesh_image.cc: New tests * tests/core/mesh_elt_window.cc: New file. * tests/core/Makefile.am (check_PROGRAMS): Add mesh_elt_window and mesh_image. (mesh_elt_window_SOURCES, mesh_image_SOURCES): New. * tests/draw/mesh.cc: Revamp this test. * TODO: Update. TODO | 3 mln/core/box_piter.hh | 6 - mln/core/mesh_elt_window.hh | 169 +++++++++++++++++++++++++++++++++ mln/core/mesh_image.hh | 38 ++++++- mln/core/mesh_p.hh | 15 +- mln/core/mesh_p_piter.hh | 92 ++++++++++++++---- mln/core/mesh_psite.hh | 56 ++++++++--- mln/core/mesh_window_piter.hh | 211 ++++++++++++++++++++++++++++++++++++++++++ mln/draw/mesh.hh | 3 mln/trait/image/props.hh | 41 ++++++++ mln/trait/images.hh | 3 mln/util/graph.hh | 37 +++---- tests/core/Makefile.am | 4 tests/core/mesh_elt_window.cc | 82 ++++++++++++++++ tests/core/mesh_image.cc | 115 ++++++++++++++++++++++ tests/draw/mesh.cc | 101 +++++++++++++++++--- tests/value/Makefile.am | 10 + 17 files changed, 904 insertions(+), 82 deletions(-) Index: tests/value/Makefile.am --- tests/value/Makefile.am (revision 1602) +++ tests/value/Makefile.am (working copy) @@ -2,6 +2,10 @@ include $(top_srcdir)/milena/tests/tests.mk +## FIXME: To be added to milena/tests/tests.mk. +full-check: check +## ... + SUBDIRS = \ concept \ builtin @@ -24,7 +28,7 @@ scalar \ set -# FIXME: activate when make check_full will work. +# FIXME: Enable when make check_full works. # check_full_PROGRAMS = \ # rgb_full @@ -45,9 +49,9 @@ scalar_SOURCES = scalar.cc set_SOURCES = set.cc -# FIXME: activate when make check_full will work. +# FIXME: Enable when make check_full works. # rgb_full_SOURCES = rgb_full.cc TESTS = $(check_PROGRAMS) -# FIXME: activate when make check_full will work. +# FIXME: Enable when make check_full works. # TESTS_FULL = $(check_full_PROGRAMS) Index: tests/core/mesh_image.cc --- tests/core/mesh_image.cc (revision 0) +++ tests/core/mesh_image.cc (revision 0) @@ -0,0 +1,115 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/mesh_image.cc + * + * \brief Tests on mln::mesh_image. + */ + +#include <vector> + +#include <mln/core/point2d.hh> +#include <mln/core/mesh_image.hh> +#include <mln/core/mesh_elt_window.hh> +#include <mln/core/mesh_window_piter.hh> + +#include <mln/debug/iota.hh> +#include <mln/debug/println.hh> + + +int main() +{ + using namespace mln; + + /*--------. + | Graph. | + `--------*/ + + // Points associated to nodes. + std::vector<point2d> points; + points.push_back(make::point2d(0,0)); // Point associated to node 0. + points.push_back(make::point2d(2,2)); // Point associated to node 1. + points.push_back(make::point2d(0,4)); // Point associated to node 2. + points.push_back(make::point2d(4,3)); // Point associated to node 3. + points.push_back(make::point2d(4,4)); // Point associated to node 4. + + // Edges. + util::graph<void> g; + // Populate the graph with nodes. + for (unsigned i = 0; i < points.size(); ++i) + g.add_node (); + // Populate the graph with edges. + g.add_edge(0, 1); + g.add_edge(1, 2); + g.add_edge(1, 3); + g.add_edge(3, 4); + g.add_edge(4, 2); + + /*-------. + | Mesh. | + `-------*/ + + mesh_p<point2d> mesh(g, points); + + /*-------------. + | Mesh image. | + `-------------*/ + + // Values ("empty" vector). + std::vector<int> values(5); + // Mesh image. + typedef mesh_image<point2d, int> ima_t; + ima_t ima(mesh, values); + // Initialize values. + debug::iota(ima); + // The printed result does not show the graph, only the values. + debug::println(ima); + + /*------------. + | Iterators. | + `------------*/ + + // Manual iteration over the domain of IMA. + mln_piter_(ima_t) p(ima.domain()); + for_all (p) + std::cout << "ima (" << p << ") = " << ima(p) << std::endl; + + // Manual iterations over the neighborhoods of each point site of IMA. + typedef mesh_elt_window<point2d> win_t; + win_t win; + // Reinitialize P, otherwise Q will trigger an assertion about P + // being unable to convert to a valid mesh_piter object. + p.start(); + mln_qiter_(win_t) q(win, p); + for_all (p) + { + std::cout << "neighbors of " << p << " (" << ima(p) << "), " + << "including the site itself:" << std::endl; + for_all (q) + std::cout << " " << q << " (level = " << ima(q) << ")" << std::endl; + } +} Index: tests/core/Makefile.am --- tests/core/Makefile.am (revision 1602) +++ tests/core/Makefile.am (working copy) @@ -7,6 +7,8 @@ clone \ exact \ initialize \ + mesh_elt_window \ + mesh_image \ mono_obased_rle_image \ mono_rle_image \ obased_rle_image \ @@ -19,6 +21,8 @@ clone_SOURCES = clone.cc exact_SOURCES = exact.cc initialize_SOURCES = initialize.cc +mesh_elt_window_SOURCES = mesh_elt_window.cc +mesh_image_SOURCES = mesh_image.cc mono_obased_rle_image_SOURCES = mono_obased_rle_image.cc mono_rle_image_SOURCES = mono_rle_image.cc obased_rle_image_SOURCES = obased_rle_image.cc Index: tests/core/mesh_elt_window.cc --- tests/core/mesh_elt_window.cc (revision 0) +++ tests/core/mesh_elt_window.cc (revision 0) @@ -0,0 +1,82 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/mesh_elt_window.cc + * + * \brief Tests on mln::win::mesh_elt_window. + */ + +#include <vector> + +#include <mln/core/point2d.hh> +#include <mln/core/mesh_elt_window.hh> + +#include <mln/debug/iota.hh> +#include <mln/debug/println.hh> + + +int main() +{ + using namespace mln; + + typedef point2d p_t; + + /*--------. + | Graph. | + `--------*/ + + // Points associated to nodes. + std::vector<p_t> points; + points.push_back(make::point2d(0,0)); // Point associated to node 0. + points.push_back(make::point2d(2,2)); // Point associated to node 1. + points.push_back(make::point2d(0,4)); // Point associated to node 2. + points.push_back(make::point2d(4,3)); // Point associated to node 3. + points.push_back(make::point2d(4,4)); // Point associated to node 4. + + // Edges. + mln::util::graph<void> g; + // Populate the graph with nodes. + for (unsigned i = 0; i < points.size(); ++i) + g.add_node (); + // Populate the graph with edges. + g.add_edge(0, 1); + g.add_edge(1, 2); + g.add_edge(1, 3); + g.add_edge(3, 4); + g.add_edge(4, 2); + + /*------------------. + | Mesh and window. | + `------------------*/ + + // Mesh psite set. + mesh_p<p_t> mesh(g, points); + // Mesh point site. + mesh_psite<p_t> psite(mesh, 0); + // ``Sliding'' window (in fact, neighborhood) of a psite of MESH. + mesh_elt_window<p_t> win; +} Index: tests/draw/mesh.cc --- tests/draw/mesh.cc (revision 1602) +++ tests/draw/mesh.cc (working copy) @@ -28,8 +28,14 @@ /*! \file tests/draw/mesh.cc * * \brief Tests on mln::draw::mesh. + * + * Build a graph, convert it to an image, and compare it with a + * reference images. */ +#include <vector> +#include <utility> + #include <mln/core/image2d.hh> #include <mln/core/point2d.hh> #include <mln/debug/println.hh> @@ -40,34 +46,99 @@ #include <mln/core/mesh_image.hh> #include <mln/level/compare.hh> + +/// Set of 2-D points. +typedef std::vector< mln::point2d > points_type; +/// Set of edges expressed using the identifiers of their adjecent nodes. +typedef std::vector< std::pair<int,int> > edges_type; + +using namespace mln; + +// FIXME: We might want to extract NROWS and NCOLS from REF instead of +// getting them from the caller. +void +test (points_type& points, const edges_type& edges, + unsigned nrows, unsigned ncols, const mln::image2d<int>& ref) +{ + // Graph. + util::graph<void> g; + // Populate the graph with nodes. + for (unsigned i = 0; i < points.size(); ++i) + g.add_node (); + // Populate the graph with edges. + for (edges_type::const_iterator i = edges.begin(); i != edges.end(); ++i) + g.add_edge (i->first, i->second); + // Check its consistency. + g.consistency (); + + mln::mesh_p<point2d> m(g, points); + + image2d<int> ima(nrows, ncols); + // FIXME: `draw::mesh' is not a good name. This function doesn't + // actually draw the mesh; it *converts* it to a printable image. + draw::mesh (ima, m, 2, 1); + mln_assertion (ima == ref); +} + int -main (void) +main () { - using namespace mln; + /*---------. + | Test 1. | + `---------*/ + { + // Reference image. int vs[3][3] = { {2, 0, 0}, {0, 1, 0}, {0, 0, 2} }; - image2d<int> ref (make::image2d(vs)); - util::graph<void> g; + // Points associated to nodes. + points_type points; + points.push_back (make::point2d (0,0)); // Point associated to node 0. + points.push_back (make::point2d (2,2)); // Point associated to node 1. + + // Edges. + edges_type edges; + edges.push_back (std::make_pair (0, 1)); - g.add_node (); - g.add_node (); - g.add_edge (0, 1); - g.consistency (); + test (points, edges, 3, 3, ref); + } - std::vector<point2d> v; - v.push_back (make::point2d (0,0)); - v.push_back (make::point2d (2,2)); - mesh_p<point2d> m(g, v); + /*---------. + | Test 2. | + `---------*/ - image2d<int> ima (3, 3); - draw::mesh (ima, m, 2, 1); + { + int vs[5][5] = { + {2, 0, 0, 0, 2}, + {0, 1, 0, 1, 1}, + {0, 0, 2, 0, 1}, + {0, 0, 0, 1, 1}, + {0, 0, 0, 2, 2}, + }; + image2d<int> ref (make::image2d(vs)); - mln_assertion (ima == ref); + // Points associated to nodes. + points_type points; + points.push_back (make::point2d (0,0)); // Point associated to node 0. + points.push_back (make::point2d (2,2)); // Point associated to node 1. + points.push_back (make::point2d (0,4)); // Point associated to node 2. + points.push_back (make::point2d (4,3)); // Point associated to node 3. + points.push_back (make::point2d (4,4)); // Point associated to node 4. + + // Edges. + edges_type edges; + edges.push_back (std::make_pair (0, 1)); + edges.push_back (std::make_pair (1, 2)); + edges.push_back (std::make_pair (1, 3)); + edges.push_back (std::make_pair (3, 4)); + edges.push_back (std::make_pair (4, 2)); + + test (points, edges, 5, 5, ref); + } } Index: TODO --- TODO (revision 1602) +++ TODO (working copy) @@ -1,3 +1,4 @@ + -*- outline -*- @@ -34,6 +35,8 @@ value::other (for use in labeling) ... +** Roland +R�importer les algos de LPE depuis Olena 0.11 et Olena proto-1.0. Index: mln/trait/image/props.hh --- mln/trait/image/props.hh (revision 1602) +++ mln/trait/image/props.hh (working copy) @@ -198,6 +198,47 @@ } // end of namespace mln::trait + + + // FIXME: To be moved elsewhere? + + /// Compute the image::space trait from a point type. + /// \{ + + // Fwd decl. (used by trait::image::space_from_point). + template <typename M, typename C> struct point_; + typedef point_<grid::tick, int> point1d; + typedef point_<grid::square, int> point2d; + typedef point_<grid::cube, int> point3d; + + namespace trait + { + namespace image + { + + /// Function mapping a point type to the corresponding space trait. + /// \{ + template <typename P> + struct space_from_point + { typedef undef ret; }; + + template <> + struct space_from_point<point1d> + { typedef trait::image::space::one_d ret; }; + + template <> + struct space_from_point<point2d> + { typedef trait::image::space::two_d ret; }; + + template <> + struct space_from_point<point3d> + { typedef trait::image::space::three_d ret; }; + /// \} + + } // end of namespace mln::trait::image + + } // end of namespace mln::trait + } // end of namespace mln Index: mln/trait/images.hh --- mln/trait/images.hh (revision 1602) +++ mln/trait/images.hh (working copy) @@ -100,11 +100,9 @@ namespace value { template <unsigned n, typename I> struct stack_image; } - namespace trait { - template <typename I> struct undefined_image_ { @@ -119,6 +117,7 @@ // related to I::pset typedef undef access; // random, browsing + // FIXME: Wouldn't it be nicer to use metal::int_<DIM>? typedef undef space; // one_d, two_d, three_d typedef undef size; // huge or regular typedef undef support; // irregular, aligned < regular Index: mln/core/mesh_psite.hh --- mln/core/mesh_psite.hh (revision 1602) +++ mln/core/mesh_psite.hh (working copy) @@ -35,6 +35,8 @@ * \todo Clean-up! */ +# include <mln/core/mesh_p.hh> + namespace mln { @@ -44,43 +46,73 @@ // FIXME: Doc! + // FIXME: Fix access to member. template<typename P> - struct mesh_psite : public Point_Site< mesh_psite<P> > + class mesh_psite : public Point_Site< mesh_psite<P> > { + typedef mesh_psite<P> self_; + + public: typedef mln_mesh(P) mesh; enum { dim = P::dim }; typedef P point; typedef mln_dpoint(P) dpoint; typedef mln_coord(P) coord; - mesh_psite(unsigned i, mesh_p<P>* m_ptr); + /// Construction and assignment. + /// \{ + mesh_psite(const mesh_p<P>& mesh_, unsigned i); + mesh_psite(const self_& rhs); + self_& operator= (const self_& rhs); + /// \} operator P() const; - const point& to_point() const; - coord operator[](unsigned i) const; + // FIXME: These shouldn't be public. + const mesh_p<P>& mesh_; unsigned i_; - - mesh_p<P>* m_ptr_; }; # ifndef MLN_INCLUDE_ONLY template<typename P> inline - mesh_psite<P>::mesh_psite(unsigned i, mesh_p<P>* m_ptr) - : i_(i) , - m_ptr_(m_ptr) + mesh_psite<P>::mesh_psite(const mesh_p<P>& mesh, unsigned i) + : mesh_(mesh), + i_(i) + { + } + + template<typename P> + inline + mesh_psite<P>::mesh_psite(const mesh_psite<P>& rhs) + : mesh_(rhs.mesh_), + i_(rhs.i_) + { + } + + template<typename P> + inline + mesh_psite<P>& + mesh_psite<P>::operator= (const mesh_psite<P>& rhs) { + if (&rhs == this) + return *this; + // FIXME: Could we get rid of this cast? + const_cast< mesh_p<P>& >(mesh_) = rhs.mesh_; + i_ = rhs.i_; + return *this; } template<typename P> inline mesh_psite<P>::operator P() const { - return m_ptr_->loc_[i_]; + // FIXME: This is quite unsafe: we should check that i_ is a valid + // index before dereferencing loc_ to ensure clear error messages. + return mesh_.loc_[i_]; } template<typename P> @@ -88,7 +120,9 @@ const P& mesh_psite<P>::to_point() const { - return m_ptr_->loc_[i_]; + // FIXME: This is quite unsafe: we should check that i_ is a valid + // index before dereferencing loc_ to ensure clear error messages. + return mesh_.loc_[i_]; } template<typename P> Index: mln/core/mesh_p.hh --- mln/core/mesh_p.hh (revision 1602) +++ mln/core/mesh_p.hh (working copy) @@ -35,6 +35,9 @@ # include <mln/core/mesh_psite.hh> # include <mln/core/mesh_p_piter.hh> +// FIXME: Rename as mesh_p_set? We shall definitely write a coding +// style somewhere. + /*! \file mln/core/mesh_p.hh * * \brief Definition of an point set based on graph. @@ -48,8 +51,10 @@ template<typename P> struct mesh_p : public internal::point_set_base_< P, mesh_p<P> > { - mesh_p (util::graph<void>& gr, - std::vector<P>& loc); + typedef util::graph<void> graph; + + /// Construct a mesh psite set from a graph and an array of locations. + mesh_p (graph& gr, std::vector<P>& loc); /// Point_Site associated type. typedef mesh_psite<P> psite; @@ -67,8 +72,9 @@ bool has(const psite& p) const; - util::graph<void> gr_; + graph gr_; std::vector<P> loc_; + // FIXME: (Roland) Is it really useful/needed? box_<P> bb_; }; @@ -76,8 +82,7 @@ template<typename P> inline - mesh_p<P>::mesh_p (util::graph<void>& gr, - std::vector<P>& loc) + mesh_p<P>::mesh_p (util::graph<void>& gr, std::vector<P>& loc) : gr_ (gr), loc_ (loc) { Index: mln/core/mesh_p_piter.hh --- mln/core/mesh_p_piter.hh (revision 1602) +++ mln/core/mesh_p_piter.hh (working copy) @@ -30,6 +30,7 @@ # include <mln/core/internal/point_iterator_base.hh> # include <mln/core/mesh_p.hh> +# include <mln/core/mesh_psite.hh> /*! \file mln/core/mesh_p_piter.hh * @@ -38,8 +39,12 @@ namespace mln { + // Fwd decls. + template<typename P> class mesh_p; + template<typename P> class mesh_psite; - template<typename P> class mesh_p_piter_; + + // FIXME: Why `mesh_p_piter_' and not `mesh_p_piter' (without `_')? template<typename P> class mesh_p_piter_ : public internal::point_iterator_base_< P, mesh_p_piter_<P> > @@ -51,11 +56,10 @@ // Make definitions from super class available. enum { dim = super_::dim }; + typedef mesh_psite<P> psite; + typedef P point; - mesh_p_piter_(const mesh_p<P>& s); - - /// Reference to the corresponding point. - const P& to_point() const; + mesh_p_piter_(const mesh_p<P>& psite_set); /// Read-only access to the \p i-th coordinate. mln_coord(P) operator[](unsigned i) const; @@ -72,13 +76,26 @@ /// Go to the next point. void next_(); + /// Update the internal data of the iterator. + void update_(); + + /// Reference to the corresponding point. + const point& to_point () const; + + /// Reference to the corresponding point site. + const psite& to_psite () const; + /// Convert the iterator into a point. - operator P() const; + operator point() const; + + /// Convert the iterator into a mesh psite. + operator psite() const; protected: - const std::vector<P>& loc_; + const mesh_p<P>& psite_set_; unsigned i_; P p_; + psite psite_; }; @@ -87,22 +104,18 @@ template<typename P> inline - mesh_p_piter_<P>::mesh_p_piter_(const mesh_p<P>& s) - : loc_(s.loc_) + mesh_p_piter_<P>::mesh_p_piter_(const mesh_p<P>& psite_set) + : psite_set_(psite_set), + p_(), + // Initialize psite_ to a dummy value. + psite_(psite_set, psite_set_.loc_.size()) { + // Invalidate i_. invalidate(); } template<typename P> inline - const P& - mesh_p_piter_<P>::to_point() const - { - return p_; - } - - template<typename P> - inline mln_coord(P) mesh_p_piter_<P>::operator[](unsigned i) const { @@ -114,7 +127,7 @@ bool mesh_p_piter_<P>::is_valid() const { - return i_ != loc_.size(); + return i_ != psite_set_.loc_.size(); } template<typename P> @@ -122,7 +135,7 @@ void mesh_p_piter_<P>::invalidate() { - i_ = loc_.size(); + i_ = psite_set_.loc_.size(); } template<typename P> @@ -132,7 +145,7 @@ { i_ = 0; if (is_valid()) - p_ = loc_[i_]; + update_(); } template<typename P> @@ -142,7 +155,36 @@ { ++i_; if (is_valid()) - p_ = loc_[i_]; + update_(); + } + + template<typename P> + inline + void + mesh_p_piter_<P>::update_() + { + // Update p_. + p_ = psite_set_.loc_[i_]; + // Update psite_. + psite_ = mesh_psite<P>(psite_set_, i_); + } + + template<typename P> + inline + const P& + mesh_p_piter_<P>::to_point() const + { + mln_precondition(is_valid()); + return p_; + } + + template<typename P> + inline + const mesh_psite<P>& + mesh_p_piter_<P>::to_psite() const + { + mln_precondition(is_valid()); + return psite_; } template<typename P> @@ -153,6 +195,14 @@ return p_; } + template<typename P> + inline + mesh_p_piter_<P>::operator mesh_psite<P>() const + { + mln_precondition(is_valid()); + return psite_; + } + # endif // ! MLN_INCLUDE_ONLY } // end of mln Index: mln/core/mesh_window_piter.hh --- mln/core/mesh_window_piter.hh (revision 0) +++ mln/core/mesh_window_piter.hh (revision 0) @@ -0,0 +1,211 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_MESH_WINDOW_PITER_HH +# define MLN_CORE_MESH_WINDOW_PITER_HH + +// FIXME: Doc. + +// FIXME: Shall we rename `piter' as `qiter'? + +# include <mln/core/concept/point_iterator.hh> +# include <mln/core/mesh_p.hh> +# include <mln/core/mesh_psite.hh> + + +namespace mln +{ + // Fwd decls. + template <typename P> class mesh_p; + template <typename P> class mesh_psite; + + + template <typename P> + class mesh_window_fwd_piter : + public Point_Iterator< mesh_window_fwd_piter<P> > // or Iterator<...>? + { + typedef mesh_window_fwd_piter<P> self_; + typedef Point_Iterator< self_ > super_; + + public: + typedef mesh_psite<P> psite; + + enum { dim = P::dim }; + typedef mesh_p<P> mesh; + + typedef P point; + // FIXME: Dummy typedef. + typedef void dpoint; + typedef mln_coord(P) coord; + + public: + template <typename W, typename Pref> + mesh_window_fwd_piter(const W& win, + const Point_Site<Pref>& p_ref); + + bool is_valid() const; + void invalidate(); + void start(); + + void next_(); + bool adjacent_or_equal_to_p_ref_() const; + + // FIXME: In fact, this method should be named `to_psite', since + // it return as mln::mesh_psite<P> object, not a P object. + const point& to_point() const; + operator psite () const; + coord operator[](unsigned i) const; + + private: + /// The ``central'' point of the window. + const psite& p_ref_; + + /// An internal iterator on the set of nodes of the underlying graph. + unsigned i_; + }; + + // FIXME: mesh_window_bkd_piter. + + +# ifndef MLN_INCLUDE_ONLY + + // FIXME: Currently, argument win is ignored. + template <typename P> + template <typename W, typename Pref> + mesh_window_fwd_piter<P>::mesh_window_fwd_piter(const W& /* win */, + const Point_Site<Pref>& p_ref) + : p_ref_(exact(p_ref).to_psite()) + { + // Invalidate i_. + invalidate(); + } + + template <typename P> + bool + mesh_window_fwd_piter<P>::is_valid() const + { + // FIXME: We depend too much on the implementation of util::graph + // here. The util::graph should provide the service to abstract + // these manipulations. + return i_ >= 0 && i_ < p_ref_.mesh_.gr_.nb_node_; + } + + template <typename P> + void + mesh_window_fwd_piter<P>::invalidate() + { + i_ = p_ref_.mesh_.gr_.nb_node_; + } + + template <typename P> + void + mesh_window_fwd_piter<P>::start() + { + i_ = 0; + if (!adjacent_or_equal_to_p_ref_()) + next_(); + } + + template <typename P> + void + mesh_window_fwd_piter<P>::next_() + { + // FIXME: This is inefficient. The graph structure should be able + // to produce the set of adjacent nodes fast. Boost Graphs + // probably provides adequates structures to get fecth these + // neighbors in constant time. + do + ++i_; + while (is_valid() && !adjacent_or_equal_to_p_ref_()); + } + + template <typename P> + bool + mesh_window_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const + { + // FIXME: Likewise, this is inefficient. + + // Check wether the iterator points to P_REF_. + if (i_ == p_ref_.i_) + return true; + + typedef std::list<unsigned> adjacency_type; + + // Check whether the iterator is among the neighbors of P_REF_. + { + // Paranoid assertion. + assert (p_ref_.i_ >= 0 && + p_ref_.i_ < p_ref_.mesh_.gr_.nodes_.size ()); + const adjacency_type& p_ref_neighbs = + p_ref_.mesh_.gr_.nodes_[p_ref_.i_]->links; + adjacency_type::const_iterator j = + std::find (p_ref_neighbs.begin(), p_ref_neighbs.end(), i_); + if (j != p_ref_neighbs.end()) + return true; + } + + // Check whether P_REF_ is among the neighbors of the iterator. + { + assert (is_valid ()); + const adjacency_type& i_neighbs = p_ref_.mesh_.gr_.nodes_[i_]->links; + adjacency_type::const_iterator k = + std::find (i_neighbs.begin(), i_neighbs.end(), p_ref_.i_); + if (k != i_neighbs.end()) + return true; + } + + // Otherwise, the iterator is not adjacent to P_REF_. + return false; + } + + template <typename P> + const P& + mesh_window_fwd_piter<P>::to_point() const + { + return p_ref_.mesh_.loc_[i_]; + } + + template <typename P> + mesh_window_fwd_piter<P>::operator mesh_psite<P> () const + { + return mesh_psite<P>(p_ref_.mesh_, i_); + } + + template <typename P> + inline + mln_coord(P) + mesh_window_fwd_piter<P>::operator[](unsigned i) const + { + assert(i < dim); + return to_point()[i]; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_CORE_MESH_WINDOW_PITER_HH Index: mln/core/mesh_elt_window.hh --- mln/core/mesh_elt_window.hh (revision 0) +++ mln/core/mesh_elt_window.hh (revision 0) @@ -0,0 +1,169 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_WIN_MESH_ELT_WINDOW_HH +# define MLN_WIN_MESH_ELT_WINDOW_HH + +/*! \file mln/core/mesh_elt_window.hh + * + * \brief Definition of the elementary neighborhood (wrongly + * -- but purposefully -- named "window" here, for consistency + * reasons) on a mesh (a graph, in fact). + * + * \todo Make naming coherent: we have window (without '_') but + * point_, neighb_, etc. + */ + +# include <mln/core/concept/window.hh> +# include <mln/core/mesh_psite.hh> +# include <mln/core/mesh_window_piter.hh> + + +namespace mln +{ + // Fwd decls. + template <typename P> class mesh_window_fwd_piter; + template <typename P> class mesh_window_bkd_piter; + + + /*! \brief Elementary window on mesh class. + * + * FIXME: Doc. + */ + template <typename P> + class mesh_elt_window : public Window< mesh_elt_window<P> > + { + typedef mesh_elt_window<P> self_; + + public: + /// Associated types. + /// \{ + /// The type of point stored into the window. + // FIXME: Is this right, if we consider that this window stores + // psites, not points? + typedef P point; + + // FIXME: This is a dummy value. This is yet another evidence + // that mesh_elt_window shall not be a Window, and therefore be + // renamed as mesh_elt_neighb, or better: elt_graph_neighb. + typedef void dpoint; + + /*! \brief Point_Iterator type to browse the points of a generic window + * w.r.t. the ordering of delta-points. + */ + typedef mesh_window_fwd_piter<P> fwd_qiter; + + /*! \brief Point_Iterator type to browse the points of a generic window + * w.r.t. the reverse ordering of delta-points. + */ + typedef mesh_window_bkd_piter<P> bkd_qiter; + + /// The default qiter type. + typedef fwd_qiter qiter; + /// \} + + /// Construct an elementary mesh window centered on \a psite. + mesh_elt_window(/*const mesh_psite<P>& psite*/); + + // FIXME: The following methods make no sense for a + // general-purpose neighborhood. Anyway, we provide + // implementations for them for this first draft of graph + // neighborhood. + bool is_empty() const; + bool is_centered() const; + bool is_symmetric() const; + unsigned delta() const; + self_& sym(); + + // protected: + // const mesh_psite<P>& psite_; + }; + + + // FIXME: Add an operator<< on ostreams ? + + +# ifndef MLN_INCLUDE_ONLY + + template <typename P> + inline + mesh_elt_window<P>::mesh_elt_window(/*const mesh_psite<P>& psite*/) + // : psite_(psite) + { + } + + template <typename P> + inline + bool + mesh_elt_window<P>::is_empty() const + { + // FIXME: Dummy value. + return false; + } + + template <typename P> + inline + bool + mesh_elt_window<P>::is_centered() const + { + // FIXME: Dummy value. + return false; + } + + template <typename P> + inline + bool + mesh_elt_window<P>::is_symmetric() const + { + // FIXME: Dummy value. + return false; + } + + template <typename P> + inline + unsigned + mesh_elt_window<P>::delta() const + { + // FIXME: Dummy value. + return 0; + } + + template <typename P> + inline + mesh_elt_window<P>& + mesh_elt_window<P>::sym() + { + // FIXME: Dummy value. + return *this; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_WIN_MESH_ELT_WINDOW_HH Index: mln/core/box_piter.hh --- mln/core/box_piter.hh (revision 1602) +++ mln/core/box_piter.hh (working copy) @@ -62,7 +62,7 @@ */ box_fwd_piter_(const box_<P>& b); - /// Convertion to point. + /// Conversion to point. operator P() const; /// Reference to the corresponding point. @@ -112,7 +112,7 @@ */ box_bkd_piter_(const box_<P>& b); - /// Convertion to point. + /// Conversion to point. operator P() const; /// Reference to the corresponding point. @@ -164,7 +164,7 @@ */ box_bounds_piter_(const box_<P>& b); - /// Convertion to point. + /// Conversion to point. operator P() const; /// Reference to the corresponding point. Index: mln/core/mesh_image.hh --- mln/core/mesh_image.hh (revision 1602) +++ mln/core/mesh_image.hh (working copy) @@ -30,13 +30,16 @@ /*! \file mln/core/mesh_image.hh * - * \brief Definition of an graph-based image. + * \brief Definition of a graph-based image. */ -# include <mln/core/internal/image_identity.hh> +# include <mln/trait/images.hh> + +# include <mln/core/internal/image_primary.hh> # include <mln/metal/vec.hh> # include <mln/core/mesh_p.hh> # include <mln/core/mesh_psite.hh> +# include <mln/value/set.hh> # include <vector> namespace mln @@ -59,11 +62,36 @@ } // end of namespace mln::internal + + namespace trait + { + + template <typename P, typename V> + struct image_< mesh_image<P, V> > : default_image_< V, mesh_image<P, V> > + { + typedef trait::image::category::primary category; + + // FIXME: Is that right? + typedef trait::image::access::random access; + typedef typename trait::image::space_from_point<P>::ret space; + typedef trait::image::size::regular size; + typedef trait::image::support::irregular support; + + typedef trait::image::border::none border; + typedef trait::image::data::stored data; + typedef trait::image::io::read_write io; + // FIXME: Is that right? + typedef trait::image::speed::fast speed; + }; + + } // end of namespace mln::trait + /*! \brief FIXME * */ template <typename P, typename V> - struct mesh_image : public internal::image_primary_< mesh_p<P>, mesh_image<P, V> > + struct mesh_image : + public internal::image_primary_< mesh_p<P>, mesh_image<P, V> > { typedef mln::internal::image_base_< mesh_p<P>, mesh_image<P, V> > super_; @@ -143,7 +171,7 @@ const V& mesh_image<P, V>::operator()(const mesh_psite<P>& p) const { - mln_precondition(p.m_ptr_ == & this->data_->mesh_); + mln_precondition(&p.mesh_ == &this->data_->mesh_); mln_precondition(p.i_ < this->data_->val_.size()); return this->data_->val_[p.i_]; } @@ -153,7 +181,7 @@ V& mesh_image<P, V>::operator()(const mesh_psite<P>& p) { - mln_precondition(p.m_ptr_ == & this->data_->mesh_); + mln_precondition(&p.mesh_ == &this->data_->mesh_); mln_precondition(p.i_ < this->data_->val_.size()); return this->data_->val_[p.i_]; } Index: mln/draw/mesh.hh --- mln/draw/mesh.hh (revision 1602) +++ mln/draw/mesh.hh (working copy) @@ -75,6 +75,9 @@ # ifndef MLN_INCLUDE_ONLY + // FIXME: Add assertions on the size of the image: it must be big + // enough to hold the reprensentation of the graph. + template <typename I, typename P> inline void Index: mln/util/graph.hh --- mln/util/graph.hh (revision 1602) +++ mln/util/graph.hh (working copy) @@ -40,6 +40,9 @@ * \brief Definition of a graph. */ +// FIXME: Rename `s_node' to `node'. +// FIXME: Rename `s_edge' to `edge'. +// FIXME: Rename `links' to `edges'. namespace mln { @@ -53,6 +56,7 @@ struct s_node { T data; + // FIXME: Rename to `out_edges'. std::vector<unsigned> links; }; @@ -63,6 +67,7 @@ template<> struct s_node<void> { + // FIXME: Rename to `out_edges'. std::list<unsigned> links; }; @@ -88,21 +93,21 @@ unsigned node2; }; - /*! \brief Generic graph using s_node and s_edge. - * - */ + /// \brief Generic graph structure using s_node and s_edge. + /* FIXME: We don't mention anywhere whether this graph structure + handles directed or undirected graphs! */ template<typename N, typename E = void> struct graph { - /*! \brief Constructor. - * - */ + /// The type of the set of nodes. + typedef std::vector< s_node<N>* > nodes; + /// The type of the set of edges. + typedef std::vector< s_edge<E>* > edges; + graph (); - /*! \brief Add a void node. - * - */ - void add_node (void); + /*! \brief Add a void node. */ + void add_node (); /*! \brief Add a void edge between \p n1 and \p n2. @@ -112,7 +117,6 @@ * * \pre n1 < nb_node_. * \pre n2 < nb_node_. - * */ void add_edge (unsigned n1, unsigned n2); @@ -123,7 +127,6 @@ * * \pre nodes_.size () == nb_node_. * \pre links_.size () == nb_link_. - * */ void consistency () const; @@ -131,7 +134,6 @@ /*! \brief Print on \p ostr the graph. * * \param[in] ostr The output stream. - * */ void print_debug (std::ostream& ostr) const; @@ -144,12 +146,13 @@ unsigned nb_link_; /// The vector where is stocked the pointers of nodes. - std::vector<struct s_node<N>*> nodes_; + nodes nodes_; /// The vector where is stocked the pointers of links. - std::vector<struct s_edge<E>*> links_; + edges links_; }; + # ifndef MLN_INCLUDE_ONLY template<typename N, typename E> @@ -165,7 +168,7 @@ template<typename N, typename E> inline void - graph<N, E>::add_node (void) + graph<N, E>::add_node () { struct s_node<N>* n = new struct s_node<N>; @@ -183,7 +186,7 @@ struct s_edge<E>* edge; - edge = new struct s_edge<E>; + edge = new s_edge<E>; edge->node1 = n1; edge->node2 = n2; links_.push_back (edge);