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 exp/scribo-z has been updated
via 4515a1dc6803595b389196a908ed01c18c63a804 (commit)
via db5fcd6bc95f6202aed69fd811d18584e719cdf5 (commit)
from 18262984b19ffbd72f33e37e5e208b03521513e1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
No new revisions were added by this update.
-----------------------------------------------------------------------
Summary of changes:
milena/ChangeLog | 4 +++
milena/mln/value/int_s.hh | 11 ++++++-
scribo/ChangeLog | 5 +++
scribo/scribo/core/line_info.hh | 56 +++++++++++++++++++++++++++------------
4 files changed, 57 insertions(+), 19 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
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 next has been updated
via 4515a1dc6803595b389196a908ed01c18c63a804 (commit)
via db5fcd6bc95f6202aed69fd811d18584e719cdf5 (commit)
via 18262984b19ffbd72f33e37e5e208b03521513e1 (commit)
via 6e783da9ec7535fe373a5a9f90fce24495a84d93 (commit)
via 206ddb6ba62ad2cdee862db36c025761d52898af (commit)
via d2e8cf68fc8af6d5de279bb70535516f53e56df8 (commit)
from 2520689648f68e6cbd3eb47c375102053af53019 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
No new revisions were added by this update.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 13 ++++++
configure.ac | 81 ++++++++++++++++++++++++--------------
m4/oln-with-lib.m4 | 7 ++-
milena/ChangeLog | 4 ++
milena/mln/value/int_s.hh | 11 ++++-
scribo/ChangeLog | 9 ++++
scribo/scribo/core/line_info.hh | 56 +++++++++++++++++++--------
scribo/src/Makefile.am | 53 +++++++++----------------
8 files changed, 149 insertions(+), 85 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
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 exp/next-build-ok has been updated
discards 7aad3ee217c527eef754831822f2067fad7c3adb (commit)
discards 38c94688a42d132ad9b2b8d5b2ff8a7914e1f8cd (commit)
discards 79263eb8957ea0cc946d73fc71cfdfd9f6b31abe (commit)
via 18262984b19ffbd72f33e37e5e208b03521513e1 (commit)
via 6e783da9ec7535fe373a5a9f90fce24495a84d93 (commit)
via 206ddb6ba62ad2cdee862db36c025761d52898af (commit)
via d2e8cf68fc8af6d5de279bb70535516f53e56df8 (commit)
via 2520689648f68e6cbd3eb47c375102053af53019 (commit)
via eecd7d1ced5f4dfc8d46bccc2edc1dacddbe635e (commit)
via c6904964636040aa2cf81dbe4f0c9f26078e8fac (commit)
via 565a8acd20101cf22d58b674d4d1695d8e9926c6 (commit)
via 7671c7df2acc25243c83131813db612be8a654b2 (commit)
via 15a057175710227bdea5a9702dcbf5bd64704a9d (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (7aad3ee217c527eef754831822f2067fad7c3adb)
\
N -- N -- N (18262984b19ffbd72f33e37e5e208b03521513e1)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
No new revisions were added by this update.
-----------------------------------------------------------------------
Summary of changes:
AUTHORS | 12 ++-
ChangeLog | 14 +++
m4/oln-with-lib.m4 | 7 +-
m4/swig.m4 | 9 +-
milena/ChangeLog | 28 +++++
milena/mln/io/magick/load.hh | 202 ++++++++++++++++++------------------
milena/mln/io/magick/save.hh | 145 ++++++++++++++-----------
milena/sandbox/ChangeLog | 44 ++++----
milena/tests/io/magick/Makefile.am | 8 +-
milena/tests/io/magick/load.cc | 72 +++++++++++--
milena/tests/io/magick/save.cc | 86 +++++++++++++--
scribo/ChangeLog | 7 ++
12 files changed, 417 insertions(+), 217 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
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 exp/scribo-z has been updated
discards 2434455d28293575f4bacc80f3e7bb3cd648c3c0 (commit)
via 18262984b19ffbd72f33e37e5e208b03521513e1 (commit)
via 6e783da9ec7535fe373a5a9f90fce24495a84d93 (commit)
via 206ddb6ba62ad2cdee862db36c025761d52898af (commit)
via d2e8cf68fc8af6d5de279bb70535516f53e56df8 (commit)
via 2520689648f68e6cbd3eb47c375102053af53019 (commit)
via eecd7d1ced5f4dfc8d46bccc2edc1dacddbe635e (commit)
via c6904964636040aa2cf81dbe4f0c9f26078e8fac (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (2434455d28293575f4bacc80f3e7bb3cd648c3c0)
\
N -- N -- N (18262984b19ffbd72f33e37e5e208b03521513e1)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
No new revisions were added by this update.
-----------------------------------------------------------------------
Summary of changes:
AUTHORS | 12 +++++-
ChangeLog | 23 ++++++++++++
configure.ac | 81 ++++++++++++++++++++++++++---------------
m4/oln-with-lib.m4 | 7 +++-
m4/swig.m4 | 9 +++--
milena/mln/io/magick/save.hh | 1 +
scribo/ChangeLog | 4 ++
scribo/src/Makefile.am | 21 +++++------
8 files changed, 109 insertions(+), 49 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
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
* mln/io/vtk/save.hh: New.
---
milena/ChangeLog | 6 +
milena/mln/io/vtk/save.hh | 623 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 629 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/io/vtk/save.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index f83deda..6523940 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,9 @@
+2010-06-24 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Start a VTK output for complex-based images.
+
+ * mln/io/vtk/save.hh: New.
+
2010-08-18 Roland Levillain <roland(a)lrde.epita.fr>
* mln/topo/skeleton/breadth_first_thinning.hh: Reindent.
diff --git a/milena/mln/io/vtk/save.hh b/milena/mln/io/vtk/save.hh
new file mode 100644
index 0000000..10c3f0b
--- /dev/null
+++ b/milena/mln/io/vtk/save.hh
@@ -0,0 +1,623 @@
+// Copyright (C) 2008, 2009, 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.
+
+#ifndef MLN_IO_VTK_SAVE_HH
+# define MLN_IO_VTK_SAVE_HH
+
+/// \file
+/// Input saving function for VTK files.
+///
+/// \see http://www.vtk.org/VTK/img/file-formats.pdf
+/// \see http://dunne.uni-hd.de/VisuSimple/documents/vtkfileformat.html
+
+# include <cstdlib>
+
+# include <iostream>
+# include <fstream>
+# include <sstream>
+
+# include <string>
+
+# include <mln/core/alias/complex_image.hh>
+# include <mln/core/image/complex_neighborhoods.hh>
+# include <mln/core/image/complex_neighborhood_piter.hh>
+
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace vtk
+ {
+
+ /** \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. */
+ void save(const bin_2complex_image3df& ima,
+ const std::string& filename);
+
+ /** \brief Save an 8-bit grey-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. */
+ void save(const int_u8_2complex_image3df& ima,
+ const std::string& filename);
+
+ /** \brief Save a floating-point value grey-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. */
+ 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. */
+ void save(const rgb8_2complex_image3df& ima,
+ const std::string& filename);
+
+
+ namespace internal
+ {
+
+ template <typename I, typename E>
+ struct vtk_saver : public Object<E>
+ {
+ /// Type of the image.
+ typedef I image;
+
+ /// Type of the values.
+ typedef mln_value(I) value;
+
+ /// Dimension of the built complex.
+ static const unsigned D = 2;
+
+ /// \brief Constructor, with static checks.
+ vtk_saver();
+
+ /// Save an image \a ima into \a filename.
+ void operator()(const I& ima, const std::string& filename) const;
+
+ protected:
+ /// Helper factoring the task of writing scalar data
+ /// associated to faces.
+ void write_scalar_data(std::ostream& ostr, const image& ima,
+ const std::string& data_type) const;
+ };
+
+
+ struct bin_vtk_saver
+ : public vtk_saver< bin_2complex_image3df, bin_vtk_saver >
+ {
+ /// \brief Save face data.
+ void write_face_data(std::ostream& ostr, const image& ima) const;
+ };
+
+ struct int_u8_vtk_saver
+ : public vtk_saver< int_u8_2complex_image3df, int_u8_vtk_saver >
+ {
+ /// \brief Save face data.
+ void write_face_data(std::ostream& ostr, const image& ima) const;
+ };
+
+
+ struct float_vtk_saver
+ : public vtk_saver< float_2complex_image3df, float_vtk_saver >
+ {
+ /// \brief Save face data.
+ void write_face_data(std::ostream& ostr, const image& ima) const;
+ };
+
+
+ struct rgb8_vtk_saver
+ : public vtk_saver< rgb8_2complex_image3df, rgb8_vtk_saver >
+ {
+ /// \brief Save face data.
+ void write_face_data(std::ostream& ostr, const image& ima) const;
+ };
+
+ } // end of namespace mln::io::vtk::internal
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*----------.
+ | Facades. |
+ `----------*/
+
+ void
+ save(const bin_2complex_image3df& ima, const std::string& filename)
+ {
+ trace::entering("mln::io::vtk::save");
+ internal::bin_vtk_saver()(ima, filename);
+ trace::exiting("mln::io::vtk::save");
+ }
+
+ void
+ save(const int_u8_2complex_image3df& ima, const std::string& filename)
+ {
+ trace::entering("mln::io::vtk::save");
+ internal::int_u8_vtk_saver()(ima, filename);
+ trace::exiting("mln::io::vtk::save");
+ }
+
+ void
+ save(const float_2complex_image3df& ima, const std::string& filename)
+ {
+ trace::entering("mln::io::vtk::save");
+ internal::float_vtk_saver()(ima, filename);
+ trace::exiting("mln::io::vtk::save");
+ }
+
+ void
+ save(const rgb8_2complex_image3df& ima, const std::string& filename)
+ {
+ trace::entering("mln::io::vtk::save");
+ internal::rgb8_vtk_saver()(ima, filename);
+ trace::exiting("mln::io::vtk::save");
+ }
+
+
+ /*-------------------------.
+ | Actual implementations. |
+ `-------------------------*/
+
+ // -------- //
+ // Canvas. //
+ // -------- //
+
+ namespace internal
+ {
+
+ template <typename I, typename E>
+ vtk_saver<I, E>::vtk_saver()
+ {
+ // Concept checking.
+ void (E::*m1)(std::ostream&, const I&) const =
+ &E::write_face_data;
+ m1 = 0;
+ }
+
+
+ template <typename I, typename E>
+ void
+ vtk_saver<I, E>::operator()(const I& ima,
+ const std::string& filename) const
+ {
+ 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. //
+ // --------- //
+
+ 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. //
+ // ---------- //
+
+ /* 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)
+ ++nvertices;
+
+ if (nvertices > 0)
+ {
+ 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)
+ ostr << "1 " << v.unproxy_().face().face_id() << std::endl;
+ ostr << std::endl;
+ }
+
+ // ------- //
+ // Edges. //
+ // ------- //
+
+ // 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)
+ ++nedges;
+
+ if (nedges > 0)
+ {
+ 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)
+ {
+ 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. //
+ // ---------- //
+
+ // Same comment as above about the count of N-faces.
+ unsigned npolygons = 0;
+ p_n_faces_fwd_piter<D, G> p(ima.domain(), 2);
+ for_all (p)
+ ++npolygons;
+
+ if (npolygons > 0)
+ {
+ // 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)
+ {
+ 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)
+ {
+ 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;
+ }
+ ostr << 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).'' */
+
+ unsigned nfaces = nvertices + nedges + npolygons;
+ if (nfaces > 0)
+ {
+ // We don't use POINT_DATA (to associate values to
+ // POINTs), since CELL_DATA is used to associate values
+ // to VERTICES, EDGES and POLYGONS.
+ ostr << "CELL_DATA " << nfaces << std::endl;
+ exact(this)->write_face_data(ostr, ima);
+ }
+
+ ostr.close();
+ }
+
+ // ---------------- //
+ // Specific parts. //
+ // ---------------- //
+
+ /* ``Dataset Attribute Format. The Visualization Toolkit
+ supports the following dataset attributes: scalars
+ (one to four components), vectors, normals,
+ texture coordinates (1D, 2D, and 3D), 3 x 3
+ tensors, and field data. In addition, a lookup
+ table using the RGBA color specification,
+ associated with the scalar data, can be defined as
+ well. Dataset attributes are supported for both
+ points and cells.
+ Each type of attribute data has a `dataName'
+ associated with it. This is a character string
+ (without embedded whitespace) used to identify a
+ particular data. The `dataName' is used by the VTK
+ readers to extract data. As a result, more than
+ one attribute data of the same type can be
+ included in a file. For example, two different
+ scalar fields defined on the dataset points,
+ pressure and temperature, can be contained in the
+ same file. (If the appropriate dataName is not
+ specified in the VTK reader, then the first data
+ of that type is extracted from the file.)
+
+ * Scalars
+ Scalar definition includes specification of a
+ lookup table. The definition of a lookup table
+ is optional.
+
+ [...]
+
+ SCALARS dataName dataType numComp
+ LOOKUP_TABLE tableName
+ s0
+ s1
+ ...
+ sn-1''
+
+ Note: values accepted by Paraview 3.8 for `dataType' are:
+ "bit", "char", "unsigned_char", "short", "unsigned_short",
+ "vtkidtype", "int", "unsigned_int", "long",
+ "unsigned_long", "vtktypeint64", "vtktypeuint64", "float",
+ "double", "string", "utf8_string" and "variant". */
+
+ /** \{ */
+ template <typename I, typename E>
+ void
+ vtk_saver<I, E>::write_scalar_data(std::ostream& ostr,
+ const image& ima,
+ const std::string& data_type) const
+ {
+ ostr << "SCALARS values " << data_type << std::endl
+ << "LOOKUP_TABLE default" << std::endl;
+ // Iterate on all faces, dimension increasing.
+ mln_fwd_piter(image) p(ima.domain());
+ for_all(p)
+ ostr << ima(p) << std::endl;
+ }
+
+
+ void
+ bin_vtk_saver::write_face_data(std::ostream& ostr,
+ const image& ima) const
+ {
+ write_scalar_data(ostr, ima, "bit");
+ }
+
+ void
+ int_u8_vtk_saver::write_face_data(std::ostream& ostr,
+ const image& ima) const
+ {
+ write_scalar_data(ostr, ima, "unsigned_char");
+ }
+
+ void
+ float_vtk_saver::write_face_data(std::ostream& ostr,
+ const image& ima) const
+ {
+ write_scalar_data(ostr, ima, "float");
+ }
+
+ /* ``The definition of color scalars (i.e., unsigned
+ char values directly mapped to color) varies
+ depending upon the number of values (`nValues')
+ per scalar. If the file format is ASCII, the
+ color scalars are defined using nValues float
+ values between (0,1).
+
+ COLOR_SCALARS dataName nValues
+ c00 c01 ... c0(nValues-1)
+ c10 c11 ... c1(nValues-1)
+ ...
+ c(n-1)0 c(n-1)1 ... c(n-1)(nValues-1)'' */
+
+ void
+ rgb8_vtk_saver::write_face_data(std::ostream& ostr,
+ const image& ima) const
+ {
+ ostr << "COLOR_SCALARS values 4" << std::endl;
+ // Iterate on all faces, dimension increasing.
+ mln_fwd_piter_(image) p(ima.domain());
+ for_all(p)
+ // RGBA values (with alpha channel always set to 1.0).
+ ostr << float(ima(p).red()) / mln_max(value::red_t) << ' '
+ << float(ima(p).green()) / mln_max(value::green_t) << ' '
+ << float(ima(p).blue()) / mln_max(value::blue_t) << ' '
+ << 1.f
+ << std::endl;
+ }
+ /** \} */
+
+ } // end of namespace mln::io::vtk::internal
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::vtk
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_VTK_SAVE_HH
--
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