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