---
milena/ChangeLog | 4 ++++
milena/mln/io/off/load.hh | 14 +++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 00d6b64..7af357d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -24,6 +24,10 @@
2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+ * mln/io/off/load.hh: Polish this file.
+
+2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Exercise mln::io::off:save.
* tests/io/off/load_save_bin.cc: New test.
diff --git a/milena/mln/io/off/load.hh b/milena/mln/io/off/load.hh
index 1a00f3d..6cdf3d5 100644
--- a/milena/mln/io/off/load.hh
+++ b/milena/mln/io/off/load.hh
@@ -52,13 +52,13 @@ namespace mln
namespace off
{
- /** \brief Load a (boolean) OFF image into a complex image.
+ /** \brief Load a (binary) 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. */
+ The image is said binary since data only represent the
+ existence of faces. */
void load(bin_2complex_image3df& ima, const std::string& filename);
namespace internal
@@ -73,14 +73,14 @@ namespace mln
void load(bin_2complex_image3df& ima, const std::string& filename)
{
- const std::string me = "mln::io::load::off";
+ const std::string me = "mln::io::off::load";
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
+ exceptions, 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!). */
@@ -92,9 +92,9 @@ namespace mln
`---------*/
/* ``The .off files in the Princeton Shape Benchmark conform
- to the following standard. */
+ to the following standard''. */
- /* OFF files are all ASCII files beginning with the keyword
+ /* ``OFF files are all ASCII files beginning with the keyword
OFF. '' */
std::string type;
istr >> internal::eat_comment >> type;
--
1.6.0.1
* tests/io/off/load_save_bin.cc: New test.
* tests/io/off/Makefile.am (check_PROGRAMS): Add load_save_bin.
(load_save_bin_SOURCES): New.
---
milena/ChangeLog | 8 +++++
milena/tests/io/off/Makefile.am | 4 ++-
milena/tests/io/off/load_save_bin.cc | 50 ++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+), 1 deletions(-)
create mode 100644 milena/tests/io/off/load_save_bin.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 50ba108..00d6b64 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -24,6 +24,14 @@
2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+ Exercise mln::io::off:save.
+
+ * tests/io/off/load_save_bin.cc: New test.
+ * tests/io/off/Makefile.am (check_PROGRAMS): Add load_save_bin.
+ (load_save_bin_SOURCES): New.
+
+2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a routine to save a complex-based image to an OFF file.
* mln/io/off/save.hh: New.
diff --git a/milena/tests/io/off/Makefile.am b/milena/tests/io/off/Makefile.am
index 4b592ce..30f4824 100644
--- a/milena/tests/io/off/Makefile.am
+++ b/milena/tests/io/off/Makefile.am
@@ -3,8 +3,10 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
- load_bin
+ load_bin \
+ load_save_bin
load_bin_SOURCES = load_bin.cc
+load_save_bin_SOURCES = load_save_bin.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/io/off/load_save_bin.cc b/milena/tests/io/off/load_save_bin.cc
new file mode 100644
index 0000000..2dbbdcb
--- /dev/null
+++ b/milena/tests/io/off/load_save_bin.cc
@@ -0,0 +1,50 @@
+// 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_save_bin.cc
+/// \brief Test mln::io::off::load with and mln::io::off::save with an
+/// mln::bin_2complex_image3df.
+
+#include <algorithm>
+#include <iterator>
+#include <iostream>
+
+#include <mln/io/off/load.hh>
+#include <mln/io/off/save.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef bin_2complex_image3df ima_t;
+ ima_t ima;
+ io::off::load(ima, MLN_MESH_DIR "/tetrahedron.off");
+ io::off::save(ima, "out.off");
+}
--
1.6.0.1
* mln/io/off/save.hh: New.
---
milena/ChangeLog | 6 ++
milena/mln/io/off/save.hh | 197 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 203 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/io/off/save.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index cfd2a4f..50ba108 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -24,6 +24,12 @@
2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a routine to save a complex-based image to an OFF file.
+
+ * mln/io/off/save.hh: New.
+
+2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Enrich the interface of mln::util::multi_site.
* mln/util/multi_site.hh (mln::util::multi_site<P>::front):
diff --git a/milena/mln/io/off/save.hh b/milena/mln/io/off/save.hh
new file mode 100644
index 0000000..eba2aeb
--- /dev/null
+++ b/milena/mln/io/off/save.hh
@@ -0,0 +1,197 @@
+// 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_SAVE_HH
+# define MLN_IO_OFF_SAVE_HH
+
+/// \file mln/io/off/save.hh
+/// \brief Input saving function for OFF files.
+///
+/// \see http://shape.cs.princeton.edu/benchmark/documentation/off_format.html
+
+# include <cstdlib>
+
+# include <iostream>
+# include <fstream>
+# include <sstream>
+
+# include <string>
+
+# include <mln/core/alias/bin_2complex_image3df.hh>
+# include <mln/core/image/complex_neighborhoods.hh>
+# include <mln/core/image/complex_neighborhood_piter.hh>
+
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace off
+ {
+
+ /** \brief Save a (binary) OFF image into a complex image.
+
+ \param[in] ima The image to save.
+ \param[in] filename The name of the file where to save the image.
+
+ The image is said binary since data only represent the
+ existence of faces. */
+ void save(const bin_2complex_image3df& ima, const std::string& filename);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ void save(const bin_2complex_image3df& ima, const std::string& filename)
+ {
+ const std::string me = "mln::io::off::save";
+
+ std::ofstream ostr(filename.c_str());
+ if (!ostr)
+ {
+ std::cerr << me << ": `" << filename << "' invalid file."
+ << std::endl;
+ /* FIXME: Too violent. We should allow the use of
+ exceptions, 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. '' */
+ ostr << "OFF" << std::endl;
+
+ // A comment.
+ ostr << "# Generated by Milena 1.0 http://olena.lrde.epita.fr\n"
+ << "# EPITA Research and Development Laboratory (LRDE)"
+ << std::endl;
+
+ /* ``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.'' */
+ /* FIXME: This is too long. We shall be able to write
+
+ ima.domain().nfaces<0>()
+
+ or even
+
+ ima.nfaces<0>().
+ */
+ ostr << ima.domain().cplx().nfaces<0>() << ' '
+ << ima.domain().cplx().nfaces<1>() << ' '
+ << ima.domain().cplx().nfaces<2>() << std::endl;
+
+ /*-------.
+ | Data. |
+ `-------*/
+
+ // --------- //
+ // Complex. //
+ // --------- //
+
+ typedef mln::bin_2complex_image3df I;
+ const unsigned D = I::dim;
+ typedef mln_geom_(I) G;
+
+ // ------------------------------------------ //
+ // Vertices & geometry (vertices locations). //
+ // ------------------------------------------ //
+
+ /* ``The vertices are listed with x, y, z coordinates, written
+ one per line. */
+
+ // Traverse the 0-faces (vertices).
+ p_n_faces_fwd_piter<D, G> v(ima.domain(), 0);
+ for_all(v)
+ {
+ mln_invariant(v.to_site().size() == 1);
+ ostr << v.to_site().front()[0] << ' '
+ << v.to_site().front()[1] << ' '
+ << v.to_site().front()[2] << std::endl;
+ }
+
+ // --------------- //
+ // 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.'' */
+
+ // Traverse the 2-faces (polygons).
+ p_n_faces_fwd_piter<D, G> f(ima.domain(), 2);
+
+ typedef complex_m_face_neighborhood<D, G> nbh_t;
+ // A neighborhood where neighbors are the set of 0-faces
+ // transitively adjacent to the reference point.
+ nbh_t nbh;
+ mln_fwd_niter_(nbh_t) u(nbh, f);
+ /* FIXME: We should be able to pas this value (m) either at
+ the construction of the neighborhood or at the construction
+ of the iterator. */
+ u.iter().set_m(0);
+
+ // For each (2-)face, iterate on (transitively) ajacent
+ // vertices (0-faces).
+ for_all(f)
+ {
+ unsigned nvertices = 0;
+ std::ostringstream vertices;
+ for_all(u)
+ {
+ // FIXME: Likewise, this is a bit too long...
+ vertices << ' ' << u.unproxy_().face().face_id();
+ ++nvertices;
+ }
+ ostr << nvertices << vertices.str() << std::endl;
+ }
+
+ ostr.close();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::off
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_OFF_SAVE_HH
--
1.6.0.1
* mln/geom/complex_geometry.hh
(mln::geom::complex_geometry<D, P>::operator()):
Use mln::topo::adj_m_face_fwd_iter to simplify the implementation
of this operator.
---
milena/ChangeLog | 9 ++++++
milena/mln/geom/complex_geometry.hh | 52 +++++-----------------------------
2 files changed, 17 insertions(+), 44 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 736c0cc..6c52239 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -24,6 +24,15 @@
2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+ Simplify mln::geom::complex_geometry.
+
+ * mln/geom/complex_geometry.hh
+ (mln::geom::complex_geometry<D, P>::operator()):
+ Use mln::topo::adj_m_face_fwd_iter to simplify the implementation
+ of this operator.
+
+2008-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Exercise iterators on transitively adjacent m-faces.
* tests/topo/complex.cc: Here.
diff --git a/milena/mln/geom/complex_geometry.hh b/milena/mln/geom/complex_geometry.hh
index 2e44ad4..1634a65 100644
--- a/milena/mln/geom/complex_geometry.hh
+++ b/milena/mln/geom/complex_geometry.hh
@@ -38,6 +38,7 @@
# include <set>
# include <mln/topo/face.hh>
+# include <mln/topo/adj_m_face_iter.hh>
# include <mln/util/multi_site.hh>
# include <mln/util/tracked_ptr.hh>
@@ -162,56 +163,19 @@ namespace mln
}
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()]);
- }
+ /* F is an n-face, with n > 0.
+ Compute the set of 0-faces transitively adjacent to F. */
+ topo::adj_m_face_fwd_iter<D> g(f, 0);
+ for_all(g)
+ s.push_back(data_->zero_faces[g.face().face_id()]);
}
return s;
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of mln::geom
+ } // end of mln::geom
- } // end of mln
+} // end of mln
#endif // MLN_GEOM_COMPLEX_GEOMETRY_HH
--
1.6.0.1