forked from icemiliang/lscm
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
127 lines (119 loc) · 4.72 KB
/
main.cpp
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
// Least squares conformal mapping
//
// Author : Mi, Liang (Arizona State University)
// Email : [email protected]
// Date : June 13th 2018
#include <cmath>
#include "Mesh.h"
#include "FormTrait.h"
#include "LSCM.h"
#include <iostream>
#include <sstream>
#include <vector>
#include <string.h>
using namespace MeshLib;
int main(int argc, char * argv[])
{
// Parse the fixed vertex definitions if any
// They are give in format --fixed-vertex coordX,coordY,coordZ or -v coordX,coordY,coordZ
int currentArgument = 1;
std::string inFilePath("");
std::string outFilePath("");
std::vector<FixedVertexDefinition> fixedVertices;
while (currentArgument < argc) {
// Fixed point positions: --fixedPoint or -p
if (!strcmp(argv[currentArgument], "--fixedPoint") || !strcmp(argv[currentArgument], "-p")) {
currentArgument++;
std::string fixedVertexArg(argv[currentArgument]);
double fixedVertexPos[3] = {0.0, 0.0, 0.0};
for (int i=0; i<3; i++) {
size_t commaPos = fixedVertexArg.find(",");
if (i<2 && commaPos == std::string::npos) {
std::cerr << "Invalid fixed vertex argument: " << argv[currentArgument] << std::endl;
break;
}
std::stringstream ss;
ss << fixedVertexArg.substr(0, commaPos);
if (ss.bad()) {
std::cerr << "Cannot parse fixed vertex argument: " << argv[currentArgument] << std::endl;
break;
}
ss >> fixedVertexPos[i];
fixedVertexArg = fixedVertexArg.substr(commaPos+1);
}
// Only store the first two fixed vertices. The whole markups fiducial list is passed to the CLI, but
// we only need to use the first two for flattening. The rest are for the user for fitting.
if (fixedVertices.size() < 2) {
FixedVertexDefinition currentFixedVertex(fixedVertexPos[0], fixedVertexPos[1], fixedVertexPos[2]);
fixedVertices.push_back(currentFixedVertex);
}
}
// Fixed texture coordinates: --fixedTextureCoords or -c
else if (!strcmp(argv[currentArgument], "--fixedTextureCoords") || !strcmp(argv[currentArgument], "-c")) {
// Determine if the argument comes in individual coordinates or together and parse accordingly
std::string fixedCoordArg(argv[currentArgument+1]);
std::vector<std::string> fixedCoordsStrVector;
if (fixedCoordArg.find(" ") == std::string::npos) {
std::cout << "Fixed texture coordinates given separately in individual arguments" << std::endl;
for (int i=0; i<fixedVertices.size(); ++i) {
fixedCoordsStrVector.push_back(argv[currentArgument+1]);
fixedCoordsStrVector.push_back(argv[currentArgument+2]);
currentArgument += 2;
}
} else {
std::cout << "Fixed texture coordinates given together in a single argument" << std::endl;
size_t separatorPosition = fixedCoordArg.find(" ");
while (separatorPosition != std::string::npos) {
fixedCoordsStrVector.push_back(fixedCoordArg.substr(0, separatorPosition));
fixedCoordArg = fixedCoordArg.substr(separatorPosition+1);
separatorPosition = fixedCoordArg.find(" ");
}
if (!fixedCoordArg.empty()) {
fixedCoordsStrVector.push_back(fixedCoordArg);
}
currentArgument++;
}
if (fixedCoordsStrVector.size() != fixedVertices.size() * 2) {
std::cerr << "Failed to parse fixed texture coordinates correctly" << std::endl;
return 1;
}
for (int i=0; i<fixedVertices.size(); ++i) {
double fixedTexturePos[2] = {0.0, 0.0};
std::stringstream ss;
ss << fixedCoordsStrVector[2*i] << " " << fixedCoordsStrVector[2*i+1];
ss >> fixedTexturePos[0] >> fixedTexturePos[1];
std::cout << "Fixed texture coordinates #" << i << ": " << fixedTexturePos[0] << ", " << fixedTexturePos[1] << std::endl;
fixedVertices[i].set_fixed_points(fixedTexturePos[0], fixedTexturePos[1]);
}
}
// Input file
else if (inFilePath.empty()) {
inFilePath = std::string(argv[currentArgument]);
}
// Output file
else {
outFilePath = std::string(argv[currentArgument]);
}
currentArgument++;
}
std::cout << "--> Reading mesh..." << std::endl;
Mesh mesh;
mesh.read_obj(inFilePath.c_str());
if (mesh.numVertices() == 0) {
std::cerr << "Failed to read mesh from file " << inFilePath << std::endl;
return 1;
} else {
std::cout << "Mesh read successfully. " << mesh.numVertices() << " vertices and " << mesh.numFaces() << " cells." << std::endl;
}
if (fixedVertices.size() > 0) {
std::cout << "--> Applying fixed vertices..." << std::endl;
mesh.apply_fixed_vertices(fixedVertices);
}
FormTrait traits(&mesh);
std::cout << "--> Computing conformal map..." << std::endl;
LSCM lscm(&mesh);
lscm.project();
std::cout << "--> Writing mesh..." << std::endl;
mesh.write_obj(outFilePath.c_str());
return 0;
}