* tests/io/Makefile.am (SUBDIRS): Add io.
* tests/io/off/: New directory.
* tests/io/off/load_bin.cc: New.
* tests/io/off/Makefile.am: New.
---
milena/ChangeLog | 9 +++++
milena/tests/io/Makefile.am | 1 +
milena/tests/io/{ => off}/Makefile.am | 13 +++----
milena/tests/io/off/load_bin.cc | 64 +++++++++++++++++++++++++++++++++
4 files changed, 80 insertions(+), 7 deletions(-)
copy milena/tests/io/{ => off}/Makefile.am (56%)
create mode 100644 milena/tests/io/off/load_bin.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 546bec0..d8b0307 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+ Exercise mln::io::load on OFF file (with no color data).
+
+ * tests/io/Makefile.am (SUBDIRS): Add io.
+ * tests/io/off/: New directory.
+ * tests/io/off/load_bin.cc: New.
+ * tests/io/off/Makefile.am: New.
+
+2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a routine to create a complex-based image from an OFF file.
* mln/io/off/load.hh: New.
diff --git a/milena/tests/io/Makefile.am b/milena/tests/io/Makefile.am
index 89cfa56..36d7797 100644
--- a/milena/tests/io/Makefile.am
+++ b/milena/tests/io/Makefile.am
@@ -4,6 +4,7 @@ include $(top_srcdir)/milena/tests/tests.mk
SUBDIRS = \
fits \
+ off \
pbm \
pfm \
pgm \
diff --git a/milena/tests/io/Makefile.am b/milena/tests/io/off/Makefile.am
similarity index 56%
copy from milena/tests/io/Makefile.am
copy to milena/tests/io/off/Makefile.am
index 89cfa56..4b592ce 100644
--- a/milena/tests/io/Makefile.am
+++ b/milena/tests/io/off/Makefile.am
@@ -2,10 +2,9 @@
include $(top_srcdir)/milena/tests/tests.mk
-SUBDIRS = \
- fits \
- pbm \
- pfm \
- pgm \
- pnm \
- ppm
+check_PROGRAMS = \
+ load_bin
+
+load_bin_SOURCES = load_bin.cc
+
+TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/io/off/load_bin.cc b/milena/tests/io/off/load_bin.cc
new file mode 100644
index 0000000..e171704
--- /dev/null
+++ b/milena/tests/io/off/load_bin.cc
@@ -0,0 +1,64 @@
+// Copyright (C) 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/io/off/load_bin.cc
+/// \brief Test mln::io::off::load with an
+/// mln::complex_image<3, geom::complex_data<3, point3df>, bool>.
+
+#include <algorithm>
+#include <iterator>
+#include <iostream>
+
+#include <mln/io/off/load.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ /* FIXME: Create an alias in milena/mln/core/alias/ for this
+ particular image type? */
+ typedef mln::complex_image<2, geom::complex_geometry<2,point3df>, bool> ima_t;
+ ima_t ima;
+ io::off::load(ima, MLN_MESH_DIR "/tetrahedron.off");
+
+ std::cout << ima.domain().cplx() << std::endl;
+
+ mln_piter_(ima_t) p(ima.domain());
+ for_all(p)
+ {
+ std::cout << "ima(" << p << ") = " << ima(p) << " ( ";
+ // Print site(s).
+ typedef mln_site_(ima_t) site_t;
+ site_t s(p);
+ std::copy (s.sites.begin(), s.sites.end(),
+ std::ostream_iterator<site_t::location>(std::cout, " "));
+ std::cout << ")" << std::endl;
+ }
+}
--
1.6.0.1
* mln/io/off/load.hh: New.
---
milena/ChangeLog | 6 +
milena/mln/io/off/load.hh | 308 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 314 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/io/off/load.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 30e48e9..546bec0 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a routine to create a complex-based image from an OFF file.
+
+ * mln/io/off/load.hh: New.
+
+2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a macro containing the path to meshes, to be used in tests.
* tests/data.hh.in (MLN_MESH_DIR): New macro.
diff --git a/milena/mln/io/off/load.hh b/milena/mln/io/off/load.hh
new file mode 100644
index 0000000..ff8d106
--- /dev/null
+++ b/milena/mln/io/off/load.hh
@@ -0,0 +1,308 @@
+// Copyright (C) 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_IO_OFF_LOAD_HH
+# define MLN_IO_OFF_LOAD_HH
+
+/// \file mln/io/off/load.hh
+/// \brief Input loading function for OFF files.
+///
+/// \see http://shape.cs.princeton.edu/benchmark/documentation/off_format.html
+
+# include <cstdlib>
+
+# include <iostream>
+# include <fstream>
+
+# include <string>
+
+# include <mln/core/image/complex_image.hh>
+# include <mln/geom/complex_geometry.hh>
+# include <mln/core/alias/point3df.hh>
+
+// // FIXME: Really needed?
+// # include <mln/topo/n_faces_set.hh>
+
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace off
+ {
+
+ /** \brief Load a (boolean) OFF image into a complex image.
+
+ \param[out] ima A reference to the image to construct.
+ \param[in] filename The name of the file to load.
+
+ The image is said boolean since data only represent the
+ existence of vertices and faces. */
+ void load(complex_image<2, geom::complex_geometry<2,point3df>, bool>& ima,
+ const std::string& filename);
+
+ namespace internal
+ {
+ /// A stream manipulator eating comments starting with a `#'
+ /// and ending at an end of line
+ std::istream& eat_comment (std::istream& istr);
+ }
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ void load(complex_image<2 ,geom::complex_geometry<2,point3df>, bool>& ima,
+ const std::string& filename)
+ {
+ const std::string me = "mln::io::load::off";
+
+ std::ifstream istr(filename.c_str());
+ if (!istr)
+ {
+ std::cerr << me << ": `" << filename << "' not found." << std::endl;
+ /* FIXME: Too violent. We should allow the use of
+ exception, at least to have Milena's code behave
+ correctly in interpreted environments (std::exit() or
+ std::abort() causes the termination of a Python
+ interpreter, for instance!). */
+ std::exit(1);
+ }
+
+ /*---------.
+ | Header. |
+ `---------*/
+
+ /* ``The .off files in the Princeton Shape Benchmark conform
+ to the following standard. */
+
+ /* OFF files are all ASCII files beginning with the keyword
+ OFF. '' */
+ std::string type;
+ istr >> internal::eat_comment >> type;
+ if (type != "OFF")
+ {
+ std::cerr << me << ": `" << filename << "': ill-formed header."
+ << std::endl;
+ std::exit(1);
+ }
+
+ /* ``The next line states the number of vertices, the number
+ of faces, and the number of edges. The number of edges can
+ be safely ignored.'' */
+ unsigned nvertices, nfaces, nedges;
+ istr >> internal::eat_comment >> nvertices
+ >> internal::eat_comment >> nfaces
+ >> internal::eat_comment >> nedges;
+
+ /*-------.
+ | Data. |
+ `-------*/
+
+ /* FIXME: Maybe we could sugar all this (using make_whatever
+ helpers?). */
+
+ // --------- //
+ // Complex. //
+ // --------- //
+
+ const unsigned D = 2;
+ topo::complex<D> c;
+
+ // ------------------------------------------ //
+ // Vertices & geometry (vertices locations). //
+ // ------------------------------------------ //
+
+ /* ``The vertices are listed with x, y, z coordinates, written
+ one per line. */
+
+ /* FIXME: We should have a faster way to create a bunch of
+ 0-faces (vertices). */
+ for (unsigned v = 0; v < nvertices; ++v)
+ c.add_face();
+
+ typedef point3df P;
+ typedef mln_coord_(P) C;
+ typedef geom::complex_geometry<D, P> G;
+ G geom;
+ for (unsigned v = 0; v < nvertices; ++v)
+ {
+ C x, y, z;
+ istr >> internal::eat_comment >> x
+ >> internal::eat_comment >> y
+ >> internal::eat_comment >> z;
+ geom.add_location(point3df(x, y, z));
+ }
+
+ // --------------- //
+ // Faces & edges. //
+ // --------------- //
+
+ /* After the list of vertices, the faces are listed, with one
+ face per line. For each face, the number of vertices is
+ specified, followed by indices into the list of
+ vertices.'' */
+
+ // An adjacenty matrix recording the edges seen so far.
+ typedef std::vector< std::vector<bool> > complex_edges_t;
+ complex_edges_t complex_edges (nvertices,
+ std::vector<bool>(nvertices, false));
+
+ for (unsigned f = 0; f < nfaces; ++f)
+ {
+ unsigned nface_vertices;
+ istr >> internal::eat_comment >> nface_vertices;
+ if (nface_vertices <= 2)
+ {
+ std::cerr << me << ": `" << filename
+ << "': ill-formed face (" << nface_vertices
+ << " vertices)" << std::endl;
+ std::exit(1);
+ }
+
+ // The edges of the face.
+ topo::n_faces_set<1, D> face_edges_set;
+ face_edges_set.reserve(nface_vertices);
+
+ // The first vertex id of the face.
+ unsigned first_vertex_id;
+ istr >> internal::eat_comment >> first_vertex_id;
+ // The current vertex id initialized with the first id.
+ unsigned vertex_id = first_vertex_id;
+ if (first_vertex_id >= nvertices)
+ {
+ std::cerr << me << ": `" << filename
+ << "': invalid vertex id " << first_vertex_id
+ << std::endl;
+ std::exit(1);
+ }
+ // Iterate on vertices and form edges.
+ for (unsigned v = 0; v < nface_vertices; ++v)
+ {
+ /* The next vertex id. The pair (vertex_id, next_vertex_id)
+ is an edge of the mesh/complex. */
+ unsigned next_vertex_id;
+ /* When V is the id of the last vertex of the face F,
+ set next_vertex_id to first_vertex_id; otherwise,
+ read it from the input. */
+ if (v == nface_vertices - 1)
+ next_vertex_id = first_vertex_id;
+ else
+ {
+ istr >> internal::eat_comment >> next_vertex_id;
+ if (next_vertex_id >= nvertices)
+ {
+ std::cerr << me << ": `" << filename
+ << "': invalid vertex id " << next_vertex_id
+ << std::endl;
+ std::exit(1);
+ }
+ }
+ // The ends of the current edge.
+ topo::n_face<0, D> vertex(c, vertex_id);
+ topo::n_face<0, D> next_vertex(c, next_vertex_id);
+ // The current edge.
+ topo::n_face<1, D> edge;
+ // If the edge has been constructed yet, create it;
+ // otherwise, retrieve its id from the complex.
+ if (!complex_edges[vertex_id][next_vertex_id])
+ {
+ complex_edges[vertex_id][next_vertex_id] = true;
+ complex_edges[next_vertex_id][vertex_id] = true;
+ edge = c.add_face(vertex + next_vertex);
+ }
+ else
+ {
+ edge = topo::edge(vertex, next_vertex);
+ mln_assertion(edge.is_valid());
+ }
+ // Record this edge.
+ face_edges_set += edge;
+ // Next vertex.
+ vertex_id = next_vertex_id;
+ }
+
+ // Add face.
+ c.add_face(face_edges_set);
+ }
+
+ /*--------.
+ | Image. |
+ `--------*/
+
+ // Value type.
+ typedef bool V;
+
+ // Site set.
+ p_complex<D, G> pc(c, geom);
+
+ // Values.
+ metal::vec<D + 1, std::vector<V> > values;
+ for (unsigned i = 0; i <= D; ++i)
+ values[i].insert(values[i].begin(), pc.cplx().nfaces(i), true);
+
+ // Image.
+ ima.init_(pc, values);
+
+ istr.close();
+ }
+
+
+ namespace internal
+ {
+ /// A stream manipulator eating comments starting with a `#'
+ /// and ending at an end of line
+ std::istream& eat_comment (std::istream& istr)
+ {
+ // Skip whitespace and newlines.
+ std::ws(istr);
+ while (istr.peek() == '#')
+ {
+ /* Eat the `#' and the rest of the line until `\n' or
+ `\r' is found or the end of the file is reached. */
+ char c;
+ do
+ istr.get(c);
+ while (c != '\n' && c != '\r' && !istr.eof());
+ // Skip whitespace and newlines.
+ std::ws(istr);
+ }
+ return istr;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::off
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_OFF_LOAD_HH
--
1.6.0.1
* tests/data.hh.in (MLN_MESH_DIR): New macro.
---
milena/ChangeLog | 6 ++++++
milena/tests/data.hh.in | 9 ++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 582245d..30e48e9 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a macro containing the path to meshes, to be used in tests.
+
+ * tests/data.hh.in (MLN_MESH_DIR): New macro.
+
+2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+
Add more meshes.
* mesh/cube.off,
diff --git a/milena/tests/data.hh.in b/milena/tests/data.hh.in
index f30cfdc..f26299b 100644
--- a/milena/tests/data.hh.in
+++ b/milena/tests/data.hh.in
@@ -30,10 +30,13 @@
# include <string>
-/** \brief The absolute path to the img directory of Milena.
+/* Macros are evil, but they save us an extra compilation unit here
+ (as well as additional burden in Makefiles, too.). */
- Macros are evil, but they save us an extra compilation unit here
- (as well as additional burden in Makefiles, too.). */
+/// \brief The absolute path to the img directory of Milena.
# define MLN_IMG_DIR "@abs_top_srcdir@/milena/img"
+/// \brief The absolute path to the mesh directory of Milena.
+# define MLN_MESH_DIR "@abs_top_srcdir@/milena/mesh"
+
#endif // ! TESTS_DATA_HH
--
1.6.0.1
* mln/geom/complex_geometry.hh: New.
---
milena/ChangeLog | 6 +
milena/mln/geom/complex_geometry.hh | 217 +++++++++++++++++++++++++++++++++++
2 files changed, 223 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/geom/complex_geometry.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 36dd95d..afe3d11 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a functor encoding the geometry of a complex using its 0-faces.
+
+ * mln/geom/complex_geometry.hh: New.
+
+2008-10-16 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a multiple-site type.
* mln/util/multi_site.hh: New.
diff --git a/milena/mln/geom/complex_geometry.hh b/milena/mln/geom/complex_geometry.hh
new file mode 100644
index 0000000..2e44ad4
--- /dev/null
+++ b/milena/mln/geom/complex_geometry.hh
@@ -0,0 +1,217 @@
+// Copyright (C) 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_GEOM_COMPLEX_GEOMETRY_HH
+# define MLN_GEOM_COMPLEX_GEOMETRY_HH
+
+/// \file mln/geom/complex_geometry.hh
+/// \brief A functor associating geometry (location) data to the faces
+/// of a complex.
+///
+/// \see mln::topo::complex.
+
+# include <vector>
+# include <set>
+
+# include <mln/topo/face.hh>
+
+# include <mln/util/multi_site.hh>
+# include <mln/util/tracked_ptr.hh>
+
+
+/* FIXME: Also provide functors where the locations are computed using
+ a function (useful for a complex on a regular grid/support. */
+
+/* FIXME: This class could probably be turned into something more
+ generic, usable for other other purpose, e.g. attaching sites to
+ graphs. */
+
+/* FIXME: Also provide another geometry type where everything is
+ stored even for n-face with n > 0. */
+
+
+namespace mln
+{
+
+ namespace geom
+ {
+
+ // Forward declaration.
+ namespace internal
+ {
+ template <typename P> struct complex_geometry_data;
+ }
+
+
+ /** \brief A functor returning the sites of the faces of a complex
+ where the locations of each 0-face is stored. Faces of higher
+ dimensions are computed.
+
+ \arg \p D The dimension of the complex.
+ \arg \p P The type of the location of a 0-face.
+
+ Locations of 0-face are usually points (hence the \p P above),
+ but can possibly be any (default-constructible) values.
+
+ The functor returns a std::vector of locations: 0-faces are
+ singletons, 1-faces are (usually) pairs, faces of higher
+ dimensions are arrays of locations.
+
+ Note that for consistency reasons w.r.t. the return type of
+ operator(), returned sites are always <em>arrays</em> of
+ locations attached to 0-faces; hence the returned singletons
+ (of locations) for 0-faces. */
+ template <unsigned D, typename P>
+ class complex_geometry
+ {
+ public:
+ typedef P location;
+ typedef util::multi_site<P> site;
+
+ public:
+ /// \brief Build a complex geometry object.
+ complex_geometry();
+
+ public:
+ /// \brief Populate the set of locations.
+ ///
+ /// Append a new location \a p. Return the index of the newly
+ /// created location (which should semantically match the id of
+ /// the corresonding 0-face in the complex).
+ unsigned add_location(const P& p);
+
+ /// \brief Retrieve the site associated to \a f.
+ site operator()(const mln::topo::face<D>& f) const;
+
+ private:
+ mln::util::tracked_ptr< internal::complex_geometry_data<P> > data_;
+ };
+
+
+ namespace internal
+ {
+ /// \brief The data stored in a complex_geometry object.
+ ///
+ /// \arg \p P The type of the location of a 0-face.
+ template <typename P>
+ struct complex_geometry_data
+ {
+ util::multi_site<P> zero_faces;
+ };
+ }
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned D, typename P>
+ inline
+ complex_geometry<D, P>::complex_geometry()
+ : data_(new internal::complex_geometry_data<P>())
+ {
+ }
+
+ template <unsigned D, typename P>
+ inline
+ unsigned
+ complex_geometry<D, P>::add_location(const P& p)
+ {
+ mln_precondition(data_);
+ // FIXME: These two lines are not thread safe.
+ data_->zero_faces.push_back(p);
+ return data_->zero_faces.size();
+ }
+
+ template <unsigned D, typename P>
+ inline
+ util::multi_site<P>
+ complex_geometry<D, P>::operator()(const mln::topo::face<D>& f) const
+ {
+ mln_precondition(data_);
+ site s;
+ s.reserve(1);
+ if (f.n() == 0)
+ {
+ // F is a 0-face.
+ mln_assertion(f.face_id() < data_->zero_faces.size());
+ s.push_back(data_->zero_faces[f.face_id()]);
+ }
+ else
+ {
+ // F is an n-face, with n > 0.
+ typedef std::vector < topo::face<D> > faces_t;
+ typedef std::set < topo::face<D> > faces_set_t;
+
+ // The adjacent m-faces.
+ faces_t m_faces = f.lower_dim_adj_faces();
+ // The set of (m-1)-face being built.
+ /* FIXME: This pattern is recurring in Milena---using an
+ std::set (or any fast associative container) to improve
+ the lookup speed of an std::vector; we should create a
+ class for this, a bit like mln::util::set, but with a
+ garantee on the order of insertion. */
+ faces_t work_faces;
+ faces_set_t work_faces_set;
+
+ // Iteratively compute the set of locations.
+ for (unsigned m = f.n() - 1; m > 0; --m)
+ {
+ for (typename faces_t::const_iterator g = m_faces.begin();
+ g != m_faces.end(); ++g)
+ {
+ faces_t m_minus_one_faces = g->lower_dim_adj_faces();
+ // Don't insert a face twice.
+ for (typename faces_t::const_iterator h =
+ m_minus_one_faces.begin();
+ h != m_minus_one_faces.end(); ++h)
+ if (work_faces_set.find(*h) == work_faces_set.end())
+ {
+ work_faces.push_back(*h);
+ work_faces_set.insert(*h);
+ }
+ }
+ work_faces.swap(m_faces);
+ work_faces.clear();
+ work_faces_set.clear();
+ }
+ for (typename faces_t::const_iterator g = m_faces.begin();
+ g != m_faces.end(); ++g)
+ {
+ mln_assertion(g->face_id() < data_->zero_faces.size());
+ s.push_back(data_->zero_faces[g->face_id()]);
+ }
+ }
+ return s;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of mln::geom
+
+ } // end of mln
+
+#endif // MLN_GEOM_COMPLEX_GEOMETRY_HH
--
1.6.0.1