Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00029 00030 #include <cstdlib> 00031 00032 #include <algorithm> 00033 #include <vector> 00034 #include <iostream> 00035 #include <utility> 00036 00037 #include <TriMesh.h> 00038 00039 #include <mln/math/max.hh> 00040 #include <mln/math/sqr.hh> 00041 #include <mln/accu/stat/min_max.hh> 00042 #include <mln/fun/v2v/linear.hh> 00043 00044 #include "io.hh" 00045 00046 00047 int main(int argc, char* argv[]) 00048 { 00049 if (argc != 3) 00050 { 00051 std::cerr << "usage: " << argv[0] << " input.off output.off" 00052 << std::endl; 00053 std::exit(1); 00054 } 00055 00056 std::string input_filename = argv[1]; 00057 std::string output_filename = argv[2]; 00058 00059 00060 // TriMesh is a pain: it systematically allocates on the heap. 00061 // Introduce another name to manipulate the mesh as a (non-pointer) 00062 // object. 00063 TriMesh* mesh_ptr = TriMesh::read(input_filename.c_str()); 00064 if (!mesh_ptr) 00065 std::exit(2); 00066 TriMesh& mesh = *mesh_ptr; 00067 00068 // Computes faces (triangles). 00069 mesh.need_faces(); 00070 // Computation of the curvature on each vertex of the mesh. 00071 mesh.need_curvatures(); 00072 00073 std::vector<float> vertex_m(mesh.vertices.size(), 0.f); 00074 for (unsigned v = 0; v < mesh.vertices.size(); ++v) 00075 // Max curvature. 00076 vertex_m[v] = mln::math::max(mln::math::sqr(mesh.curv1[v]), 00077 mln::math::sqr(mesh.curv2[v])); 00078 00079 // For each face of the mesh, computean an average curvature value 00080 // from the mean curvature at its vertices. 00081 std::vector<float> face_m(mesh.faces.size(), 0.f); 00082 mln::accu::stat::min_max<float> acc; 00083 for (unsigned f = 0; f < mesh.faces.size(); ++f) 00084 { 00085 float m = (vertex_m[mesh.faces[f][0]] + 00086 vertex_m[mesh.faces[f][1]] + 00087 vertex_m[mesh.faces[f][2]]) / 3; 00088 face_m[f] = m; 00089 acc.take(m); 00090 } 00091 00092 /* Shrink the values of FACE_M into the range 0..1, as these are 00093 the only values accepted a an RGB floating-point component in the 00094 OFF file format. */ 00095 std::vector<float> normalized_face_m(face_m.size(), 0.0f); 00096 std::pair<float, float> min_max(acc); 00097 // FIXME: Taken from mln/data/stretch.hh (this should be factored). 00098 float min = min_max.first; 00099 float max = min_max.second; 00100 // Don't normalize actually if the curvature is constant (i.e., 00101 // if min == max). 00102 if (min != max) 00103 { 00104 float m = 0.0f; 00105 float M = 1.0f; 00106 float a = (M - m) / (max - min); 00107 float b = (m * max - M * min) / (max - min); 00108 mln::fun::v2v::linear<float, float, float> f(a, b); 00109 std::transform(face_m.begin(), face_m.end(), 00110 normalized_face_m.begin(), f); 00111 } 00112 00113 // Taken and adapted from TriMesh_io.cc 00114 FILE* f_out = fopen(output_filename.c_str(), "wb"); 00115 if (!f_out) 00116 { 00117 std::cerr << "Error opening " << output_filename.c_str() 00118 << " for writing." << std::endl; 00119 std::exit(2); 00120 } 00121 write_off_float(mesh_ptr, normalized_face_m, f_out); 00122 fclose(f_out); 00123 00124 delete mesh_ptr; 00125 }