2577: Add more services to mln::topo::n_face.

* mln/topo/n_face.hh (mln::topo::n_face<N, D>::lower_dim_adj_faces) (mln::topo::n_face<N, D>::higher_dim_adj_faces): New methods. (mln::topo::edge(const n_face<0, D>&, const n_face<0, D>&)): New function. * mln/topo/face_data.hh (mln::topo::internal::lower_dim_faces_data_mixin): Make mln::topo::n_face<N, D>::lower_dim_adj_faces a friend of this class. (mln::topo::internal::higher_dim_faces_data_mixin): Make mln::topo::n_face<N, D>::higher_dim_adj_faces a friend of this class. --- milena/ChangeLog | 18 +++++++++ milena/mln/topo/face_data.hh | 10 ++++- milena/mln/topo/n_face.hh | 79 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 7bda463..83ba017 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,23 @@ 2008-10-16 Roland Levillain <roland@lrde.epita.fr> + Add more services to mln::topo::n_face. + + * mln/topo/n_face.hh + (mln::topo::n_face<N, D>::lower_dim_adj_faces) + (mln::topo::n_face<N, D>::higher_dim_adj_faces): + New methods. + (mln::topo::edge(const n_face<0, D>&, const n_face<0, D>&)): + New function. + * mln/topo/face_data.hh + (mln::topo::internal::lower_dim_faces_data_mixin): Make + mln::topo::n_face<N, D>::lower_dim_adj_faces a friend of this + class. + (mln::topo::internal::higher_dim_faces_data_mixin): Make + mln::topo::n_face<N, D>::higher_dim_adj_faces a friend of this + class. + +2008-10-16 Roland Levillain <roland@lrde.epita.fr> + Manipulate complexes as plain objects (instead of pointers) in face handles. diff --git a/milena/mln/topo/face_data.hh b/milena/mln/topo/face_data.hh index 28d425e..27e78cd 100644 --- a/milena/mln/topo/face_data.hh +++ b/milena/mln/topo/face_data.hh @@ -115,7 +115,10 @@ namespace mln private: friend class mln::topo::internal::lower_dim_faces_set_mixin<N, D>; friend class mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D>; - // FIXME: Rename as lower_dim_adj_faces_? + friend std::vector< n_face<N - 1, D> > + mln::topo::n_face<N, D>::lower_dim_adj_faces() const; + + // FIXME: Rename as lower_dim_adj_faces_ (as well as related members). std::vector< n_face<N - 1, D> > lower_dim_faces_; }; @@ -127,7 +130,10 @@ namespace mln private: friend class mln::topo::internal::higher_dim_faces_set_mixin<N, D>; friend class mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D>; - // FIXME: Rename as higher_dim_adj_faces_? + friend std::vector< n_face<N + 1, D> > + mln::topo::n_face<N, D>::higher_dim_adj_faces() const; + + // FIXME: Rename as higher_dim_adj_faces_ (as well as related members). std::vector< n_face<N + 1, D> > higher_dim_faces_; }; /// \} diff --git a/milena/mln/topo/n_face.hh b/milena/mln/topo/n_face.hh index 534df69..68a9512 100644 --- a/milena/mln/topo/n_face.hh +++ b/milena/mln/topo/n_face.hh @@ -32,6 +32,7 @@ /// \brief n-face of a complex. #include <limits> +#include <vector> #include <mln/core/contract.hh> @@ -93,6 +94,13 @@ namespace mln /// Return the mln::topo::face_data pointed by this handle. face_data<N, D>& data() const; + + /* FIXME: We should not provide lower_dim_adj_faces() when N == + 0 nor higher_dim_adj_faces() when N == D. */ + /// \Return an array of face handles pointing to adjacent (n-1)-faces. + std::vector< n_face<N - 1, D> > lower_dim_adj_faces() const; + /// Return an array of face handles pointing to adjacent (n+1)-faces. + std::vector< n_face<N + 1, D> > higher_dim_adj_faces() const; /// \} private: @@ -147,6 +155,31 @@ namespace mln operator<<(std::ostream& ostr, const n_face<N, D>& f); + /// \brief Helpers + /// \{ + + /** \brief Return the 1-face (edge) linking the 0-faces (vertices) + \a f1 and \a f2. If there is no 1-face between \a f1 and \a + f2, return an invalid 1-face. + + \pre \a f1 and \a f2 must belong to the same complex. + + Note: this routine assumes the complex is not degenerated, i.e, + \li it does not check that \a f1 and \a f2 are the only + 0-faces adjacent to an hypothetical 1-face; it just checks + that \a f1 and \a f2 <em>share</em> a common 1-face; + + \li if there are several ajacent 1-faces shared by \a f1 and + \a f2 (if the complex is ill-formed), there is no + guarantee on the returned 1-face (the current + implementation return the first 1-face found, but client + code should not rely on this implementation-defined + behavior). */ + template <unsigned D> + n_face<1, D> edge(const n_face<0, D>& f1, const n_face<0, D>& f2); + /// \} + + # ifndef MLN_INCLUDE_ONLY @@ -250,6 +283,26 @@ namespace mln return cplx_.template face_data_<N>(face_id_); } + template <unsigned N, unsigned D> + inline + std::vector< n_face<N - 1, D> > + n_face<N, D>::lower_dim_adj_faces() const + { + mln_precondition(N > 0); + mln_precondition(is_valid()); + return cplx_.template face_data_<N>(face_id_).lower_dim_faces_; + } + + template <unsigned N, unsigned D> + inline + std::vector< n_face<N + 1, D> > + n_face<N, D>::higher_dim_adj_faces() const + { + mln_precondition(N <= D); + mln_precondition(is_valid()); + return cplx_.template face_data_<N>(face_id_).higher_dim_faces_; + } + template <unsigned N, unsigned D> inline @@ -300,6 +353,32 @@ namespace mln << ", id = " << f.face_id() << ')'; } + /*----------. + | Helpers. | + `----------*/ + + template <unsigned D> + n_face<1, D> edge(const n_face<0, D>& f1, const n_face<0, D>& f2) + { + typedef std::vector< n_face<0, D> > n0_faces_t; + typedef std::vector< n_face<1, D> > n1_faces_t; + + n1_faces_t f1_adj_edges = f1.higher_dim_adj_faces(); + for (typename n1_faces_t::const_iterator e = f1_adj_edges.begin(); + e != f1_adj_edges.end(); ++e) + { + n0_faces_t e_adj_vertices = e->lower_dim_adj_faces(); + for (typename n0_faces_t::const_iterator w = e_adj_vertices.begin(); + w != e_adj_vertices.end(); ++w) + if (*w == f2) + // E is the edge linking F1 and F2. + return *e; + } + + // If no shared edge was found, retun an empty (invalid) 1-face. + return n_face<1, D>(); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::topo -- 1.6.0.1
participants (1)
-
Roland Levillain