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/graph_image.hh>
00047 #include <mln/core/image/graph_elt_neighborhood.hh>
00048
00049 #include <mln/morpho/closing/area.hh>
00050 #include <mln/labeling/regional_minima.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 std::vector<float> vertex_h_inv(mesh.faces.size(), 0.f);
00090 for (unsigned v = 0; v < mesh.vertices.size(); ++v)
00091 {
00092 float h = (mesh.curv1[v] + mesh.curv2[v]) / 2;
00093 float h_inv = 1 / pi * atan(-h) + pi / 2;
00094 vertex_h_inv[v] = h_inv;
00095 }
00096
00097
00098
00099
00100 typedef int curv_t;
00101 std::vector<curv_t> face_h_inv(mesh.faces.size(), 0.f);
00102 for (unsigned f = 0; f < mesh.faces.size(); ++f)
00103 {
00104 float h_inv =
00105 (vertex_h_inv[mesh.faces[f][0]] +
00106 vertex_h_inv[mesh.faces[f][1]] +
00107 vertex_h_inv[mesh.faces[f][2]])
00108 / 3;
00109
00110
00111
00112
00113 face_h_inv[f] = 1000 * h_inv;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 mln::util::graph<mln::point3d> g;
00127
00128 for (unsigned i = 0; i < mesh.faces.size(); ++i)
00129 g.add_vertex (mln::point3d(i, i, i));
00130
00131
00132 mesh.need_across_edge();
00133 for (unsigned f = 0; f < mesh.faces.size(); ++f)
00134 for (unsigned e = 0; e < 3; ++e)
00135 {
00136 int f_adj = mesh.across_edge[f][e];
00137 if (f_adj != -1)
00138
00139 g.add_edge(f, f_adj);
00140 }
00141
00142
00143
00144
00145
00146 mln::p_graph<mln::point3d> pg(g);
00147
00148 typedef mln::graph_image<mln::point3d, curv_t> ima_t;
00149 ima_t g_ima(pg, face_h_inv);
00150
00151
00152
00153
00154
00155 typedef mln::graph_elt_neighborhood<mln::point3d> nbh_t;
00156 nbh_t nbh;
00157
00158 ima_t closed_g_ima = mln::morpho::closing::area(g_ima, nbh, lambda);
00159
00160
00161
00162
00163
00164 typedef unsigned label_t;
00165 label_t nlabels;
00166 typedef mln::graph_image<mln::point3d, label_t> label_ima_t;
00167 label_ima_t minima =
00168 mln::labeling::regional_minima(closed_g_ima, nbh, nlabels);
00169 std::cout << "nlabels = " << nlabels << std::endl;
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 std::vector<bool> face_value (minima.domain().nvertices(), true);
00186 mln_piter_(label_ima_t) pm(minima.domain());
00187 for_all(pm)
00188
00189 if (minima(pm) != 0)
00190 {
00191
00192
00193 mln_psite_(label_ima_t) pp(pm);
00194 face_value[pp.id().to_equiv()] = false;
00195 }
00196
00197
00198 FILE* f_out = fopen(output_filename.c_str(), "wb");
00199 if (!f_out)
00200 {
00201 std::cerr << "Error opening " << output_filename.c_str()
00202 << " for writing." << std::endl;
00203 std::exit(2);
00204 }
00205 write_off_binary(mesh_ptr, face_value, f_out);
00206 fclose(f_out);
00207
00208 delete mesh_ptr;
00209 }