0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_indexpolygons.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_indexpolygons :
6
7
8 REMARQUES:
9 ---------- 
10
11 Le culling et le backfacing ne marchent pas.
12
13
14 HISTORIQUE DES MODIFICATIONS   :
15 --------------------------------
16 xx-xx-xx : xxx ; Creation.
17 11-03-96 : FMN ; Correction warning compilation
18 01-04-96 : CAL ; Integration MINSK portage WNT
19 09-08-96 : FMN ; Suppression appel glMatrixMode() avant glGetFloatv()
20 21-10-96 : FMN ; Suppression LMC_COLOR fait dans OpenGl_execstruct.c
21 30-06-97 : FMN ; Suppression OpenGl_telem_light.h
22 18-07-97 : FMN ; Ajout desactivation des lights suivant front_lighting_model
23 21-07-97 : FMN ; Amelioration des performances OPTIMISATION_FMN
24 - suppression calcul inutile sur les front faces
25 - utilisation de GL_TRIANGLES et GL_QUADS
26 27-08-97 : FMN ; Correction affichage des edges
27 On n'affiche que les edges dans le mode IS_EMPTY
28 27-08-97 : FMN ; Correction affichage des edges visibility [PRO9859]
29 10-09-97 : FMN ; Amelioration des perfs liees aux lights.
30 15-09-97 : PCT ; Ajout coordonnees textures
31 24-09-97 : FMN ; Suppression OPTIMISATION_FMN.
32 08-12-97 : FMN ; Suppression appel TsmGetAttri inutile.
33 31-12-97 : FMN ; Simplification pour le highlight
34 15-01-98 : FMN ; Ajout Hidden line
35 08-03-01 : GG  ; BUC60823 Avoid crash in the normal computation method
36 on confuse point.
37
38 ************************************************************************/
39
40 #define xPRINT
41
42 #define G003  /* EUG 07-10-99 Degeneration mode support 
43 */
44
45 #define G004  /* VKH 25-01-00 View dump management
46 Disable animation during dump
47 */
48
49 #define BUC60876  /* GG 5/4/2001 Disable local display list
50 //      when animation is not required
51 */
52
53 #define OCC749          /* SAV 19/09/02 added processing of colored vertices */
54 #define OCC7824         /* ASL 26/01/05 transparency of polygon with colors assigned to vertices */
55
56 /*----------------------------------------------------------------------*/
57 /*
58 * Includes
59 */ 
60
61 #include <OpenGl_tgl_all.hxx>
62
63 #include <stddef.h>
64 #include <stdio.h>
65 #include <string.h>
66 #include <GL/gl.h>
67 #include <GL/glu.h>
68
69 #include <OpenGl_cmn_varargs.hxx>
70 //#include <OpenGl_cmn_memory.hxx>
71 #include <OpenGl_telem_attri.hxx>
72 #include <OpenGl_tsm.hxx>
73 #include <OpenGl_telem.hxx>
74 #include <OpenGl_telem_util.hxx>
75 #include <OpenGl_telem_highlight.hxx>
76 #include <OpenGl_telem_inquire.hxx>
77 #include <OpenGl_telem_view.hxx>
78 #include <OpenGl_tgl_funcs.hxx>
79 #include <OpenGl_LightBox.hxx>
80 #include <OpenGl_TextureBox.hxx>
81
82 #ifdef G003
83 # include <float.h>
84 # define DEF_DS_INTERNAL
85 # include <OpenGl_degeneration.hxx>
86 # ifdef G004
87 extern GLboolean g_fBitmap;
88 # endif /* G004 */
89 #endif  /* G003 */
90
91 static long s_Rand = 1L;
92 # define OPENGL_RAND() (  ( unsigned )( s_Rand = s_Rand * 214013L + 2531011L ))
93
94 /*----------------------------------------------------------------------*/
95 /*
96 * Constantes
97 */ 
98
99 /*----------------------------------------------------------------------*/
100 /*
101 * Prototypes
102 */ 
103
104 static  TStatus  PolygonIndicesDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
105 static  TStatus  PolygonIndicesAdd( TSM_ELEM_DATA, Tint, cmn_key* );
106 static  TStatus  PolygonIndicesDelete( TSM_ELEM_DATA, Tint, cmn_key* );
107 static  TStatus  PolygonIndicesPrint( TSM_ELEM_DATA, Tint, cmn_key* );
108 static  TStatus  PolygonIndicesInquire( TSM_ELEM_DATA, Tint, cmn_key* );
109
110 /*static  GLboolean   lighting_mode;*/
111
112 struct TEL_INDEXPOLY_DATA
113 {
114   Tint       num_vertices;   /* Number of vertices */
115   Tint       num_bounds;     /* Number of bounds */
116   Tint       facet_flag;     /* TEL_FA_NONE or TEL_FA_NORMAL */
117   Tint       vertex_flag;    /* TEL_VT_NONE or TEL_VT_NORMAL */
118   Tint       shape_flag;     /* TEL_SHAPE_UNKNOWN or TEL_SHAPE_COMPLEX or
119                              TEL_SHAPE_CONVEX  or TEL_SHAPE_CONCAVE */
120   Tint       *edge_vis;      /* Edge visibility indicators for each edge */
121   Tint       *bounds;        /* Bounds array */
122   Tint       *indices;       /* Connectivity array */
123   tel_point  fnormals;       /* Facet normals */
124   tel_colour fcolours;       /* Facet colour values */
125   tel_point  vertices;       /* Vertices */
126   tel_colour vcolours;       /* Vertex colour values */
127   tel_point  vnormals;       /* Vertex normals */
128   tel_texture_coord vtexturecoord; /* Texture Coordinates */
129   Tint       edge_count;     /* Internal field */
130 #ifdef G003
131   DS_INTERNAL d;
132 #endif  /* G003 */
133   IMPLEMENT_MEMORY_OPERATORS
134 };
135 typedef TEL_INDEXPOLY_DATA* tel_indexpoly_data;
136
137 static TEL_INDEXPOLY_DATA indexpoly_defaults =
138 {
139   0,                    /* num_vertices */
140   0,                    /* num_bounds */
141   TEL_FA_NONE,          /* facet_flag */
142   TEL_VT_NONE,          /* vertex_flag */
143   TEL_SHAPE_UNKNOWN,    /* shape_flag */
144   0,                    /* edge_vis */
145   0,                    /* bounds */
146   0,                    /* indices */
147   0,                    /* fnormal */
148   0,                    /* fcolour */
149   0,                    /* vertices */
150   0,                    /* vcolours */
151   0,                    /* vnormals */
152   0,                    /* vtexturecoord */
153   0                     /* edge_count */
154 #ifdef G003
155   , { 0, 0, 0, -1, 0.0F, NULL }
156 #endif  /* G003 */
157 };
158
159 static void draw_indexpoly(
160                            tel_indexpoly_data,
161                            Tint,          /* highlight_flag */
162                            Tint,          /* front_lighting_model,  */
163                            Tint,          /* interior_style,  */
164                            tel_colour     /* edge_colour, */
165 #ifdef OCC749
166                            , tel_surf_prop
167 #endif
168                            );
169
170 #ifdef G003
171 static void draw_edges                 ( tel_indexpoly_data, tel_colour, Tint, Tint );
172 static void draw_degenerates_as_points ( tel_indexpoly_data                         );
173 static void draw_degenerates_as_bboxs  ( tel_indexpoly_data                         );
174 void set_drawable_items         ( GLboolean*, int                            );
175 #else
176 static void draw_edges( tel_indexpoly_data,tel_colour, Tint);
177 #endif
178
179 static  TStatus  (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
180 {
181   PolygonIndicesDisplay,             /* PickTraverse */
182     PolygonIndicesDisplay,
183     PolygonIndicesAdd,
184     PolygonIndicesDelete,
185     PolygonIndicesPrint,
186     PolygonIndicesInquire
187 };
188
189 /*----------------------------------------------------------------------*/
190 /*
191 * Variables externes
192 */
193
194 extern  Tint  ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
195 extern int   g_nDegenerateModel;
196
197 #ifdef G003
198 extern float g_fSkipRatio;
199 extern GLboolean g_fAnimation;
200 #endif  /* G003 */
201
202 /*----------------------------------------------------------------------*/
203
204 MtblPtr
205 TelPolygonIndicesInitClass( TelType* el )
206 {
207   *el = TelPolygonIndices;
208   return MtdTbl;
209 }
210
211 /*----------------------------------------------------------------------*/
212
213 static  TStatus
214 PolygonIndicesAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
215 {
216   Tint             i, j, a, b, edge_count=0;
217   tel_indexpoly_data data;
218
219   for( i = 0; i < n; i++ )
220   {
221     if( k[i]->id == NUM_VERTICES_ID )
222       break;
223   }
224   if( i == n )
225     return TFailure;
226
227   if( !(k[i]->data.ldata) )
228     return TFailure;
229
230   for( j = 0; j < n; j++ )
231   {
232     if( k[j]->id == VERTICES_ID )
233       break;
234   }
235   if( j == n )
236     return TFailure;
237
238   for( a = 0; a < n; a++ )
239   {
240     if( k[a]->id == NUM_FACETS_ID )
241       break;
242   }
243   if( a == n )
244     return TFailure;
245
246   //cmn_memreserve( data, 1, 1 );
247   data = new TEL_INDEXPOLY_DATA();
248   if( !data )
249     return TFailure;
250
251   /* load defaults */
252   //cmn_memcpy<TEL_INDEXPOLY_DATA>( data, &indexpoly_defaults, 1 );
253   memcpy( data, &indexpoly_defaults, sizeof(TEL_INDEXPOLY_DATA) );
254
255   data->num_vertices = k[i]->data.ldata;
256   //cmn_memreserve( data->vertices, data->num_vertices, 0 );
257   data->vertices = new TEL_POINT[data->num_vertices];  
258   //cmn_memcpy<TEL_POINT>( data->vertices, k[j]->data.pdata, data->num_vertices );
259   memcpy( data->vertices, k[j]->data.pdata, data->num_vertices*sizeof(TEL_POINT) );
260   data->num_bounds = k[a]->data.ldata;
261
262   for( b = 0; b < n; b++ )
263   {
264     if( k[b]->id == BOUNDS_DATA_ID )
265       break;
266   }
267   if( b == n )
268   {
269     //cmn_freemem( data->vertices );
270     delete[] data->vertices;
271     return TFailure;
272   }
273   //cmn_memreserve( data->bounds, data->num_bounds, 0 );
274   data->bounds = new Tint[data->num_bounds];
275   //cmn_memcpy<Tint>( data->bounds, k[b]->data.pdata, data->num_bounds );
276   memcpy( data->bounds, k[b]->data.pdata, data->num_bounds*sizeof(Tint) );
277
278   for( b = 0; b < data->num_bounds; b++ )
279     edge_count += data->bounds[b];
280
281   data->edge_count = edge_count;
282
283   for( i = 0; i < n; i++ )
284   {
285     switch( k[i]->id )
286     {
287     case EDGE_DATA_ID:
288        data->edge_vis = new Tint[edge_count];
289       memcpy( data->edge_vis, k[i]->data.pdata, edge_count*sizeof(Tint) );
290       break;
291
292     case CONNECTIVITY_ID:
293       data->indices = new Tint[edge_count];
294       memcpy( data->indices, k[i]->data.pdata, edge_count*sizeof(Tint) );
295       break;
296
297     case FNORMALS_ID:
298       data->facet_flag = TEL_FA_NORMAL;
299        data->fnormals = new TEL_POINT[data->num_bounds];
300       memcpy( data->fnormals, k[i]->data.pdata, data->num_bounds*sizeof(TEL_POINT) );
301       for( a = 0; a < data->num_bounds; a++ )
302         vecnrm( data->fnormals[a].xyz );
303       break;
304
305     case FACET_COLOUR_VALS_ID:
306       data->fcolours = new TEL_COLOUR[data->num_bounds];
307       memcpy( data->fcolours, k[i]->data.pdata, data->num_bounds*sizeof(TEL_COLOUR) );
308       break;
309
310     case VERTEX_COLOUR_VALS_ID:
311       data->vcolours = new TEL_COLOUR[data->num_vertices];
312       memcpy( data->vcolours, k[i]->data.pdata, data->num_vertices*sizeof(TEL_COLOUR) );
313       break;
314
315     case VNORMALS_ID:
316       data->vertex_flag = TEL_VT_NORMAL;
317       data->vnormals = new TEL_POINT[data->num_vertices];      
318       memcpy( data->vnormals, k[i]->data.pdata, data->num_vertices*sizeof(TEL_POINT) );
319       for( j = 0; j < data->num_vertices; j++ )
320         vecnrm( data->vnormals[j].xyz );
321       break;
322
323     case SHAPE_FLAG_ID:
324       data->shape_flag = k[i]->data.ldata;
325       break;
326
327     case VTEXTURECOORD_ID:
328       data->vtexturecoord = new TEL_TEXTURE_COORD[data->num_vertices];
329       memcpy( data->vtexturecoord, k[i]->data.pdata, data->num_vertices*sizeof(TEL_TEXTURE_COORD) );
330       break;
331     }
332   }
333
334   if( data->facet_flag != TEL_FA_NORMAL )
335   {
336     data->fnormals = new TEL_POINT[data->num_bounds];
337     for( i = 0, a = 0; i < data->num_bounds; i++ ) {
338 #ifdef BUC60823
339       TelGetPolygonNormal( data->vertices, &data->indices[a],
340         data->bounds[i], data->fnormals[i].xyz );
341 #else
342       TelGetNormal( data->vertices[data->indices[a]].xyz,
343         data->vertices[data->indices[a+1]].xyz,
344         data->vertices[data->indices[a+j]].xyz,
345         data->fnormals[i].xyz );
346       vecnrm(data->fnormals[i].xyz);
347 #endif
348       a += data->bounds[i];
349     }
350   }
351 #ifdef G003
352   data->d.bDraw = new unsigned char[data->num_bounds];
353 #endif  /* G003 */
354   ((tsm_elem_data)(d.pdata))->pdata = data;
355
356   return TSuccess;
357 }
358
359 /*----------------------------------------------------------------------*/
360
361 static  TStatus
362 PolygonIndicesDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
363 {
364   CMN_KEY       k11, k12, k17, k111, k114;
365 #ifdef OCC749
366   CMN_KEY       k117;
367 #endif
368
369   Tint           front_lighting_model;
370   Tint           interior_style;
371   TEL_COLOUR     interior_colour;
372   TEL_COLOUR     edge_colour;
373 #ifdef OCC749
374   TEL_SURF_PROP  prop;
375 #endif
376
377   tel_indexpoly_data d;
378
379   k12.id          = TelInteriorReflectanceEquation;
380   k17.id          = TelInteriorStyle;
381   k111.id         = TelInteriorColour;
382   k111.data.pdata = &interior_colour;
383   k114.id         = TelEdgeColour;
384   k114.data.pdata = &edge_colour;
385 #ifdef OCC749
386   k117.id         = TelSurfaceAreaProperties;
387   k117.data.pdata = &prop;
388 #endif
389
390 #ifdef OCC749
391   TsmGetAttri( 5, &k12, &k17, &k111, &k114, &k117);
392 #else
393   TsmGetAttri( 4, &k12, &k17, &k111, &k114);
394 #endif
395
396   front_lighting_model     = k12.data.ldata;
397   interior_style           = k17.data.ldata;
398
399 #ifdef PRINT
400   printf("PolygonIndicesDisplay \n"); 
401 #endif
402
403   /* 
404   * Use highlight colours 
405   */
406
407   if( k[0]->id == TOn )
408   {                         
409     TEL_HIGHLIGHT  hrep;
410
411     k11.id = TelHighlightIndex;
412     TsmGetAttri( 1, &k11 );
413     if( TelGetHighlightRep( TglActiveWs, k11.data.ldata, &hrep ) == TSuccess )
414     {
415       if( hrep.type == TelHLForcedColour )
416       {
417         edge_colour = interior_colour = hrep.col;
418         front_lighting_model = CALL_PHIGS_REFL_NONE;
419       }
420       else if( hrep.type == TelHLColour )
421       {
422         edge_colour = hrep.col;
423         k[0]->id = TOff;
424       }
425     }
426     else
427     {
428       TelGetHighlightRep( TglActiveWs, 0, &hrep );
429       if( hrep.type == TelHLForcedColour )
430       {
431         edge_colour = interior_colour = hrep.col;
432         front_lighting_model = CALL_PHIGS_REFL_NONE;
433       }
434       else if( hrep.type == TelHLColour )
435       {
436         edge_colour = hrep.col;
437         k[0]->id = TOff;
438       }
439     }
440   }
441
442   d = (tel_indexpoly_data)data.pdata;
443
444   glColor3fv( interior_colour.rgb );
445 #ifdef PRINT
446   printf("PolygonIndicesDisplay.interior_colour %f,%f,%f \n",
447     interior_colour.rgb[0],interior_colour.rgb[1],interior_colour.rgb[2]); 
448 #endif
449
450   draw_indexpoly( d, k[0]->id,
451     front_lighting_model,
452     interior_style,
453     &edge_colour
454 #ifdef OCC749
455     , &prop
456 #endif
457     );
458
459   return TSuccess;
460
461 }
462
463 /*----------------------------------------------------------------------*/
464
465 static void
466 draw_indexpoly( tel_indexpoly_data p, Tint hflag,
467                Tint front_lighting_model,
468                Tint interior_style,
469                tel_colour edge_colour
470 #ifdef OCC749
471                , tel_surf_prop prop
472 #endif
473                )
474 {
475   Tint i, j, k, a, newList = 0;
476   Tint  lighting_model;
477
478   /* Following pointers have been provided for performance improvement */
479   Tint       *ind;
480   tel_point  pfn, pvn, pv;
481   tel_colour pvc, pfc;
482   tel_texture_coord pvt;
483
484   ind = p->indices;
485   pfn = p->fnormals;
486   pvn = p->vnormals;
487   pvc = p->vcolours;
488   pfc = p->fcolours;
489   pv  = p->vertices;
490   pvt = p->vtexturecoord;
491 #ifdef G003
492   if ( g_nDegenerateModel < 2 && interior_style != TSM_EMPTY ) 
493 #else
494   if ( interior_style != TSM_EMPTY ) 
495 #endif  /* G003 */
496   {      
497     if( hflag == TOn )
498     {
499       pvc = 0;
500       pfc = 0;
501     }
502
503     if ( interior_style == TSM_HIDDENLINE)
504     {
505       pvc = 0;
506       pfc = 0;
507     }
508
509     if (front_lighting_model == CALL_PHIGS_REFL_NONE)
510       LightOff();
511     else LightOn();
512
513     lighting_model = front_lighting_model;
514
515 #ifdef G003
516 #ifdef BUC60876
517     if ( !g_fAnimation ) 
518       goto doDraw; /* Disable object display list out of animation */
519 #endif
520 #ifdef G004
521     if ( g_fBitmap ) 
522       goto doDraw;  /* dipsplay lists are NOT shared between */
523     /*  window's context and bitmap's one    */
524 #endif /* G004 */
525
526     if ( p -> d.model != lighting_model || !p -> d.list ||
527       p -> d.model == -1 ||( g_nDegenerateModel && p -> d.skipRatio != g_fSkipRatio )) {
528
529         p -> d.skipRatio = g_fSkipRatio;
530         p -> d.model     = lighting_model;
531         p -> d.degMode   = g_nDegenerateModel;
532 #endif  /* G003 */
533 #ifdef G003
534         if ( g_fSkipRatio == 0.0 ) {
535           if ( !p -> d.list ) p -> d.list = glGenLists ( 1 );
536
537           glNewList ( p -> d.list, GL_COMPILE_AND_EXECUTE );
538           newList = 1;
539 doDraw:
540 #endif  /* G003 */
541
542           if ( lighting_model == CALL_PHIGS_REFL_NONE ) {
543             if ( p -> bounds[ 0 ] == 3 )
544               glBegin ( GL_TRIANGLES );
545             else if ( p -> bounds[ 0 ] == 4 )
546               glBegin ( GL_QUADS );
547             else glBegin ( GL_POLYGON );
548
549             if ( pvc ) {
550               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
551                 a = j + p -> bounds[ i ];
552                 for ( ; j < a; ++j ) {
553                   glColor3fv  ( pvc[  ind[ j ]  ].rgb  );
554                   glVertex3fv ( pv[   ind[ j ]  ].xyz  );
555                 }  /* end for ( j . . . ) */
556               }  /* end for ( i . . . ) */
557             } else if ( pfc ) {
558               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
559                 a = j + p -> bounds[ i ];
560                 glColor3fv ( pfc[ i ].rgb );
561                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
562               }  /* end for */
563             } else {
564               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
565                 a = j + p -> bounds[ i ];
566                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
567               }  /* end for */
568             }  /* end else */
569             glEnd ();
570           } else {   /* lighting_model != TelLModelNone */
571             if ( p -> bounds[ 0 ] == 3 )
572               glBegin ( GL_TRIANGLES );
573             else if ( p -> bounds[ 0 ] == 4 )
574               glBegin ( GL_QUADS );
575             else glBegin ( GL_POLYGON );
576
577 #ifdef OCC749
578             for ( i = a = 0; i < p -> num_bounds; ++i ) {
579               j = a; a += p -> bounds[ i ];
580               if( pfn ) glNormal3fv ( pfn[ i ].xyz );
581               if( pfc && !prop->isphysic ) {
582                 GLfloat diff[4], ambi[4], emsv[4], r, g, b;
583
584 #ifdef OCC7824
585                 ambi[3] = diff[3] = emsv[3] = prop->trans;
586 #else
587                 ambi[3] = 1.0f;  diff[3] = 1.0f;  emsv[3] = 1.0f;
588 #endif
589
590                 r = pfc[ i ].rgb[0];  g = pfc[ i ].rgb[1];  b = pfc[ i ].rgb[2];
591
592                 if( prop->isamb ) {
593                   ambi[0] = prop->amb * r;
594                   ambi[1] = prop->amb * g;
595                   ambi[2] = prop->amb * b;
596                   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambi);
597                 }
598                 if( prop->isdiff ) {
599                   diff[0] = prop->diff * r;
600                   diff[1] = prop->diff * g;
601                   diff[2] = prop->diff * b;
602                   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
603                 }
604                 if( prop->isemsv ) {
605                   emsv[0] = prop->emsv * r;
606                   emsv[1] = prop->emsv * g;
607                   emsv[2] = prop->emsv * b;
608                   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emsv);
609                 }
610               }
611               for ( ; j < a; ++j ) {
612                 k = ind[ j ];
613                 if( pvn ) glNormal3fv ( pvn[ k ].xyz );
614                 if( pvc && !prop->isphysic ) {
615                   GLfloat diff[4], ambi[4], emsv[4], r, g, b;
616
617 #ifdef OCC7824
618                   ambi[3] = diff[3] = emsv[3] = prop->trans;
619 #else
620                   ambi[3] = 1.0f;  diff[3] = 1.0f;  emsv[3] = 1.0f;
621 #endif
622
623                   r = pvc[ k ].rgb[0];  g = pvc[ k ].rgb[1];  b = pvc[ k ].rgb[2];
624
625                   if( prop->isamb ) {
626                     ambi[0] = prop->amb * r;
627                     ambi[1] = prop->amb * g;
628                     ambi[2] = prop->amb * b;
629                     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambi);
630                   }
631                   if( prop->isdiff ) {
632                     diff[0] = prop->diff * r;
633                     diff[1] = prop->diff * g;
634                     diff[2] = prop->diff * b;
635                     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
636                   }
637                   if( prop->isemsv ) {
638                     emsv[0] = prop->emsv * r;
639                     emsv[1] = prop->emsv * g;
640                     emsv[2] = prop->emsv * b;
641                     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emsv);
642                   }
643                 }
644                 if( pvt && !ForbidSetTextureMapping ) glTexCoord2fv ( pvt[ k ].xy  );
645                 glVertex3fv ( pv[ k ].xyz );
646               }  /* end for ( j . . . ) */
647             }  /* end for ( i . . . ) */
648             glEnd ();  
649 #else
650             if ( pvn ) {
651               if ( pvt && !ForbidSetTextureMapping )
652                 for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
653                   a = j + p -> bounds[ i ];
654                   for ( ; j < a; ++j ) {
655                     glNormal3fv   ( pvn[  ind[ j ]  ].xyz );
656                     glTexCoord2fv ( pvt[  ind[ j ]  ].xy  );
657                     glVertex3fv   ( pv[   ind[ j ]  ].xyz );
658                   }  /* end for ( j . . . ) */
659                 }  /* end for ( i . . . ) */
660               else
661                 for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
662                   a = j + p -> bounds[ i ];
663                   for ( ; j < a; ++j ) {
664                     glNormal3fv ( pvn[  ind[ j ]  ].xyz  );
665                     glVertex3fv ( pv[   ind[ j ]  ].xyz  );
666                   }  /* end for ( j . . . ) */
667                 }  /* end for ( i . . . ) */
668             } else { /* !pvn */
669               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
670                 a = j + p -> bounds[ i ];
671                 glNormal3fv ( pfn[ i ].xyz );
672                 for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
673               }  /* end for */
674             }  /* end else */
675             glEnd ();  
676 #endif /* OCC749 */
677
678           }  /* end else */
679 #ifdef G003
680         } else if ( g_fSkipRatio != 1.0 ) {
681           if ( !p -> d.dlist ) p -> d.dlist = glGenLists ( 1 );
682           glNewList ( p -> d.dlist, GL_COMPILE_AND_EXECUTE );
683           newList = 1;
684           set_drawable_items ( p -> d.bDraw, p -> num_bounds );
685           if ( lighting_model == CALL_PHIGS_REFL_NONE ) {
686             if ( p -> bounds[ 0 ] == 3 )
687               glBegin ( GL_TRIANGLES );
688             else if ( p -> bounds[ 0 ] == 4 )
689               glBegin ( GL_QUADS );
690             else glBegin ( GL_POLYGON );
691
692             if ( pvc ) {
693               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
694                 a = j + p -> bounds[ i ];
695                 if ( p -> d.bDraw[ i ] )
696                   for ( ; j < a; ++j ) {
697                     glColor3fv  ( pvc[  ind[ j ]  ].rgb  );
698                     glVertex3fv ( pv[   ind[ j ]  ].xyz  );
699                   }  /* end for ( j . . . ) */
700                 else j = a;
701               }  /* end for ( i . . . ) */
702             } else if ( pfc ) {
703               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
704                 a = j + p -> bounds[ i ];
705                 if ( p -> d.bDraw[ i ] ) {
706                   glColor3fv ( pfc[ i ].rgb );
707                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
708                 } else j = a;
709               }  /* end for */
710             } else {
711               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
712                 a = j + p -> bounds[ i ];
713                 if ( p -> d.bDraw[ i ] )
714                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
715                 else j = a;
716               }  /* end for */
717             }  /* end else */
718             glEnd ();
719           } else {   /* lighting_model != TelLModelNone */
720             if ( p -> bounds[ 0 ] == 3 )
721               glBegin ( GL_TRIANGLES );
722             else if ( p -> bounds[ 0 ] == 4 )
723               glBegin ( GL_QUADS );
724             else glBegin ( GL_POLYGON );
725
726             if ( pvn ) {
727               if ( pvt && !ForbidSetTextureMapping )
728                 for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
729                   a = j + p->bounds[ i ];
730                   if ( p -> d.bDraw[ i ] )
731                     for ( ; j < a; ++j ) {
732                       glNormal3fv   ( pvn[  ind[ j ]  ].xyz );
733                       glTexCoord2fv ( pvt[  ind[ j ]  ].xy  );
734                       glVertex3fv   ( pv[   ind[ j ]  ].xyz );
735                     }  /* end for ( j . . . ) */
736                   else j = a;
737                 }  /* end for ( i . . . ) */
738               else
739                 for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
740                   a = j + p -> bounds[ i ];
741                   if ( p -> d.bDraw[ i ] )
742                     for ( ; j < a; ++j ) {
743                       glNormal3fv ( pvn[  ind[ j ]  ].xyz  );
744                       glVertex3fv ( pv[   ind[ j ]  ].xyz  );
745                     }  /* end for ( j . . . ) */
746                   else j = a;
747                 }  /* end for ( i . . . ) */
748             } else {  /* !pvn */
749               for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
750                 a = j + p -> bounds[ i ];
751                 if ( p -> d.bDraw[ i ] ) {
752                   glNormal3fv ( pfn[ i ].xyz );
753                   for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz  );
754                 } else j = a;
755               }  /* end for */
756             }  /* end else */
757             glEnd ();  
758           }  /* end else */
759         } else {
760           if ( !p -> d.dlist ) p -> d.dlist = glGenLists ( 1 );
761           glNewList ( p -> d.dlist, GL_COMPILE_AND_EXECUTE );
762           newList = 1;
763         }  /* end else */
764 #endif  /* G003 */
765 #ifdef G003
766         if ( newList ) glEndList ();
767         if ( g_nDegenerateModel ) return;
768       } else {
769         glCallList ( g_fSkipRatio == 0.0 ? p -> d.list : p -> d.dlist );
770         if ( g_nDegenerateModel ) return;
771       }  /* end else */
772 #endif  /* G003 */
773   }
774 #ifdef G003
775   i = 0;
776
777   switch ( g_nDegenerateModel ) {
778
779 default:
780   break;
781
782 case 2:  /* XXX_TDM_WIREFRAME */
783   i = 1;
784   break;
785
786 case 3:  /* XXX_TDM_MARKER */
787   draw_degenerates_as_points ( p );
788   return;
789
790 case 4:  /* XXX_TDM_BBOX */
791   draw_degenerates_as_bboxs ( p );
792   return;
793
794   }  /* end switch */
795
796   draw_edges ( p, edge_colour, interior_style, i );
797 #else
798   draw_edges( p, edge_colour, interior_style );
799 #endif
800 }
801
802 /*----------------------------------------------------------------------*/
803
804 static  TStatus
805 PolygonIndicesDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
806 {
807   tel_indexpoly_data p;
808
809   p = (tel_indexpoly_data)data.pdata;
810   if( p->edge_vis )
811     //cmn_freemem( p->edge_vis );
812     delete[] p->edge_vis;
813   if( p->bounds )
814     //cmn_freemem( p->bounds );
815     delete[] p->bounds;
816   if( p->indices )
817     //cmn_freemem( p->indices );
818     delete[] p->indices;
819   if( p->fcolours )
820     //cmn_freemem( p->fcolours );
821     delete[] p->fcolours;
822   if( p->fnormals )
823     //cmn_freemem( p->fnormals );
824     delete[] p->fnormals;
825   if( p->vertices )
826     //cmn_freemem( p->vertices );
827     delete[] p->vertices;
828   if( p->vcolours )
829     //cmn_freemem( p->vcolours );
830     delete[] p->vcolours;
831   if( p->vnormals )
832     //cmn_freemem( p->vnormals );
833     delete[] p->vnormals;
834   if (p->vtexturecoord)
835     //cmn_freemem( p->vtexturecoord );
836     delete[] p->vtexturecoord;
837 #ifdef G003
838   if (  GET_GL_CONTEXT() != NULL  ) {
839
840     if ( p -> d.list ) glDeleteLists ( p ->  d.list, 1 );
841     if ( p -> d.dlist ) glDeleteLists ( p -> d.dlist, 1 );
842
843   }  /* end if */
844
845   if ( p -> d.bDraw )
846     //cmn_freemem ( p -> d.bDraw );
847     delete[] p -> d.bDraw;
848 #endif  /* G003 */
849
850   //cmn_freemem( data.pdata );
851   if (data.pdata)
852     delete data.pdata;
853   return TSuccess;
854 }
855
856 /*----------------------------------------------------------------------*/
857
858 static  TStatus
859 PolygonIndicesPrint( TSM_ELEM_DATA data, Tint n, cmn_key *k )
860 {
861   Tint             i;
862   tel_indexpoly_data p;
863
864   p = (tel_indexpoly_data)data.pdata;
865
866   fprintf( stdout, "TelPolygonIndices. Number of Vertices: %d\n", p->num_vertices );
867   switch( p->shape_flag )
868   {
869   case TEL_SHAPE_UNKNOWN:
870     fprintf( stdout, "\t\tShape Flag : UNKNOWN\n" );
871     break;
872
873   case TEL_SHAPE_COMPLEX:
874     fprintf( stdout, "\t\tShape Flag : COMPLEX\n" );
875     break;
876
877   case TEL_SHAPE_CONCAVE:
878     fprintf( stdout, "\t\tShape Flag : CONCAVE\n" );
879     break;
880
881   case TEL_SHAPE_CONVEX:
882     fprintf( stdout, "\t\tShape Flag : CONVEX\n" );
883     break;
884
885   }
886   switch( p->facet_flag )
887   {
888   case TEL_FA_NONE:
889     if( p->fcolours )
890       fprintf( stdout, "\t\tFacet Flag : COLOUR\n" );
891     else
892       fprintf( stdout, "\t\tFacet Flag : NONE\n" );
893     break;
894
895   case TEL_FA_NORMAL:
896     if( p->fcolours )
897       fprintf( stdout, "\t\tFacet Flag : COLOURNORMAL\n" );
898     else
899       fprintf( stdout, "\t\tFacet Flag : NORMAL\n" );
900     break;
901   }
902   switch( p->vertex_flag )
903   {
904   case TEL_VT_NONE:
905     if( p->vcolours )
906       fprintf( stdout, "\t\tVertex Flag : COLOUR\n" );
907     else
908       fprintf( stdout, "\t\tVertex Flag : NONE\n" );
909     break;
910
911   case TEL_VT_NORMAL:
912     if( p->vcolours )
913       fprintf( stdout, "\t\tVertex Flag : COLOURNORMAL\n" );
914     else
915       fprintf( stdout, "\t\tVertex Flag : NORMAL\n" );
916     break;
917   }
918   if( p->edge_vis )
919   {
920     fprintf( stdout, "\t\tEdge Visibility Data :\n" );
921     for( i = 0; i < p->edge_count; i++ )
922       fprintf( stdout, "\t\t%d ", p->edge_vis[i] );
923     fprintf( stdout, "\n" );
924   }
925   if( p->bounds )
926   {
927     fprintf( stdout, "\t\tBounds array :\n" );
928     for( i = 0; i < p->num_bounds; i++ )
929       fprintf( stdout, "\t\tb[%d] %d \n", i, p->bounds[i] );
930   }
931   if( p->indices )
932   {
933     fprintf( stdout, "\t\tConnectivity array :\n" );
934     for( i = 0; i < p->edge_count; i++ )
935       fprintf( stdout, "\t\tI[%d] %d \n", i, p->indices[i] );
936   }
937   if( p->fnormals )
938   {
939     fprintf( stdout, "\n\t\tFacet Normals : " );
940     for( i = 0; i < p->num_bounds; i++ )
941       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
942       p->fnormals[i].xyz[0],
943       p->fnormals[i].xyz[1],
944       p->fnormals[i].xyz[2] );
945     fprintf( stdout, "\n" );
946   }
947   else
948     fprintf( stdout, "\n\t\tFacet Normals not specified\n" );
949
950   if( p->fcolours )
951   {
952     fprintf( stdout, "\n\t\tFacet Colours : " );
953     for( i = 0; i < p->num_bounds; i++ )
954       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
955       p->fcolours[i].rgb[0],
956       p->fcolours[i].rgb[1],
957       p->fcolours[i].rgb[2] );    }
958   else
959     fprintf( stdout, "\n\t\tFacet Colours not specified\n" );
960
961   if( p->vertices )
962   {
963     fprintf( stdout, "\n\t\tVertices : " );
964     for( i = 0; i < p->num_vertices; i++ )
965       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
966       p->vertices[i].xyz[0],
967       p->vertices[i].xyz[1],
968       p->vertices[i].xyz[2] );
969   }
970
971   fprintf( stdout, "\n" );
972   if( p->vcolours )
973   {
974     fprintf( stdout, "\n\t\tVertex Colours : " );
975     for( i = 0; i < p->num_vertices; i++ )
976       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
977       p->vcolours[i].rgb[0],
978       p->vcolours[i].rgb[1],
979       p->vcolours[i].rgb[2] );
980   }
981   else
982     fprintf( stdout, "\n\t\tVertex Colours not specified\n" );
983
984   if( p->vnormals )
985   {
986     fprintf( stdout, "\n\t\tVertex Normals : " );
987     for( i = 0; i < p->num_vertices; i++ )
988       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
989       p->vnormals[i].xyz[0],
990       p->vnormals[i].xyz[1],
991       p->vnormals[i].xyz[2] );
992   }
993   else
994     fprintf( stdout, "\n\t\tVertex Normals not specified\n" );
995
996   if (p->vtexturecoord)
997   {
998     fprintf(stdout, "\n\t\tTexture Coordinates : ");
999     for (i=0; i<p->num_vertices; i++)
1000       fprintf(stdout, "\n\t\t v[%d] = %g %g", i,
1001       p->vtexturecoord[i].xy[0],
1002       p->vtexturecoord[i].xy[1]);
1003   }
1004   else
1005     fprintf( stdout, "\n\t\tTexture Coordinates not specified\n");
1006
1007   fprintf( stdout, "\n" );
1008
1009   return TSuccess;
1010 }
1011
1012 /*----------------------------------------------------------------------*/
1013
1014 static TStatus
1015 PolygonIndicesInquire( TSM_ELEM_DATA data, Tint n, cmn_key *k )
1016 {
1017   Tint                 i, j;
1018   tel_indexpoly_data   d;
1019   Tint                 size_reqd=0;
1020   TStatus              status = TSuccess;
1021   Tchar                *cur_ptr = 0;
1022
1023   d = (tel_indexpoly_data)data.pdata;
1024
1025   if( d->edge_vis )
1026     size_reqd += ( d->edge_count * sizeof( Tint ) );
1027
1028   size_reqd += ( d->num_bounds * sizeof( Tint ) ); /* bounds */
1029   size_reqd += ( d->edge_count * sizeof( Tint ) ); /* connectivity */
1030
1031   if( d->fcolours )
1032     size_reqd += ( d->num_bounds * sizeof( TEL_COLOUR ) );
1033
1034   if( d->facet_flag == TEL_FA_NORMAL )
1035     size_reqd += ( d->num_bounds * sizeof( TEL_POINT ) );
1036
1037   size_reqd += ( d->num_vertices * sizeof( TEL_POINT ) );
1038
1039   if( d->vcolours )
1040     size_reqd += ( d->num_vertices * sizeof( TEL_COLOUR ) );
1041
1042   if( d->vertex_flag == TEL_VT_NORMAL )
1043     size_reqd += ( d->num_vertices * sizeof( TEL_POINT ) );
1044
1045   for( i = 0; i < n; i++ )
1046   {
1047     switch( k[i]->id )
1048     {
1049     case INQ_GET_SIZE_ID:
1050       {
1051         k[i]->data.ldata = size_reqd;
1052         break;
1053       }
1054
1055     case INQ_GET_CONTENT_ID:
1056       {
1057         TEL_INQ_CONTENT *c;
1058         Teldata         *w;
1059
1060         c = (tel_inq_content)k[i]->data.pdata;
1061         c->act_size = size_reqd;
1062         w = c->data;
1063
1064         cur_ptr = c->buf;
1065         w->indexedpolygons3data.shpflag = d->shape_flag;
1066         w->indexedpolygons3data.num_bounds = d->num_bounds;
1067         w->indexedpolygons3data.num_vertices = d->num_vertices;
1068         if( d->edge_vis )
1069           w->indexedpolygons3data.edgflag = TOn;
1070         else
1071           w->indexedpolygons3data.edgflag = TOff;
1072
1073         if( c->size >= size_reqd )
1074         {
1075           if( d->facet_flag == TEL_FA_NORMAL )
1076           {
1077             if( d->fcolours )
1078             {
1079               w->indexedpolygons3data.fctflag = TEL_FAFLAG_COLOURNORMAL;
1080               w->indexedpolygons3data.gnormals = (tel_point)(c->buf);
1081               for( j = 0; j < d->num_bounds; j++ )
1082               {
1083                 w->indexedpolygons3data.gnormals[j] = d->fnormals[j];
1084               }
1085               cur_ptr += ( d->num_bounds * sizeof( TEL_POINT ) );
1086
1087               w->indexedpolygons3data.facet_colour_vals =
1088                 (tel_colour)(cur_ptr);
1089               for( j = 0; j < d->num_bounds; j++ )
1090               {
1091                 w->indexedpolygons3data.facet_colour_vals[j] =
1092                   d->fcolours[j];
1093               }
1094               cur_ptr += ( d->num_bounds * sizeof( TEL_COLOUR ) );
1095             }
1096             else
1097             {
1098               w->indexedpolygons3data.fctflag = TEL_FAFLAG_NORMAL;
1099               w->indexedpolygons3data.facet_colour_vals = 0;
1100               w->indexedpolygons3data.gnormals = (tel_point)(c->buf);
1101               for( j = 0; j < d->num_bounds; j++ )
1102               {
1103                 w->indexedpolygons3data.gnormals[j] = d->fnormals[j];
1104               }
1105               cur_ptr += ( d->num_bounds * sizeof( TEL_POINT ) );
1106             }
1107           }
1108           else
1109           {
1110             w->indexedpolygons3data.gnormals = 0;
1111             if( d->fcolours )
1112             {
1113               w->indexedpolygons3data.fctflag = TEL_FAFLAG_COLOUR;
1114               w->indexedpolygons3data.facet_colour_vals =
1115                 (tel_colour)(c->buf );
1116               for( j = 0; j < d->num_bounds; j++ )
1117               {
1118                 w->indexedpolygons3data.facet_colour_vals[j] =
1119                   d->fcolours[j];
1120               }
1121               cur_ptr += ( d->num_bounds * sizeof( TEL_COLOUR ) );
1122             }
1123             else
1124             {
1125               w->indexedpolygons3data.fctflag = TEL_FAFLAG_NONE;
1126               w->indexedpolygons3data.facet_colour_vals = 0;
1127             }
1128           }
1129
1130           if( d->edge_vis )
1131           {
1132             w->indexedpolygons3data.edgvis = (Tint *)(cur_ptr);
1133             //             cmn_memcpy<Tint>( w->indexedpolygons3data.edgvis,
1134             //                               d->edge_vis,
1135             //                               d->edge_count );
1136             memcpy( w->indexedpolygons3data.edgvis, d->edge_vis, d->edge_count*sizeof(Tint) );
1137             cur_ptr += (d->edge_count * sizeof( Tint ) );
1138           }
1139
1140           w->indexedpolygons3data.points = (tel_point)cur_ptr;
1141           for( j = 0; j < d->num_vertices; j++ )
1142           {
1143             w->indexedpolygons3data.points[j] = d->vertices[j];
1144           }
1145           cur_ptr += ( d->num_vertices * sizeof( TEL_POINT ) );
1146
1147           w->indexedpolygons3data.bounds = (Tint *)cur_ptr;
1148           //           cmn_memcpy<Tint>( w->indexedpolygons3data.bounds,
1149           //                             d->bounds,
1150           //                             d->num_bounds );
1151           memcpy( w->indexedpolygons3data.bounds, d->bounds, d->num_bounds*sizeof(Tint) );
1152           cur_ptr += ( d->num_bounds * sizeof( Tint ) );
1153
1154           w->indexedpolygons3data.indices = (Tint *)cur_ptr;
1155           //           cmn_memcpy<Tint>( w->indexedpolygons3data.indices,
1156           //                             d->indices,
1157           //                             d->edge_count );
1158           memcpy( w->indexedpolygons3data.indices, d->indices, d->edge_count*sizeof(Tint) );
1159           cur_ptr += ( d->edge_count * sizeof( Tint ) );
1160
1161           if( d->vertex_flag == TEL_VT_NORMAL )
1162           {
1163             if( d->vcolours )
1164             {
1165               w->indexedpolygons3data.vrtflag = TEL_VTFLAG_COLOURNORMAL;
1166               w->indexedpolygons3data.vnormals = (tel_point)(cur_ptr);
1167               for( j = 0; j < d->num_vertices; j++ )
1168               {
1169                 w->indexedpolygons3data.vnormals[j] = d->vnormals[i];
1170               }
1171               cur_ptr += ( d->num_vertices * sizeof( TEL_POINT ) );
1172
1173               w->indexedpolygons3data.colours = (tel_colour)(cur_ptr);
1174
1175               for( j = 0; j < d->num_vertices; j++ )
1176               {
1177                 w->indexedpolygons3data.colours[j] = d->vcolours[i];
1178               }
1179             }
1180             else
1181             {
1182               w->indexedpolygons3data.vrtflag = TEL_VTFLAG_NORMAL;
1183               w->indexedpolygons3data.colours = 0;
1184               w->indexedpolygons3data.vnormals = (tel_point)(cur_ptr);
1185
1186               for( j = 0; j < d->num_vertices; j++ )
1187               {
1188                 w->indexedpolygons3data.vnormals[j] = d->vnormals[i];
1189               }
1190             }
1191           }
1192           else
1193           {
1194             w->indexedpolygons3data.vnormals = 0;
1195             if( d->vcolours )
1196             {
1197               w->indexedpolygons3data.vrtflag = TEL_VTFLAG_COLOUR;
1198               w->indexedpolygons3data.colours = (tel_colour)(cur_ptr);
1199               for( j = 0; j < d->num_vertices; j++ )
1200               {
1201                 w->indexedpolygons3data.colours[j] = d->vcolours[i];
1202               }
1203             }
1204             else
1205             {
1206               w->indexedpolygons3data.vrtflag = TEL_VTFLAG_NONE;
1207               w->indexedpolygons3data.colours = 0;
1208             }
1209           }
1210
1211           status = TSuccess;
1212         }
1213         else
1214           status = TFailure;
1215         break;
1216       }
1217     }
1218   }
1219   return status;
1220 }
1221
1222 /*----------------------------------------------------------------------*/
1223
1224 static void
1225 #ifdef G003
1226 draw_edges ( tel_indexpoly_data p, tel_colour edge_colour,
1227             Tint interior_style, Tint forceDraw )
1228 #else
1229 draw_edges( tel_indexpoly_data p, tel_colour edge_colour, Tint interior_style )
1230 #endif
1231 {
1232   CMN_KEY k, k1, k2, k3, k4;
1233   Tint    *ind, *vis;
1234   Tint    i, j, a, newList = 0;
1235   Tint    edge_type, line_type_preserve;
1236   Tfloat  edge_width, line_width_preserve;
1237   GLboolean texture_on;
1238
1239   tel_point  pv;
1240
1241 #ifdef G003
1242   if ( interior_style != TSM_HIDDENLINE && !forceDraw )
1243 #else 
1244   if (interior_style != TSM_HIDDENLINE)
1245 #endif
1246   {
1247     k.id = TelEdgeFlag;
1248     TsmGetAttri( 1, &k );
1249     if( k.data.ldata == TOff )return;
1250   } 
1251
1252   pv  = p->vertices;
1253   ind = p->indices;
1254   vis = p->edge_vis;
1255
1256   LightOff();
1257   texture_on = IsTextureEnabled();
1258   if (texture_on) DisableTexture();
1259
1260   k1.id  = TelPolylineWidth;
1261   k2.id  = TelPolylineType;
1262   k3.id  = TelEdgeType;
1263   k4.id  = TelEdgeWidth;
1264
1265   TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
1266
1267   line_width_preserve = k1.data.fdata;
1268   line_type_preserve  = k2.data.ldata;
1269   edge_type           = k3.data.ldata;
1270   edge_width          = k4.data.fdata;
1271
1272   if( line_width_preserve != edge_width )
1273   {
1274     k.id = TelPolylineWidth;
1275     k.data.fdata = edge_width;
1276     TsmSetAttri( 1, &k );
1277   }
1278   if( line_type_preserve != edge_type )
1279   {
1280     k.id = TelPolylineType;
1281     k.data.ldata = edge_type;
1282     TsmSetAttri( 1, &k );
1283   }
1284
1285 #ifdef G003 
1286   if ( !forceDraw ) {
1287
1288     glColor3fv    ( edge_colour -> rgb         );
1289     glPushAttrib  ( GL_POLYGON_BIT             );
1290     glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
1291
1292     for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1293
1294       a = j + p -> bounds[ i ];
1295
1296       glBegin ( GL_POLYGON );
1297
1298       for ( ; j < a; ++j ) {
1299
1300         glEdgeFlag (   ( GLboolean )( vis[ j ] == 1 ? GL_TRUE : GL_FALSE )  );
1301         glVertex3fv ( pv[  ind[ j ]  ].xyz );
1302
1303       }  /* end for */
1304
1305       glEnd();
1306
1307       glEdgeFlag ( GL_TRUE );
1308
1309     }  /* end for */
1310
1311     glPopAttrib ();
1312
1313   } else {
1314
1315 #ifdef BUC60876
1316     if ( !g_fAnimation ) 
1317       goto doDraw; /* Disable object display list out of animation */
1318 #endif
1319 #ifdef G004
1320     if ( g_fBitmap ) 
1321       goto doDraw;
1322 #endif /* G004 */
1323
1324     if ( p -> d.degMode != 2 || p -> d.skipRatio != g_fSkipRatio || !p -> d.dlist ) {
1325
1326       if ( !p -> d.dlist ) p -> d.dlist = glGenLists ( 1 );
1327
1328       p -> d.degMode   = 2;
1329       p -> d.skipRatio = g_fSkipRatio;
1330       glNewList ( p -> d.dlist, GL_COMPILE_AND_EXECUTE );
1331       newList = 1;
1332
1333 doDraw:
1334       glPushAttrib ( GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT );
1335
1336       glEdgeFlag    ( GL_TRUE                    );
1337       glDisable     ( GL_DEPTH_TEST              );
1338       glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
1339
1340       if ( g_fSkipRatio == 0.0F )
1341
1342         for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1343
1344           a = j + p -> bounds[ i ];
1345
1346           glBegin ( GL_POLYGON );
1347
1348           for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
1349
1350           glEnd();
1351
1352         }  /* end for */
1353
1354       else if ( g_fSkipRatio != 1.0F ) {
1355
1356         set_drawable_items ( p -> d.bDraw, p -> num_bounds );
1357
1358         for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1359
1360           a = j + p -> bounds[ i ];
1361
1362           if ( p -> d.bDraw[ i ] ) {
1363
1364             glBegin ( GL_POLYGON );
1365
1366             for ( ; j < a; ++j ) glVertex3fv ( pv[  ind[ j ]  ].xyz );
1367
1368             glEnd();
1369
1370           } else j = a;
1371
1372         }  /* end for */
1373
1374       }  /* end if */
1375
1376       glPopAttrib ();
1377       if ( newList ) glEndList ();
1378
1379     } else glCallList ( p -> d.dlist );
1380
1381   }  /* end else */
1382 #else
1383   glColor3fv( edge_colour->rgb );
1384   glPushAttrib(GL_POLYGON_BIT);    
1385   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
1386   for( i = 0, j = 0, a = 0; i < p->num_bounds; i++ )
1387   {
1388     a = j + p->bounds[i];
1389     glBegin(GL_POLYGON);
1390     for( ; j < a; j++ )
1391     {
1392       if( vis[j] == 1) glEdgeFlag( GL_TRUE ); 
1393       else glEdgeFlag( GL_FALSE ); 
1394       glVertex3fv( pv[ ind[j] ].xyz );
1395     }
1396     glEnd();
1397     glEdgeFlag(GL_TRUE);
1398   }
1399
1400   glPopAttrib();
1401 #endif  /* G003 */
1402
1403   if( line_width_preserve != edge_width )
1404   {
1405     k.id = TelPolylineWidth;
1406     k.data.fdata = line_width_preserve;
1407     TsmSetAttri( 1, &k );
1408   }
1409   if( line_type_preserve != edge_type )
1410   {
1411     k.id = TelPolylineType;
1412     k.data.ldata = line_type_preserve;
1413     TsmSetAttri( 1, &k );
1414   }
1415   if (texture_on) EnableTexture();
1416 }
1417 /*----------------------------------------------------------------------*/
1418 #ifdef G003
1419 static void draw_degenerates_as_points ( tel_indexpoly_data p ) {
1420
1421   Tint*      ind, *vis;
1422   Tint       i, j, n, a, newList = 0;
1423   GLfloat    pt[ 3 ];
1424   tel_point  pv;
1425
1426   pv  = p -> vertices;
1427   ind = p -> indices;
1428   vis = p -> edge_vis;
1429
1430   LightOff ();
1431
1432 #ifdef G004
1433   if ( g_fBitmap ) goto doDraw;
1434 #endif /* G004 */
1435
1436   if ( p -> d.degMode != 3 || p -> d.skipRatio != g_fSkipRatio || !p -> d.dlist ) {
1437
1438     if ( !p -> d.dlist ) p -> d.dlist = glGenLists ( 1 );
1439
1440     p -> d.degMode   = 3;
1441     p -> d.skipRatio = g_fSkipRatio;
1442     glNewList ( p -> d.dlist, GL_COMPILE_AND_EXECUTE );
1443     newList = 1;
1444 doDraw:
1445     if ( g_fSkipRatio == 0.0F ) {
1446
1447       glBegin ( GL_POINTS );
1448
1449       for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1450
1451         n = p -> bounds[ i ];
1452         a = j + n;
1453
1454         for ( pt [ 0 ] = pt[ 1 ] = pt[ 2 ] = 0.; j < a; ++j ) {
1455
1456           pt[ 0 ] += pv[  ind[ j ]  ].xyz[ 0 ];
1457           pt[ 1 ] += pv[  ind[ j ]  ].xyz[ 1 ];
1458           pt[ 2 ] += pv[  ind[ j ]  ].xyz[ 2 ];
1459
1460         }  /* end for ( j ) */
1461
1462         pt[ 0 ] /= n;
1463         pt[ 1 ] /= n;
1464         pt[ 2 ] /= n;
1465
1466         glVertex3fv ( pt );
1467
1468       }  /* end for ( i ) */
1469
1470       glEnd ();
1471
1472     } else if ( g_fSkipRatio != 1.0 ) {
1473
1474       set_drawable_items ( p -> d.bDraw, p -> num_bounds );
1475
1476       glBegin ( GL_POINTS );
1477
1478       for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1479
1480         n = p -> bounds[ i ];
1481         a = j + n;
1482
1483         if ( p -> d.bDraw[ i ] ) {
1484
1485           for ( pt [ 0 ] = pt[ 1 ] = pt[ 2 ] = 0.; j < a; ++j ) {
1486
1487             pt[ 0 ] += pv[  ind[ j ]  ].xyz[ 0 ];
1488             pt[ 1 ] += pv[  ind[ j ]  ].xyz[ 1 ];
1489             pt[ 2 ] += pv[  ind[ j ]  ].xyz[ 2 ];
1490
1491           }  /* end for ( j ) */
1492
1493           pt[ 0 ] /= n;
1494           pt[ 1 ] /= n;
1495           pt[ 2 ] /= n;
1496
1497           glVertex3fv ( pt );
1498
1499         } else j = a;
1500
1501       }  /* end for ( i ) */
1502
1503       glEnd ();
1504
1505     }  /* end if */
1506
1507 #ifdef G004
1508     if ( !g_fBitmap )
1509 #endif /* G004 */
1510       glEndList ();
1511
1512   } else glCallList ( p -> d.dlist );
1513
1514 }  /* end draw_degenerates_as_points */
1515
1516 static void draw_degenerates_as_bboxs ( tel_indexpoly_data p ) {
1517
1518   Tint*     ind, *vis;
1519   Tint      i, j, n, a, newList = 0;
1520   GLfloat   minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
1521   GLfloat   maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
1522   tel_point pv;
1523
1524   pv  = p -> vertices;
1525   ind = p -> indices;
1526   vis = p -> edge_vis;
1527
1528   LightOff ();
1529
1530 #ifdef G004
1531   if ( g_fBitmap ) goto doDraw;
1532 #endif /* G004 */
1533
1534   if ( p -> d.degMode != 4 || !p -> d.dlist ) {
1535
1536     if ( !p -> d.dlist ) p -> d.dlist = glGenLists ( 1 );
1537
1538     p -> d.degMode = 4;
1539
1540     glNewList ( p -> d.dlist, GL_COMPILE_AND_EXECUTE );
1541     newList = 1;
1542 doDraw:
1543     for ( i = 0, j = 0, a = 0; i < p -> num_bounds; ++i ) {
1544
1545       n = p -> bounds[ i ];
1546       a = j + n;
1547
1548       for ( ; j < a; ++j ) {
1549
1550         if ( pv[  ind[ j ]  ].xyz[ 0 ] < minp[ 0 ] )
1551           minp[ 0 ] = pv[  ind[ j ]  ].xyz[ 0 ] ;
1552         if ( pv[  ind[ j ]  ].xyz[ 1 ] < minp[ 1 ] )
1553           minp[ 1 ] = pv[  ind[ j ]  ].xyz[ 1 ] ;
1554         if ( pv[  ind[ j ]  ].xyz[ 2 ] < minp[ 2 ] )
1555           minp[ 2 ] = pv[  ind[ j ]  ].xyz[ 2 ] ;
1556
1557         if ( pv[  ind[ j ]  ].xyz[ 0 ] > maxp[ 0 ] )
1558           maxp[ 0 ] = pv[  ind[ j ]  ].xyz[ 0 ] ;
1559         if ( pv[  ind[ j ]  ].xyz[ 1 ] > maxp[ 1 ] )
1560           maxp[ 1 ] = pv[  ind[ j ]  ].xyz[ 1 ] ;
1561         if ( pv[  ind[ j ]  ].xyz[ 2 ] > maxp[ 2 ] )
1562           maxp[ 2 ] = pv[  ind[ j ]  ].xyz[ 2 ] ;
1563
1564       }  /* end for ( j ) */
1565
1566     }  /* end for ( i ) */
1567
1568     /* OCC11904 -- Temporarily disable environment mapping */
1569     glPushAttrib(GL_ENABLE_BIT);
1570     glDisable(GL_TEXTURE_1D);
1571     glDisable(GL_TEXTURE_2D);
1572
1573     glBegin ( GL_LINE_STRIP );
1574
1575     glVertex3fv ( minp );
1576     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1577     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1578     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1579     glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
1580
1581     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1582     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1583     glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1584     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1585     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
1586
1587     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1588     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
1589     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
1590     glVertex3fv ( maxp );
1591     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1592     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
1593
1594     glEnd();
1595     glPopAttrib();
1596 #ifdef G004
1597     if ( !g_fBitmap )
1598 #endif /* G004 */
1599       glEndList ();
1600
1601   } else glCallList ( p -> d.dlist );
1602
1603 }  /* end draw_degenerates_as_bboxs */
1604 #endif  /* G003 */
1605
1606 void set_drawable_items ( GLboolean* pbDraw, int n ) {
1607
1608   int i;
1609
1610   memset (  pbDraw, 0, sizeof ( GLboolean ) * n  );
1611
1612   i = ( int )(  ( 1.0F - g_fSkipRatio ) * n  );
1613
1614   while ( i-- ) pbDraw[ OPENGL_RAND() % n ] = 1;
1615
1616 }  /* end set_drawable_items */