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
00038
00039
00040
00041
00042
00043
00044
00045 #include <assert.h>
00046 #include <math.h>
00047 #include <stdio.h>
00048
00049 #include "VRender.h"
00050 #include "ParserGL.h"
00051
00052 using namespace vrender ;
00053 using namespace std;
00054
00055 class ParserUtils
00056 {
00057 public:
00058 static void NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin, GLfloat& zmax) ;
00059
00060 static PtrPrimitive checkPoint(Point *& P);
00061 static PtrPrimitive checkSegment(Segment *& P);
00062 static PtrPrimitive checkPolygon(Polygone *& P);
00063
00064 static void ComputeBufferBB(GLint size, GLfloat * buffer,
00065 GLfloat & xmin, GLfloat & xmax,
00066 GLfloat & ymin, GLfloat & ymax,
00067 GLfloat & zmin, GLfloat & zmax) ;
00068
00069 private:
00070 static void print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer) ;
00071 static void debug_printBuffer(GLint size, GLfloat *buffer) ;
00072
00073 static void NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax) ;
00074 static void ComputePrimitiveBB( GLfloat * & loc,
00075 GLfloat & xmin,GLfloat & xmax,
00076 GLfloat & ymin,GLfloat & ymax,
00077 GLfloat & zmin,GLfloat & zmax);
00078
00079 static const char *nameOfToken(int token);
00080
00081 static const double EGALITY_EPS ;
00082 };
00083
00084 const double ParserUtils::EGALITY_EPS = 0.00001 ;
00085
00086 void ParserGL::parseFeedbackBuffer( GLfloat *buffer,int size,
00087 std::vector<PtrPrimitive>& primitive_tab,
00088 VRenderParams& vparams)
00089 {
00090 int token;
00091 int nvertices = 0 ;
00092 nb_lines = 0 ;
00093 nb_polys = 0 ;
00094 nb_points = 0 ;
00095 nb_degenerated_lines = 0 ;
00096 nb_degenerated_polys = 0 ;
00097 nb_degenerated_points = 0 ;
00098
00099
00100
00101 _xmin = FLT_MAX ;
00102 _ymin = FLT_MAX ;
00103 _zmin = FLT_MAX ;
00104 _xmax = -FLT_MAX ;
00105 _ymax = -FLT_MAX ;
00106 _zmax = -FLT_MAX ;
00107
00108 ParserUtils::ComputeBufferBB(size, buffer, _xmin,_xmax,_ymin,_ymax,_zmin,_zmax) ;
00109
00110 #ifdef DEBUGEPSRENDER
00111 printf("Buffer bounding box: %f %f %f %f %f %f\n",xmin,xmax,ymin,ymax,zmin,zmax) ;
00112 #endif
00113 float Zdepth = max(_ymax-_ymin,_xmax-_xmin) ;
00114 ParserUtils::NormalizeBufferCoordinates(size,buffer,Zdepth,_zmin,_zmax) ;
00115
00116
00117 GLfloat *end = buffer + size;
00118
00119 GLfloat *loc = buffer ;
00120 int next_step = 0 ;
00121 int N = size/200 + 1 ;
00122
00123 while (loc < end)
00124 {
00125 token = int(0.5f + *loc) ;
00126 loc++;
00127
00128 if((end-loc)/N >= next_step)
00129 vparams.progress((end-loc)/(float)size, QGLViewer::tr("Parsing feedback buffer.")), ++next_step ;
00130
00131 switch (token)
00132 {
00133 case GL_LINE_TOKEN:
00134 case GL_LINE_RESET_TOKEN:
00135 {
00136 Segment *S = new Segment(Feedback3DColor(loc),Feedback3DColor(loc+Feedback3DColor::sizeInBuffer())) ;
00137
00138 primitive_tab.push_back(ParserUtils::checkSegment(S)) ;
00139
00140 if(S == NULL)
00141 nb_degenerated_lines++ ;
00142
00143 nb_lines++ ;
00144 loc += 2*Feedback3DColor::sizeInBuffer();
00145 }
00146 break;
00147
00148 case GL_POLYGON_TOKEN:
00149 {
00150 nvertices = int(0.5f + *loc) ;
00151 loc++;
00152
00153 std::vector<Feedback3DColor> verts ;
00154
00155 for(int i=0;i<nvertices;++i)
00156 verts.push_back(Feedback3DColor(loc)),loc+=Feedback3DColor::sizeInBuffer() ;
00157
00158 Polygone *P = new Polygone(verts) ;
00159
00160 primitive_tab.push_back(ParserUtils::checkPolygon(P)) ;
00161
00162 if(P == NULL)
00163 nb_degenerated_polys++ ;
00164
00165 nb_polys++ ;
00166 }
00167 break ;
00168
00169 case GL_POINT_TOKEN:
00170 {
00171 Point *Pt = new Point(Feedback3DColor(loc)) ;
00172
00173 primitive_tab.push_back(Pt);
00174
00175 if(Pt == NULL)
00176 nb_degenerated_points++ ;
00177
00178 nb_points++ ;
00179 loc += Feedback3DColor::sizeInBuffer();
00180 }
00181 break;
00182 default:
00183 break;
00184 }
00185 }
00186
00187 }
00188
00189
00190
00191
00192 PtrPrimitive ParserUtils::checkPoint(Point *& P)
00193 {
00194 return P ;
00195 }
00196
00197 PtrPrimitive ParserUtils::checkSegment(Segment *& P)
00198 {
00199 if((P->vertex(0) - P->vertex(1)).infNorm() < EGALITY_EPS)
00200 {
00201 Point *pp = new Point(P->sommet3DColor(0)) ;
00202 delete P ;
00203 P = NULL ;
00204
00205 return checkPoint(pp) ;
00206 }
00207
00208 return P ;
00209 }
00210
00211 PtrPrimitive ParserUtils::checkPolygon(Polygone *& P)
00212 {
00213 if(P->nbVertices() != 3)
00214 {
00215 cout << "unexpected case: Polygon with " << P->nbVertices() << " vertices !" << endl ;
00216 delete P ;
00217 return NULL ;
00218 }
00219
00220 if(P->FlatFactor() < FLAT_POLYGON_EPS)
00221 {
00222
00223
00224 int n = P->nbVertices() ;
00225
00226 for(int i=0;i<n;++i)
00227 if( (P->vertex(i) - P->vertex((i+1)%n)).norm() > EGALITY_EPS)
00228 {
00229 Segment *pp = new Segment(P->sommet3DColor((i+1)%n),P->sommet3DColor((i+2)%n)) ;
00230 delete P ;
00231 P = NULL ;
00232
00233 return checkSegment(pp) ;
00234 }
00235
00236 Point *pp = new Point(P->sommet3DColor(0)) ;
00237 delete P ;
00238 P = NULL ;
00239
00240 return checkPoint(pp) ;
00241 }
00242
00243
00244
00245 return P ;
00246 }
00247
00248
00249
00250
00251 void ParserUtils::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer)
00252 {
00253 int i;
00254
00255 printf(" ");
00256 for (i = 0; i < Feedback3DColor::sizeInBuffer(); i++)
00257 {
00258 printf("%4.2f ", buffer[size - (*count)]);
00259 *count = *count - 1;
00260 }
00261 printf("\n");
00262 }
00263
00264 void ParserUtils::debug_printBuffer(GLint size, GLfloat * buffer)
00265 {
00266 GLint count;
00267 int token, nvertices;
00268
00269 count = size;
00270 while (count) {
00271 token = int(buffer[size - count]);
00272 count--;
00273 switch (token)
00274 {
00275 case GL_PASS_THROUGH_TOKEN:
00276 printf("GL_PASS_THROUGH_TOKEN\n");
00277 printf(" %4.2f\n", buffer[size - count]);
00278 count--;
00279 break;
00280 case GL_POINT_TOKEN:
00281 printf("GL_POINT_TOKEN\n");
00282 print3DcolorVertex(size, &count, buffer);
00283 break;
00284 case GL_LINE_TOKEN:
00285 printf("GL_LINE_TOKEN\n");
00286 print3DcolorVertex(size, &count, buffer);
00287 print3DcolorVertex(size, &count, buffer);
00288 break;
00289 case GL_LINE_RESET_TOKEN:
00290 printf("GL_LINE_RESET_TOKEN\n");
00291 print3DcolorVertex(size, &count, buffer);
00292 print3DcolorVertex(size, &count, buffer);
00293 break;
00294 case GL_POLYGON_TOKEN:
00295 printf("GL_POLYGON_TOKEN\n");
00296 nvertices = int(buffer[size - count]) ;
00297 count--;
00298 for (; nvertices > 0; nvertices--)
00299 print3DcolorVertex(size, &count, buffer);
00300 }
00301 }
00302 }
00303
00304 void ParserUtils::NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax)
00305 {
00306 int token;
00307 int nvertices, i;
00308
00309 token = int(*loc) ;
00310 loc++;
00311 int size = Feedback3DColor::sizeInBuffer() ;
00312
00313 switch (token)
00314 {
00315 case GL_LINE_RESET_TOKEN:
00316 case GL_LINE_TOKEN:
00317 {
00318 for (i = 0; i < 2; i++)
00319 (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
00320
00321 loc += 2*size;
00322 break;
00323 }
00324 case GL_POLYGON_TOKEN:
00325 {
00326 nvertices = int(*loc) ;
00327 loc++;
00328
00329 for (i = 0; i < nvertices; i++)
00330 (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
00331
00332 loc += nvertices * size;
00333 break;
00334 }
00335 case GL_POINT_TOKEN:
00336 {
00337 loc[2] = (loc[2] - zmin)/(zmax-zmin)*MaxSize ;
00338
00339 loc += size;
00340 break;
00341 }
00342 default:
00343
00344 #ifdef DEBUGEPSRENDER
00345 printf("%s (%d) not handled yet. Sorry.\n", ParserUtils::nameOfToken(token), token);
00346 #endif
00347 ;
00348 }
00349 }
00350
00351 void ParserUtils::ComputePrimitiveBB(GLfloat * & loc,GLfloat & xmin,GLfloat & xmax,GLfloat & ymin,GLfloat & ymax, GLfloat & zmin,GLfloat & zmax)
00352 {
00353 int token;
00354 int nvertices, i;
00355
00356 token = int(*loc) ;
00357 loc++;
00358 int size = Feedback3DColor::sizeInBuffer() ;
00359
00360 switch (token)
00361 {
00362 case GL_LINE_RESET_TOKEN:
00363 case GL_LINE_TOKEN:
00364 {
00365 for (i = 0; i < 2; i++)
00366 {
00367 Feedback3DColor f(loc+size*i) ;
00368
00369 if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00370 if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00371 if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00372 if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00373 if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00374 if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00375 }
00376
00377 loc += 2*size;
00378
00379 break;
00380 }
00381 case GL_POLYGON_TOKEN:
00382 {
00383 nvertices = int(*loc) ;
00384 loc++;
00385
00386 for (i = 0; i < nvertices; i++)
00387 {
00388 Feedback3DColor f(loc+size*i) ;
00389
00390 if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00391 if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00392 if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00393 if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00394 if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00395 if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00396 }
00397
00398 loc += nvertices * size;
00399
00400 break;
00401 }
00402 case GL_POINT_TOKEN:
00403 {
00404 Feedback3DColor f(loc) ;
00405
00406 if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00407 if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00408 if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00409 if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00410 if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00411 if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00412
00413 loc += size;
00414
00415 break;
00416 }
00417 default:
00418
00419 #ifdef DEBUGEPSRENDER
00420 printf("Incomplete implementation. Unexpected token (%d).\n", token);
00421 #endif
00422 ;
00423 }
00424 }
00425
00426 void ParserUtils::NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin,GLfloat& zmax)
00427 {
00428 GLfloat *loc, *end;
00429
00430 if(zmax == zmin)
00431 {
00432 #ifdef DEBUGEPSRENDER
00433 printf("Warning: zmin = zmax in NormalizePrimitiveCoordinates\n") ;
00434 #endif
00435 return ;
00436 }
00437
00438 loc = buffer;
00439 end = buffer + size;
00440
00441 while (loc < end)
00442 NormalizePrimitiveCoordinates(loc,MaxSize,zmin,zmax);
00443
00444 zmin = 0.0 ;
00445 zmax = MaxSize ;
00446 }
00447
00448 void ParserUtils::ComputeBufferBB(GLint size, GLfloat * buffer,
00449 GLfloat & xmin, GLfloat & xmax,
00450 GLfloat & ymin, GLfloat & ymax,
00451 GLfloat & zmin, GLfloat & zmax)
00452 {
00453 GLfloat *loc, *end;
00454
00455 loc = buffer;
00456 end = buffer + size;
00457
00458 while (loc < end)
00459 ComputePrimitiveBB(loc,xmin,xmax,ymin,ymax,zmin,zmax);
00460 }
00461
00462 typedef struct _DepthIndex {
00463 GLfloat *ptr;
00464 GLfloat depth;
00465 } DepthIndex;
00466
00467 const char *ParserUtils::nameOfToken(int token)
00468 {
00469 switch(token)
00470 {
00471 case GL_PASS_THROUGH_TOKEN: return "GL_PASS_THROUGH_TOKEN" ;
00472 case GL_POINT_TOKEN: return "GL_POINT_TOKEN" ;
00473 case GL_LINE_TOKEN: return "GL_LINE_TOKEN" ;
00474 case GL_POLYGON_TOKEN: return "GL_POLYGON_TOKEN" ;
00475 case GL_BITMAP_TOKEN: return "GL_BITMAP_TOKEN" ;
00476 case GL_DRAW_PIXEL_TOKEN: return "GL_DRAW_PIXEL_TOKEN" ;
00477 case GL_COPY_PIXEL_TOKEN: return "GL_COPY_PIXEL_TOKEN" ;
00478 case GL_LINE_RESET_TOKEN: return "GL_LINE_RESET_TOKEN" ;
00479 default:
00480 return "(Unidentified token)" ;
00481 }
00482 }
00483