0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one...
[occt.git] / src / OpenGl / OpenGl_Mesh.cxx
1 // File:      OpenGl_Mesh.cxx
2 // Created:   13 July 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #define OCC749          /* SAV 19/09/02 added processing of colored vertices */
7 #define OCC7824         /* ASL 26/01/05 transparency of polygon with colors assigned to vertices */
8
9 /*----------------------------------------------------------------------*/
10 /*
11 * Includes
12 */ 
13
14 #include <OpenGl_GlCore11.hxx>
15
16 #include <OpenGl_Mesh.hxx>
17
18 #include <OpenGl_telem_util.hxx>
19 #include <OpenGl_TextureBox.hxx>
20
21 #include <OpenGl_AspectFace.hxx>
22 #include <OpenGl_Structure.hxx>
23
24 #include <float.h>
25
26 static long s_Rand = 1L;
27 # define OPENGL_RAND() ( ( unsigned )( s_Rand = s_Rand * 214013L + 2531011L ) )
28
29 /*----------------------------------------------------------------------*/
30 /*
31 * Prototypes
32 */ 
33
34 typedef TEL_INDEXPOLY_DATA* tel_indexpoly_data;
35
36 void set_drawable_items ( GLboolean*, int, const float );
37
38 /*----------------------------------------------------------------------*/
39
40 void OpenGl_Mesh::draw_indexpoly (const Tint front_lighting_model,
41                                  const Aspect_InteriorStyle interior_style,
42                                  const TEL_COLOUR *edge_colour,
43                                  const OPENGL_SURF_PROP *prop,
44                                  const Handle(OpenGl_Workspace) &AWorkspace) const
45 {
46   Tint i, j, k, a, newList = 0;
47   Tint  lighting_model;
48
49   /* Following pointers have been provided for performance improvement */
50   Tint       *ind;
51   tel_point  pfn, pvn, pv;
52   tel_colour pvc, pfc;
53   tel_texture_coord pvt;
54
55   ind = myData.indices;
56   pfn = myData.fnormals;
57   pvn = myData.vnormals;
58   pvc = myData.vcolours;
59   pfc = myData.fcolours;
60   pv  = myData.vertices;
61   pvt = myData.vtexturecoord;
62   if ( AWorkspace->DegenerateModel < 2 && interior_style != Aspect_IS_EMPTY )
63   {      
64     if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
65     {
66       pvc = 0;
67       pfc = 0;
68     }
69
70     if ( interior_style == Aspect_IS_HIDDENLINE)
71     {
72       pvc = 0;
73       pfc = 0;
74     }
75
76     if ( front_lighting_model )
77       glEnable(GL_LIGHTING);
78     else
79       glDisable(GL_LIGHTING);
80
81     lighting_model = front_lighting_model;
82
83     if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 )
84       goto doDraw; /* Disable object display list out of animation */
85     /*  window's context and bitmap's one    */
86
87     if ( myDS->model != lighting_model || !myDS->list ||
88          myDS->model == -1 || ( AWorkspace->DegenerateModel && myDS->skipRatio != AWorkspace->SkipRatio ))
89     {
90         myDS->skipRatio = AWorkspace->SkipRatio;
91         myDS->model     = lighting_model;
92         myDS->degMode   = AWorkspace->DegenerateModel;
93         if ( AWorkspace->SkipRatio <= 0.f ) {
94           if ( !myDS->list ) myDS->list = glGenLists ( 1 );
95
96           glNewList ( myDS->list, GL_COMPILE_AND_EXECUTE );
97           newList = 1;
98 doDraw:
99           if ( !lighting_model )
100           {
101             if ( myData.num_bounds == 3 )
102               glBegin ( GL_TRIANGLES );
103             else if ( myData.num_bounds == 4 )
104               glBegin ( GL_QUADS );
105             else glBegin ( GL_POLYGON );
106
107             if ( pvc )
108             {
109               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i )
110               {
111                 a = j + myData.num_bounds;
112                 for ( ; j < a; ++j )
113                 {
114                   glColor3fv  ( pvc[  ind[ j ]  ].rgb  );
115                   glVertex3fv ( pv[   ind[ j ]  ].xyz  );
116                 }
117               }
118             }
119             else if ( pfc )
120             {
121               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i )
122               {
123                 a = j + myData.num_bounds;
124                 glColor3fv ( pfc[ i ].rgb );
125                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
126               }
127             }
128             else
129             {
130               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i )
131               {
132                 a = j + myData.num_bounds;
133                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
134               }
135             }
136             glEnd ();
137           }
138           else
139           {
140             /* lighting_model != TelLModelNone */
141             if ( myData.num_bounds == 3 )
142               glBegin ( GL_TRIANGLES );
143             else if ( myData.num_bounds == 4 )
144               glBegin ( GL_QUADS );
145             else glBegin ( GL_POLYGON );
146
147 #ifdef OCC749
148             for ( i = a = 0; i < myData.num_facets; ++i ) {
149               j = a; a += myData.num_bounds;
150               if( pfn ) glNormal3fv ( pfn[ i ].xyz );
151               if( pfc && !prop->isphysic ) {
152                 GLfloat diff[4], ambi[4], emsv[4], r, g, b;
153
154                 ambi[3] = diff[3] = emsv[3] = prop->trans;
155
156                 r = pfc[ i ].rgb[0];  g = pfc[ i ].rgb[1];  b = pfc[ i ].rgb[2];
157
158                 if( prop->color_mask & OPENGL_AMBIENT_MASK ) {
159                   ambi[0] = prop->amb * r;
160                   ambi[1] = prop->amb * g;
161                   ambi[2] = prop->amb * b;
162                   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambi);
163                 }
164                 if( prop->color_mask & OPENGL_DIFFUSE_MASK ) {
165                   diff[0] = prop->diff * r;
166                   diff[1] = prop->diff * g;
167                   diff[2] = prop->diff * b;
168                   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
169                 }
170                 if( prop->color_mask & OPENGL_EMISSIVE_MASK ) {
171                   emsv[0] = prop->emsv * r;
172                   emsv[1] = prop->emsv * g;
173                   emsv[2] = prop->emsv * b;
174                   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emsv);
175                 }
176               }
177               for ( ; j < a; ++j ) {
178                 k = ind[ j ];
179                 if( pvn ) glNormal3fv ( pvn[ k ].xyz );
180                 if( pvc && !prop->isphysic ) {
181                   GLfloat diff[4], ambi[4], emsv[4], r, g, b;
182
183                   ambi[3] = diff[3] = emsv[3] = prop->trans;
184
185                   r = pvc[ k ].rgb[0];  g = pvc[ k ].rgb[1];  b = pvc[ k ].rgb[2];
186
187                   if( prop->color_mask & OPENGL_AMBIENT_MASK ) {
188                     ambi[0] = prop->amb * r;
189                     ambi[1] = prop->amb * g;
190                     ambi[2] = prop->amb * b;
191                     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambi);
192                   }
193                   if( prop->color_mask & OPENGL_DIFFUSE_MASK ) {
194                     diff[0] = prop->diff * r;
195                     diff[1] = prop->diff * g;
196                     diff[2] = prop->diff * b;
197                     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
198                   }
199                   if( prop->color_mask & OPENGL_EMISSIVE_MASK ) {
200                     emsv[0] = prop->emsv * r;
201                     emsv[1] = prop->emsv * g;
202                     emsv[2] = prop->emsv * b;
203                     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emsv);
204                   }
205                 }
206                 if( pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0 ) glTexCoord2fv ( pvt[ k ].xy  );
207                 glVertex3fv ( pv[ k ].xyz );
208               }  /* end for ( j . . . ) */
209             }  /* end for ( i . . . ) */
210             glEnd ();  
211 #else
212             if ( pvn ) {
213               if ( pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0 )
214                 for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
215                   a = j + myData.num_bounds;
216                   for ( ; j < a; ++j ) {
217                     glNormal3fv   ( pvn[  ind[ j ]  ].xyz );
218                     glTexCoord2fv ( pvt[  ind[ j ]  ].xy  );
219                     glVertex3fv   ( pv[   ind[ j ]  ].xyz );
220                   }  /* end for ( j . . . ) */
221                 }  /* end for ( i . . . ) */
222               else
223                 for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
224                   a = j + myData.num_bounds;
225                   for ( ; j < a; ++j ) {
226                     glNormal3fv ( pvn[  ind[ j ]  ].xyz  );
227                     glVertex3fv ( pv[   ind[ j ]  ].xyz  );
228                   }  /* end for ( j . . . ) */
229                 }  /* end for ( i . . . ) */
230             } else { /* !pvn */
231               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
232                 a = j + myData.num_bounds;
233                 glNormal3fv ( pfn[ i ].xyz );
234                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
235               }  /* end for */
236             }  /* end else */
237             glEnd ();  
238 #endif /* OCC749 */
239
240           }  /* end else */
241         } else if ( AWorkspace->SkipRatio < 1.f ) {
242           if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
243           glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
244           newList = 1;
245           set_drawable_items ( myDS->bDraw, myData.num_facets, AWorkspace->SkipRatio );
246           if ( !lighting_model ) {
247             if ( myData.num_bounds == 3 )
248               glBegin ( GL_TRIANGLES );
249             else if ( myData.num_bounds == 4 )
250               glBegin ( GL_QUADS );
251             else glBegin ( GL_POLYGON );
252
253             if ( pvc ) {
254               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
255                 a = j + myData.num_bounds;
256                 if ( myDS->bDraw[ i ] )
257                   for ( ; j < a; ++j ) {
258                     glColor3fv  ( pvc[  ind[ j ]  ].rgb  );
259                     glVertex3fv ( pv[   ind[ j ]  ].xyz  );
260                   }  /* end for ( j . . . ) */
261                 else j = a;
262               }  /* end for ( i . . . ) */
263             } else if ( pfc ) {
264               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
265                 a = j + myData.num_bounds;
266                 if ( myDS->bDraw[ i ] ) {
267                   glColor3fv ( pfc[ i ].rgb );
268                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
269                 } else j = a;
270               }  /* end for */
271             } else {
272               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
273                 a = j + myData.num_bounds;
274                 if ( myDS->bDraw[ i ] )
275                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
276                 else j = a;
277               }  /* end for */
278             }  /* end else */
279             glEnd ();
280           } else {   /* lighting_model != TelLModelNone */
281             if ( myData.num_bounds == 3 )
282               glBegin ( GL_TRIANGLES );
283             else if ( myData.num_bounds == 4 )
284               glBegin ( GL_QUADS );
285             else glBegin ( GL_POLYGON );
286
287             if ( pvn ) {
288               if ( pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0 )
289                 for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
290                   a = j + myData.num_bounds;
291                   if ( myDS->bDraw[ i ] )
292                     for ( ; j < a; ++j ) {
293                       glNormal3fv   ( pvn[  ind[ j ]  ].xyz );
294                       glTexCoord2fv ( pvt[  ind[ j ]  ].xy  );
295                       glVertex3fv   ( pv[   ind[ j ]  ].xyz );
296                     }  /* end for ( j . . . ) */
297                   else j = a;
298                 }  /* end for ( i . . . ) */
299               else
300                 for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
301                   a = j + myData.num_bounds;
302                   if ( myDS->bDraw[ i ] )
303                     for ( ; j < a; ++j ) {
304                       glNormal3fv ( pvn[  ind[ j ]  ].xyz  );
305                       glVertex3fv ( pv[   ind[ j ]  ].xyz  );
306                     }  /* end for ( j . . . ) */
307                   else j = a;
308                 }  /* end for ( i . . . ) */
309             } else {  /* !pvn */
310               for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
311                 a = j + myData.num_bounds;
312                 if ( myDS->bDraw[ i ] ) {
313                   glNormal3fv ( pfn[ i ].xyz );
314                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
315                 } else j = a;
316               }  /* end for */
317             }  /* end else */
318             glEnd ();  
319           }  /* end else */
320         } else {
321           if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
322           glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
323           newList = 1;
324         }  /* end else */
325         if ( newList ) glEndList ();
326         if ( AWorkspace->DegenerateModel ) return;
327       } else {
328         glCallList ( AWorkspace->SkipRatio <= 0.f ? myDS->list : myDS->dlist );
329         if ( AWorkspace->DegenerateModel ) return;
330       }  /* end else */
331   }
332
333   i = 0;
334
335   switch ( AWorkspace->DegenerateModel )
336   {
337     default:
338       break;
339
340     case 2:  /* XXX_TDM_WIREFRAME */
341       i = 1;
342       break;
343
344     case 3:  /* XXX_TDM_MARKER */
345       draw_degenerates_as_points ( AWorkspace->SkipRatio );
346       return;
347
348     case 4:  /* XXX_TDM_BBOX */
349       draw_degenerates_as_bboxs ();
350       return;
351   }
352
353   draw_edges ( edge_colour, interior_style, i, AWorkspace );
354 }
355
356 /*----------------------------------------------------------------------*/
357
358 void OpenGl_Mesh::draw_edges (const TEL_COLOUR *edge_colour, const Aspect_InteriorStyle interior_style,
359                              Tint forceDraw, const Handle(OpenGl_Workspace) &AWorkspace) const
360 {
361   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
362
363   if ( interior_style != Aspect_IS_HIDDENLINE && !forceDraw && aspect_face->Context().Edge == TOff )
364     return;
365
366   glDisable(GL_LIGHTING);
367   const GLboolean texture_on = IsTextureEnabled();
368   if (texture_on) DisableTexture();
369
370   // Setup line aspect
371   const OpenGl_AspectLine *aspect_line_old = AWorkspace->SetAspectLine( aspect_face->AspectEdge() );
372   AWorkspace->AspectLine( Standard_True );
373
374   tel_point pv = myData.vertices;
375   Tint *ind = myData.indices;
376   Tint *vis = myData.edge_vis;
377
378   Tint i, j, a, newList = 0;
379
380   if ( !forceDraw ) {
381
382     glColor3fv    ( edge_colour -> rgb         );
383     glPushAttrib  ( GL_POLYGON_BIT             );
384     glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
385
386     for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
387
388       a = j + myData.num_bounds;
389
390       glBegin ( GL_POLYGON );
391
392       for ( ; j < a; ++j ) {
393
394         glEdgeFlag (   ( GLboolean )( vis[ j ] == 1 ? GL_TRUE : GL_FALSE )  );
395         glVertex3fv ( pv[  ind[ j ]  ].xyz );
396
397       }  /* end for */
398
399       glEnd();
400
401       glEdgeFlag ( GL_TRUE );
402
403     }  /* end for */
404
405     glPopAttrib ();
406
407   } else {
408
409     if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 ) 
410       goto doDraw; /* Disable object display list out of animation */
411
412     if ( myDS->degMode != 2 || myDS->skipRatio != AWorkspace->SkipRatio || !myDS->dlist ) {
413
414       if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
415
416       myDS->degMode   = 2;
417       myDS->skipRatio = AWorkspace->SkipRatio;
418       glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
419       newList = 1;
420
421 doDraw:
422       glPushAttrib ( GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT );
423
424       glEdgeFlag    ( GL_TRUE                    );
425       glDisable     ( GL_DEPTH_TEST              );
426       glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
427
428       if ( AWorkspace->SkipRatio <= 0.f )
429
430         for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
431
432           a = j + myData.num_bounds;
433
434           glBegin ( GL_POLYGON );
435
436           for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
437
438           glEnd();
439
440         }  /* end for */
441
442       else if ( AWorkspace->SkipRatio < 1.f ) {
443
444         set_drawable_items ( myDS->bDraw, myData.num_facets, AWorkspace->SkipRatio );
445
446         for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
447
448           a = j + myData.num_bounds;
449
450           if ( myDS->bDraw[ i ] ) {
451
452             glBegin ( GL_POLYGON );
453
454             for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
455
456             glEnd();
457
458           } else j = a;
459
460         }  /* end for */
461
462       }  /* end if */
463
464       glPopAttrib ();
465       if ( newList ) glEndList ();
466
467     } else glCallList ( myDS->dlist );
468
469   }  /* end else */
470
471   // Restore line context
472   AWorkspace->SetAspectLine( aspect_line_old );
473
474   if (texture_on) EnableTexture();
475 }
476
477 /*----------------------------------------------------------------------*/
478
479 void OpenGl_Mesh::draw_degenerates_as_points (const float aSkipRatio) const
480 {
481   Tint*      ind, *vis;
482   Tint       i, j, n, a, newList = 0;
483   GLfloat    pt[ 3 ];
484   tel_point  pv;
485
486   pv  = myData.vertices;
487   ind = myData.indices;
488   vis = myData.edge_vis;
489
490   glDisable(GL_LIGHTING);
491
492   if ( myDS->degMode != 3 || myDS->skipRatio != aSkipRatio || !myDS->dlist ) {
493
494     if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
495
496     myDS->degMode   = 3;
497     myDS->skipRatio = aSkipRatio;
498     glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
499     newList = 1;
500
501     if ( aSkipRatio <= 0.f ) {
502
503       glBegin ( GL_POINTS );
504
505       for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
506
507         n = myData.num_bounds;
508         a = j + n;
509
510         for ( pt [ 0 ] = pt[ 1 ] = pt[ 2 ] = 0.; j < a; ++j ) {
511
512           pt[ 0 ] += pv[  ind[ j ]  ].xyz[ 0 ];
513           pt[ 1 ] += pv[  ind[ j ]  ].xyz[ 1 ];
514           pt[ 2 ] += pv[  ind[ j ]  ].xyz[ 2 ];
515
516         }  /* end for ( j ) */
517
518         pt[ 0 ] /= n;
519         pt[ 1 ] /= n;
520         pt[ 2 ] /= n;
521
522         glVertex3fv ( pt );
523
524       }  /* end for ( i ) */
525
526       glEnd ();
527
528     } else if ( aSkipRatio < 1.f ) {
529
530       set_drawable_items ( myDS->bDraw, myData.num_facets, aSkipRatio );
531
532       glBegin ( GL_POINTS );
533
534       for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
535
536         n = myData.num_bounds;
537         a = j + n;
538
539         if ( myDS->bDraw[ i ] ) {
540
541           for ( pt [ 0 ] = pt[ 1 ] = pt[ 2 ] = 0.; j < a; ++j ) {
542
543             pt[ 0 ] += pv[  ind[ j ]  ].xyz[ 0 ];
544             pt[ 1 ] += pv[  ind[ j ]  ].xyz[ 1 ];
545             pt[ 2 ] += pv[  ind[ j ]  ].xyz[ 2 ];
546
547           }  /* end for ( j ) */
548
549           pt[ 0 ] /= n;
550           pt[ 1 ] /= n;
551           pt[ 2 ] /= n;
552
553           glVertex3fv ( pt );
554
555         } else j = a;
556
557       }  /* end for ( i ) */
558
559       glEnd ();
560
561     }  /* end if */
562
563     glEndList ();
564
565   } else glCallList ( myDS->dlist );
566
567 }
568
569 void OpenGl_Mesh::draw_degenerates_as_bboxs () const
570 {
571   Tint*     ind, *vis;
572   Tint      i, j, n, a, newList = 0;
573   GLfloat   minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
574   GLfloat   maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
575   tel_point pv;
576
577   pv  = myData.vertices;
578   ind = myData.indices;
579   vis = myData.edge_vis;
580
581   glDisable(GL_LIGHTING);
582
583   if ( myDS->degMode != 4 || !myDS->dlist ) {
584
585     if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
586
587     myDS->degMode = 4;
588
589     glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
590     newList = 1;
591
592     for ( i = 0, j = 0, a = 0; i < myData.num_facets; ++i ) {
593
594       n = myData.num_bounds;
595       a = j + n;
596
597       for ( ; j < a; ++j ) {
598
599         if ( pv[  ind[ j ]  ].xyz[ 0 ] < minp[ 0 ] )
600           minp[ 0 ] = pv[  ind[ j ]  ].xyz[ 0 ] ;
601         if ( pv[  ind[ j ]  ].xyz[ 1 ] < minp[ 1 ] )
602           minp[ 1 ] = pv[  ind[ j ]  ].xyz[ 1 ] ;
603         if ( pv[  ind[ j ]  ].xyz[ 2 ] < minp[ 2 ] )
604           minp[ 2 ] = pv[  ind[ j ]  ].xyz[ 2 ] ;
605
606         if ( pv[  ind[ j ]  ].xyz[ 0 ] > maxp[ 0 ] )
607           maxp[ 0 ] = pv[  ind[ j ]  ].xyz[ 0 ] ;
608         if ( pv[  ind[ j ]  ].xyz[ 1 ] > maxp[ 1 ] )
609           maxp[ 1 ] = pv[  ind[ j ]  ].xyz[ 1 ] ;
610         if ( pv[  ind[ j ]  ].xyz[ 2 ] > maxp[ 2 ] )
611           maxp[ 2 ] = pv[  ind[ j ]  ].xyz[ 2 ] ;
612
613       }  /* end for ( j ) */
614
615     }  /* end for ( i ) */
616
617     /* OCC11904 -- Temporarily disable environment mapping */
618     glPushAttrib(GL_ENABLE_BIT);
619     glDisable(GL_TEXTURE_1D);
620     glDisable(GL_TEXTURE_2D);
621
622     glBegin ( GL_LINE_STRIP );
623
624     glVertex3fv ( minp );
625     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
626     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
627     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
628     glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
629
630     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
631     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
632     glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
633     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
634     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
635
636     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
637     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
638     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
639     glVertex3fv ( maxp );
640     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
641     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
642
643     glEnd();
644     glPopAttrib();
645     glEndList ();
646
647   } else glCallList ( myDS->dlist );
648 }
649
650 /*----------------------------------------------------------------------*/
651
652 void set_drawable_items ( GLboolean* pbDraw, int n, const float aSkipRatio )
653 {
654   memset (  pbDraw, 0, sizeof ( GLboolean ) * n  );
655
656   int i = ( int )(  ( 1.0F - aSkipRatio ) * n  );
657
658   while ( i-- ) pbDraw[ OPENGL_RAND() % n ] = 1;
659 }
660
661 /*----------------------------------------------------------------------*/
662
663 OpenGl_Mesh::OpenGl_Mesh (const Graphic3d_Array1OfVertex& AListVertex, const Aspect_Array1OfEdge& AListEdge)
664 {
665   const Standard_Integer nv = AListVertex.Length();
666
667   // Dynamic allocation
668   TEL_POINT *points = new TEL_POINT[nv];
669   memcpy( points, &AListVertex(AListVertex.Lower()), nv*sizeof(TEL_POINT) );
670
671   Init (nv,points,NULL,NULL,NULL,AListEdge,3);
672 }
673
674 /*----------------------------------------------------------------------*/
675
676 OpenGl_Mesh::OpenGl_Mesh (const Graphic3d_Array1OfVertexN& AListVertex, const Aspect_Array1OfEdge& AListEdge)
677 {
678   const Standard_Integer nv = AListVertex.Length ();
679
680   // Dynamic allocation
681   TEL_POINT *points = new TEL_POINT[nv];
682   TEL_POINT *normals = new TEL_POINT[nv];
683
684   Standard_Integer i = 0, j = AListVertex.Lower();
685   Standard_Real X, Y, Z;
686   for ( ; i < nv; i++, j++)
687   {
688     AListVertex(j).Coord(X, Y, Z);
689     points[i].xyz[0] = float (X);
690     points[i].xyz[1] = float (Y);
691     points[i].xyz[2] = float (Z);
692     AListVertex(j).Normal(X, Y, Z);
693     normals[i].xyz[0] = float (X);
694     normals[i].xyz[1] = float (Y);
695     normals[i].xyz[2] = float (Z);
696   }
697
698   Init (nv,points,normals,NULL,NULL,AListEdge,3);
699 }
700
701 /*----------------------------------------------------------------------*/
702
703 OpenGl_Mesh::OpenGl_Mesh (const Graphic3d_Array1OfVertexC& AListVertex, const Aspect_Array1OfEdge& AListEdge)
704 {
705   const Standard_Integer nv = AListVertex.Length ();
706
707   // Dynamic allocation
708   TEL_POINT *points = new TEL_POINT[nv];
709   TEL_COLOUR *colors = new TEL_COLOUR[nv];
710
711   Standard_Integer i = 0, j = AListVertex.Lower();
712   Standard_Real X, Y, Z;
713   for ( ; i < nv; i++, j++)
714   {
715     AListVertex(j).Coord(X, Y, Z);
716     points[i].xyz[0] = float (X);
717     points[i].xyz[1] = float (Y);
718     points[i].xyz[2] = float (Z);
719     AListVertex(j).Color().Values (X, Y, Z, Quantity_TOC_RGB);
720     colors[i].rgb[0] = float (X);
721     colors[i].rgb[1] = float (Y);
722     colors[i].rgb[2] = float (Z);
723     colors[i].rgb[3] = 1.0F;
724   }
725
726   Init (nv,points,NULL,colors,NULL,AListEdge,3);
727 }
728
729 /*----------------------------------------------------------------------*/
730
731 OpenGl_Mesh::OpenGl_Mesh (const Graphic3d_Array1OfVertexNC& AListVertex, const Aspect_Array1OfEdge& AListEdge)
732 {
733   const Standard_Integer nv = AListVertex.Length ();
734
735   // Dynamic allocation
736   TEL_POINT *points = new TEL_POINT[nv];
737   TEL_POINT *normals = new TEL_POINT[nv];
738   TEL_COLOUR *colors = new TEL_COLOUR[nv];
739
740   Standard_Integer i = 0, j = AListVertex.Lower();
741   Standard_Real X, Y, Z;
742   for ( ; i < nv; i++, j++)
743   {
744     AListVertex(j).Coord(X, Y, Z);
745     points[i].xyz[0] = float (X);
746     points[i].xyz[1] = float (Y);
747     points[i].xyz[2] = float (Z);
748     AListVertex(j).Normal(X, Y, Z);
749     normals[i].xyz[0] = float (X);
750     normals[i].xyz[1] = float (Y);
751     normals[i].xyz[2] = float (Z);
752     AListVertex(j).Color().Values (X, Y, Z, Quantity_TOC_RGB);
753     colors[i].rgb[0] = float (X);
754     colors[i].rgb[1] = float (Y);
755     colors[i].rgb[2] = float (Z);
756     colors[i].rgb[3] = 1.0F;
757   }
758
759   Init (nv,points,normals,colors,NULL,AListEdge,3);
760 }
761
762 /*----------------------------------------------------------------------*/
763
764 OpenGl_Mesh::OpenGl_Mesh (const Graphic3d_Array1OfVertexNT& AListVertex, const Aspect_Array1OfEdge& AListEdge)
765 {
766   const Standard_Integer nv = AListVertex.Length ();
767
768   // Dynamic allocation
769   TEL_POINT *points = new TEL_POINT[nv];
770   TEL_POINT *normals = new TEL_POINT[nv];
771   TEL_TEXTURE_COORD *tcoords = new TEL_TEXTURE_COORD[nv];
772
773   Standard_Integer i = 0, j = AListVertex.Lower();
774   Standard_Real X, Y, Z;
775   for ( ; i < nv; i++, j++)
776   {
777     AListVertex(j).Coord(X, Y, Z);
778     points[i].xyz[0] = float (X);
779     points[i].xyz[1] = float (Y);
780     points[i].xyz[2] = float (Z);
781     AListVertex(j).Normal(X, Y, Z);
782     normals[i].xyz[0] = float (X);
783     normals[i].xyz[1] = float (Y);
784     normals[i].xyz[2] = float (Z);
785     AListVertex(j).TextureCoordinate(X, Y);
786     tcoords[i].xy[0] = float(X);
787     tcoords[i].xy[1] = float(Y);
788   }
789
790   Init (nv,points,normals,NULL,tcoords,AListEdge,3);
791 }
792
793 /*----------------------------------------------------------------------*/
794
795 void OpenGl_Mesh::Init (const Tint ANbVertices, tel_point AVertices,
796                        tel_point AVNormals, tel_colour AVColors, tel_texture_coord ATCoords,
797                        const Aspect_Array1OfEdge& AListEdge, const Tint ANbBounds)
798 {
799   // Get number of bounds in a facet
800   myData.num_bounds = ANbBounds;
801
802   // Get number of vertices
803   myData.num_vertices = ANbVertices;
804
805   // Get vertices
806   myData.vertices = AVertices;
807
808   // Get number of edges
809   const Standard_Integer nb_edges = AListEdge.Length ();
810
811   myData.indices = new Tint[nb_edges];
812   myData.edge_vis = new Tint[nb_edges];
813
814   const Standard_Integer LowerE = AListEdge.Lower ();
815   const Standard_Integer UpperE = AListEdge.Upper ();
816
817   // Loop on edges
818   Standard_Integer i, j;
819   for (j=0, i=LowerE; i<=UpperE; i++, j++)
820   {
821     myData.indices[j] = AListEdge(i).FirstIndex() - LowerE; //LastIndex unused
822     myData.edge_vis[j]  = AListEdge(i).Type() ? TOff : TOn;
823   }
824
825   // Get number of facets
826   myData.num_facets = nb_edges / ANbBounds;
827
828   myData.vnormals = AVNormals;
829   if (AVNormals)
830   {
831     myData.vertex_flag = TEL_VT_NORMAL;
832     for( i = 0; i < ANbVertices; i++ )
833       vecnrm( myData.vnormals[i].xyz );
834   }
835   else
836   {
837     myData.vertex_flag = TEL_VT_NONE;
838   }
839
840   myData.vcolours = AVColors;
841   myData.vtexturecoord = ATCoords;
842
843   myData.facet_flag = TEL_FA_NONE;
844   myData.fnormals = new TEL_POINT[myData.num_facets];
845   for( i = 0, j = 0; i < myData.num_facets; i++ )
846   {
847     TelGetPolygonNormal( myData.vertices, &myData.indices[j], myData.num_bounds, myData.fnormals[i].xyz );
848     j += myData.num_bounds;
849   }
850
851   myData.fcolours = NULL;
852
853   myDS = new DS_INTERNAL();
854   myDS->list      =  0;
855   myDS->dlist     =  0;
856   myDS->degMode   =  0;
857   myDS->model     = -1;
858   myDS->skipRatio =  0.0F;
859   myDS->bDraw = new unsigned char[myData.num_facets];
860 }
861
862 /*----------------------------------------------------------------------*/
863
864 OpenGl_Mesh::~OpenGl_Mesh ()
865 {
866   if( myData.edge_vis )
867     delete[] myData.edge_vis;
868   if( myData.indices )
869     delete[] myData.indices;
870   if( myData.fcolours )
871     delete[] myData.fcolours;
872   if( myData.fnormals )
873     delete[] myData.fnormals;
874   if( myData.vertices )
875     delete[] myData.vertices;
876   if( myData.vcolours )
877     delete[] myData.vcolours;
878   if( myData.vnormals )
879     delete[] myData.vnormals;
880   if( myData.vtexturecoord )
881     delete[] myData.vtexturecoord;
882
883   if ( myDS )
884   {
885     if ( GET_GL_CONTEXT() != NULL )
886     {
887       if ( myDS->list ) glDeleteLists ( myDS->list, 1 );
888       if ( myDS->dlist ) glDeleteLists ( myDS->dlist, 1 );
889     }
890
891     if ( myDS->bDraw )
892       delete[] myDS->bDraw;
893
894         delete myDS;
895   }
896 }
897
898 /*----------------------------------------------------------------------*/
899
900 void OpenGl_Mesh::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
901 {
902   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
903
904   Tint front_lighting_model = aspect_face->Context().IntFront.color_mask;
905   const TEL_COLOUR *interior_colour = &aspect_face->Context().IntFront.matcol;
906   const TEL_COLOUR *edge_colour = &aspect_face->AspectEdge()->Color();
907
908   // Use highlight colors
909   if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
910   {                         
911     edge_colour = interior_colour = AWorkspace->HighlightColor;
912     front_lighting_model = 0;
913   }
914
915   glColor3fv( interior_colour->rgb );
916
917   draw_indexpoly( front_lighting_model,
918                   aspect_face->Context().InteriorStyle,
919                   edge_colour,
920                   &aspect_face->Context().IntFront,
921                   AWorkspace );
922 }
923
924 /*----------------------------------------------------------------------*/