Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 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 00030 00031 #include <cstdlib> 00032 #include <cmath> 00033 00034 #include <utility> 00035 #include <iostream> 00036 00037 #include <mln/core/image/complex_image.hh> 00038 #include <mln/core/image/complex_neighborhoods.hh> 00039 00040 #include <mln/data/fill.hh> 00041 #include <mln/literal/zero.hh> 00042 00043 #include <mln/math/max.hh> 00044 #include <mln/math/sqr.hh> 00045 #include <mln/accu/stat/min_max.hh> 00046 #include <mln/fun/v2v/linear.hh> 00047 #include <mln/data/transform.hh> 00048 00049 #include <mln/literal/white.hh> 00050 00051 #include <mln/io/off/load.hh> 00052 #include <mln/io/off/save.hh> 00053 00054 #include "trimesh/misc.hh" 00055 00056 00057 // Doesn't C++ have a better way to express Pi? 00058 static const float pi = 4 * atanf(1); 00059 00060 00061 int main(int argc, char* argv[]) 00062 { 00063 if (argc != 3) 00064 { 00065 std::cerr << "usage: " << argv[0] << " input.off output.off" 00066 << std::endl; 00067 std::exit(1); 00068 } 00069 00070 std::string input_filename = argv[1]; 00071 std::string output_filename = argv[2]; 00072 00073 /*----------------. 00074 | Complex image. | 00075 `----------------*/ 00076 00077 // Image type. 00078 typedef mln::float_2complex_image3df ima_t; 00079 // Dimension of the image (and therefore of the complex). 00080 static const unsigned D = ima_t::dim; 00081 // Geometry of the image. 00082 typedef mln_geom_(ima_t) G; 00083 00084 mln::bin_2complex_image3df input; 00085 mln::io::off::load(input, input_filename); 00086 00087 // // ------------------------------------------------------------ 00088 // // FIXME: TEST. 00089 // mln::complex_image< 2, mln::space_2complex_geometry, mln::algebra::vec<3, float> > 00090 // normal = mesh_normal(input.domain()); 00091 // mln::p_n_faces_fwd_piter<D, G> v_(normal.domain(), 0); 00092 // for_all(v_) 00093 // std::cout << normal(v_) << std::endl; 00094 // std::exit(0); 00095 // // ------------------------------------------------------------ 00096 00097 std::pair<ima_t, ima_t> curv = mln::geom::mesh_curvature(input.domain()); 00098 00099 // Compute the max curvature at each vertex. 00100 ima_t max_curv(input.domain()); 00101 mln::data::fill(max_curv, mln::literal::zero); 00102 mln::p_n_faces_fwd_piter<D, G> v(max_curv.domain(), 0); 00103 for_all(v) 00104 max_curv(v) = mln::math::max(mln::math::sqr(curv.first(v)), 00105 mln::math::sqr(curv.second(v))); 00106 00107 // Propagate these values on triangles. 00108 mln::p_n_faces_fwd_piter<D, G> t(max_curv.domain(), 2); 00109 typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t; 00110 adj_vertices_nbh_t adj_vertices_nbh; 00111 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, t); 00112 /* FIXME: Not really user friendly! The `m' value should pass at 00113 the construction of ADJ_V. */ 00114 adj_v.iter().set_m(0); 00115 mln::accu::stat::min_max<float> acc; 00116 // Iterate on triangles (2-faces). 00117 for_all(t) 00118 { 00119 float s = 0.0f; 00120 unsigned n = 0; 00121 // Iterate on vertices (0-faces). 00122 for_all(adj_v) 00123 { 00124 s += max_curv(adj_v); 00125 ++n; 00126 } 00127 float m = s / n; 00128 max_curv(t) = m; 00129 acc.take(m); 00130 // A triangle should be adjacent to exactly three vertices. 00131 mln_invariant(n <= 3); 00132 } 00133 00134 // Normalize values between 0 and 1. 00135 /* Shrink the values of FACE_M into the range 0..1, as these are 00136 the only values accepted a an RGB floating-point component in the 00137 OFF file format. */ 00138 ima_t output(max_curv.domain()); 00139 mln::data::fill(output, mln::literal::zero); 00140 std::pair<float, float> min_max(acc); 00141 // FIXME: Taken from mln/data/stretch.hh (this should be factored). 00142 float min = min_max.first; 00143 float max = min_max.second; 00144 std::cout << min << std::endl; 00145 std::cout << max << std::endl; 00146 // Don't normalize actually if the curvature is constant (i.e., 00147 // if min == max). 00148 if (min != max) 00149 { 00150 float m = 0.0f; 00151 float M = 1.0f; 00152 float a = (M - m) / (max - min); 00153 float b = (m * max - M * min) / (max - min); 00154 mln::fun::v2v::linear<float, float, float> f(a, b); 00155 output = mln::data::transform(max_curv, f); 00156 } 00157 00158 // Output. 00159 mln::io::off::save(output, output_filename); 00160 }