-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmoother_addon.cpp
More file actions
80 lines (59 loc) · 2.37 KB
/
smoother_addon.cpp
File metadata and controls
80 lines (59 loc) · 2.37 KB
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
#include <ultimaille/all.h>
#include <param_parser/param_parser.h>
using namespace UM;
vec3 triNormal(Triangles& m, Surface::Facet f) {
const vec3 & p1 = m.points[f.vertex(0)];
const vec3 & p2 = m.points[f.vertex(1)];
const vec3 & p3 = m.points[f.vertex(2)];
return cross(p2 - p1, p3 - p1);
}
void smooth(Triangles &m, PointAttribute<bool>& lock) {
PointAttribute<vec4> bary(m.points);
for (auto v : m.iter_vertices()) {
for (auto h : v.iter_halfedges()) {
vec3 neighbor_pos = h.to().pos();
bary[v] += {neighbor_pos.x, neighbor_pos.y, neighbor_pos.z, 1.};
}
}
for (auto v : m.iter_vertices()) {
if (lock[v]) continue;
vec4 cur_bary = bary[v];
vec3 p = vec3(cur_bary[0], cur_bary[1], cur_bary[2]) / cur_bary[3];
v.pos() = p;
}
}
int main(int argc, char** argv) {
// Create parameters
Parameters params;
// Add program parameters
params.add("input", "model", "").description("Model to process");
params.add(Parameters::Type::VerticesBool(1), "lock_attribute", "").description("Name of attribute to lock");
params.add(Parameters::Type::Int, "n_iter", "100").description("Number of iterations");
/* Parse program arguments */
params.init_from_args(argc, argv);
// Get parameters
std::string filename = params["model"];
std::string lock_attr_name = params["lock_attribute"];
int n_iter = params["n_iter"];
std::filesystem::path result_path(params.result_path());
// Print
std::cout << "Input model: " << filename << std::endl;
Triangles m;
SurfaceAttributes attr = read_by_extension(filename, m);
PointAttribute<bool> lock_attr(lock_attr_name, attr, m);
m.connect();
// Converge to a minimal surface
for (int i = 0; i < n_iter; i ++)
smooth(m, lock_attr);
// Save
// Output model to output directory at working dir if no result_path given
if (result_path.empty() && !std::filesystem::is_directory("output")) {
std::filesystem::create_directories("output");
result_path = "output";
}
// Get file name and output path
std::string file = std::filesystem::path(filename).filename().string();
std::string out_filename = (result_path / file).string();
write_by_extension(out_filename, m, {attr.points, attr.facets, attr.corners});
return 0;
}