* apps/generic-skel/image3d-skel.hh (save_vtk_polyhedrons):
New function.
Use it...
* apps/generic-skel/image3d-skel-unconstrained.cc,
* apps/generic-skel/image3d-skel-with-end-points.cc:
...here, instead of save_vtk_polygons.
---
milena/ChangeLog | 11 +++
.../generic-skel/image3d-skel-unconstrained.cc | 4 +-
.../generic-skel/image3d-skel-with-end-points.cc | 4 +-
milena/apps/generic-skel/image3d-skel.hh | 79 ++++++++++++++++++++
4 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 52e8f97..b894eaa 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,16 @@
2011-07-11 Roland Levillain <roland(a)lrde.epita.fr>
+ Introduce a better VTK output routine in apps/generic-skel.
+
+ * apps/generic-skel/image3d-skel.hh (save_vtk_polyhedrons):
+ New function.
+ Use it...
+ * apps/generic-skel/image3d-skel-unconstrained.cc,
+ * apps/generic-skel/image3d-skel-with-end-points.cc:
+ ...here, instead of save_vtk_polygons.
+
+2011-07-11 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a VTK output routine in apps/generic-skel.
* apps/generic-skel/image3d-skel.hh: Aesthetic changes.
diff --git a/milena/apps/generic-skel/image3d-skel-unconstrained.cc
b/milena/apps/generic-skel/image3d-skel-unconstrained.cc
index 65ef1c1..236361d 100644
--- a/milena/apps/generic-skel/image3d-skel-unconstrained.cc
+++ b/milena/apps/generic-skel/image3d-skel-unconstrained.cc
@@ -76,7 +76,7 @@ int main()
std::cerr << input.domain() << std::endl;
save_raw_3d(input, "image3d-skel-unconstrained-input.raw");
- save_vtk_polygons(input, "image3d-skel-unconstrained-input.vtk");
+ save_vtk_polyhedrons(input, "image3d-skel-unconstrained-input.vtk");
// FIXME: Debug.
unsigned n_fg_comps;
@@ -102,5 +102,5 @@ int main()
is_simple,
detach);
save_raw_3d(output, "image3d-skel-unconstrained-skel.raw");
- save_vtk_polygons(output, "image3d-skel-unconstrained-skel.vtk");
+ save_vtk_polyhedrons(output, "image3d-skel-unconstrained-skel.vtk");
}
diff --git a/milena/apps/generic-skel/image3d-skel-with-end-points.cc
b/milena/apps/generic-skel/image3d-skel-with-end-points.cc
index e5c3774..32f3634 100644
--- a/milena/apps/generic-skel/image3d-skel-with-end-points.cc
+++ b/milena/apps/generic-skel/image3d-skel-with-end-points.cc
@@ -77,7 +77,7 @@ int main()
std::cerr << input.domain() << std::endl;
save_raw_3d(input, "image3d-skel-with-end-points-input.raw");
- save_vtk_polygons(input, "image3d-skel-with-end-points-input.vtk");
+ save_vtk_polyhedrons(input, "image3d-skel-with-end-points-input.vtk");
// FIXME: Debug.
unsigned n_fg_comps;
@@ -110,5 +110,5 @@ int main()
detach,
constraint);
save_raw_3d(output, "image3d-skel-with-end-points-skel.raw");
- save_vtk_polygons(output, "image3d-skel-with-end-points-skel.vtk");
+ save_vtk_polyhedrons(output, "image3d-skel-with-end-points-skel.vtk");
}
diff --git a/milena/apps/generic-skel/image3d-skel.hh
b/milena/apps/generic-skel/image3d-skel.hh
index 7abf4fb..051a50d 100644
--- a/milena/apps/generic-skel/image3d-skel.hh
+++ b/milena/apps/generic-skel/image3d-skel.hh
@@ -187,6 +187,85 @@ save_vtk_polygons(const mln::image3d<bool>& ima,
}
}
+// Save a binary 3D image as a VTK file where each voxel is
+// represented by a cube (voxel polyhedron). This routine generates
+// smaller files than save_vtk_polygons.
+void
+save_vtk_polyhedrons(const mln::image3d<bool>& ima,
+ const std::string& filename)
+{
+ std::ofstream file(filename.c_str());
+
+ // Header.
+ file
+ << "# vtk DataFile Version 2.0" << std::endl
+ << "Generated by " OLN_PACKAGE_STRING " (" OLN_PACKAGE_URL
")" << std::endl
+ << "ASCII" << std::endl
+ << std::endl;
+
+ // Number of object (foreground) sites to represent as a cube.
+ unsigned ncubes = 0;
+ mln_piter_(mln::image3d<bool>) p(ima.domain());
+ for_all(p)
+ if (ima(p))
+ ++ncubes;
+
+ /* FIXME: The current approach duplicates some of the vertices (when
+ they are shared by two cubes or more). */
+
+ // Points (locations).
+ file << "DATASET UNSTRUCTURED_GRID" << std::endl;
+ // Each site (voxel) is defined by the location of its 8 corners.
+ file << "POINTS " << ncubes * 8 << " float"
<< std::endl;
+
+ // ``Radius'' (half-length) of a cube.
+ float r = 0.5;
+
+ // Cubes (voxels).
+ for_all(p)
+ if (ima(p))
+ file << p[0] - r << ' ' << p[1] - r << ' '
<< p[2] - r << " "
+ << p[0] + r << ' ' << p[1] - r << ' '
<< p[2] - r << " "
+ << p[0] + r << ' ' << p[1] + r << ' '
<< p[2] - r << " "
+ << p[0] - r << ' ' << p[1] + r << ' '
<< p[2] - r << " "
+ << p[0] - r << ' ' << p[1] - r << ' '
<< p[2] + r << " "
+ << p[0] + r << ' ' << p[1] - r << ' '
<< p[2] + r << " "
+ << p[0] + r << ' ' << p[1] + r << ' '
<< p[2] + r << " "
+ << p[0] - r << ' ' << p[1] + r << ' '
<< p[2] + r
+ << std::endl;
+ file << std::endl;
+
+ // Create a polyhedron for each voxel.
+ file << "CELLS " << ncubes << ' '
+ /* Each cubes (VTK_VOXEL) requires 9 parameters: 1 for the number
+ of vertices of the cube (always `8'), and 8 for the indices of
+ the vertices of this polyhedron. */
+ << ncubes * (1 + 8) << std::endl;
+
+ // ``Draw'' the 6 faces of each cube.
+ for (unsigned i = 0; i < ncubes; ++i)
+ {
+ /* Vertices. The 8 vertices of associated with the `i'-th cube
+ have indices `8 * i' to `8 * i + 7'. */
+ unsigned v[8] =
+ { 8 * i + 0, 8 * i + 1, 8 * i + 2, 8 * i + 3,
+ 8 * i + 4, 8 * i + 5, 8 * i + 6, 8 * i + 7 };
+ // The order of the vertices follows the conventions of the VTK
+ // file format specification.
+ file << "8 "
+ << v[0] << ' ' << v[1] << ' ' << v[3]
<< ' ' << v[2] << ' '
+ << v[4] << ' ' << v[5] << ' ' << v[7]
<< ' ' << v[6]
+ << std::endl;
+ }
+ file << std::endl;
+
+ // Announce the type of cells used.
+ file << "CELL_TYPES " << ncubes << std::endl;
+ for (unsigned i = 0; i < ncubes; ++i)
+ // The VTK_VERTEX cell type has number `11'.
+ file << 11 << std::endl;
+}
+
/*--------------.
| Subsampling. |
--
1.7.2.5