2633: Add a routine to save a complex-based image to an OFF file.

* 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@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@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
participants (1)
-
Roland Levillain