00001
00010 #define _USE_MATH_DEFINES
00011 #include <math.h>
00012 #include <iostream>
00013 #include <fstream>
00014 #include <string>
00015 #include <string.h>
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <time.h>
00019 #ifdef _WIN32
00020 #ifndef MSKDLL
00021 #define MSKDLL
00022 #endif
00023 #endif
00024 #include "mosek.h"
00025 #include "util.h"
00026 #include "Mesh.h"
00027 #include "AnglesOptimization.h"
00028 #include "EnergyMinimization.h"
00029 #include "Layout.h"
00030
00031 using namespace std;
00032
00033 void putOptionsInFromFile (int & argc, char * argv[], vector<string> & options);
00034 void putOptionsIn (int & argc, char * argv[], vector<string> & options);
00035 void parseOptions (const vector<string> & options, ProgramOptions &po);
00036 void checkOptions (ProgramOptions &po);
00037 void initializeMosek (MSKenv_t & env, MSKtask_t & angleTask, MSKtask_t & radiiTask);
00038
00043 int main (int argc, char *argv[]) {
00044
00045 vector<string> options;
00046
00047 if (argc < 2 || (argc != 2 && argc < 5))
00048 usage();
00049
00050 if (argc == 2) {
00051 if (!strcmp(argv[1],"-help")){
00052 usage();
00053 exit(1);
00054 }
00055 else if (!strcmp(argv[1],"-h")){
00056 usage();
00057 exit(1);
00058 }
00059 putOptionsInFromFile(argc, argv, options);
00060 }
00061 else
00062 putOptionsIn(argc, argv, options);
00063
00064 clock_t startTime, finishTime;
00065
00066
00067 ProgramOptions po;
00068 parseOptions(options, po);
00069 checkOptions(po);
00070
00071
00072 cout << "Parsing the mesh ";
00073 Mesh mesh;
00074 if (po.read_obj) {
00075 cout << po.file_in << " (OBJ format)..." << endl;
00076 mesh.readOBJ(po.file_in.c_str());
00077 mesh.computeMeshInfo();
00078 mesh.computeLengths();
00079 mesh.computeInitAngles();
00080 }
00081 else if (po.read_conn) {
00082 cout << po.file_in << " (CON format)..." << endl;
00083 mesh.readCON(po.file_in.c_str());
00084 mesh.computeMeshInfo();
00085 mesh.computeInitAngles();
00086 }
00087
00088 if (po.read_vert) {
00089 cout << "Reading cone singularities file " << po.vert_file << "..." << endl;
00090 mesh.readCONE_VERT(po.vert_file.c_str());
00091 }
00092
00093 startTime = clock ();
00094
00095 if (po.do_optim) {
00096 mesh.checkGaussianCurvature();
00097
00098
00099 MSKenv_t env;
00100 MSKtask_t angleTask, radiiTask;
00101 initializeMosek(env, angleTask, radiiTask);
00102
00103
00104 cout << "Optimizing for valid angles..." << endl;
00105 AnglesOptimization anglesOptimization(&mesh, env);
00106 anglesOptimization.doSolve();
00107
00109 cout << "Minimizing energy to find radii..." << endl;
00110 EnergyMinimization energyMin(&mesh, env);
00111 energyMin.doSolve();
00112 }
00113
00114
00115 cout << "Laying out the mesh.." << endl;
00116 Layout lay(&mesh);
00117 if (po.do_optim)
00118 lay.computeEdgeLengthAndAngles();
00119
00120
00121 if (po.read_edges) {
00122 cout << "Reading edges from " << po.edge_file << "..." << endl;
00123 cout << "Cutting the mesh..." << endl;
00124 mesh.readCUT_EDGES(po.edge_file.c_str());
00125 }
00126
00127 if (po.write_obj || po.write_vt) {
00128 if (po.read_edges) {
00129 lay.validCuts();
00130 }
00131 lay.layoutMesh();
00132 }
00133
00134 finishTime = clock();
00135
00136 if (po.write_conn) {
00137 cout << "Writing out the results " << endl;
00138 cout << po.conn_file_out << " (CON format)..." << endl;
00139 mesh.writeCON(po.conn_file_out.c_str());
00140 }
00141
00142 if (po.write_obj) {
00143 cout << "Writing out the results " << endl;
00144 cout << po.obj_file_out << " (OBJ format)..." << endl;
00145 mesh.writeOBJ(po.obj_file_out.c_str());
00146 }
00147
00148 if (po.write_vt) {
00149 cout << "Writing out the results " << endl;
00150 cout << po.obj_file_out << " (VT format)..." << endl;
00151 mesh.writeVT(po.vt_file_out.c_str());
00152 }
00153
00154 cout << "\nFinnished, total: "
00155 << ((double(finishTime)-double(startTime))/CLOCKS_PER_SEC) << " seconds." << endl;
00156
00157 }
00158
00159 void initializeMosek (MSKenv_t & env, MSKtask_t & angleTask, MSKtask_t & radiiTask) {
00160 int r = MSK_RES_OK;
00161
00162
00163
00164 r = MSK_makeenv(&env,NULL,NULL,NULL,NULL);
00165 check_error (r != MSK_RES_OK, "Cannot create MOSEK enviroment.");
00166
00167
00168
00169 r = MSK_linkfiletoenvstream(env, MSK_STREAM_LOG, "_EnvMosekOut.txt", 0);
00170 check_error (r != MSK_RES_OK, "Cannot link MOSEK \"_EnvMosekOut.txt\" output file.");
00171
00172
00173 r = MSK_initenv(env);
00174 check_error (r != MSK_RES_OK, "Cannot initialize MOSEK enviroment.");
00175 }
00176
00177 void putOptionsInFromFile (int & argc, char * argv[], vector<string> & options) {
00178 ifstream in (argv[1]);
00179 check_error(!in, "Cannot open input file with options: " + string(argv[1]));
00180 string option;
00181 while (!in.eof()) {
00182 in >> ws;
00183 if (in.peek() == '\"') {
00184 in.ignore(1);
00185 getline(in, option, '\"');
00186 in.ignore(1);
00187 }
00188 else
00189 in >> option;
00190 options.push_back(option);
00191 }
00192 }
00193
00194 void putOptionsIn (int & argc, char * argv[], vector<string> & options) {
00195 for (int i = 1; i < argc; i++) {
00196 options.push_back(string(argv[i]));
00197 }
00198 }
00199
00200 void checkOptions (ProgramOptions &po) {
00201 check_error((po.read_obj && po.read_conn), "Can only read one format at a time." );
00202 check_error((!po.read_obj && !po.read_conn), "No input file specified." );
00203 check_error((!po.write_conn && !po.write_obj && !po.write_vt), "No output file specified." );
00204 }
00205
00206 void parseOptions (const vector<string> & options, ProgramOptions &po) {
00207 for (unsigned int i = 0; i < options.size(); i++) {
00208 if (!strcmp(options[i].c_str(),"-io")){
00209 po.read_obj = true;
00210 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00211 po.file_in = options[++i].c_str();
00212
00213 }
00214 else if (!strcmp(options[i].c_str(),"-ic")){
00215 po.read_conn = true;
00216 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00217 po.file_in = options[++i].c_str();
00218 }
00219 else if (!strcmp(options[i].c_str(),"-iv")){
00220 po.read_vert = true;
00221 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00222 po.vert_file = options[++i].c_str();
00223 }
00224 else if (!strcmp(options[i].c_str(),"-ie")){
00225 po.read_edges = true;
00226 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00227 po.edge_file = options[++i].c_str();
00228 }
00229 else if (!strcmp(options[i].c_str(),"-oo")){
00230 po.write_obj = true;
00231 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00232 po.obj_file_out = options[++i].c_str();
00233 }
00234 else if (!strcmp(options[i].c_str(),"-ovt")){
00235 po.write_vt = true;
00236 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00237 po.vt_file_out = options[++i].c_str();
00238 }
00239 else if (!strcmp(options[i].c_str(),"-oc")){
00240 po.write_conn = true;
00241 check_error(i >= (options.size() - 1), string("No value for option speficied: ")+options[i]);
00242 po.conn_file_out = options[++i].c_str();
00243 }
00244 else if (!strcmp(options[i].c_str(),"-no")){
00245 po.do_optim = false;
00246 }
00247 else {
00248 cerr << "Warning, Unrecognized option: " << options[i].c_str() << endl;
00249 }
00250 }
00251 }
00252