
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Nicolas Ballas <ballas@lrde.epita.fr> Add an image type based on boost adjacency_list. * tests/core/bgraph_image.cc, * tests/core/p_bgraph.cc: New test. * mln/core/p_bgraph_piter.hh: Point Iterator on p_bgraph. * mln/core/bgraph_image.hh: New image type (not fully tested yet). * mln/core/p_bgraph.hh: New, Point Set based on a boost graph. * mln/core/bgraph_psite.hh: New. * mln/util/internal/boost_graph.hh, * mln/util/internal/boost_graph_structure.hh: Fix some bugs. mln/core/bgraph_image.hh | 309 +++++++++++++++++++++++++++++ mln/core/bgraph_psite.hh | 178 ++++++++++++++++ mln/core/p_bgraph.hh | 221 ++++++++++++++++++++ mln/core/p_bgraph_piter.hh | 244 ++++++++++++++++++++++ mln/util/internal/boost_graph.hh | 43 +++- mln/util/internal/boost_graph_structure.hh | 12 - tests/core/bgraph_image.cc | 94 ++++++++ tests/core/p_bgraph.cc | 87 ++++++++ 8 files changed, 1178 insertions(+), 10 deletions(-) Index: tests/core/bgraph_image.cc --- tests/core/bgraph_image.cc (revision 0) +++ tests/core/bgraph_image.cc (revision 0) @@ -0,0 +1,94 @@ +// Copyright (C) 2007, 2008 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/bgraph_image.cc +/// \brief Tests on mln::bgraph_image. + +#include <vector> +#include <mln/core/point2d.hh> +#include <mln/core/bgraph_image.hh> + + + +int main() +{ + using namespace mln; + + /*--------. + | Graph. | + `--------*/ + using namespace mln; + typedef util::internal::boost_graph<point2d, util::empty> Graph; + + // Make convenient labels for the vertices + const int num_vertices = 5; + + // writing out the edges in the graph + typedef std::pair<int, int> Edge; + Edge edge_array[] = { + Edge(0, 1), Edge(0, 3), Edge(2, 0), Edge(3, 2), + Edge(2, 4), Edge(1, 3), Edge(3, 4) + }; + + const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]); + // declare a graph object + Graph g(num_vertices); + + // add the edges to the graph object + for (int i = 0; i < num_edges; ++i) + boost::add_edge(edge_array[i].first, edge_array[i].second, g); + + g[0] = make::point2d(0, 0); + g[1] = make::point2d(0, 1); + g[2] = make::point2d(1, 0); + g[3] = make::point2d(1, 1); + g[4] = make::point2d(0, 2); + + /*------------------. + | Boost Graph Image | + `-------------------*/ + + /*--------------. + | Vector values | + `--------------*/ + + typedef bgraph_image<point2d, int> ima_type; + + std::vector<int> values; + values.push_back(1); + values.push_back(2); + values.push_back(3); + values.push_back(4); + values.push_back(5); + + ima_type ima(g, values); + mln_piter_(ima_type) p(ima.domain()); + for_all(p) + std::cout << ima(p) << std::endl; + + return 0; +} Index: tests/core/p_bgraph.cc --- tests/core/p_bgraph.cc (revision 0) +++ tests/core/p_bgraph.cc (revision 0) @@ -0,0 +1,87 @@ +// Copyright (C) 2007, 2008 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/p_bgraph.cc +/// \brief Tests on mln::p_bgraph (the psite based on boost-graph). + +#include <mln/core/p_bgraph.hh> +#include <mln/core/point2d.hh> +#include <mln/util/internal/boost_graph.hh> +#include <boost/typeof/std/utility.hpp> + +struct empty {}; + +int main() +{ + /*--------------. + | boost_graph. | + `--------------*/ + + using namespace mln; + typedef util::internal::boost_graph<point2d, util::empty> Graph; + + // Make convenient labels for the vertices + const int num_vertices = 5; + + // writing out the edges in the graph + typedef std::pair<int, int> Edge; + Edge edge_array[] = { + Edge(0, 1), Edge(0, 3), Edge(2, 0), Edge(3, 2), + Edge(2, 4), Edge(1, 3), Edge(3, 4) + }; + + const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]); + // declare a graph object + Graph g(num_vertices); + + // add the edges to the graph object + for (int i = 0; i < num_edges; ++i) + boost::add_edge(edge_array[i].first, edge_array[i].second, g); + + g[0] = make::point2d(0, 0); + g[1] = make::point2d(0, 1); + g[2] = make::point2d(1, 0); + g[3] = make::point2d(1, 1); + g[4] = make::point2d(0, 2); + + /*-----------. + | p_bgraph. | + `-----------*/ + + /// Creation + p_bgraph<point2d> pset(g); + + /// Iterator + p_bgraph_piter_<point2d> p(pset); + + for (p.start(); p.is_valid(); p.next()) + std::cout << p << std::endl; + + + + return 0; +} Index: mln/core/p_bgraph_piter.hh --- mln/core/p_bgraph_piter.hh (revision 0) +++ mln/core/p_bgraph_piter.hh (revision 0) @@ -0,0 +1,244 @@ +// Copyright (C) 2007, 2008 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. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_P_BGRAPH_PITER_HH +# define MLN_CORE_P_BGRAPH_PITER_HH + +# include <utility> + +# include <mln/core/internal/point_iterator_base.hh> +# include <mln/core/p_bgraph.hh> +# include <mln/core/bgraph_psite.hh> + +/*! \file mln/core/p_bgraph_piter.hh + * + * \brief Definition of point iterator on boost-graph-based point set. + */ + +namespace mln +{ + // Fwd decls. + template<typename P> class p_bgraph; + template<typename P> class bgraph_psite; + + + // FIXME: check the constraint due to the boost iterators + template<typename P> + class p_bgraph_piter_ + : public internal::point_iterator_base_< P, p_bgraph_piter_<P> > + { + typedef p_bgraph_piter_<P> self_; + typedef internal::point_iterator_base_< P, self_ > super_; + typedef std::pair<typename p_bgraph<P>::node_iterator, + typename p_bgraph<P>::node_iterator> iterators_type_; + + public: + + // Make definitions from super class available. + enum { dim = super_::dim }; + typedef bgraph_psite<P> psite; + typedef P point; + + p_bgraph_piter_(const p_bgraph<P>& pg); + + /// Read-only access to the \p i-th coordinate. + mln_coord(P) operator[](unsigned i) const; + + /// Test if the iterator is valid. + bool is_valid() const; + + /// Invalidate the iterator. + void invalidate(); + + /// Start an iteration. + void start(); + + /// 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 point() const; + + /// Convert the iterator into a graph psite. + operator psite() const; + + protected: + /// The p_graph this point site belongs to. + const p_bgraph<P>& pg_; + + /// The psite corresponding to this iterator. + psite psite_; + /// The point corresponding to this iterator. + point p_; + + private: + iterators_type_ iterators_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + template<typename P> + inline + p_bgraph_piter_<P>::p_bgraph_piter_(const p_bgraph<P>& pg) + : pg_(pg), + // Initialize psite_ to a dummy value. + psite_(pg, pg_.npoints()), + p_() + { + // Initialize the iterators + start(); + + // Invalidate id_. + invalidate(); + } + + template<typename P> + inline + mln_coord(P) + p_bgraph_piter_<P>::operator[](unsigned i) const + { + return p_[i]; + } + + template<typename P> + inline + bool + p_bgraph_piter_<P>::is_valid() const + { + return iterators_.first != iterators_.second; + } + + template<typename P> + inline + void + p_bgraph_piter_<P>::invalidate() + { + iterators_.first == iterators_.second; + } + + template<typename P> + inline + void + p_bgraph_piter_<P>::start() + { + /// FIXME: Hide implementation details? + iterators_ = boost::vertices(pg_.to_graph()); + update_(); + } + + template<typename P> + inline + void + p_bgraph_piter_<P>::next_() + { + ++iterators_.first; + update_(); + } + + template<typename P> + inline + void + p_bgraph_piter_<P>::update_() + { + // Update psite_. + psite_ = bgraph_psite<P>(pg_, *iterators_.first); + // Update p_. + p_ = pg_.point_from_id(*iterators_.first); + } + + template<typename P> + inline + const P& + p_bgraph_piter_<P>::to_point() const + { + /* We don't check whether the iterator is valid before returning + the value using + + mln_precondition(is_valid()); + + since this method may be called *before* the iterator is + actually initialized. This is the case for instance when this + point iterator (say, P) is used to initialize another iterator + on window or neighborhood (say, Q); most of the time, for_all() + is responsible for the initialization of P, but it takes place + *after* the creation of Q. */ + return p_; + } + + template<typename P> + inline + const bgraph_psite<P>& + p_bgraph_piter_<P>::to_psite() const + { + /* We don't check whether the iterator is valid before returning + the value using + + mln_precondition(is_valid()); + + since this method may be called *before* the iterator is + actually initialized. This is the case for instance when this + point iterator (say, P) is used to initialize another iterator + on window or neighborhood (say, Q); most of the time, for_all() + is responsible for the initialization of P, but it takes place + *after* the creation of Q. */ + + return psite_; + } + + template<typename P> + inline + p_bgraph_piter_<P>::operator P() const + { + mln_precondition(is_valid()); + return p_; + } + + template<typename P> + inline + p_bgraph_piter_<P>::operator bgraph_psite<P>() const + { + mln_precondition(is_valid()); + return psite_; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of mln + + +#endif // MLN_P_BGRAPH_PITER_HH Index: mln/core/bgraph_image.hh --- mln/core/bgraph_image.hh (revision 0) +++ mln/core/bgraph_image.hh (revision 0) @@ -0,0 +1,309 @@ +// Copyright (C) 2007, 2008 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_BGRAPH_IMAGE_HH +# define MLN_CORE_BGRAPH_IMAGE_HH + +/// \file mln/core/bgraph_image.hh +/// \brief Definition of a boost-graph-based image. + +# include <mln/trait/images.hh> +# include <mln/core/internal/image_primary.hh> +# include <mln/metal/vec.hh> + +# include <mln/core/p_bgraph.hh> +# include <mln/core/bgraph_psite.hh> +# include <mln/value/set.hh> +# include <vector> + +namespace mln +{ + + // Fwd decl. + template <typename P, typename V> struct bgraph_image; + + namespace internal + { + + /// \internal Data structure for \c mln::bgraph_image<P,V>. + template <typename P, typename V> + struct data_< bgraph_image<P, V> > + { + data_(const p_bgraph<P>& g, const std::vector<V>& val); + + std::vector<V> val_; + /* The graph point set is handled by address, so that we can + check the compatibility of images w.r.t. to their point + sites. We could use a safer (and more complex) facility to + ensure (memory) equality of line graph point sets, but using + addresses is simple and efficient enough for the moment. */ + const p_bgraph<P>& pg_; + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename P, typename V> + struct image_< bgraph_image<P, V> > : + default_image_< V, bgraph_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 Kind of image based on a boost graph structure. + * + */ + template <typename P, typename V> + struct bgraph_image : + public internal::image_primary_< p_bgraph<P>, bgraph_image<P, V> > + { + + typedef mln::internal::image_base_< p_bgraph<P>, bgraph_image<P, V> > + super_; + + /// Value associated type. + typedef V value; + + /// Return type of read-write access. + /// + /// We use the associated type \c reference instead of a plain + /// reference on th value type (\v V), because it's the only way + /// to safely form a reference on the element in the case of a + /// std::vector<bool>. + typedef typename std::vector<V>::reference lvalue; + + /// Return type of read-only access. + typedef typename std::vector<V>::const_reference rvalue; + + /// Value set associated type. + typedef mln::value::set<value> vset; + + + /// Skeleton. + typedef bgraph_image< tag::psite_<P>, tag::value_<V> > skeleton; + + /// Constructors. + /// \{ + bgraph_image(); + bgraph_image(const p_bgraph<P>& g); + bgraph_image(const p_bgraph<P>& g, const std::vector<V>& val); + /// \} + + /// Initialize an empty image. + void init_(const p_bgraph<P>& g, const std::vector<V>& val); + + /// Read-only access of pixel value at point site \p p. + rvalue operator()(const bgraph_psite<P>& p) const; + + /// Read-write access of pixel value at point site \p p. + lvalue operator()(const bgraph_psite<P>& p); + + /// Accessors. + /// \{ + /// Return the domain of psites od the image. + const p_bgraph<P>& domain() const; + /// Return the domain of values of the image. + const vset& values() const; + + /// Return the array of values associated to the nodes. + const std::vector<V>& node_values() const; + /// \} + + /* FIXME: Do we want to provide these two methods? (at least, in + the interface of the class? */ + + /// Return the point of the first node adjacent to the edge with + /// id \a e. + const P& node1(const typename p_bgraph<P>::edge_id& e) const; + /// Return the point of the second node adjacent to the edge with + /// id \a e. + const P& node2(const typename p_bgraph<P>::edge_id& e) const; +}; + + // Fwd decl. + template <typename P, typename V> + void init_(tag::image_t, + bgraph_image<P, V>& target, const bgraph_image<P, V>& model); + + +# ifndef MLN_INCLUDE_ONLY + + /*-----------------. + | Initialization. | + `-----------------*/ + + template <typename P, typename V> + inline + void init_(tag::image_t, + bgraph_image<P, V>& target, const bgraph_image<P, V>& model) + { + target.init_(model.domain(), model.node_values ()); + } + + /*-------. + | Data. | + `-------*/ + + namespace internal + { + template <typename P, typename V> + inline + data_< bgraph_image<P, V> >::data_(const p_bgraph<P>& g, + const std::vector<V>& val) + : val_ (val), + pg_ (g) + { + } + + } // end of namespace mln::internal + + /*---------------. + | Construction. | + `---------------*/ + + template <typename P, typename V> + inline + bgraph_image<P, V>::bgraph_image() + { + } + + template <typename P, typename V> + inline + bgraph_image<P, V>::bgraph_image(const p_bgraph<P>& g) + { + init_(g, std::vector<V>(g.npoints())); + } + + template <typename P, typename V> + inline + bgraph_image<P, V>::bgraph_image(const p_bgraph<P>& g, + const std::vector<V>& val) + { + init_(g, val); + } + + template <typename P, typename V> + inline + void + bgraph_image<P, V>::init_(const p_bgraph<P>& g, const std::vector<V>& val) + { + /* FIXME: We leak memory here: calling init_ twice loses the + previous content pointed by data_. + + We should definitely write down formal guidelines on + initialization and memory management in general! */ + this->data_ = new internal::data_< bgraph_image<P, V> > (g, val); + } + + /*---------------. + | Manipulation. | + `---------------*/ + + template <typename P, typename V> + inline + typename bgraph_image<P, V>::rvalue + bgraph_image<P, V>::operator()(const bgraph_psite<P>& p) const + { + mln_precondition(&p.pg() == &this->data_->pg_); + mln_precondition(p.id() < this->data_->val_.size()); + return this->data_->val_[p.id()]; + } + + template <typename P, typename V> + inline + typename bgraph_image<P, V>::lvalue + bgraph_image<P, V>::operator()(const bgraph_psite<P>& p) + { + mln_precondition(&p.pg() == &this->data_->pg_); + mln_precondition(p.id() < this->data_->val_.size()); + return this->data_->val_[p.id()]; + } + + template <typename P, typename V> + inline + const mln::value::set<V> & + bgraph_image<P, V>::values() const + { + return vset::the(); + } + + template <typename P, typename V> + inline + const std::vector<V>& + bgraph_image<P, V>::node_values() const + { + return this->data_->val_; + } + + template <typename P, typename V> + inline + const p_bgraph<P>& + bgraph_image<P, V>::domain() const + { + mln_precondition(this->has_data()); + return this->data_->pg_; + } + + template <typename P, typename V> + inline + const P& + bgraph_image<P, V>::node1(const typename p_bgraph<P>::edge_id& e) const + { + return this->domain().node1(e); + } + + template <typename P, typename V> + inline + const P& + bgraph_image<P, V>::node2(const typename p_bgraph<P>::edge_id& e) const + { + return this->domain().node2(e); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_BGRAPH_IMAGE_HH Index: mln/core/p_bgraph.hh --- mln/core/p_bgraph.hh (revision 0) +++ mln/core/p_bgraph.hh (revision 0) @@ -0,0 +1,221 @@ +// Copyright (C) 2007, 2008 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. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_BGRAPH_P_HH +# define MLN_CORE_BGRAPH_P_HH + +# include <utility> + +# include <mln/core/concept/point_site.hh> +# include <mln/core/internal/point_set_base.hh> +# include <mln/accu/bbox.hh> +# include <mln/util/internal/boost_graph.hh> +# include <mln/core/bgraph_psite.hh> +# include <mln/core/p_bgraph_piter.hh> + + + +/// \file mln/core/p_bgraph.hh +/// \brief Definition of a point set based on a boost graph. + +namespace mln +{ + + template<typename P> class p_bgraph_piter_; + + template<typename P> + struct p_bgraph + : public internal::point_set_base_< graph_psite<P>, p_bgraph<P> > + { + typedef util::internal::boost_graph<P, util::empty> graph; + + /// Construct a graph psite set from a graph of points. + p_bgraph (graph& gr); + + /// Point_Site associated type. + typedef bgraph_psite<P> psite; + + /// Forward Point_Iterator associated type. + typedef p_bgraph_piter_<P> fwd_piter; + + /// Backward Point_Iterator associated type. + typedef p_bgraph_piter_<P> bkd_piter; + + /// Graph vertex/edge identifier + typedef typename graph::vertex_descriptor node_id; + typedef typename graph::edge_descriptor edge_id; + + /// Graph vertex/edge iterator + typedef typename graph::vertex_iterator node_iterator; + typedef typename graph::edge_iterator edge_iterator; + typedef std::pair<node_iterator, node_iterator> node_iterators; + + + /// Return The number of points (i.e., nodes) in the graph. + std::size_t npoints() const; + + /// Return The number of lines (i.e., edges) in the graph. + std::size_t nlines() const; + + /// Give the exact bounding box. + const box_<P>& bbox() const; + + bool has(const psite& p) const; + + /// Return the graph point (FIXME site?) from an index + const P& point_from_id(const node_id& id) const; + P& point_from_id(const node_id& id); + + /// Return the point contained in the first node adjacent + // to the edge id \a e. + const P& node1(const edge_id& e) const; + /// Return the point contained in the second node adjacent + /// to the edge id \a e. + const P& node2(const edge_id& e) const; + + /// Return the graph associated to the p_bgraph domain: + const graph& to_graph() const; + graph& to_graph(); + + + private: + graph gr_; + // FIXME: (Roland) Is it really useful/needed? + /* 2007-12-19: It seems so, since graph_image must implement a method + named bbox(). Now the question is: should each image type have a + bounding box? */ + box_<P> bb_; + }; + +# ifndef MLN_INCLUDE_ONLY + + template<typename P> + inline + p_bgraph<P>::p_bgraph (typename p_bgraph<P>::graph& gr) + : gr_ (gr) + { + // FIXME: Warning: if the underlying graph is updated later, this + // won't be taken into account by this p_bgraph! + accu::bbox<P> a; + + for (node_iterators iter = boost::vertices(gr_); + iter.first != iter.second; + ++iter.first) + a.take(gr_[*iter.first]); + bb_ = a.to_result(); + } + + template<typename P> + inline + std::size_t + p_bgraph<P>::npoints() const + { + return boost::num_vertices((gr_)); + } + + template<typename P> + inline + std::size_t + p_bgraph<P>::nlines() const + { + return boost::num_edges(gr_.nedges()); + } + + template<typename P> + inline + const box_<P>& + p_bgraph<P>::bbox() const + { + return bb_; + } + + template<typename P> + inline + bool + p_bgraph<P>::has(const psite& p) const + { + return + // Check whether P is compatible with this psite set. + (&p.pg() == this) && + // Check that the node id of P belongs to the range of valid node ids. + (p.id() < this->npoints()); + } + + + template <typename P> + const P& + p_bgraph<P>::point_from_id(const typename p_bgraph<P>::node_id& id) const + { + return this->gr_[id]; + } + + template <typename P> + P& + p_bgraph<P>::point_from_id(const typename p_bgraph<P>::node_id& id) + { + return this->gr_[id]; + } + + + /// FIXME: Compare to p_bgraph, here we are loosing the vertex ordering + /// information. Is it bad?? + template <typename P> + const P& + p_bgraph<P>::node1(const typename p_bgraph<P>::edge_id& e) const + { + return this->point_from_id(source(e, this->gr_)); + } + + /// FIXME: same as node1... + template <typename P> + const P& + p_bgraph<P>::node2(const typename p_bgraph<P>::edge_id& e) const + { + return this->point_from_id(target(e, this->gr_)); + } + + template <typename P> + const typename p_bgraph<P>::graph& + p_bgraph<P>::to_graph() const + { + return this->gr_; + } + + template <typename P> + typename p_bgraph<P>::graph& + p_bgraph<P>::to_graph() + { + return this->gr_; + } + + +# endif // ! MLN_INCLUDE_ONLY + +} // end of mln + + +#endif // MLN_CORE_BGRAPH_P_HH Index: mln/core/bgraph_psite.hh --- mln/core/bgraph_psite.hh (revision 0) +++ mln/core/bgraph_psite.hh (revision 0) @@ -0,0 +1,178 @@ +// Copyright (C) 2007, 2008 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. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_BGRAPH_PSITE_HH +# define MLN_CORE_BGRAPH_PSITE_HH + +/// \file mln/core/bgraph_psite.hh +/// \brief Definition of a boost-graph-based point site. + +# include <mln/core/p_graph.hh> + + +namespace mln +{ + + // Fwd decl. + template<typename P> class p_bgraph; + + + /// \brief Point site associated to a mln::graph_image. + template<typename P> + class bgraph_psite : public Point_Site< bgraph_psite<P> > + { + typedef bgraph_psite<P> self_; + typedef Point_Site< bgraph_psite<P> > super_; + + public: + typedef mln_mesh(P) mesh; + enum { dim = P::dim }; + typedef P point; + typedef mln_dpoint(P) dpoint; + typedef mln_coord(P) coord; + + /// Construction and assignment. + /// \{ + bgraph_psite(const p_bgraph<P>& pg_, typename p_bgraph<P>::node_id id); + bgraph_psite(const self_& rhs); + /// \pre This psite must have the same graph point set as \a rhs. + self_& operator= (const self_& rhs); + /// \} + + /// Access to psite. + const self_& to_psite() const; + + /// Access to point. + /// \{ + operator P() const; + const point& to_point() const; + coord operator[](unsigned id) const; + /// \} + + /// Return the p_graph this point site belongs to. + const p_bgraph<P>& pg() const; + /// Return the node id of this point site. + typename p_bgraph<P>::node_id id() const; + + private: + /// The p_graph this point site belongs to. + const p_bgraph<P>& pg_; + /// The id of the node this psite is pointing towards. + typename p_bgraph<P>::node_id id_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + template<typename P> + inline + bgraph_psite<P>::bgraph_psite(const p_bgraph<P>& g, + typename p_bgraph<P>::node_id id) + : pg_(g), + id_(id) + { + } + + + /// FIXME: Is it normal to have to call super_() ? + template<typename P> + inline + bgraph_psite<P>::bgraph_psite(const bgraph_psite<P>& rhs) + : super_(), + pg_(rhs.pg_), + id_(rhs.id_) + { + } + + template<typename P> + inline + bgraph_psite<P>& + bgraph_psite<P>::operator= (const bgraph_psite<P>& rhs) + { + if (&rhs == this) + return *this; + // Assigning a psite from a graph point set to a psite from + // another graph point set is meaningless. + mln_assertion(&pg_ == &rhs.pg_); + id_ = rhs.id_; + return *this; + } + + template<typename P> + inline + const bgraph_psite<P>& + bgraph_psite<P>::to_psite() const + { + return *this; + } + + template<typename P> + inline + bgraph_psite<P>::operator P() const + { + return pg_.point_from_id(id_); + } + + template<typename P> + inline + const P& + bgraph_psite<P>::to_point() const + { + return pg_.point_from_id(id_); + } + + template<typename P> + inline + mln_coord(P) + bgraph_psite<P>::operator[](unsigned i) const + { + return to_point()[i]; + } + + template<typename P> + inline + const p_bgraph<P>& + bgraph_psite<P>::pg() const + { + return pg_; + } + + template<typename P> + inline + typename p_bgraph<P>::node_id + bgraph_psite<P>::id() const + { + return id_; + } + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of mln + +#endif // MLN_CORE_BGRAPH_PSITE_HH Index: mln/util/internal/boost_graph.hh --- mln/util/internal/boost_graph.hh (revision 1760) +++ mln/util/internal/boost_graph.hh (working copy) @@ -25,8 +25,8 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_UTIL_BOOST_GRAPH_HH -# define MLN_UTIL_BOOST_GRAPH_HH +#ifndef MLN_UTIL_INTERNAL_BOOST_GRAPH_HH +# define MLN_UTIL_INTERNAL_BOOST_GRAPH_HH /// \file mln/util/internal/boost_graph.hh /// \brief Definition of the boost::adjacenly_list decorator. @@ -39,12 +39,15 @@ namespace util { + struct empty {}; + namespace internal { /// \brief Boost graph decorator base /// Graph class which rests on boost::adjacency_list class. - template <typename VertexProperty, typename EdgeProperty> + template <typename VertexProperty = empty, + typename EdgeProperty = empty> class boost_graph { typedef boost_graph<VertexProperty, EdgeProperty> self_type; @@ -74,8 +77,12 @@ typedef typename decorated::edge_parallel_category edge_parallel_category; typedef typename decorated::vertex_property_type vertex_property_type; + typedef typename decorated::edge_property_type edge_property_type; typedef typename decorated::graph_tag graph_tag; + /// Properties. + typedef typename decorated::vertex_bundled vertex_bundled; + /// Sizes. typedef typename decorated::vertices_size_type vertices_size_type; typedef typename decorated::edges_size_type edges_size_type; @@ -108,6 +115,10 @@ const decorated& graph() const; + /// Provides acces to the graph bundle properties + vertex_bundled& operator[](vertex_descriptor v); + const vertex_bundled& operator[](vertex_descriptor v) const; + protected: decorated graph_; @@ -161,19 +172,39 @@ } template <typename VertexProp, typename EdgeProp> - inline typename boost_graph<VertexProp, EdgeProp>::decorated& + inline + typename boost_graph<VertexProp, EdgeProp>::decorated& boost_graph<VertexProp, EdgeProp>::graph() { return this->graph_; } template <typename VertexProp, typename EdgeProp> - inline const typename boost_graph<VertexProp, EdgeProp>::decorated& + inline + const typename boost_graph<VertexProp, EdgeProp>::decorated& boost_graph<VertexProp, EdgeProp>::graph() const { return this->graph_; } + template <typename V, typename E> + inline + typename boost_graph<V, E>::vertex_bundled& + boost_graph<V, E>::operator[](typename boost_graph<V, E>:: + vertex_descriptor v) + { + return this->graph_[v]; + } + + template <typename V, typename E> + inline + const typename boost_graph<V, E>::vertex_bundled& + boost_graph<V, E>::operator[](typename boost_graph<V, E>:: + vertex_descriptor v) const + { + return this->graph_[v]; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::util::internal @@ -186,4 +217,4 @@ # include "boost_graph_structure.hh" # include "boost_graph_property.hh" -#endif // ! MLN_UTIL_BOOST_GRAPH_HH +#endif // ! MLN_UTIL_INTERNAL_BOOST_GRAPH_HH Index: mln/util/internal/boost_graph_structure.hh --- mln/util/internal/boost_graph_structure.hh (revision 1760) +++ mln/util/internal/boost_graph_structure.hh (working copy) @@ -64,7 +64,8 @@ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor, bool> add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u, typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v, - const typename mlnu::boost_graph<VProp, EProp>::EdgeProperties& p, + const typename mlnu::boost_graph<VProp, EProp>:: + edge_property_type& p, typename mlnu::boost_graph<VProp, EProp>& g); /// \brief Removes the edge (u,v) from the graph. @@ -122,7 +123,8 @@ /// Returns the vertex descriptor for the new vertex. template <typename VProp, typename EProp> typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor - add_vertex(const typename mlnu::boost_graph<VProp, EProp>::VertexProperties& p, + add_vertex(const typename mlnu::boost_graph<VProp, EProp>:: + vertex_property_type& p, typename mlnu::boost_graph<VProp, EProp>& g); /// \brief Removes all edges to and from vertex u. @@ -170,7 +172,8 @@ bool> add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u, typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v, - const typename mlnu::boost_graph<VProp, EProp>::EdgeProperties& p, + const typename mlnu::boost_graph<VProp, EProp>:: + edge_property_type& p, typename mlnu::boost_graph<VProp, EProp>& g) { return add_edge(u, v, p, g.graph()); @@ -235,7 +238,8 @@ template <typename VProp, typename EProp> typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor - add_vertex(const typename mlnu::boost_graph<VProp, EProp>::VertexProperties& p, + add_vertex(const typename mlnu::boost_graph<VProp, EProp>:: + vertex_property_type& p, typename mlnu::boost_graph<VProp, EProp>& g) { return add_vertex(p, g.graph());