https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)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());