1 #include "config.hpp"
2 #include "field-math.hpp"
3 #include "optimizer.hpp"
4 #include "parametrizer.hpp"
5 #include <stdlib.h>
6
7 #ifdef WITH_CUDA
8 #include <cuda_runtime.h>
9 #endif
10
11 using namespace qflow;
12
13 Parametrizer field;
14
main(int argc,char ** argv)15 int main(int argc, char** argv) {
16 setbuf(stdout, NULL);
17
18 #ifdef WITH_CUDA
19 cudaFree(0);
20 #endif
21 int t1, t2;
22 std::string input_obj, output_obj;
23 int faces = -1;
24 for (int i = 0; i < argc; ++i) {
25 if (strcmp(argv[i], "-f") == 0) {
26 sscanf(argv[i + 1], "%d", &faces);
27 } else if (strcmp(argv[i], "-i") == 0) {
28 input_obj = argv[i + 1];
29 } else if (strcmp(argv[i], "-o") == 0) {
30 output_obj = argv[i + 1];
31 } else if (strcmp(argv[i], "-sharp") == 0) {
32 field.flag_preserve_sharp = 1;
33 } else if (strcmp(argv[i], "-boundary") == 0) {
34 field.flag_preserve_boundary = 1;
35 } else if (strcmp(argv[i], "-adaptive") == 0) {
36 field.flag_adaptive_scale = 1;
37 } else if (strcmp(argv[i], "-mcf") == 0) {
38 field.flag_minimum_cost_flow = 1;
39 } else if (strcmp(argv[i], "-sat") == 0) {
40 field.flag_aggresive_sat = 1;
41 } else if (strcmp(argv[i], "-seed") == 0) {
42 field.hierarchy.rng_seed = atoi(argv[i + 1]);
43 }
44 }
45 printf("%d %s %s\n", faces, input_obj.c_str(), output_obj.c_str());
46 if (input_obj.size() >= 1) {
47 field.Load(input_obj.c_str());
48 } else {
49 assert(0);
50 // field.Load((std::string(DATA_PATH) + "/fertility.obj").c_str());
51 }
52
53 printf("Initialize...\n");
54 t1 = GetCurrentTime64();
55 field.Initialize(faces);
56 t2 = GetCurrentTime64();
57 printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
58
59 if (field.flag_preserve_boundary) {
60 printf("Add boundary constrains...\n");
61 Hierarchy& mRes = field.hierarchy;
62 mRes.clearConstraints();
63 for (uint32_t i = 0; i < 3 * mRes.mF.cols(); ++i) {
64 if (mRes.mE2E[i] == -1) {
65 uint32_t i0 = mRes.mF(i % 3, i / 3);
66 uint32_t i1 = mRes.mF((i + 1) % 3, i / 3);
67 Vector3d p0 = mRes.mV[0].col(i0), p1 = mRes.mV[0].col(i1);
68 Vector3d edge = p1 - p0;
69 if (edge.squaredNorm() > 0) {
70 edge.normalize();
71 mRes.mCO[0].col(i0) = p0;
72 mRes.mCO[0].col(i1) = p1;
73 mRes.mCQ[0].col(i0) = mRes.mCQ[0].col(i1) = edge;
74 mRes.mCQw[0][i0] = mRes.mCQw[0][i1] = mRes.mCOw[0][i0] = mRes.mCOw[0][i1] =
75 1.0;
76 }
77 }
78 }
79 mRes.propagateConstraints();
80 }
81
82 printf("Solve Orientation Field...\n");
83 t1 = GetCurrentTime64();
84
85 Optimizer::optimize_orientations(field.hierarchy);
86 field.ComputeOrientationSingularities();
87 t2 = GetCurrentTime64();
88 printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
89
90 if (field.flag_adaptive_scale == 1) {
91 printf("Estimate Slop...\n");
92 t1 = GetCurrentTime64();
93 field.EstimateSlope();
94 t2 = GetCurrentTime64();
95 printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
96 }
97 printf("Solve for scale...\n");
98 t1 = GetCurrentTime64();
99 Optimizer::optimize_scale(field.hierarchy, field.rho, field.flag_adaptive_scale);
100 field.flag_adaptive_scale = 1;
101 t2 = GetCurrentTime64();
102 printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
103
104 printf("Solve for position field...\n");
105 t1 = GetCurrentTime64();
106 Optimizer::optimize_positions(field.hierarchy, field.flag_adaptive_scale);
107
108 field.ComputePositionSingularities();
109 t2 = GetCurrentTime64();
110 printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
111 t1 = GetCurrentTime64();
112 printf("Solve index map...\n");
113 field.ComputeIndexMap();
114 t2 = GetCurrentTime64();
115 printf("Indexmap Use %lf seconds\n", (t2 - t1) * 1e-3);
116 printf("Writing the file...\n");
117
118 if (output_obj.size() < 1) {
119 assert(0);
120 // field.OutputMesh((std::string(DATA_PATH) + "/result.obj").c_str());
121 } else {
122 field.OutputMesh(output_obj.c_str());
123 }
124 printf("finish...\n");
125 // field.LoopFace(2);
126 return 0;
127 }
128