* 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(a)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(a)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