00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00031
00032
00033
00034 #include <cstdlib>
00035 #include <cmath>
00036
00037 #include <utility>
00038 #include <iostream>
00039
00040 #include <TriMesh.h>
00041
00042 #include <mln/core/alias/point3d.hh>
00043 #include <mln/core/alias/point3d.hh>
00044
00045 #include <mln/util/graph.hh>
00046 #include <mln/core/image/line_graph_image.hh>
00047 #include <mln/core/image/line_graph_elt_neighborhood.hh>
00048
00049 #include <mln/morpho/closing/area.hh>
00050 #include <mln/morpho/meyer_wst.hh>
00051
00052 #include "io.hh"
00053
00054
00055
00056 const float pi = 4 * atanf(1);
00057
00058
00059 int main(int argc, char* argv[])
00060 {
00061 if (argc != 4)
00062 {
00063 std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
00064 << std::endl;
00065 std::exit(1);
00066 }
00067
00068 std::string input_filename = argv[1];
00069 unsigned lambda = atoi(argv[2]);
00070 std::string output_filename = argv[3];
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 TriMesh* mesh_ptr = TriMesh::read(input_filename.c_str());
00081 if (!mesh_ptr)
00082 std::exit(2);
00083 TriMesh& mesh = *mesh_ptr;
00084
00085
00086 mesh.need_faces();
00087
00088 mesh.need_curvatures();
00089
00090
00091
00092 typedef int curv_t;
00093 std::vector<curv_t> vertex_h_inv(mesh.vertices.size(), 0.f);
00094 for (unsigned v = 0; v < mesh.vertices.size(); ++v)
00095 {
00096 float h = (mesh.curv1[v] + mesh.curv2[v]) / 2;
00097 float h_inv = 1 / pi * atan(-h) + pi / 2;
00098
00099
00100
00101
00102 vertex_h_inv[v] = 1000 * h_inv;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 std::vector<curv_t> vertex_values (mesh.faces.size(), 0.f);
00117 std::vector<curv_t> edge_values;
00118
00119
00120
00121 mln::util::graph<mln::point3d> g;
00122
00123 for (unsigned i = 0; i < mesh.faces.size(); ++i)
00124 g.add_vertex (mln::point3d(i, i, i));
00125
00126
00127 mesh.need_across_edge();
00128 for (unsigned f = 0; f < mesh.faces.size(); ++f)
00129 for (unsigned e = 0; e < 3; ++e)
00130 {
00131 int f_adj = mesh.across_edge[f][e];
00132 if (f_adj != -1)
00133 {
00134
00135 if (g.add_edge(f, f_adj) != mln_max(mln::util::edge_id::equiv))
00136 {
00137
00138
00139
00140
00141 std::vector<int> adj_vertices;
00142 adj_vertices.reserve(2);
00143 for (unsigned i = 0; i < 3; ++i)
00144 for (unsigned j = 0; j < 3; ++j)
00145 if (mesh.faces[f][i] == mesh.faces[f_adj][j])
00146 adj_vertices.push_back(mesh.faces[f][i]);
00147 mln_assertion(adj_vertices.size() == 2);
00148
00149
00150 edge_values.push_back((vertex_h_inv[adj_vertices[0]] +
00151 vertex_h_inv[adj_vertices[1]])
00152 / 2);
00153 }
00154
00155
00156 mln_assertion(g.edges().size() == edge_values.size());
00157 }
00158 }
00159
00160
00161
00162
00163
00164 mln::p_line_graph<mln::point3d> plg(g);
00165
00166 typedef mln::line_graph_image<mln::point3d, curv_t> ima_t;
00167 ima_t lg_ima(plg, vertex_values, edge_values);
00168
00169
00170
00171
00172
00173 typedef mln::line_graph_elt_neighborhood<mln::point3d> nbh_t;
00174 nbh_t nbh;
00175
00176 ima_t closed_lg_ima = mln::morpho::closing::area(lg_ima, nbh, lambda);
00177
00178
00179
00180
00181
00182 typedef unsigned wst_val_t;
00183 wst_val_t nbasins;
00184 typedef mln::line_graph_image<mln::point3d, wst_val_t> wst_ima_t;
00185 wst_ima_t wshed = mln::morpho::meyer_wst(closed_lg_ima, nbh, nbasins);
00186 std::cout << "nbasins = " << nbasins << std::endl;
00187
00188
00189
00190
00191
00192
00193
00194 std::vector<unsigned> vertex_label(wshed.domain().nvertices(), 0);
00195 mln_piter_(wst_ima_t) pw(wshed.domain());
00196 for_all(pw)
00197 if (wshed(pw) != 0)
00198 {
00199 mln_psite_(wst_ima_t) pp(pw);
00200 vertex_label[pp.first_id().to_equiv()] = wshed(pw);
00201 vertex_label[pp.second_id().to_equiv()] = wshed(pw);
00202 }
00203
00204
00205
00206
00207
00208
00209 std::vector<mln::value::rgb8> basin_color (nbasins + 1);
00210 for (unsigned i = 0; i <= nbasins; ++i)
00211 basin_color[i] = mln::value::rgb8(random() % 256,
00212 random() % 256,
00213 random() % 256);
00214
00215
00216 std::vector<mln::value::rgb8> face_color (vertex_label.size());
00217 for (unsigned i = 0; i < vertex_label.size() ; ++i)
00218 face_color[i] = basin_color[vertex_label[i]];
00219
00220
00221 FILE* f_out = fopen(output_filename.c_str(), "wb");
00222 if (!f_out)
00223 {
00224 std::cerr << "Error opening " << output_filename.c_str()
00225 << " for writing." << std::endl;
00226 std::exit(2);
00227 }
00228 write_off_colored(mesh_ptr, face_color, f_out);
00229 fclose(f_out);
00230
00231 delete mesh_ptr;
00232 }