Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
mesh-complex-max-curv.cc
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
30 
31 #include <cstdlib>
32 #include <cmath>
33 
34 #include <utility>
35 #include <iostream>
36 
37 #include <mln/core/image/complex_image.hh>
38 #include <mln/core/image/complex_neighborhoods.hh>
39 
40 #include <mln/data/fill.hh>
41 #include <mln/literal/zero.hh>
42 
43 #include <mln/math/max.hh>
44 #include <mln/math/sqr.hh>
45 #include <mln/accu/stat/min_max.hh>
46 #include <mln/fun/v2v/linear.hh>
47 #include <mln/data/transform.hh>
48 
49 #include <mln/literal/white.hh>
50 
51 #include <mln/io/off/load.hh>
52 #include <mln/io/off/save.hh>
53 
54 #include "trimesh/misc.hh"
55 
56 
57 // Doesn't C++ have a better way to express Pi?
58 static const float pi = 4 * atanf(1);
59 
60 
61 int main(int argc, char* argv[])
62 {
63  if (argc != 3)
64  {
65  std::cerr << "usage: " << argv[0] << " input.off output.off"
66  << std::endl;
67  std::exit(1);
68  }
69 
70  std::string input_filename = argv[1];
71  std::string output_filename = argv[2];
72 
73  /*----------------.
74  | Complex image. |
75  `----------------*/
76 
77  // Image type.
78  typedef mln::float_2complex_image3df ima_t;
79  // Dimension of the image (and therefore of the complex).
80  static const unsigned D = ima_t::dim;
81  // Geometry of the image.
82  typedef mln_geom_(ima_t) G;
83 
84  mln::bin_2complex_image3df input;
85  mln::io::off::load(input, input_filename);
86 
87 // // ------------------------------------------------------------
88 // // FIXME: TEST.
89 // mln::complex_image< 2, mln::space_2complex_geometry, mln::algebra::vec<3, float> >
90 // normal = mesh_normal(input.domain());
91 // mln::p_n_faces_fwd_piter<D, G> v_(normal.domain(), 0);
92 // for_all(v_)
93 // std::cout << normal(v_) << std::endl;
94 // std::exit(0);
95 // // ------------------------------------------------------------
96 
97  std::pair<ima_t, ima_t> curv = mln::geom::mesh_curvature(input.domain());
98 
99  // Compute the max curvature at each vertex.
100  ima_t max_curv(input.domain());
101  mln::data::fill(max_curv, mln::literal::zero);
102  mln::p_n_faces_fwd_piter<D, G> v(max_curv.domain(), 0);
103  for_all(v)
104  max_curv(v) = mln::math::max(mln::math::sqr(curv.first(v)),
105  mln::math::sqr(curv.second(v)));
106 
107  // Propagate these values on triangles.
108  mln::p_n_faces_fwd_piter<D, G> t(max_curv.domain(), 2);
109  typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t;
110  adj_vertices_nbh_t adj_vertices_nbh;
111  mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, t);
112  /* FIXME: Not really user friendly! The `m' value should pass at
113  the construction of ADJ_V. */
114  adj_v.iter().set_m(0);
115  mln::accu::stat::min_max<float> acc;
116  // Iterate on triangles (2-faces).
117  for_all(t)
118  {
119  float s = 0.0f;
120  unsigned n = 0;
121  // Iterate on vertices (0-faces).
122  for_all(adj_v)
123  {
124  s += max_curv(adj_v);
125  ++n;
126  }
127  float m = s / n;
128  max_curv(t) = m;
129  acc.take(m);
130  // A triangle should be adjacent to exactly three vertices.
131  mln_invariant(n <= 3);
132  }
133 
134  // Normalize values between 0 and 1.
135  /* Shrink the values of FACE_M into the range 0..1, as these are
136  the only values accepted a an RGB floating-point component in the
137  OFF file format. */
138  ima_t output(max_curv.domain());
140  std::pair<float, float> min_max(acc);
141  // FIXME: Taken from mln/data/stretch.hh (this should be factored).
142  float min = min_max.first;
143  float max = min_max.second;
144  std::cout << min << std::endl;
145  std::cout << max << std::endl;
146  // Don't normalize actually if the curvature is constant (i.e.,
147  // if min == max).
148  if (min != max)
149  {
150  float m = 0.0f;
151  float M = 1.0f;
152  float a = (M - m) / (max - min);
153  float b = (m * max - M * min) / (max - min);
155  output = mln::data::transform(max_curv, f);
156  }
157 
158  // Output.
159  mln::io::off::save(output, output_filename);
160 }