This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch distribute-scribo has been created
at 01410e4425360fbaf2651969c30f11fe51f8b3da (commit)
- Log -----------------------------------------------------------------
01410e4 Distribute Scribo.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
---
milena/ChangeLog | 4 ++++
milena/mln/io/vtk/save.hh | 38 ++++++++++++++++----------------------
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 41c681c..d27ada3 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,7 @@
+2010-07-28 Roland Levillain <roland(a)lrde.epita.fr>
+
+ * mln/io/vtk/save.hh: Fix documentation.
+
2010-07-27 Roland Levillain <roland(a)lrde.epita.fr>
* mln/io/vtk/all.hh: New.
diff --git a/milena/mln/io/vtk/save.hh b/milena/mln/io/vtk/save.hh
index 10c3f0b..2a4a51f 100644
--- a/milena/mln/io/vtk/save.hh
+++ b/milena/mln/io/vtk/save.hh
@@ -58,41 +58,35 @@ namespace mln
/** \brief Save a (binary) VTK 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 represent only the
- existence of faces. */
+ \param[in] filename The name of the file where to save the
+ image.
+ */
void save(const bin_2complex_image3df& ima,
const std::string& filename);
- /** \brief Save an 8-bit grey-level VTK image into a complex image.
+ /** \brief Save an 8-bit gray-level VTK 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.
-
- Only data is attached to 2-faces is saved; the VTK file
- cannot store data attached to faces of other dimensions. */
+ \param[in] filename The name of the file where to save the
+ image.
+ */
void save(const int_u8_2complex_image3df& ima,
const std::string& filename);
- /** \brief Save a floating-point value grey-level VTK image into
+ /** \brief Save a floating-point value gray-level VTK 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.
-
- Only data is attached to 2-faces is saved; the VTK file
- cannot store data attached to faces of other dimensions. */
+ \param[in] filename The name of the file where to save the
+ image. */
void save(const float_2complex_image3df& ima,
const std::string& filename);
/** \brief Save a 3x8-bit RGB (color) VTK 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.
-
- Only data is attached to 2-faces is saved; the VTK file
- cannot store data attached to faces of other dimensions. */
+ \param[in] filename The name of the file where to save the
+ image. */
void save(const rgb8_2complex_image3df& ima,
const std::string& filename);
@@ -248,7 +242,7 @@ namespace mln
parts.'' */
/* ``1. The first part is the file version and
- identifier. This part contains the single line:
+ identifier. This part contains the single line:
# vtk DataFile Version x.x.
@@ -268,9 +262,9 @@ namespace mln
<< std::endl;
/* ``3. The next part is the file format. The file format
- describes the type of file, either ASCII or
- binary. On this line the single word ASCII or BINARY
- must appear.'' */
+ describes the type of file, either ASCII or
+ binary. On this line the single word ASCII or BINARY
+ must appear.'' */
ostr << "ASCII" << std::endl;
/*-------.
--
1.5.6.5
* apps/mesh-segm-skel/save_bin_alt.hh
(mln::io::vtk::save_bin_alt): New function.
---
milena/ChangeLog | 7 +
milena/apps/mesh-segm-skel/save_bin_alt.hh | 310 +++++++++++++++++++++++++++-
2 files changed, 312 insertions(+), 5 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index c8219e9..d850e40 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2010-06-24 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a specific (temporary) VTK output routine for binary mesh images.
+
+ * apps/mesh-segm-skel/save_bin_alt.hh
+ (mln::io::vtk::save_bin_alt): New function.
+
+2010-06-24 Roland Levillain <roland(a)lrde.epita.fr>
+
Exercise mln::io::vtk::save.
* tests/io/vtk/save.cc: New.
diff --git a/milena/apps/mesh-segm-skel/save_bin_alt.hh b/milena/apps/mesh-segm-skel/save_bin_alt.hh
index 034b840..b09fa88 100644
--- a/milena/apps/mesh-segm-skel/save_bin_alt.hh
+++ b/milena/apps/mesh-segm-skel/save_bin_alt.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Milena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +28,11 @@
#ifndef APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH
# define APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH
-/*--------------------------------------------------------------------.
-| FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, |
-| because fixing image_if + complex_image was much too long. Sorry. |
-`--------------------------------------------------------------------*/
+/*-------------------------------------------------------------------.
+| FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, |
+| and mln/io/vtk/save.hh,because fixing image_if + complex_image was |
+| much too long. Sorry. |
+`-------------------------------------------------------------------*/
# include <cstdlib>
@@ -51,6 +52,10 @@ namespace mln
namespace io
{
+ /*------.
+ | OFF. |
+ `------*/
+
namespace off
{
@@ -181,6 +186,301 @@ namespace mln
} // end of namespace mln::io::off
+
+ /*------.
+ | VTK. |
+ `------*/
+
+ namespace vtk
+ {
+ /** FIXME: Similar to
+ mln::io::vtk::save(const bin_2complex_image3df&, const std::string&),
+ but does not save faces whose value is `false'. */
+ template <typename I>
+ void save_bin_alt(const I& ima,
+ const std::string& filename)
+ {
+ const std::string me = "mln::io::vtk::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 legacy VTK file formats consist of five basic
+ parts.'' */
+
+ /* ``1. The first part is the file version and
+ identifier. This part contains the single line:
+
+ # vtk DataFile Version x.x.
+
+ This line must be exactly as shown with the
+ exception of the version number x.x, which will vary
+ with different releases of VTK. (Note: the current
+ version number is 3.0. Version 1.0 and 2.0 files are
+ compatible with version 3.0 files.)'' */
+ ostr << "# vtk DataFile Version 2.0" << std::endl;
+
+ /* ``2. The second part is the header. The header consists
+ of a character string terminated by end-of-line
+ character `\n'. The header is 256 characters
+ maximum. The header can be used to describe the data
+ and include any other pertinent information.'' */
+ ostr << "Generated by Milena 1.0 http://olena.lrde.epita.fr"
+ << std::endl;
+
+ /* ``3. The next part is the file format. The file format
+ describes the type of file, either ASCII or
+ binary. On this line the single word ASCII or BINARY
+ must appear.'' */
+ ostr << "ASCII" << std::endl;
+
+ /*-------.
+ | Data. |
+ `-------*/
+
+ /* ``4. The fourth part is the dataset structure. The
+ geometry part describes the geometry and topology of
+ the dataset. This part begins with a line containing
+ the keyword DATASET followed by a keyword describing
+ the type of dataset. Then, depending upon the type
+ of dataset, other keyword/data combinations define
+ the actual data.''
+
+ [...]
+
+ Dataset Format. The Visualization Toolkit supports
+ five different dataset formats: structured points,
+ structured grid, rectilinear grid, unstructured
+ grid, and polygonal data.'' */
+
+ ostr << "DATASET POLYDATA" << std::endl << std::endl;
+
+ // --------- //
+ // Complex. //
+ // --------- //
+
+ static const unsigned D = I::dim;
+ typedef mln_geom(I) G;
+
+ /* ``* Polygonal Data
+ The polygonal dataset consists of arbitrary
+ combinations of surface graphics primitives
+ vertices (and polyvertices), lines (and
+ polylines), polygons (of various types), and
+ triangle strips. Polygonal data is defined by
+ the POINTS, VERTICES, LINES, POLYGONS, or
+ TRIANGLE_STRIPS sections. The POINTS definition
+ is the same as we saw for structured grid
+ datasets.'' */
+
+ // ---------------------------- //
+ // Geometry (point locations). //
+ // ---------------------------- //
+
+ ostr << "POINTS "
+ << ima.domain().cplx().template nfaces_of_static_dim<0>()
+ << " float" << std::endl;
+ // Iterate on 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;
+ }
+ ostr << std::endl;
+
+ /* ``The VERTICES, LINES, POLYGONS, or
+ TRIANGLE_STRIPS keywords define the polygonal
+ dataset topology. Each of these keywords
+ requires two parameters: the number of cells `n'
+ and the size of the cell list `size'. The cell
+ list size is the total number of integer values
+ required to represent the list (i.e., sum of
+ `numPoints' and connectivity indices over each
+ cell). None of the keywords VERTICES, LINES,
+ POLYGONS, or TRIANGLE_STRIPS is required.'' */
+
+ // ---------- //
+ // Vertices. //
+ // ---------- //
+
+ /* FIXME: Do not create a VERTICES section if there is no
+ vertex.
+
+ Likewise, only process vertices having a value attached
+ to them, i.e., which are part of the domain of the image
+ (which is different from the complex, upon which the
+ domain is based). */
+
+ /* We do not use
+
+ ima.domain().cplx().template nfaces_of_static_dim<N>()
+
+ to get the number of N-faces, since the image may be
+ masked, and exhibit less N-faces than its underlying
+ complex. Iterating on the N-faces is safer. */
+ /* FIXME: Is there anything faster? See what the interface
+ of the (morphed) image can provide. */
+ unsigned nvertices = 0;
+ for_all(v) if (ima(v))
+ ++nvertices;
+
+ ostr << "VERTICES " << nvertices << ' '
+ /* Each vertex requires two numbers: the cardinal of its
+ ends (which is always 1) and the indices of the point
+ among the POINTS section. Hence the total number of
+ values in the VERTEX section is nvertices * 2. */
+ << nvertices * 2 << std::endl;
+
+ for_all(v) if (ima(v))
+ ostr << "1 " << v.unproxy_().face().face_id() << std::endl;
+ ostr << std::endl;
+
+ // ------- //
+ // Edges. //
+ // ------- //
+
+ /* FIXME: Do not create a LINES section if there is no
+ edge.
+
+ Likewise, only process edges having a value attached
+ to them, i.e., which are part of the domain of the image
+ (which is different from the complex, upon which the
+ domain is based). */
+
+ // Same comment as above about the count of N-faces.
+ unsigned nedges = 0;
+ p_n_faces_fwd_piter<D, G> e(ima.domain(), 1);
+ for_all (e) if (ima(e))
+ ++nedges;
+
+ ostr << "LINES " << nedges << ' '
+ /* Each edge requires three numbers: the cardinal of its
+ ends (which is always 2) and the indices of these ends
+ among the POINTS section. Hence the total number of
+ values in the LINES section is nedges * 3. */
+ << nedges * 3 << std::endl;
+
+ // Vertices adjacent to edges.
+ typedef complex_lower_neighborhood<D, G> adj_vertices_nbh_t;
+ adj_vertices_nbh_t adj_vertices_nbh;
+ mln_niter(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, e);
+ // Iterate on 1-faces (edges).
+ for_all (e) if (ima(e))
+ {
+ ostr << "2";
+ // Iterate on vertices (0-faces).
+ for_all (adj_v)
+ {
+ // FIXME: Accessing the face id is too complicated.
+ ostr << " " << adj_v.unproxy_().face().face_id();
+ }
+ ostr << std::endl;
+ }
+ ostr << std::endl;
+
+ // ---------- //
+ // Polygons. //
+ // ---------- //
+
+ /* FIXME: Do not create a POLYGONS section if there is no
+ polygon.
+
+ Likewise, only process polygons having a value attached
+ to them, i.e., which are part of the domain of the image
+ (which is different from the complex, upon which the
+ domain is based). */
+
+ // Same comment as above about the count of N-faces.
+ unsigned npolygons = 0;
+ p_n_faces_fwd_piter<D, G> p(ima.domain(), 2);
+
+ // FIXME: Merge this loop with the next one.
+
+ for_all (p) if (ima(p))
+ ++npolygons;
+
+ // A neighborhood where neighbors are the set of 0-faces
+ // transitively adjacent to the reference point.
+ typedef complex_m_face_neighborhood<D, G> nbh_t;
+ nbh_t nbh;
+ mln_fwd_niter(nbh_t) u(nbh, p);
+ /* FIXME: We should be able to pass this value (m) either at
+ the construction of the neighborhood or at the construction
+ of the iterator. */
+ u.iter().set_m(0);
+
+ /* Compute the number of values (`size') to be passed as
+ second parameter of the POLYGONS keyword. */
+ unsigned polygons_size = 0;
+ // Iterate on polygons (2-face).
+ for_all(p) if (ima(p))
+ {
+ unsigned nvertices = 0;
+ /* FIXME: There may be a faster way to do this (e.g.,
+ the neighbordhood may provide a method returning the
+ number of P's neighbors. */
+ // Iterate on transitively adjacent vertices (0-face).
+ for_all(u)
+ ++nvertices;
+ // The number of values describing this polygon P is the
+ // cardinal of its set of vertices (1 value) plus the
+ // NVERTICES indices of these vertices.
+ polygons_size += 1 + nvertices;
+ }
+ ostr << "POLYGONS " << npolygons << ' ' << polygons_size
+ << std::endl;
+
+ /* Output polygons (one per line), with their number of
+ vertices and the indices of these vertices. */
+ // Iterate on polygons (2-face).
+ for_all(p) if (ima(p))
+ {
+ unsigned nvertices = 0;
+ std::ostringstream vertices;
+ // Iterate on transitively adjacent vertices (0-face).
+ for_all(u)
+ {
+ // FIXME: Likewise, this is a bit too long...
+ vertices << ' ' << u.unproxy_().face().face_id();
+ ++nvertices;
+ }
+ ostr << nvertices << vertices.str() << std::endl;
+ }
+
+ /* ``5. The final part describes the dataset
+ attributes. This part begins with the keywords
+ POINT_DATA or CELL_DATA,followed by an integer
+ number specifying the number of points or cells,
+ respectively. (It doesn't matter whether POINT_DATA
+ or CELL_DATA comes first.) Other keyword/data
+ combinations then define the actual dataset
+ attribute values (i.e., scalars, vectors, tensors,
+ normals, texture coordinates, or field data).'' */
+
+ // FIXME: To do.
+
+ ostr.close();
+ }
+
+ } // end of namespace mln::io::vtk
+
} // end of namespace mln::io
} // end of namespace mln
--
1.5.6.5
* tests/io/vtk/save.cc: New.
* tests/io/vtk/Makefile.am: New.
* tests/io/Makefile.am (SUBDIRS): Add vtk.
---
milena/ChangeLog | 8 +++
milena/tests/io/Makefile.am | 3 +-
milena/tests/io/{pbm => vtk}/Makefile.am | 16 ++---
milena/tests/io/vtk/save.cc | 97 ++++++++++++++++++++++++++++++
4 files changed, 114 insertions(+), 10 deletions(-)
copy milena/tests/io/{pbm => vtk}/Makefile.am (74%)
create mode 100644 milena/tests/io/vtk/save.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6523940..c8219e9 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
2010-06-24 Roland Levillain <roland(a)lrde.epita.fr>
+ Exercise mln::io::vtk::save.
+
+ * tests/io/vtk/save.cc: New.
+ * tests/io/vtk/Makefile.am: New.
+ * tests/io/Makefile.am (SUBDIRS): Add vtk.
+
+2010-06-24 Roland Levillain <roland(a)lrde.epita.fr>
+
Start a VTK output for complex-based images.
* mln/io/vtk/save.hh: New.
diff --git a/milena/tests/io/Makefile.am b/milena/tests/io/Makefile.am
index bd6c0a4..41dce69 100644
--- a/milena/tests/io/Makefile.am
+++ b/milena/tests/io/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+# Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
# Laboratory (LRDE).
#
# This file is part of Olena.
@@ -32,6 +32,7 @@ SUBDIRS = \
pnm \
ppm \
ppms \
+ vtk \
fld
## ------------------------------------------------- ##
diff --git a/milena/tests/io/pbm/Makefile.am b/milena/tests/io/vtk/Makefile.am
similarity index 74%
copy from milena/tests/io/pbm/Makefile.am
copy to milena/tests/io/vtk/Makefile.am
index 690c895..3467f78 100644
--- a/milena/tests/io/pbm/Makefile.am
+++ b/milena/tests/io/vtk/Makefile.am
@@ -1,5 +1,4 @@
-# Copyright (C) 2007, 2009, 2010 EPITA Research and Development
-# Laboratory (LRDE).
+# Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -17,15 +16,14 @@
include $(top_srcdir)/milena/tests/tests.mk
-check_PROGRAMS = \
- pbm \
- pbm_ascii
+check_PROGRAMS = save
-pbm_SOURCES = pbm.cc
-pbm_ascii_SOURCES = pbm_ascii.cc
+save_SOURCES = save.cc
TESTS = $(check_PROGRAMS)
MOSTLYCLEANFILES = \
- pbm-out.pbm \
- pbm_ascii-out.pbm
+ save-tetrahedron-bool.vtk \
+ save-tetrahedron-int_u8.vtk \
+ save-tetrahedron-float.vtk \
+ save-tetrahedron-rgb8.vtk
diff --git a/milena/tests/io/vtk/save.cc b/milena/tests/io/vtk/save.cc
new file mode 100644
index 0000000..908636b
--- /dev/null
+++ b/milena/tests/io/vtk/save.cc
@@ -0,0 +1,97 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+#include <mln/io/off/load.hh>
+#include <mln/io/vtk/save.hh>
+
+#include <mln/literal/colors.hh>
+
+#include "tests/data.hh"
+
+
+template <typename I>
+inline
+I
+make_image(const mln::bin_2complex_image3df& bin_ima,
+ const std::vector<mln_value(I)>& values)
+{
+ I ima;
+ mln::initialize(ima, bin_ima);
+ mln_piter(I) p(ima.domain());
+ unsigned i = 0;
+ for_all(p)
+ ima(p) = values[i++ % values.size()];
+ return ima;
+}
+
+
+int
+main()
+{
+ using namespace mln;
+
+ // Boolean values.
+ typedef bin_2complex_image3df bin_ima_t;
+ bin_ima_t bin_ima;
+ /* FIXME: It would be better not to depend on the OFF file loader to
+ create the complex-based image, to be saved as a VTK file; build
+ this image by hand instead? */
+ io::off::load(bin_ima, MLN_MESH_DIR "/tetrahedron.off");
+
+ io::vtk::save(bin_ima, "save-tetrahedron-bool.vtk");
+
+ unsigned nfaces = bin_ima.domain().cplx().nfaces();
+
+ // `int_u8' values.
+ {
+ std::vector<value::int_u8> values(nfaces);
+ for (unsigned i = 0; i < nfaces; ++i)
+ values[i] = mln_max(value::int_u8) * i / nfaces;
+ io::vtk::save(make_image<int_u8_2complex_image3df>(bin_ima, values),
+ "save-tetrahedron-int_u8.vtk");
+ }
+
+ // Floating-point values.
+ {
+ std::vector<float> values(nfaces);
+ for (unsigned i = 0; i < nfaces; ++i)
+ values[i] = mln_max(float) / nfaces * i;
+ io::vtk::save(make_image<float_2complex_image3df>(bin_ima, values),
+ "save-tetrahedron-float.vtk");
+ }
+
+ // `rgb8' values.
+ {
+ value::rgb8 colors_array[] =
+ { literal::red, literal::green, literal::blue, literal::brown,
+ literal::lime, literal::orange, literal::pink, literal::purple,
+ literal::teal, literal::violet, literal::cyan, literal::magenta,
+ literal::yellow, literal::olive };
+ const unsigned colors_size = sizeof(colors_array) / sizeof(value::rgb8);
+ std::vector<value::rgb8> colors (colors_array, colors_array + colors_size);
+ io::vtk::save(make_image<rgb8_2complex_image3df>(bin_ima, colors),
+ "save-tetrahedron-rgb8.vtk");
+ }
+}
--
1.5.6.5