forked from weisui-ad/ImageBasedModellingEdu
/
task6-2_meshclean.cc
executable file
·189 lines (172 loc) · 6.31 KB
/
task6-2_meshclean.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* Copyright (C) 2015, Simon Fuhrmann
* TU Darmstadt - Graphics, Capture and Massively Parallel Computing
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD 3-Clause license. See the LICENSE.txt file for details.
*/
#include <cstdlib>
#include <iostream>
#include <string>
#include "util/system.h"
#include "util/timer.h"
#include "util/arguments.h"
#include "core/mesh.h"
#include "core/mesh_io.h"
#include "core/mesh_io_ply.h"
#include "core/mesh_tools.h"
#include "surface/mesh_clean.h"
struct AppSettings
{
std::string in_mesh;
std::string out_mesh;
bool clean_degenerated;
bool delete_scale;
bool delete_conf;
bool delete_colors;
float conf_threshold;
int component_size;
};
void
remove_low_conf_vertices (core::TriangleMesh::Ptr mesh, float const thres)
{
core::TriangleMesh::ConfidenceList const& confs = mesh->get_vertex_confidences();
std::vector<bool> delete_list(confs.size(), false);
for (std::size_t i = 0; i < confs.size(); ++i)
{
if (confs[i] > thres)
continue;
delete_list[i] = true;
}
mesh->delete_vertices_fix_faces(delete_list);
}
int
main (int argc, char** argv)
{
util::system::register_segfault_handler();
util::system::print_build_timestamp("MVE FSSR Mesh Cleaning");
/* Setup argument parser. */
util::Arguments args;
args.set_exit_on_error(true);
args.set_nonopt_minnum(2);
args.set_nonopt_maxnum(2);
args.set_helptext_indent(25);
args.set_usage(argv[0], "[ OPTS ] IN_MESH OUT_MESH");
args.add_option('t', "threshold", true, "Threshold on the geometry confidence [1.0]");
args.add_option('c', "component-size", true, "Minimum number of vertices per component [1000]");
args.add_option('n', "no-clean", false, "Prevents cleanup of degenerated faces");
args.add_option('\0', "delete-scale", false, "Delete scale attribute from mesh");
args.add_option('\0', "delete-conf", false, "Delete confidence attribute from mesh");
args.add_option('\0', "delete-color", false, "Delete color attribute from mesh");
args.set_description("The application cleans degenerated faces resulting "
"from MC-like algorithms. Vertices below a confidence threshold and "
"vertices in small isolated components are deleted as well.");
args.parse(argc, argv);
/* Init default settings. */
AppSettings conf;
conf.in_mesh = args.get_nth_nonopt(0);
conf.out_mesh = args.get_nth_nonopt(1);
conf.conf_threshold = 1.0f;
conf.component_size = 1000;
conf.clean_degenerated = true;
conf.delete_scale = false;
conf.delete_conf = false;
conf.delete_colors = false;
/* Scan arguments. */
while (util::ArgResult const* arg = args.next_option())
{
if (arg->opt->lopt == "threshold")
conf.conf_threshold = arg->get_arg<float>();
else if (arg->opt->lopt == "component-size")
conf.component_size = arg->get_arg<int>();
else if (arg->opt->lopt == "no-clean")
conf.clean_degenerated = false;
else if (arg->opt->lopt == "delete-scale")
conf.delete_scale = true;
else if (arg->opt->lopt == "delete-conf")
conf.delete_conf = true;
else if (arg->opt->lopt == "delete-color")
conf.delete_colors = true;
else
{
std::cerr << "Invalid option: " << arg->opt->sopt << std::endl;
return EXIT_FAILURE;
}
}
/* Load input mesh. */
core::TriangleMesh::Ptr mesh;
try
{
std::cout << "Loading mesh: " << conf.in_mesh << std::endl;
mesh = core::geom::load_mesh(conf.in_mesh);
}
catch (std::exception& e)
{
std::cerr << "Error loading mesh: " << e.what() << std::endl;
return EXIT_FAILURE;
}
/* Sanity checks. */
if (mesh->get_vertices().empty())
{
std::cerr << "Error: Mesh is empty!" << std::endl;
return EXIT_FAILURE;
}
if (!mesh->has_vertex_confidences() && conf.conf_threshold > 0.0f)
{
std::cerr << "Error: Confidence cleanup requested, but mesh "
"has no confidence values." << std::endl;
return EXIT_FAILURE;
}
if (mesh->get_faces().empty()
&& (conf.clean_degenerated || conf.component_size > 0))
{
std::cerr << "Error: Components/faces cleanup "
"requested, but mesh has no faces." << std::endl;
return EXIT_FAILURE;
}
/* Remove low-confidence geometry. */
if (conf.conf_threshold > 0.0f)
{
std::cout << "Removing low-confidence geometry (threshold "
<< conf.conf_threshold << ")..." << std::endl;
std::size_t num_verts = mesh->get_vertices().size();
remove_low_conf_vertices(mesh, conf.conf_threshold);
std::size_t new_num_verts = mesh->get_vertices().size();
std::cout << " Deleted " << (num_verts - new_num_verts)
<< " low-confidence vertices." << std::endl;
}
/* Remove isolated components if requested. */
if (conf.component_size > 0)
{
std::cout << "Removing isolated components below "
<< conf.component_size << " vertices..." << std::endl;
std::size_t num_verts = mesh->get_vertices().size();
core::geom::mesh_components(mesh, conf.component_size);
std::size_t new_num_verts = mesh->get_vertices().size();
std::cout << " Deleted " << (num_verts - new_num_verts)
<< " vertices in isolated regions." << std::endl;
}
/* Remove degenerated faces from the mesh. */
if (conf.clean_degenerated)
{
std::cout << "Removing degenerated faces..." << std::endl;
std::size_t num_collapsed = fssr::clean_mc_mesh(mesh);
std::cout << " Collapsed " << num_collapsed << " edges." << std::endl;
}
/* Write output mesh. */
std::cout << "Writing mesh: " << conf.out_mesh << std::endl;
if (util::string::right(conf.out_mesh, 4) == ".ply")
{
core::geom::SavePLYOptions ply_opts;
ply_opts.write_vertex_colors = !conf.delete_colors;
ply_opts.write_vertex_confidences = !conf.delete_conf;
ply_opts.write_vertex_values = !conf.delete_scale;
core::geom::save_ply_mesh(mesh, conf.out_mesh, ply_opts);
}
else
{
core::geom::save_mesh(mesh, conf.out_mesh);
}
return EXIT_SUCCESS;
}