MeshKit
1.0
|
00001 #include <iostream> 00002 00003 #include <time.h> 00004 #include <stdlib.h> 00005 #include <cstring> 00006 #include <cstring> 00007 00008 #include "QslimDecimation.h" 00009 #include "QslimOptions.h" 00010 00011 #define DEFAULT_TEST_FILE "cow.smf" 00012 #define ERROR(a) {if (iBase_SUCCESS != err) std::cerr << a << std::endl;} 00013 #define ERRORR(a,b) {if (iBase_SUCCESS != err) {std::cerr << a << std::endl; return b;}} 00014 00015 std::string usage_string = 00016 "-o <file> Output final model to given file.\n" 00017 "-s <count> Set the target number of faces.\n" 00018 "-i <timings> Intervals for timing reports.\n" 00019 "-e <thresh> Set the maximum error tolerance.\n" 00020 "-t <t> Set pair selection tolerance.\n" 00021 "-Q[pv] Select what constraint quadrics to use [default=p].\n" 00022 "-On Optimal placement policy.\n" 00023 " 0=endpoints, 1=endormid, 2=line, 3=optimal [default]\n" 00024 "-B <weight> Use boundary preservation planes with given weight.\n" 00025 "-b preserve boundary (do not use with -B option) \n" 00026 "-m Preserve mesh quality.\n" 00027 "-a Enable area weighting.\n" 00028 "-p Height fields positivity. Used for height fields, assume \n" 00029 " triangles are originally positively oriented. \n" 00030 "-d Use delayed deletion, as opposed to merging \n" 00031 "-c keep costs in a (sparse!!!!) tag \n" 00032 "\n"; 00033 00034 std::string logging_usage_string = 00035 "-l <file> Log all simplification operations to given file.\n" 00036 "-L[xqcvfdA] Set information to be output.\n" 00037 " x=contractions, q=quadrics, c=cost\n" 00038 " v=vert. notes, f=face notes\n" 00039 " d=model defn, A=All.\n"; 00040 00041 int main(int argc, char* argv[]) 00042 { 00043 // check command line arg 00044 const char *filename = 0; 00045 const char *outfile = 0; 00046 00047 //process options 00048 QslimOptions options; 00049 // process all options, as given with regular qslim 00050 // the last argument must be the input file 00051 // one argument must be -o <the output file>, otherwise it is the standard output 00052 // in the process, a mesh file is read (instanced) and the 00053 // set of triangles is passed 00054 // it could be the root set for the mesh 00055 std::string fstr, ostr; 00056 if (argc<=1) 00057 { 00058 std::cout<<usage_string; 00059 std::cout << "\n\n"; 00060 std::cout<< "default arguments: -s 4500 -B 1000 -p -o out.smf ./partBed.smf \n"; 00061 options.face_target = 4500; 00062 options.will_constrain_boundaries = true; 00063 options.boundary_constraint_weight = 1000; 00064 options.height_fields = 1; 00065 fstr="./partBed.smf"; 00066 filename = fstr.c_str(); 00067 ostr = "out.smf"; 00068 outfile = ostr.c_str(); 00069 } 00070 else 00071 { 00072 // the file should be the last argument; if not, we have a problem, we will not be able to read it 00073 filename = argv[argc-1]; 00074 int i=1;// will loop through arguments, and process them 00075 for (i=1; i<argc-1 ; i++) 00076 { 00077 if (argv[i][0]=='-') 00078 { 00079 switch (argv[i][1]) 00080 { 00081 case 'l': 00082 { 00083 // open a log file 00084 options.logfile = new std::ofstream(argv[i+1]); 00085 if (!options.logfile) 00086 { 00087 // cannot open log file, exit 00088 std::cout << "can't open log file\n"; 00089 return 1; 00090 } 00091 i++; 00092 break; 00093 } 00094 case 'L': 00095 // parse the logging options 00096 { 00097 char *c; 00098 int errflg = 0; 00099 c = argv[i]+2;// skip -L 00100 while( *c ) 00101 { 00102 if( *c=='x' ) 00103 options.selected_output |= OUTPUT_CONTRACTIONS; 00104 else if( *c=='q' ) 00105 options.selected_output |= OUTPUT_QUADRICS; 00106 else if( *c=='c' ) 00107 options.selected_output |= OUTPUT_COST; 00108 else if( *c=='v' ) 00109 options.selected_output |= OUTPUT_VERT_NOTES; 00110 else if( *c=='f' ) 00111 options.selected_output |= OUTPUT_FACE_NOTES; 00112 else if( *c=='d' ) 00113 options.selected_output |= OUTPUT_MODEL_DEFN; 00114 else if( *c=='A' ) 00115 options.selected_output |= OUTPUT_ALL; 00116 else 00117 errflg++; 00118 c++; 00119 } 00120 if (errflg>0) 00121 { 00122 std::cout<<logging_usage_string; 00123 std::cout<< "!! Ignore the error it\n"; 00124 00125 } 00126 break; 00127 } 00128 case 'a': 00129 { 00130 options.will_weight_by_area = 1; 00131 break; 00132 } 00133 case 'B': 00134 { 00135 options.boundary_constraint_weight = atof(argv[i+1]); 00136 options.will_constrain_boundaries = 1; 00137 i++; 00138 break; 00139 } 00140 case 's': 00141 { 00142 options.face_target = atoi(argv[i+1]); 00143 i++; 00144 break; 00145 } 00146 case 't': 00147 { 00148 options.pair_selection_tolerance = atof(argv[i+1]); 00149 i++; 00150 break; 00151 } 00152 case 'o': 00153 { 00154 outfile = argv[i+1]; 00155 i++; 00156 break; 00157 } 00158 00159 case 'O': 00160 { 00161 char * c ; 00162 c = argv[i]+2; 00163 int ival = atoi(c); 00164 if( ival < 0 || ival > PLACE_OPTIMAL ) 00165 ival=PLACE_OPTIMAL; 00166 options.placement_policy = ival; 00167 break; 00168 } 00169 00170 case 'Q': 00171 { 00172 options.will_use_plane_constraint = false; 00173 options.will_use_vertex_constraint = false; 00174 options.will_use_plane_constraint = false; 00175 00176 char * c ; 00177 c = argv[i]+2; 00178 while( *c ) 00179 { 00180 if( *c=='p' ) 00181 options.will_use_plane_constraint = true; 00182 else if( *c=='v' ) 00183 options.will_use_vertex_constraint = true; 00184 else 00185 { 00186 std::cout<< "wrong input " << argv[i] << std::endl; 00187 } 00188 c++; 00189 } 00190 break; 00191 } 00192 00193 case 'e': 00194 { 00195 options.error_tolerance = atof(argv[i+1]); 00196 i++; 00197 break; 00198 } 00199 00200 case 'b': 00201 { 00202 options.will_preserve_boundaries = true; 00203 break; 00204 } 00205 00206 case 'm': 00207 { 00208 options.will_preserve_mesh_quality = true; 00209 break; 00210 } 00211 00212 case 'p': 00213 { 00214 options.height_fields = true; 00215 break; 00216 } 00217 case 'i': 00218 { 00219 options.timingIntervals=atof(argv[i+1]); 00220 i++; 00221 break; 00222 } 00223 case 'd': 00224 { 00225 options.useDelayedDeletion = true; 00226 break; 00227 } 00228 case 'c': 00229 { 00230 options.plotCost = 1; 00231 break; 00232 } 00233 00234 default : 00235 { 00236 std::cout << "unsupported wrong input argument " << argv[i] <<std::endl; 00237 return 0; 00238 } 00239 } 00240 } 00241 } 00242 } 00243 // initialize the Mesh 00244 int err; 00245 iMesh_Instance mesh; 00246 iMesh_newMesh("", &mesh, &err, 0); 00247 ERRORR("Couldn't create mesh.", 1); 00248 00249 iBase_EntitySetHandle root_set; 00250 iMesh_getRootSet(mesh, &root_set, &err); 00251 ERRORR("Couldn't get root set.", 1); 00252 00253 // read initial mesh file 00254 clock_t start_time = clock(); 00255 iMesh_load(mesh, root_set, filename, NULL, &err, strlen(filename), 0); 00256 ERRORR("Couldn't load mesh file.", 1); 00257 clock_t load_time = clock(); 00258 00259 // make decimate mesher 00260 QslimDecimation *qsld = new QslimDecimation(mesh, root_set); 00261 00262 // do simplification 00263 err = qsld->decimate(options); 00264 ERRORR("Couldn't decimate mesh.", 1); 00265 clock_t decimate_time = clock(); 00266 00267 if (outfile && strlen(outfile) > 0) 00268 { 00269 std::cout << "Writing output file " << outfile <<std::endl; 00270 // save the output in a new file 00271 iMesh_save(mesh, root_set, outfile, NULL, &err, strlen(outfile), 0); 00272 ERRORR("Couldn't save result mesh file.", 1); 00273 } 00274 else 00275 std::cout << " no output file provided. \n"; 00276 clock_t write_time = clock(); 00277 00278 00279 std::cout << "Decimate algorithm successful." << std::endl; 00280 00281 std::cout << " load time: " 00282 << (double) (load_time - start_time)/CLOCKS_PER_SEC 00283 << "s \n simplification time: " 00284 << (double) (decimate_time - load_time)/CLOCKS_PER_SEC 00285 << "s \n write time: " 00286 << (double) (write_time - decimate_time )/CLOCKS_PER_SEC 00287 << " s." << std::endl; 00288 00289 delete qsld; 00290 iMesh_dtor(mesh, &err); 00291 ERRORR("Couldn't destroy mesh.", 1); 00292 00293 return 0; 00294 }