ParserGL.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the VRender library.
3  Copyright (C) 2005 Cyril Soler (Cyril.Soler@imag.fr)
4  Version 1.0.0, released on June 27, 2005.
5 
6  http://artis.imag.fr/Members/Cyril.Soler/VRender
7 
8  VRender is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  VRender is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with VRender; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 
23 /****************************************************************************
24 
25  Copyright (C) 2002-2014 Gilles Debunne. All rights reserved.
26 
27  This file is part of the QGLViewer library version 2.6.3.
28 
29  http://www.libqglviewer.com - contact@libqglviewer.com
30 
31  This file may be used under the terms of the GNU General Public License
32  versions 2.0 or 3.0 as published by the Free Software Foundation and
33  appearing in the LICENSE file included in the packaging of this file.
34  In addition, as a special exception, Gilles Debunne gives you certain
35  additional rights, described in the file GPL_EXCEPTION in this package.
36 
37  libQGLViewer uses dual licensing. Commercial/proprietary software must
38  purchase a libQGLViewer Commercial License.
39 
40  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
41  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
42 
43 *****************************************************************************/
44 
45 #include <assert.h>
46 #include <math.h>
47 #include <stdio.h>
48 
49 #include "VRender.h"
50 #include "ParserGL.h"
51 
52 using namespace vrender ;
53 using namespace std;
54 
56 {
57  public:
58  static void NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin, GLfloat& zmax) ;
59 
60  static PtrPrimitive checkPoint(Point *& P);
61  static PtrPrimitive checkSegment(Segment *& P);
62  static PtrPrimitive checkPolygon(Polygone *& P);
63 
64  static void ComputeBufferBB(GLint size, GLfloat * buffer,
65  GLfloat & xmin, GLfloat & xmax,
66  GLfloat & ymin, GLfloat & ymax,
67  GLfloat & zmin, GLfloat & zmax) ;
68 
69  private:
70  static void print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer) ;
71  static void debug_printBuffer(GLint size, GLfloat *buffer) ;
72 
73  static void NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax) ;
74  static void ComputePrimitiveBB( GLfloat * & loc,
75  GLfloat & xmin,GLfloat & xmax,
76  GLfloat & ymin,GLfloat & ymax,
77  GLfloat & zmin,GLfloat & zmax);
78 
79  static const char *nameOfToken(int token);
80 
81  static const double EGALITY_EPS ;
82 };
83 
84 const double ParserUtils::EGALITY_EPS = 0.00001 ;
85 
86 void ParserGL::parseFeedbackBuffer( GLfloat *buffer,int size,
87  std::vector<PtrPrimitive>& primitive_tab,
88  VRenderParams& vparams)
89 {
90  int token;
91  int nvertices = 0 ;
92  nb_lines = 0 ;
93  nb_polys = 0 ;
94  nb_points = 0 ;
95  nb_degenerated_lines = 0 ;
96  nb_degenerated_polys = 0 ;
97  nb_degenerated_points = 0 ;
98 
99  // pre-treatment of coordinates so as to get something more consistent
100 
101  _xmin = FLT_MAX ;
102  _ymin = FLT_MAX ;
103  _zmin = FLT_MAX ;
104  _xmax = -FLT_MAX ;
105  _ymax = -FLT_MAX ;
106  _zmax = -FLT_MAX ;
107 
108  ParserUtils::ComputeBufferBB(size, buffer, _xmin,_xmax,_ymin,_ymax,_zmin,_zmax) ;
109 
110 #ifdef DEBUGEPSRENDER
111  printf("Buffer bounding box: %f %f %f %f %f %f\n",xmin,xmax,ymin,ymax,zmin,zmax) ;
112 #endif
113  float Zdepth = max(_ymax-_ymin,_xmax-_xmin) ;
114  ParserUtils::NormalizeBufferCoordinates(size,buffer,Zdepth,_zmin,_zmax) ;
115 
116  // now, read buffer
117  GLfloat *end = buffer + size;
118 
119  GLfloat *loc = buffer ;
120  int next_step = 0 ;
121  int N = size/200 + 1 ;
122 
123  while (loc < end)
124  {
125  token = int(0.5f + *loc) ;
126  loc++;
127 
128  if((end-loc)/N >= next_step)
129  vparams.progress((end-loc)/(float)size, QGLViewer::tr("Parsing feedback buffer.")), ++next_step ;
130 
131  switch (token)
132  {
133  case GL_LINE_TOKEN:
134  case GL_LINE_RESET_TOKEN:
135  {
137 
138  primitive_tab.push_back(ParserUtils::checkSegment(S)) ;
139 
140  if(S == NULL)
141  nb_degenerated_lines++ ;
142 
143  nb_lines++ ;
145  }
146  break;
147 
148  case GL_POLYGON_TOKEN:
149  {
150  nvertices = int(0.5f + *loc) ;
151  loc++;
152 
153  std::vector<Feedback3DColor> verts ;
154 
155  for(int i=0;i<nvertices;++i)
156  verts.push_back(Feedback3DColor(loc)),loc+=Feedback3DColor::sizeInBuffer() ;
157 
158  Polygone *P = new Polygone(verts) ;
159 
160  primitive_tab.push_back(ParserUtils::checkPolygon(P)) ;
161 
162  if(P == NULL)
163  nb_degenerated_polys++ ;
164 
165  nb_polys++ ;
166  }
167  break ;
168 
169  case GL_POINT_TOKEN:
170  {
171  Point *Pt = new Point(Feedback3DColor(loc)) ;
172 
173  primitive_tab.push_back(Pt);//ParserUtils::checkPoint(Pt)) ;
174 
175  if(Pt == NULL)
176  nb_degenerated_points++ ;
177 
178  nb_points++ ;
180  }
181  break;
182  default:
183  break;
184  }
185  }
186 
187 }
188 
189 // Traitement des cas degeneres. Renvoie false si le polygone est degenere.
190 // Traitement des cas degeneres. Renvoie false si le segment est degenere.
191 
193 {
194  return P ;
195 }
196 
198 {
199  if((P->vertex(0) - P->vertex(1)).infNorm() < EGALITY_EPS)
200  {
201  Point *pp = new Point(P->sommet3DColor(0)) ;
202  delete P ;
203  P = NULL ;
204 
205  return checkPoint(pp) ;
206  }
207 
208  return P ;
209 }
210 
212 {
213  if(P->nbVertices() != 3)
214  {
215  cout << "unexpected case: Polygon with " << P->nbVertices() << " vertices !" << endl ;
216  delete P ;
217  return NULL ;
218  }
219 
220  if(P->FlatFactor() < FLAT_POLYGON_EPS)
221  {
222  // On ne traite que le cas du triangle plat, vu qu'on est sur d'avoir un triangle
223 
224  size_t n = P->nbVertices() ;
225 
226  for(size_t i=0;i<n;++i)
227  if( (P->vertex(i) - P->vertex((i+1)%n)).norm() > EGALITY_EPS)
228  {
229  Segment *pp = new Segment(P->sommet3DColor((i+1)%n),P->sommet3DColor((i+2)%n)) ;
230  delete P ;
231  P = NULL ;
232 
233  return checkSegment(pp) ;
234  }
235 
236  Point *pp = new Point(P->sommet3DColor(0)) ;
237  delete P ;
238  P = NULL ;
239 
240  return checkPoint(pp) ;
241  }
242 
243  // No problem detected.
244 
245  return P ;
246 }
247 
248 
249 /* Write contents of one vertex to stdout. */
250 
251 void ParserUtils::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer)
252 {
253  printf(" ");
254  for (size_t i = 0; i < Feedback3DColor::sizeInBuffer(); i++)
255  {
256  printf("%4.2f ", buffer[size - (*count)]);
257  *count = *count - 1;
258  }
259  printf("\n");
260 }
261 
262 void ParserUtils::debug_printBuffer(GLint size, GLfloat * buffer)
263 {
264  GLint count;
265  int token, nvertices;
266 
267  count = size;
268  while (count) {
269  token = int(buffer[size - count]);
270  count--;
271  switch (token)
272  {
273  case GL_PASS_THROUGH_TOKEN:
274  printf("GL_PASS_THROUGH_TOKEN\n");
275  printf(" %4.2f\n", buffer[size - count]);
276  count--;
277  break;
278  case GL_POINT_TOKEN:
279  printf("GL_POINT_TOKEN\n");
280  print3DcolorVertex(size, &count, buffer);
281  break;
282  case GL_LINE_TOKEN:
283  printf("GL_LINE_TOKEN\n");
284  print3DcolorVertex(size, &count, buffer);
285  print3DcolorVertex(size, &count, buffer);
286  break;
287  case GL_LINE_RESET_TOKEN:
288  printf("GL_LINE_RESET_TOKEN\n");
289  print3DcolorVertex(size, &count, buffer);
290  print3DcolorVertex(size, &count, buffer);
291  break;
292  case GL_POLYGON_TOKEN:
293  printf("GL_POLYGON_TOKEN\n");
294  nvertices = int(buffer[size - count]) ;
295  count--;
296  for (; nvertices > 0; nvertices--)
297  print3DcolorVertex(size, &count, buffer);
298  }
299  }
300 }
301 
302 void ParserUtils::NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax)
303 {
304  int token;
305  int nvertices, i;
306 
307  token = int(*loc) ;
308  loc++;
309  int size = Feedback3DColor::sizeInBuffer() ;
310 
311  switch (token)
312  {
313  case GL_LINE_RESET_TOKEN:
314  case GL_LINE_TOKEN:
315  {
316  for (i = 0; i < 2; i++)
317  (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
318 
319  loc += 2*size; /* Each vertex element in the feedback buffer is size GLfloats. */
320  break;
321  }
322  case GL_POLYGON_TOKEN:
323  {
324  nvertices = int(*loc) ;
325  loc++;
326 
327  for (i = 0; i < nvertices; i++)
328  (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
329 
330  loc += nvertices * size; /* Each vertex element in the feedback buffer is size GLfloats. */
331  break;
332  }
333  case GL_POINT_TOKEN:
334  {
335  loc[2] = (loc[2] - zmin)/(zmax-zmin)*MaxSize ;
336 
337  loc += size; /* Each vertex element in the feedback buffer is size GLfloats. */
338  break;
339  }
340  default:
341  /* XXX Left as an excersie to the reader. */
342 #ifdef DEBUGEPSRENDER
343  printf("%s (%d) not handled yet. Sorry.\n", ParserUtils::nameOfToken(token), token);
344 #endif
345  ;
346  }
347 }
348 
349 void ParserUtils::ComputePrimitiveBB(GLfloat * & loc,GLfloat & xmin,GLfloat & xmax,GLfloat & ymin,GLfloat & ymax, GLfloat & zmin,GLfloat & zmax)
350 {
351  int token;
352  int nvertices, i;
353 
354  token = int(*loc) ;
355  loc++;
356  int size = Feedback3DColor::sizeInBuffer() ;
357 
358  switch (token)
359  {
360  case GL_LINE_RESET_TOKEN:
361  case GL_LINE_TOKEN:
362  {
363  for (i = 0; i < 2; i++)
364  {
365  Feedback3DColor f(loc+size*i) ;
366 
367  if(f.x() < xmin) xmin = GLfloat(f.x()) ;
368  if(f.y() < ymin) ymin = GLfloat(f.y()) ;
369  if(f.z() < zmin) zmin = GLfloat(f.z()) ;
370  if(f.x() > xmax) xmax = GLfloat(f.x()) ;
371  if(f.y() > ymax) ymax = GLfloat(f.y()) ;
372  if(f.z() > zmax) zmax = GLfloat(f.z()) ;
373  }
374 
375  loc += 2*size; /* Each vertex element in the feedback
376  buffer is size GLfloats. */
377  break;
378  }
379  case GL_POLYGON_TOKEN:
380  {
381  nvertices = int(*loc) ;
382  loc++;
383 
384  for (i = 0; i < nvertices; i++)
385  {
386  Feedback3DColor f(loc+size*i) ;
387 
388  if(f.x() < xmin) xmin = GLfloat(f.x()) ;
389  if(f.y() < ymin) ymin = GLfloat(f.y()) ;
390  if(f.z() < zmin) zmin = GLfloat(f.z()) ;
391  if(f.x() > xmax) xmax = GLfloat(f.x()) ;
392  if(f.y() > ymax) ymax = GLfloat(f.y()) ;
393  if(f.z() > zmax) zmax = GLfloat(f.z()) ;
394  }
395 
396  loc += nvertices * size; /* Each vertex element in the
397  feedback buffer is size GLfloats. */
398  break;
399  }
400  case GL_POINT_TOKEN:
401  {
402  Feedback3DColor f(loc) ;
403 
404  if(f.x() < xmin) xmin = GLfloat(f.x()) ;
405  if(f.y() < ymin) ymin = GLfloat(f.y()) ;
406  if(f.z() < zmin) zmin = GLfloat(f.z()) ;
407  if(f.x() > xmax) xmax = GLfloat(f.x()) ;
408  if(f.y() > ymax) ymax = GLfloat(f.y()) ;
409  if(f.z() > zmax) zmax = GLfloat(f.z()) ;
410 
411  loc += size; /* Each vertex element in the feedback
412  buffer is size GLfloats. */
413  break;
414  }
415  default:
416  /* XXX Left as an excersie to the reader. */
417 #ifdef DEBUGEPSRENDER
418  printf("Incomplete implementation. Unexpected token (%d).\n", token);
419 #endif
420  ;
421  }
422 }
423 
424 void ParserUtils::NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin,GLfloat& zmax)
425 {
426  GLfloat *loc, *end;
427 
428  if(zmax == zmin)
429  {
430 #ifdef DEBUGEPSRENDER
431  printf("Warning: zmin = zmax in NormalizePrimitiveCoordinates\n") ;
432 #endif
433  return ;
434  }
435 
436  loc = buffer;
437  end = buffer + size;
438 
439  while (loc < end)
440  NormalizePrimitiveCoordinates(loc,MaxSize,zmin,zmax);
441 
442  zmin = 0.0 ;
443  zmax = MaxSize ;
444 }
445 
446 void ParserUtils::ComputeBufferBB(GLint size, GLfloat * buffer,
447  GLfloat & xmin, GLfloat & xmax,
448  GLfloat & ymin, GLfloat & ymax,
449  GLfloat & zmin, GLfloat & zmax)
450 {
451  GLfloat *loc, *end;
452 
453  loc = buffer;
454  end = buffer + size;
455 
456  while (loc < end)
457  ComputePrimitiveBB(loc,xmin,xmax,ymin,ymax,zmin,zmax);
458 }
459 
460 typedef struct _DepthIndex {
461  GLfloat *ptr;
462  GLfloat depth;
463 } DepthIndex;
464 
465 const char *ParserUtils::nameOfToken(int token)
466 {
467  switch(token)
468  {
469  case GL_PASS_THROUGH_TOKEN: return "GL_PASS_THROUGH_TOKEN" ;
470  case GL_POINT_TOKEN: return "GL_POINT_TOKEN" ;
471  case GL_LINE_TOKEN: return "GL_LINE_TOKEN" ;
472  case GL_POLYGON_TOKEN: return "GL_POLYGON_TOKEN" ;
473  case GL_BITMAP_TOKEN: return "GL_BITMAP_TOKEN" ;
474  case GL_DRAW_PIXEL_TOKEN: return "GL_DRAW_PIXEL_TOKEN" ;
475  case GL_COPY_PIXEL_TOKEN: return "GL_COPY_PIXEL_TOKEN" ;
476  case GL_LINE_RESET_TOKEN: return "GL_LINE_RESET_TOKEN" ;
477  default:
478  return "(Unidentified token)" ;
479  }
480 }
481 
#define FLT_MAX
Definition: Vector3.h:51
virtual const Vector3 & vertex(size_t) const
Definition: Primitive.cpp:79
static const double EGALITY_EPS
Definition: ParserGL.cpp:81
FLOAT x() const
Definition: Primitive.h:81
static size_t sizeInBuffer()
Definition: Primitive.h:103
static PtrPrimitive checkPolygon(Polygone *&P)
Definition: ParserGL.cpp:211
static PtrPrimitive checkSegment(Segment *&P)
Definition: ParserGL.cpp:197
static const char * nameOfToken(int token)
Definition: ParserGL.cpp:465
const float FLAT_POLYGON_EPS
Definition: Types.h:71
static void ComputeBufferBB(GLint size, GLfloat *buffer, GLfloat &xmin, GLfloat &xmax, GLfloat &ymin, GLfloat &ymax, GLfloat &zmin, GLfloat &zmax)
Definition: ParserGL.cpp:446
static void NormalizePrimitiveCoordinates(GLfloat *&loc, GLfloat MaxSize, GLfloat zmin, GLfloat zmax)
Definition: ParserGL.cpp:302
static void NormalizeBufferCoordinates(GLint size, GLfloat *buffer, GLfloat MaxSize, GLfloat &zmin, GLfloat &zmax)
Definition: ParserGL.cpp:424
void progress(float, const QString &)
Definition: VRender.cpp:255
double EGALITY_EPS
virtual const Feedback3DColor & sommet3DColor(size_t) const
Definition: Primitive.cpp:92
static void debug_printBuffer(GLint size, GLfloat *buffer)
Definition: ParserGL.cpp:262
virtual size_t nbVertices() const
Definition: Primitive.h:196
static void ComputePrimitiveBB(GLfloat *&loc, GLfloat &xmin, GLfloat &xmax, GLfloat &ymin, GLfloat &ymax, GLfloat &zmin, GLfloat &zmax)
Definition: ParserGL.cpp:349
void parseFeedbackBuffer(GLfloat *, int size, std::vector< PtrPrimitive > &primitive_tab, VRenderParams &vparams)
Definition: ParserGL.cpp:86
static PtrPrimitive checkPoint(Point *&P)
Definition: ParserGL.cpp:192
FLOAT z() const
Definition: Primitive.h:83
FLOAT y() const
Definition: Primitive.h:82
static void print3DcolorVertex(GLint size, GLint *count, GLfloat *buffer)
Definition: ParserGL.cpp:251
GLfloat depth
Definition: ParserGL.cpp:462
FLOAT FlatFactor() const
Definition: Primitive.h:202
GLfloat * ptr
Definition: ParserGL.cpp:461
virtual const Feedback3DColor & sommet3DColor(size_t i) const
Definition: Primitive.cpp:69
virtual const Vector3 & vertex(size_t) const
Definition: Primitive.cpp:97
struct _DepthIndex DepthIndex


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Wed Jun 5 2019 19:26:39