00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef __VCGLIB_IMPORT_RAW
00038 #define __VCGLIB_IMPORT_RAW
00039
00040 #include <stdio.h>
00041 #include <fstream>
00042 #include <iostream>
00043
00044 namespace vcg {
00045 namespace tri {
00046 namespace io {
00047
00053 template <class MESH_TYPE>
00054 class ImporterRAW
00055 {
00056 public:
00057
00058 typedef typename MESH_TYPE::VertexPointer VertexPointer;
00059 typedef typename MESH_TYPE::ScalarType ScalarType;
00060 typedef typename MESH_TYPE::VertexType VertexType;
00061 typedef typename MESH_TYPE::FaceType FaceType;
00062 typedef typename MESH_TYPE::VertexIterator VertexIterator;
00063 typedef typename MESH_TYPE::FaceIterator FaceIterator;
00064
00065
00066 #define RAW_MAX_TOKEN_LINE_DESCRIPTOR 32
00067
00068
00069 enum RAWError {
00070 E_NOERROR,
00071
00072 E_CANTOPEN,
00073 E_UNESPECTEDEOF,
00074
00075 E_INVALIDLINEDESC,
00076
00077 E_LINEERROR,
00078
00079 E_WRONGPOINTNUM
00080 };
00081
00082 static const char *ErrorMsg(int error)
00083 {
00084 static const char * raw_error_msg[] =
00085 {
00086 "No errors",
00087 "Can't open file",
00088 "Premature End of file",
00089 "Invalid line Descriptor",
00090 "Error parsing a line",
00091 "Point number different from expected"
00092 };
00093
00094 if(error>2 || error<0) return "Unknown error";
00095 else return stl_error_msg[error];
00096 };
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static int Parselinedescription(const char * linedesc, int &tokennumber, int *order)
00123 {
00124 int ii;
00125 char tok[3];
00126 int index;
00127
00128
00129
00130 int len = strlen(linedesc) + 1;
00131 if(len%3 != 0)
00132 return E_INVALIDLINEDESC;
00133
00134 index=0;
00135 tok[2] = '\0';
00136 tokennumber = 0;
00137 for(ii=0; ii<RAW_MAX_TOKEN_LINE_DESCRIPTOR; ii++)
00138 order[ii] = -1;
00139
00140 while(index <= (len-3))
00141 {
00142 tok[0] = linedesc[index ];
00143 tok[1] = linedesc[index+1];
00144
00145 if(strcmp(tok,"PX") == 0)
00146 {order[tokennumber] = 0; tokennumber++;}
00147 else if (strcmp(tok,"PY") == 0)
00148 {order[tokennumber] = 1; tokennumber++;}
00149 else if (strcmp(tok,"PZ") == 0)
00150 {order[tokennumber] = 2; tokennumber++;}
00151 else if (strcmp(tok,"NX") == 0)
00152 {order[tokennumber] = 3; tokennumber++;}
00153 else if (strcmp(tok,"NY") == 0)
00154 {order[tokennumber] = 4; tokennumber++;}
00155 else if (strcmp(tok,"NZ") == 0)
00156 {order[tokennumber] = 5; tokennumber++;}
00157 else if (strcmp(tok,"CR") == 0)
00158 {order[tokennumber] = 6; tokennumber++;}
00159 else if (strcmp(tok,"CG") == 0)
00160 {order[tokennumber] = 7; tokennumber++;}
00161 else if (strcmp(tok,"CB") == 0)
00162 {order[tokennumber] = 8; tokennumber++;}
00163 else if (strcmp(tok,"RF") == 0)
00164 {order[tokennumber] = 9; tokennumber++;}
00165 else
00166 { return E_INVALIDLINEDESC; }
00167
00168 index +=3;
00169 }
00170
00171 return E_NOERROR;
00172 }
00173
00174
00175
00176 static void Skipline(FILE *fp)
00177 {
00178 char buf;
00179
00180 fread(&(buf),sizeof(char),1,fp);
00181
00182 while(buf != '\n')
00183 fread(&(buf),sizeof(char),1,fp);
00184 }
00185
00186
00187
00188
00189 static int Parseline(int tokennumber, int *tokenorder, char *rawline, float *linebuffer)
00190 {
00191 int linelen;
00192 int ii;
00193 bool change;
00194 int foundtok;
00195
00196
00197 linelen = strlen(rawline);
00198
00199
00200 for(ii=0;ii<(linelen-1);)
00201 {
00202 change = true;
00203
00204 if(isdigit(rawline[ii]))
00205 change = false;
00206 else if(rawline[ii]==' ')
00207 change = false;
00208 else if((rawline[ii]=='-') || (rawline[ii]=='+') || (rawline[ii]=='-') || (rawline[ii]=='.'))
00209 change = false;
00210 else if(rawline[ii]=='e')
00211 {
00212 if((ii>0) || (ii<(linelen-2)))
00213 if(isdigit(rawline[ii-1]))
00214 if(isdigit(rawline[ii+1]) || (rawline[ii+1]=='+') || (rawline[ii+1]=='-'))
00215 change = false;
00216 }
00217
00218 if(change)
00219 rawline[ii++] = ' ';
00220 else
00221 ii++;
00222
00223 }
00224 rawline[linelen] = '\0';
00225
00226
00227 foundtok = 0;
00228 ii = 0;
00229 while((foundtok<tokennumber)&&(ii<linelen))
00230 {
00231
00232 while(rawline[ii] == ' ')
00233 ii++;
00234
00235 foundtok++;
00236 sscanf(&(rawline[ii]),"%f", &(linebuffer[tokenorder[foundtok-1]]));
00237
00238
00239 while((rawline[ii] != ' ')&&(rawline[ii] != '\0'))
00240 ii++;
00241 }
00242
00243 if(foundtok<tokennumber)
00244 return E_LINEERROR;
00245 else
00246 return E_NOERROR;
00247 }
00248
00249
00250 static int fillHoles( MESH_TYPE &m, size_t rowCount, size_t colCount)
00251 {
00252
00253 for (size_t i = 1; i<colCount-1; ++i)
00254 for (size_t j = 1; j<rowCount-1; ++j)
00255 {
00256
00257 size_t ind = (i) + ((j) * colCount);
00258 size_t indL = (i-1) + ((j) * colCount);
00259 size_t indR = (i+1) + ((j) * colCount);
00260 size_t indT = (i) + ((j-1) * colCount);
00261 size_t indB = (i) + ((j+1) * colCount);
00262
00263 if ((m.vert[ind].P() == vcg::Point3<MESH_TYPE::ScalarType>(0,0,0)) &&
00264 (m.vert[indL].P() != vcg::Point3<MESH_TYPE::ScalarType>(0,0,0)) &&
00265 (m.vert[indR].P() != vcg::Point3<MESH_TYPE::ScalarType>(0,0,0)) &&
00266 (m.vert[indT].P() != vcg::Point3<MESH_TYPE::ScalarType>(0,0,0)) &&
00267 (m.vert[indB].P() != vcg::Point3<MESH_TYPE::ScalarType>(0,0,0)) )
00268 {
00269 m.vert[ind].P() = ( m.vert[indL].P() + m.vert[indR].P() + m.vert[indT].P() + m.vert[indB].P() ) * 0.25;
00270
00271 }
00272
00273
00274 }
00275
00276
00277 return 1;
00278 }
00279
00288 static int Open( MESH_TYPE &m, const char * filename, bool triangulate=false, int lineskip = 0, const char * linedesc = "PX PY PZ")
00289 {
00290 int ii;
00291 int ret;
00292
00293
00294 FILE *fp;
00295 int rownumber;
00296 int colnumber;
00297
00298
00299 int tokennumber;
00300 int tokenorder[RAW_MAX_TOKEN_LINE_DESCRIPTOR];
00301
00302
00303 char rawline[512];
00304
00305
00306
00307
00308 float linebuffer[10];
00309
00310 linebuffer[0] = linebuffer[1] = linebuffer[2] = 0.0;
00311 linebuffer[3] = linebuffer[4] = linebuffer[5] = 1.0;
00312 linebuffer[6] = 0.0; linebuffer[7] = 1.0; linebuffer[8] = 0.0;
00313 linebuffer[9] = 1.0;
00314
00315
00316 fp = fopen(filename, "r");
00317
00318 if(fp == NULL)
00319 {
00320 return E_CANTOPEN;
00321 }
00322
00323
00324 for(ii=0; ii<lineskip; ii++) Skipline(fp);
00325
00326
00327
00328 if(triangulate)
00329 {
00330 fscanf(fp,"%i", &(rownumber));
00331 fscanf(fp,"%i\n", &(colnumber));
00332 }
00333
00334
00335 ret = Parselinedescription(linedesc, tokennumber, tokenorder);
00336 if(ret)
00337 return ret;
00338
00339 m.Clear();
00340 m.vert.reserve( rownumber * colnumber );
00341 int line = 0;
00342 size_t rowCounter = 0;
00343 size_t colCounter = 0;
00344 while(!feof(fp))
00345 {
00346
00347
00348
00349 ii=0;
00350 memset( rawline, 0, 512);
00351 fread(&(rawline[ii++]),sizeof(char),1,fp);
00352 while( (rawline[ii-1] != '\n') && (ii<512) )
00353 {
00354 fread(&(rawline[ii++]),sizeof(char),1,fp);
00355 }
00356 rawline[ii-1] = '\0';
00357 line++;
00358 if(strlen(rawline) >0)
00359 {
00360
00361 ret = Parseline(tokennumber, tokenorder, rawline, linebuffer);
00362 if(ret)
00363 return ret;
00364
00365
00366
00367
00368
00369
00370
00371
00372 VertexType nv;
00373
00374
00375 nv.P()[0] = linebuffer[0];
00376 nv.P()[1] = linebuffer[1];
00377 nv.P()[2] = linebuffer[2];
00378
00379
00380 if(m.HasPerVertexNormal())
00381 {
00382 nv.N()[0] = linebuffer[3];
00383 nv.N()[1] = linebuffer[4];
00384 nv.N()[2] = linebuffer[5];
00385 }
00386
00387
00388 if(m.HasPerVertexColor())
00389 {
00390 nv.C()[0] = linebuffer[6];
00391 nv.C()[1] = linebuffer[7];
00392 nv.C()[2] = linebuffer[8];
00393 }
00394
00395
00396 if(m.HasPerVertexQuality())
00397 {
00398 nv.Q() = linebuffer[9];
00399 }
00400
00401 m.vert.push_back(nv);
00402
00403
00404
00405 }
00406 }
00407 m.vn = m.vert.size();
00408 if(triangulate) fillHoles(m, rownumber, colnumber);
00409
00410
00411
00412
00413
00414 if(triangulate)
00415 {
00416 int rr,cc;
00417
00418
00419 int trinum = (rownumber-1) * (colnumber-1) * 2;
00420
00421 FaceIterator fi=Allocator<MESH_TYPE>::AddFaces(m,trinum);
00422 FaceIterator fi2 = fi;
00423 m.fn = trinum;
00424 for(cc=0; cc<colnumber-1; cc++)
00425 for(rr=0; rr<rownumber-1; rr++)
00426 {
00427
00428 (*fi).V(0) = &(m.vert[(cc+1) + ((rr ) * colnumber)]);
00429 (*fi).V(1) = &(m.vert[(cc ) + ((rr ) * colnumber)]);
00430 (*fi).V(2) = &(m.vert[(cc ) + ((rr+1) * colnumber)]);
00431
00432
00433 fi++;
00434
00435
00436 (*fi).V(0) = &(m.vert[(cc ) + ((rr+1) * colnumber)]);
00437 (*fi).V(1) = &(m.vert[(cc+1) + ((rr+1) * colnumber)]);
00438 (*fi).V(2) = &(m.vert[(cc+1) + ((rr ) * colnumber)]);
00439
00440 fi++;
00441
00442 }
00443
00444
00445 if (m.HasPerFaceFlags()) {
00446 for (; fi2!=m.face.end(); fi2++) {
00447 (*fi2).SetF(2);
00448 }
00449 }
00450
00451
00452
00453 }
00454
00455 fclose(fp);
00456 return E_NOERROR;
00457 }
00458
00459 };
00460 }
00461 }
00462 }
00463
00464 #endif