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