Repository navigation
Expand file tree
/
Copy pathsolver.cpp
More file actions
67 lines (54 loc) · 1.96 KB
/
Copy pathsolver.cpp
File metadata and controls
67 lines (54 loc) · 1.96 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
#include <ultimaille/all.h>
using namespace UM;
int main(int argc, char** argv) {
// Set the input and output directories
const std::string input_dir = "../";
const std::string output_dir = "";
// Load mesh from file
Triangles m;
auto attributes = read_by_extension(input_dir + "pre.geogram", m);
PointAttribute<bool> selection("selection", attributes, m);
m.connect();
// Declare solver, set number of variables
// Each vertex has 3 coordinates (x, y, z)
// So we have m.nverts() * 3 variables
LeastSquares solver(m.nverts() * 3);
// Select some vertices to fix
// I choose ears, muzzle and legs
// These vertices are fixed in the original mesh
// and we want to keep them in the same position
for (auto vi : m.iter_vertices()) {
if (vi.on_boundary() && !selection[vi]) {
vec3 v = m.vertex(vi);
for (int dim = 0; dim < 3; dim++)
solver.fix(vi * 3 + dim, v[dim]);
}
}
for (auto &v : m.iter_vertices()) {
for (int dim = 0; dim < 3; dim++) {
LinExpr lexpr;
// For each vertex, we want to average the positions of its neighbors
int n = 0;
for (auto &h : v.iter_halfedges()) {
auto neighbor = h.to();
lexpr += Linear::X(neighbor * 3 + dim);
n++;
}
lexpr *= (1.0 / n);
// We want to minimize the distance between the vertex and the average of its neighbors
solver.add_to_energy(Linear::X(v * 3 + dim) - lexpr);
}
}
// Solve
solver.solve();
// Update vertex positions with the solution
for (auto &v : m.iter_vertices()) {
double x = solver.value(v * 3);
double y = solver.value(v * 3 + 1);
double z = solver.value(v * 3 + 2);
v.pos() = {x, y, z};
}
// Save the mesh
write_by_extension(output_dir + "pre_solved.geogram", m);
return 0;
}