
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Start to clean up levillain/statues/. * levillain/statues/mesh-segm.cc (main): Process command line arguments. Typos and aesthetic changes. (color2uchar, write_verts_asc, write_faces_asc_colored) (write_off_colored): Move these I/O routines... * levillain/statues/io.hh: ...here. * levillain/statues/test: New test. * levillain/statues/Makefile (mesh-segm.o): Depend on io.hh (check): Depend on test. Run `test' instead of `mesh-segm'. Makefile | 5 +- io.hh | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ mesh-segm.cc | 139 +++++++++++++---------------------------------------------- test | 9 +++ 4 files changed, 159 insertions(+), 109 deletions(-) Index: levillain/statues/test --- levillain/statues/test (revision 0) +++ levillain/statues/test (revision 0) @@ -0,0 +1,9 @@ +#! /bin/sh + +set -ex + +mesh_dir=../../../mesh + +time ./mesh-segm $mesh_dir/socket.off 25 socket-segm.off +time ./mesh-segm $mesh_dir/teapot.off 50 teapot-segm.off +time ./mesh-segm $mesh_dir/bunny-holefilled.off 500 bunny-holefilled-segm.off Property changes on: levillain/statues/test ___________________________________________________________________ Name: svn:executable + * Index: levillain/statues/io.hh --- levillain/statues/io.hh (revision 0) +++ levillain/statues/io.hh (revision 0) @@ -0,0 +1,115 @@ +// 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 SANDBOX_LEVILLAIN_IO_HH +# define SANDBOX_LEVILLAIN_IO_HH + +/// \brief I/O routines adapted from TriMesh's ones. + +/// Taken from TriMesh_io.cc +/// \{ +// Convert colors float -> uchar +inline unsigned char color2uchar(float p) +{ + return min(max(int(255.0f * p + 0.5f), 0), 255); +} + +// Write a bunch of vertices to an ASCII file +inline void write_verts_asc(TriMesh *mesh, FILE *f, + const char *before_vert, + const char *before_norm, + const char *before_color, + bool float_color, + const char *before_conf, + const char *after_line) +{ + for (int i = 0; i < mesh->vertices.size(); i++) { + fprintf(f, "%s%.7g %.7g %.7g", before_vert, + mesh->vertices[i][0], + mesh->vertices[i][1], + mesh->vertices[i][2]); + if (!mesh->normals.empty() && before_norm) + fprintf(f, "%s%.7g %.7g %.7g", before_norm, + mesh->normals[i][0], + mesh->normals[i][1], + mesh->normals[i][2]); + if (!mesh->colors.empty() && before_color && float_color) + fprintf(f, "%s%.7g %.7g %.7g", before_color, + mesh->colors[i][0], + mesh->colors[i][1], + mesh->colors[i][2]); + if (!mesh->colors.empty() && before_color && !float_color) + fprintf(f, "%s%d %d %d", before_color, + color2uchar(mesh->colors[i][0]), + color2uchar(mesh->colors[i][1]), + color2uchar(mesh->colors[i][2])); + if (!mesh->confidences.empty() && before_conf) + fprintf(f, "%s%.7g", before_conf, mesh->confidences[i]); + fprintf(f, "%s\n", after_line); + } +} +/// \} + + +/// Taken and adapted from TriMesh_io.cc +/// \{ +/// Write a bunch of faces to an ASCII file with colors. +inline void write_faces_asc_colored(TriMesh *mesh, + const std::vector<mln::value::rgb8>& colors, + FILE *f, + const char *before_face, + const char *after_line) +{ + mesh->need_faces(); + for (int i = 0; i < mesh->faces.size(); i++) + { + fprintf(f, "%s%d %d %d %d %d %d%s\n", + before_face, + mesh->faces[i][0], mesh->faces[i][1], mesh->faces[i][2], + int(colors[i].red()), + int(colors[i].green()), + int(colors[i].blue()), + after_line); + } +} + +/// Write an off file with colors. +inline void write_off_colored(TriMesh *mesh, + const std::vector<mln::value::rgb8>& colors, + FILE *f) +{ + fprintf(f, "OFF\n"); + mesh->need_faces(); + fprintf(f, "%lu %lu 0\n", (unsigned long) mesh->vertices.size(), + (unsigned long) mesh->faces.size()); + write_verts_asc(mesh, f, "", 0, 0, false, 0, ""); + write_faces_asc_colored(mesh, colors, f, "3 ", ""); +} +/// \} + + +#endif // ! SANDBOX_LEVILLAIN_IO_HH Index: levillain/statues/mesh-segm.cc --- levillain/statues/mesh-segm.cc (revision 2021) +++ levillain/statues/mesh-segm.cc (working copy) @@ -25,6 +25,7 @@ // reasons why the executable file might be covered by the GNU General // Public License. +#include <cstdlib> #include <cmath> #include <utility> @@ -44,117 +45,45 @@ #include <mln/morpho/closing_area.hh> #include <mln/morpho/meyer_wst.hh> +#include "io.hh" + // Doesn't C++ have a better way to express Pi ? const float pi = 4 * atanf(1); -// ------------------------------------------------------------------- -// Taken from TriMesh_io.cc -// ------------------------------------------------------------------- -// Convert colors float -> uchar -static unsigned char color2uchar(float p) -{ - return min(max(int(255.0f * p + 0.5f), 0), 255); -} - -// Write a bunch of vertices to an ASCII file -static void write_verts_asc(TriMesh *mesh, FILE *f, - const char *before_vert, - const char *before_norm, - const char *before_color, - bool float_color, - const char *before_conf, - const char *after_line) -{ - for (int i = 0; i < mesh->vertices.size(); i++) { - fprintf(f, "%s%.7g %.7g %.7g", before_vert, - mesh->vertices[i][0], - mesh->vertices[i][1], - mesh->vertices[i][2]); - if (!mesh->normals.empty() && before_norm) - fprintf(f, "%s%.7g %.7g %.7g", before_norm, - mesh->normals[i][0], - mesh->normals[i][1], - mesh->normals[i][2]); - if (!mesh->colors.empty() && before_color && float_color) - fprintf(f, "%s%.7g %.7g %.7g", before_color, - mesh->colors[i][0], - mesh->colors[i][1], - mesh->colors[i][2]); - if (!mesh->colors.empty() && before_color && !float_color) - fprintf(f, "%s%d %d %d", before_color, - color2uchar(mesh->colors[i][0]), - color2uchar(mesh->colors[i][1]), - color2uchar(mesh->colors[i][2])); - if (!mesh->confidences.empty() && before_conf) - fprintf(f, "%s%.7g", before_conf, mesh->confidences[i]); - fprintf(f, "%s\n", after_line); - } -} -// ------------------------------------------------------------------- - - -// ------------------------------------------------------------------- -// Taken and adapted from TriMesh_io.cc -// ------------------------------------------------------------------- -// Write a bunch of faces to an ASCII file with colors. -static void write_faces_asc_colored(TriMesh *mesh, - const std::vector<mln::value::rgb8>& colors, - FILE *f, - const char *before_face, - const char *after_line) +int main(int argc, char* argv[]) { - mesh->need_faces(); - for (int i = 0; i < mesh->faces.size(); i++) + if (argc != 4) { - fprintf(f, "%s%d %d %d %d %d %d%s\n", - before_face, - mesh->faces[i][0], mesh->faces[i][1], mesh->faces[i][2], - int(colors[i].red()), - int(colors[i].green()), - int(colors[i].blue()), - after_line); - } + std::cerr << "usage: " << argv[1] << " input.off lambda output.off"; + exit(1); } -/// Write an off file with colors. -static void write_off_colored(TriMesh *mesh, - const std::vector<mln::value::rgb8>& colors, - FILE *f) -{ - fprintf(f, "OFF\n"); - mesh->need_faces(); - fprintf(f, "%lu %lu 0\n", (unsigned long) mesh->vertices.size(), - (unsigned long) mesh->faces.size()); - write_verts_asc(mesh, f, "", 0, 0, false, 0, ""); - write_faces_asc_colored(mesh, colors, f, "3 ", ""); -} -// ------------------------------------------------------------------- + std::string input_filename = argv[1]; + unsigned lambda = atoi(argv[2]); + std::string output_filename = argv[3]; -int main(int argc, char* argv[]) -{ /*-------. | Mesh. | `-------*/ -// std::string filename = "../../aroumougame/test/test.off"; - std::string filename = "bunny-holefilled.off"; - - // TriMesh is a pain: it systematically allocate on the heap. - TriMesh* mesh_ptr = TriMesh::read(filename.c_str()); + // TriMesh is a pain: it systematically allocates on the heap. + // Introduce another name to manipulate the mesh as a (non-pointer) + // object. + TriMesh* mesh_ptr = TriMesh::read(input_filename.c_str()); if (!mesh_ptr) - exit(1); + exit(2); TriMesh& mesh = *mesh_ptr; // Computes faces (triangles). mesh.need_faces(); - // Computation of the mean curvature on each vertex of the mesh. mesh.need_curvatures(); - // FIXME: Our implementation of the WST doesn't work well with floats. - // Convert to a proportional integer value for the moment. + /* FIXME: Our implementation of the WST doesn't work well with + floats. Convert floating point values to a proportional integer + value for the moment. */ typedef int curv_t; std::vector<float> vertex_h_inv(mesh.vertices.size(), 0.f); for (unsigned v = 0; v < mesh.vertices.size(); ++v) @@ -162,8 +91,9 @@ float h = (mesh.curv1[v] + mesh.curv2[v]) / 2; float h_inv = 1 / pi * atan(-h) + pi / 2; /* FIXME: This coefficient is used to distinguish small - curvature values. We sould get rid of it as soon as - meyer_wst works correctly on image of float values. */ + curvature values. We should get rid of it as soon as + morpho::meyer_wst works correctly on images of float + values. */ vertex_h_inv[v] = 1000 * h_inv; } @@ -202,7 +132,7 @@ // Find the edge (i.e., the two vertices) common to faces // F and F_ADJ. /* FIXME: We lack a proper interface from the TriMesh - strucure to do this elegantly. */ + structure to do this elegantly. */ std::vector<int> adj_vertices; adj_vertices.reserve(2); for (unsigned i = 0; i < 3; ++i) @@ -239,22 +169,21 @@ nbh_t nbh; ima_t closed_lg_ima (lg_ima.domain()); - mln::morpho::closing_area(lg_ima, nbh, 500, closed_lg_ima); + mln::morpho::closing_area(lg_ima, nbh, lambda, closed_lg_ima); /*------. | WST. | `------*/ - // Perform a Watershed Transform. typedef unsigned wst_val_t; wst_val_t nbasins; typedef mln::line_graph_image<mln::point3d, wst_val_t> wst_ima_t; wst_ima_t wshed = mln::morpho::meyer_wst(closed_lg_ima, nbh, nbasins); std::cout << "nbasins = " << nbasins << std::endl; - /*------------------------------------. - | Label graph vertices (mesh faces). | - `------------------------------------*/ + /*------------------------------------------. + | Label graph vertices (i.e., mesh faces). | + `------------------------------------------*/ /* FIXME: We should be using wshed.vertex_values_ if mln::line_graph_image were fully functional... */ @@ -272,30 +201,26 @@ | Output. | `---------*/ - // Get random colors for each basin. + // Choose random colors for each basin number. std::vector<mln::value::rgb8> basin_color (nbasins + 1); for (unsigned i = 0; i <= nbasins; ++i) basin_color[i] = mln::value::rgb8(random() % 256, random() % 256, random() % 256); - - // Assign colors to faces. + // Assign colors to graph vertices (mesh faces). std::vector<mln::value::rgb8> face_color (vertex_label.size()); for (unsigned i = 0; i < vertex_label.size() ; ++i) face_color[i] = basin_color[vertex_label[i]]; - // FIXME: This is ugly; convert to C++ code ASAP. // Taken and adapted from TriMesh_io.cc - const char* out_filename = "out.off"; - FILE* f_out = fopen(out_filename, "wb"); + FILE* f_out = fopen(output_filename.c_str(), "wb"); if (!f_out) { - perror("fopen"); - fprintf(stderr, "Error opening %s for writing.\n", out_filename); - exit(1); + std::cerr << "Error opening " << output_filename.c_str() + << " for writing." << std::endl; + exit(2); } - write_off_colored(mesh_ptr, face_color, f_out); fclose(f_out); Property changes on: levillain/statues/mesh-segm.cc ___________________________________________________________________ Name: svn:executable - * Index: levillain/statues/Makefile --- levillain/statues/Makefile (revision 2021) +++ levillain/statues/Makefile (working copy) @@ -19,11 +19,12 @@ all: mesh-segm +mesh-segm.o: mesh-segm.cc io.hh mesh-segm: mesh-segm.o $(CXX) -o $@ $(LDFLAGS) $< -check: mesh-segm - ./mesh-segm +check: mesh-segm test + ./test CLEANFILES = mesh-segm.o mesh-segm clean: