0012121: Optimization of existing selection classes
[occt.git] / src / OpenGl / OpenGl_polygon.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_polygon :
6
7
8 REMARQUES:
9 ---------- 
10
11 Le culling et le backfacing ne marchent pas.
12
13 HISTORIQUE DES MODIFICATIONS   :
14 --------------------------------
15 xx-xx-xx : xxx ; Creation.
16 11-03-96 : FMN ; Correction warning compilation
17 01-04-96 : CAL ; Integration MINSK portage WNT
18 28-06-96 : GG  ; Auto checking of the polygon facet normal with
19 the order of the points (OPTIM)
20 09-08-96 : FMN ; Suppression appel glMatrixMode() avant glGetFloatv()
21 28-02-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 27-08-97 : FMN ; Correction affichage des edges
26 On n'affiche que les edges dans le mode IS_EMPTY
27 10-09-97 : FMN ; Amelioration des perfs liees aux lights.
28 15-09-97 : PCT ; Ajout coordonnees textures
29 24-09-97 : FMN ; Suppression OPTIMISATION_FMN.
30 08-12-97 : FMN ; Suppression appel TsmGetAttri inutile.
31 31-12-97 : FMN ; Simplification pour le highlight
32 15-01-98 : FMN ; Ajout Hidden line
33 18-06-98 : CAL ; Correction PRO14340. Patch K4198 et K4199
34 08-03-01 : GG  ; BUC60823 Avoid crash in the normal computation method
35 on confuse point.
36
37 ************************************************************************/
38
39 #define G003  /* EUG 22-09-99 Degeneration management
40 */
41
42 /*----------------------------------------------------------------------*/
43 /*
44 * Includes
45 */ 
46
47 #include <OpenGl_tgl_all.hxx>
48
49 #include <stddef.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52
53 #include <OpenGl_cmn_varargs.hxx>
54 #include <OpenGl_Extension.hxx>
55 #include <OpenGl_telem_attri.hxx>
56 #include <OpenGl_tsm.hxx>
57 #include <OpenGl_telem.hxx>
58 #include <OpenGl_telem_util.hxx>
59 #include <OpenGl_telem_highlight.hxx>
60 #include <OpenGl_telem_inquire.hxx>
61 #include <OpenGl_telem_view.hxx>
62 #include <OpenGl_tgl_funcs.hxx>
63 #include <OpenGl_LightBox.hxx>
64 #include <OpenGl_TextureBox.hxx>
65 #include <OpenGl_Memory.hxx>
66
67
68
69 /*----------------------------------------------------------------------*/
70 /*
71 * Constantes
72 */ 
73
74 #ifndef WNT
75 # define CALLBACK
76 #if !defined(APIENTRY)
77 # define APIENTRY
78 #endif // APIENTRY
79 # define STATIC static
80 #else
81 # include <GL\GLU.H>
82 #define STATIC
83 typedef double GLUcoord;
84 #endif  /* WNT */
85
86 #ifdef G003
87 extern int g_nDegenerateModel;
88 #endif  /* G003 */
89
90 /*----------------------------------------------------------------------*/
91 /*
92 * Fonctions statiques
93 */ 
94
95 static TStatus  PolygonDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
96 static TStatus  PolygonAdd( TSM_ELEM_DATA, Tint, cmn_key* );
97 static TStatus  PolygonDelete( TSM_ELEM_DATA, Tint, cmn_key* );
98 static TStatus  PolygonPrint( TSM_ELEM_DATA, Tint, cmn_key* );
99 static TStatus  PolygonInquire( TSM_ELEM_DATA, Tint, cmn_key* );
100
101 /*----------------------------------------------------------------------*/
102 /*
103 * Variables externes
104 */
105
106 extern  Tint  ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
107
108 /*----------------------------------------------------------------------*/
109 /*
110 * Definition de types
111 */ 
112
113 struct EXTRA_VERTEX
114 {
115   GLfloat vert[3];
116   int ind;
117   IMPLEMENT_MEMORY_OPERATORS
118 };
119 typedef EXTRA_VERTEX* extra_vertex;
120
121 struct SEQ_
122 {
123   Tint ts_num, ts_alloc;
124   void **tmesh_sequence;
125   GLenum triangle_type; /* FSXXX OPTI */
126   IMPLEMENT_MEMORY_OPERATORS
127 };
128
129 struct DISPLAY_
130 {
131   Tint num_of_seq;
132   Tint num_alloc;
133   SEQ_ *seq;
134   IMPLEMENT_MEMORY_OPERATORS
135 };
136
137 struct TEL_POLYGON_DATA
138 {
139   Tint       num_vertices;  /* Number of vertices */
140   Tint       facet_flag;  /* TEL_FA_NONE or TEL_FA_NORMAL */
141   Tint       vertex_flag; /* TEL_VT_NONE or TEL_VT_NORMAL */
142   Tint       shape_flag;  /* TEL_SHAPE_UNKNOWN or TEL_SHAPE_COMPLEX or
143                           TEL_SHAPE_CONVEX  or TEL_SHAPE_CONCAVE */
144   GLboolean  reverse_order; /* GL_TRUE if polygon vertex must be display in reverse order */
145   TEL_POINT  fnormal;   /* Facet normal */
146   tel_colour fcolour;   /* Facet colour */
147   tel_point  vertices;    /* Vertices */
148   tel_colour vcolours;    /* Vertex colour values */
149   tel_point  vnormals;    /* Vertex normals */
150   tel_texture_coord vtexturecoord; /* Texture Coordinates */
151   DISPLAY_   *display;    /* FSXXX OPTI */
152   GLuint     triangle_dl1;     /* triangle display list 1 */
153   GLuint     triangle_dl2;     /* triangle display list 2 */
154   GLuint     triangle_dl3;     /* triangle display list 3 */
155   IMPLEMENT_MEMORY_OPERATORS
156 };
157 typedef TEL_POLYGON_DATA *tel_polygon_data;
158
159 static TEL_POLYGON_DATA polygon_defaults =
160 {
161   0,                 /* num_vertices */
162   TEL_FA_NONE,       /* facet_flag */
163   TEL_VT_NONE,       /* vertex_flag */
164   TEL_SHAPE_UNKNOWN, /* shape_flag */
165   GL_FALSE,        /* reverse_order */
166   {{ ( float )0.0, ( float )0.0, ( float )0.0 }}, /* fnormal */
167   0,                 /* fcolour */
168   0,                 /* vertices */
169   0,                 /* vcolours */
170   0,                 /* vnormals */
171   0,                 /* vtexturecoord */
172   0,                 /* display */
173   0,                 /* triangle_dl1 */
174   0,                 /* triangle_dl2 */
175   0                  /* triangle_dl3 */
176 };
177
178
179 static void bgntriangulate( tel_polygon_data, void (APIENTRY*)() );
180 static void endtriangulate(void);
181 static void draw_tmesh( tel_polygon_data, Tint );
182 static void draw_polygon( tel_polygon_data, Tint, Tint );
183 static void draw_polygon_concav( tel_polygon_data, Tint, Tint );
184
185 #if !defined(GLU_VERSION_1_2)
186 #define GLUtesselator GLUtriangulatorObj
187 void gluTessBeginContour();
188 void gluTessBeginPolygon();
189 void gluTessEndPolygon();
190 void gluTessEndContour();
191 #endif
192
193 static  TStatus  (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
194 {
195   PolygonDisplay,             /* PickTraverse */
196   PolygonDisplay,
197   PolygonAdd,
198   PolygonDelete,
199   PolygonPrint,
200   PolygonInquire
201 };
202
203 static void draw_edges( tel_polygon_data, tel_colour, Tint);
204
205 /*----------------------------------------------------------------------*/
206
207 MtblPtr
208 TelPolygonInitClass( TelType* el )
209 {
210   *el = TelPolygon;
211   return MtdTbl;
212 }
213 /*----------------------------------------------------------------------*/
214
215 static  TStatus
216 PolygonAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
217 {
218   Tint             i, j;
219   tel_polygon_data data;
220
221   for( i = 0; i < n; i++ )
222   {
223     if( k[i]->id == NUM_VERTICES_ID )
224       break;
225   }
226   if( i == n )
227     return TFailure;
228
229   if( !(k[i]->data.ldata) )
230     return TFailure;
231
232   for( j = 0; j < n; j++ )
233   {
234     if( k[j]->id == VERTICES_ID )
235       break;
236   }
237   if( j == n )
238     return TFailure;
239
240   data = new TEL_POLYGON_DATA();
241   if( !data )
242     return TFailure;
243
244   /* load defaults */
245   memcpy( data, &polygon_defaults, sizeof(TEL_POLYGON_DATA) );
246
247   data->num_vertices = k[i]->data.ldata;
248   data->vertices = new TEL_POINT[data->num_vertices];
249   memcpy( data->vertices, k[j]->data.pdata, data->num_vertices*sizeof(TEL_POINT) );
250
251   for( i = 0; i < n; i++ )
252   {
253     switch( k[i]->id )
254     {
255     case FNORMALS_ID:
256       data->facet_flag = TEL_FA_NORMAL;
257       memcpy( &data->fnormal, k[i]->data.pdata, sizeof(TEL_POINT) );
258       vecnrm( data->fnormal.xyz );
259       break;
260
261     case FACET_COLOUR_VALS_ID:
262       data->fcolour = new TEL_COLOUR();
263       memcpy( data->fcolour, k[i]->data.pdata, sizeof(TEL_COLOUR) );
264       break;
265
266     case VERTEX_COLOUR_VALS_ID:
267       data->vcolours = new TEL_COLOUR[data->num_vertices];
268       memcpy( data->vcolours, k[i]->data.pdata, data->num_vertices*sizeof(TEL_COLOUR) );
269       break;
270
271     case VNORMALS_ID:
272       data->vertex_flag = TEL_VT_NORMAL;
273       data->vnormals = new TEL_POINT[data->num_vertices];
274       memcpy( data->vnormals, k[i]->data.pdata, data->num_vertices*sizeof(TEL_POINT) );
275       for( j = 0; j < data->num_vertices; j++ )
276         vecnrm( data->vnormals[j].xyz );
277       break;
278
279     case SHAPE_FLAG_ID:
280       data->shape_flag = k[i]->data.ldata;
281       break;
282
283     case VTEXTURECOORD_ID:
284       data->vtexturecoord = new TEL_TEXTURE_COORD[data->num_vertices];
285       memcpy( data->vtexturecoord, k[i]->data.pdata, data->num_vertices*sizeof(TEL_TEXTURE_COORD) );
286       break;
287     }
288   }
289
290   if( data->facet_flag != TEL_FA_NORMAL ) {
291 #ifdef BUC60823
292     TelGetPolygonNormal( data->vertices, NULL, 
293       data->num_vertices, data->fnormal.xyz );
294 #else
295     TelGetNormal( data->vertices[0].xyz, data->vertices[1].xyz,
296       data->vertices[2].xyz, data->fnormal.xyz );
297     vecnrm( data->fnormal.xyz );
298 #endif
299   }
300   else 
301   {
302     TEL_POINT  fnormal;         /* Facet normal */
303     Tfloat sens;
304 #ifdef BUC60823
305     TelGetPolygonNormal( data->vertices, NULL, 
306       data->num_vertices, fnormal.xyz );
307 #else
308     TelGetNormal( data->vertices[0].xyz, data->vertices[1].xyz,
309       data->vertices[2].xyz, fnormal.xyz );
310 #endif
311     sens = fnormal.xyz[0]*data->fnormal.xyz[0] +
312       fnormal.xyz[1]*data->fnormal.xyz[1] +
313       fnormal.xyz[2]*data->fnormal.xyz[2];
314     if( sens < 0. ) data->reverse_order = GL_TRUE;
315   }
316   ((tsm_elem_data)(d.pdata))->pdata = data;
317
318   /* s'il n'est pas convexe, le polygone est triangule de la meme maniere
319   que les polygones a trous */
320   /* Pourrait etre place en tete de routine pour optimisation si je
321   savais recuperer le shape_flag a partir de d sans reconstruire data (!) */
322
323   /* FSXXX
324   if( data->shape_flag != TEL_SHAPE_CONVEX )
325   return(PolygonHolesAdd( d, n, k ));
326   */
327
328   return TSuccess;
329 }
330 /*----------------------------------------------------------------------*/
331
332 static  TStatus
333 PolygonDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
334 {
335   /*   Tint           front_face = 1;*/
336   CMN_KEY        k11, k12, k17, k111, k114;
337
338   Tint           front_lighting_model;
339   Tint           interior_style;
340   TEL_COLOUR     interior_colour;
341   TEL_COLOUR     edge_colour;
342
343   tel_polygon_data d;
344
345   k12.id          = TelInteriorReflectanceEquation;
346   k17.id          = TelInteriorStyle;
347   k111.id         = TelInteriorColour;
348   k111.data.pdata = &interior_colour;
349   k114.id         = TelEdgeColour;
350   k114.data.pdata = &edge_colour;
351
352   TsmGetAttri( 4, &k12, &k17, &k111, &k114);
353
354   front_lighting_model     = k12.data.ldata;
355   interior_style           = k17.data.ldata;
356
357 #ifdef PRINT
358   printf("PolygonDisplay \n"); 
359 #endif
360
361   /* 
362   * Use highlight colours 
363   */
364
365   if( k[0]->id == TOn )
366   {                         
367     TEL_HIGHLIGHT  hrep;
368
369     k11.id = TelHighlightIndex;
370     TsmGetAttri( 1, &k11 );
371     if( TelGetHighlightRep( TglActiveWs, k11.data.ldata, &hrep ) == TSuccess )
372     {
373       if( hrep.type == TelHLForcedColour )
374       {
375         interior_colour = hrep.col;
376         edge_colour = hrep.col;
377         front_lighting_model = CALL_PHIGS_REFL_NONE;
378       }
379       else
380         k[0]->id = TOff;
381     }
382     else
383     {
384       TelGetHighlightRep( TglActiveWs, 0, &hrep );
385       if( hrep.type == TelHLForcedColour )
386       {
387         interior_colour = hrep.col;
388         edge_colour = hrep.col;
389         front_lighting_model = CALL_PHIGS_REFL_NONE;
390       }
391       else
392         k[0]->id = TOff;
393     }
394   }
395
396   d = (tel_polygon_data)data.pdata;
397 #ifdef G003
398
399   if( interior_style != TSM_EMPTY && g_nDegenerateModel < 2 ) 
400 #else 
401   if( interior_style != TSM_EMPTY ) 
402 #endif  /*G003*/
403   {          
404     if (front_lighting_model == CALL_PHIGS_REFL_NONE)
405       LightOff();
406     else LightOn();
407
408     glColor3fv( interior_colour.rgb );
409
410     if( d->shape_flag != TEL_SHAPE_CONVEX )
411       draw_polygon_concav( d, front_lighting_model, k[0]->id );
412     else
413       draw_polygon( d, front_lighting_model, k[0]->id );
414   }
415
416 #ifdef G003
417   /* OCC11904 -- Temporarily disable environment mapping */
418   glPushAttrib(GL_ENABLE_BIT);
419   glDisable(GL_TEXTURE_1D);
420   glDisable(GL_TEXTURE_2D);
421
422   switch ( g_nDegenerateModel ) {
423
424 default:
425 case 0:  /* no degeneration        */
426   draw_edges ( d, &edge_colour, interior_style );
427   break;
428 case 2:  /* wireframe degeneration */
429
430 #ifdef xG003  /* GG260100 use interior color instead edge color */
431   draw_edges ( d, &interior_colour, interior_style );
432 #else
433   draw_edges ( d, &edge_colour, interior_style );
434 #endif
435   break;
436
437 case 3:  /* marker degeneration */
438
439   break;
440
441   }  /* end switch */
442
443   glPopAttrib(); /* skt: GL_ENABLE_BIT*/
444 #else
445   draw_edges( d, &edge_colour, interior_style );
446   /*skt: It is not correct to pop attributes here*/
447   /*glPopAttrib();*/
448 #endif  /*G003*/
449   return TSuccess;
450
451 }
452 /*----------------------------------------------------------------------*/
453
454 static void
455 draw_polygon( tel_polygon_data d, Tint front_lighting_model, Tint hflag )
456 {
457   Tint      i;
458
459   tel_point ptr;
460   tel_point  pvn;
461   tel_colour pfc, pvc;
462   tel_texture_coord pvt;
463
464   pfc = d->fcolour;
465   pvc = d->vcolours;
466   pvn = d->vnormals;
467   pvt = d->vtexturecoord;
468
469   if( hflag ) pvc = pfc = NULL;
470
471   ptr = d->vertices;
472   if( pfc )
473     glColor3fv( pfc->rgb );
474   if( front_lighting_model != CALL_PHIGS_REFL_NONE )
475     glNormal3fv( d->fnormal.xyz );
476
477   if( d->reverse_order ) glFrontFace( GL_CW );
478
479   if (d->num_vertices == 3) glBegin(GL_TRIANGLES);
480   else if(d->num_vertices == 4) glBegin(GL_QUADS);
481   else glBegin(GL_POLYGON);
482   if( front_lighting_model == CALL_PHIGS_REFL_NONE )
483   {
484     if( pvc )
485     {
486       for( i=0; i<d->num_vertices; i++, ptr++ )
487       {
488         glColor3fv( pvc[i].rgb );
489         glVertex3fv( ptr->xyz );
490       }
491     }
492     else
493     {
494       for( i=0; i<d->num_vertices; i++, ptr++ )
495       {
496         glVertex3fv( ptr->xyz );
497       }
498     }
499   } 
500   else
501   {
502     if( pvn )
503     {
504       if (pvt && !ForbidSetTextureMapping)
505         for( i=0; i<d->num_vertices; i++, ptr++ )
506         {
507           glNormal3fv( pvn[i].xyz );
508           glTexCoord2fv( pvt[i].xy );
509           glVertex3fv( ptr->xyz );
510         }
511       else
512         for( i=0; i<d->num_vertices; i++, ptr++ )
513         {
514           glNormal3fv( pvn[i].xyz );
515           glVertex3fv( ptr->xyz );
516         }      
517     }
518     else
519     {
520       for( i=0; i<d->num_vertices; i++, ptr++ )
521       {
522         glVertex3fv( ptr->xyz );
523       }
524     }
525   }
526   glEnd();
527   if( d->reverse_order ) glFrontFace( GL_CCW );
528
529 }
530
531 /*----------------------------------------------------------------------*/
532
533 /* JWR - allow varying the size */
534
535 #define INCREMENT    8
536
537 static int seq_increment = INCREMENT;
538
539 tel_polygon_data DaTa;
540 static GLUtesselator *tripak = 0;
541
542 STATIC void APIENTRY
543 out_bgntmesh( GLenum triangle_type )
544 {
545   DISPLAY_ *dis;
546   dis = DaTa->display;
547
548   dis->num_of_seq++;
549   if( dis->num_alloc < dis->num_of_seq )
550   {
551     dis->num_alloc += seq_increment;
552
553     if( dis->seq == 0 )
554     {
555       dis->seq = new SEQ_[dis->num_alloc];
556     }
557     else
558     {
559 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
560       dis->seq = (SEQ_*)realloc( dis->seq, dis->num_alloc*sizeof(SEQ_) );
561 #else
562       dis->seq = cmn_resizemem<SEQ_>( dis->seq, dis->num_alloc );
563 #endif
564     }
565   }
566   dis->seq[ dis->num_of_seq - 1 ].ts_num = 0;
567   dis->seq[ dis->num_of_seq - 1 ].ts_alloc = 0;
568   dis->seq[ dis->num_of_seq - 1 ].tmesh_sequence = 0;
569
570 #ifdef JWR_DEC_TRIFAN_BUG
571   dis->seq[ dis->num_of_seq - 1 ].triangle_type = GL_POLYGON;
572   glBegin(GL_POLYGON);
573 #else
574   dis->seq[ dis->num_of_seq - 1 ].triangle_type = triangle_type;
575   glBegin(triangle_type);
576 #endif
577 }
578
579 /*----------------------------------------------------------------------*/
580
581 STATIC void APIENTRY
582 out_vert1( void *data )
583 {
584   SEQ_ *s;
585
586   s  = &( DaTa->display->seq[ DaTa->display->num_of_seq - 1 ] );
587
588   s->ts_num++;
589   if( s->ts_alloc < s->ts_num )
590   {
591     s->ts_alloc += seq_increment;
592
593     if( s->tmesh_sequence == 0 )
594     {
595       s->tmesh_sequence = new void*[s->ts_alloc];
596     }
597     else
598     {
599 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
600       s->tmesh_sequence = (void**)realloc( s->tmesh_sequence, s->ts_alloc*sizeof(void*));
601 #else
602       s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence, s->ts_alloc);
603 #endif
604     }
605   }
606   s->tmesh_sequence[ s->ts_num - 1 ] = data;
607
608
609   if ( data < (void *)0xffff ) {
610     long a = (long)data;
611
612     glVertex3fv( DaTa->vertices[a].xyz );
613   }
614   else {
615     extra_vertex b = (extra_vertex) data;
616
617 #ifdef TRACE
618     printf("combine1 %e   %e   %e %d\n",
619       b->vert[0], b->vert[1], b->vert[2], (b->ind));
620 #endif
621     glVertex3fv( b->vert );
622   }
623
624 }
625
626 /*----------------------------------------------------------------------*/
627
628 STATIC void APIENTRY
629 out_vert2( void *data )
630 {
631   SEQ_ *s;
632
633   s = &( DaTa->display->seq[ DaTa->display->num_of_seq - 1 ] );
634
635   s->ts_num++;
636   if( s->ts_alloc < s->ts_num )
637   {
638     s->ts_alloc += seq_increment;
639
640     if( s->tmesh_sequence == 0 )
641     {
642       s->tmesh_sequence = new void*[s->ts_alloc];
643     }
644     else
645     {
646 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
647       s->tmesh_sequence = (void**)( s->tmesh_sequence,
648         s->ts_alloc*sizeof(void*) );
649 #else
650       s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence,
651         s->ts_alloc );
652 #endif
653     }
654   }
655   s->tmesh_sequence[ s->ts_num - 1 ] = data;
656
657   if ( data < (void *)0xffff ) {
658     long a = (long)data;
659
660     glColor3fv( DaTa->vcolours[a].rgb );
661     glVertex3fv(  DaTa->vertices[a].xyz );
662   }
663   else {
664     extra_vertex b = (extra_vertex) data;
665
666     printf("combine2 %e   %e   %e %d\n",b->vert[0], b->vert[1], b->vert[2], (b->ind));
667     glColor3fv( DaTa->vcolours[(b->ind)].rgb );
668     glVertex3fv( b->vert );
669   }
670
671 }
672
673 /*----------------------------------------------------------------------*/
674
675 STATIC void APIENTRY
676 out_vert3( void *data )
677 {
678   SEQ_ *s;
679
680   s = &( DaTa->display->seq[ DaTa->display->num_of_seq - 1 ] );
681
682   s->ts_num++;
683   if( s->ts_alloc < s->ts_num )
684   {
685     s->ts_alloc += seq_increment;
686
687     if( s->tmesh_sequence == 0 )
688     {
689       s->tmesh_sequence = new void*[s->ts_alloc];
690     }
691     else
692     {
693 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
694       s->tmesh_sequence = (void**)realloc( s->tmesh_sequence,
695         s->ts_alloc*sizeof(void*) );
696 #else
697       s->tmesh_sequence = cmn_resizemem<void*>( s->tmesh_sequence,
698         s->ts_alloc );
699 #endif
700     }
701   }
702   s->tmesh_sequence[ s->ts_num - 1 ] = data;
703
704   if ( data <= (void *)0xffff ) {
705     long a = (long)data;
706
707     glNormal3fv(  DaTa->vnormals[a].xyz );
708     glVertex3fv(  DaTa->vertices[a].xyz);
709   }
710   else {
711     extra_vertex b = (extra_vertex) data;
712
713     printf("combine3 %e   %e   %e  %d\n", b->vert[0], b->vert[1], b->vert[2], (b->ind));
714     glNormal3fv(  DaTa->vnormals[(b->ind)].xyz );
715     glVertex3fv( b->vert );
716   }
717
718 }
719
720 /*----------------------------------------------------------------------*/
721
722 STATIC void APIENTRY
723 mycombine( GLdouble coords[3], int *data, GLfloat w[4],  void **dataout)
724 {
725   extra_vertex  new_vertex;
726
727   new_vertex =  (extra_vertex) malloc(sizeof(EXTRA_VERTEX));
728
729   new_vertex->vert[0] = ( float )coords[0];
730   new_vertex->vert[1] = ( float )coords[1];
731   new_vertex->vert[2] = ( float )coords[2];
732   new_vertex->ind =   *data;
733   *dataout = new_vertex;
734 #ifdef TRACE
735   printf("mycombine3 %e   %e   %e\n",
736     new_vertex->vert[0],
737     new_vertex->vert[1],
738     new_vertex->vert[2],
739     new_vertex->ind);
740   printf("weights: %f %f %f %f\n",
741     w[0], w[1], w[2], w[3]);
742 #endif
743 }
744
745 /*----------------------------------------------------------------------*/
746
747 STATIC void APIENTRY
748 out_endtmesh( void )
749 {
750   glEnd();
751 }
752
753 /*----------------------------------------------------------------------*/
754
755 STATIC void APIENTRY
756 out_error( GLenum error )
757 {
758   printf( "POLYGON : %s\n", (char *) gluErrorString(error) );
759 }
760
761 /*----------------------------------------------------------------------*/
762
763 static void
764 bgntriangulate(tel_polygon_data d, void ( APIENTRY * out_ver)() )
765 {
766   DaTa = d;
767   if( !DaTa->display )
768     DaTa->display = new DISPLAY_();
769
770   tripak = gluNewTess();
771
772 #if defined(linux) && !defined(NOGLUfuncptr)
773   gluTessCallback( tripak, GLU_TESS_BEGIN, (_GLUfuncptr)(out_bgntmesh) );
774   gluTessCallback( tripak, GLU_TESS_VERTEX, out_ver );
775   gluTessCallback( tripak, GLU_TESS_END, out_endtmesh );
776   gluTessCallback( tripak, GLU_TESS_ERROR, (_GLUfuncptr)(out_error) );
777   gluTessCallback( tripak, GLU_TESS_COMBINE, (_GLUfuncptr)(mycombine) );
778 #else 
779   gluTessCallback( tripak, GLU_TESS_BEGIN, (void (APIENTRY*)())out_bgntmesh );
780   gluTessCallback( tripak, GLU_TESS_VERTEX, (void (APIENTRY*)())out_ver );
781   gluTessCallback( tripak, GLU_TESS_END, (void (APIENTRY*)())out_endtmesh );
782   gluTessCallback( tripak, GLU_TESS_ERROR, (void (APIENTRY*)())out_error );
783   gluTessCallback( tripak, GLU_TESS_COMBINE, (void (APIENTRY*)())mycombine );
784 #endif
785 }
786
787 /*----------------------------------------------------------------------*/
788
789 static void
790 endtriangulate()
791 {
792   DaTa = 0;
793   gluDeleteTess(tripak);
794 }
795
796 /*----------------------------------------------------------------------*/
797
798 static void
799 draw_polygon_concav( tel_polygon_data d, Tint front_lighting_model, Tint hflag )
800 {
801   long       i;
802
803   tel_point  pvn;
804   tel_point  ptr;
805   tel_colour pfc, pvc;
806   GLdouble  xyz[3];
807
808   pfc = d->fcolour;
809   pvc = d->vcolours;
810   pvn = d->vnormals;
811
812   if( hflag )
813   {
814     pvc = pfc = NULL;
815   }
816
817   ptr = d->vertices;
818   DaTa = d;
819
820   if( pfc )
821     glColor3fv( pfc->rgb );
822   if( front_lighting_model != CALL_PHIGS_REFL_NONE )
823     glNormal3fv( d->fnormal.xyz );
824
825   if( d->reverse_order ) glFrontFace( GL_CW );
826
827   if( d->display == 0 )
828   {
829
830     if( front_lighting_model == CALL_PHIGS_REFL_NONE )
831     {
832       if( pvc )
833       {
834         bgntriangulate(d, (void (APIENTRY*)())out_vert2);
835       }
836       else
837       {
838         bgntriangulate(d, (void (APIENTRY*)())out_vert1);
839       }
840     }
841     else
842     {
843       if( pvn )
844       {
845         bgntriangulate(d, (void (APIENTRY*)())out_vert3);
846       }
847       else
848       {
849         bgntriangulate(d, (void (APIENTRY*)())out_vert1);
850       }
851     }
852     gluTessBeginPolygon( tripak, NULL );
853     gluTessBeginContour( tripak);
854
855     for( i=0; i<d->num_vertices; i++, ptr++ )
856     {
857       xyz[0] = ptr->xyz[0];
858       xyz[1] = ptr->xyz[1];
859       xyz[2] = ptr->xyz[2];    
860 #ifndef WNT
861       gluTessVertex( tripak, xyz,(void * ) i );
862 #else
863       {
864         double v[ 3 ] = {ptr -> xyz[ 0 ], ptr -> xyz[ 1 ], ptr -> xyz[ 2 ]};
865         gluTessVertex (  tripak,  v, ( void* )i  );
866       }
867 #endif  /* WNT */
868     }
869     gluTessEndContour( tripak);
870     gluTessEndPolygon( tripak );
871     endtriangulate();
872   } 
873   else 
874   {
875     if( front_lighting_model == CALL_PHIGS_REFL_NONE )
876     {
877       if( pvc ) draw_tmesh( d, 2 );
878       else draw_tmesh( d, 1 );
879     }
880     else
881     {
882       if( pvn ) draw_tmesh( d, 3 );
883       else draw_tmesh( d, 1 );
884     }
885   }
886
887   if( d->reverse_order ) glFrontFace( GL_CCW );
888 }
889
890 /*----------------------------------------------------------------------*/
891
892 static void
893 draw_tmesh( tel_polygon_data d, Tint v )
894 {
895   Tint      i, j, k;
896   DISPLAY_ *dis;
897   SEQ_     *s;
898   extra_vertex b;
899
900   dis = d->display;
901   for( i = 0; i < dis->num_of_seq; i++ )
902   {
903     s = &(dis->seq[i]);
904
905     glBegin(s->triangle_type);
906     switch( v )
907     {
908     case 1:
909       {
910         for( j = 0, k = 0; j < s->ts_num; j++ )
911         {
912           if ( s->tmesh_sequence[j] < (void *)0xffff )
913             glVertex3fv( d->vertices[ (long)s->tmesh_sequence[ j ] ].xyz );
914           else {
915             extra_vertex b = (extra_vertex)s->tmesh_sequence[j];
916             glVertex3fv( b->vert );
917           }
918
919         }
920         break;
921       }
922     case 2:
923       {
924         for( j = 0, k = 0; j < s->ts_num; j++ )
925         {
926           if ( s->tmesh_sequence[j] < (void *)0xffff ) {
927             glColor3fv( d->vcolours[ (long) s->tmesh_sequence[ j ] ].rgb );
928             glVertex3fv( d->vertices[ (long) s->tmesh_sequence[ j ] ].xyz );
929           } else {
930             b = (extra_vertex) s->tmesh_sequence[j];
931             glColor3fv( d->vcolours[(b->ind)].rgb);
932             glVertex3fv( b->vert );
933           }
934         }
935         break;
936       }
937     case 3:
938       {
939         for( j = 0, k = 0; j < s->ts_num; j++ )
940         {
941           if ( s->tmesh_sequence[j] < (void *)0xffff ) {
942             glNormal3fv( d->vnormals[ (long) s->tmesh_sequence[ j ] ].xyz);
943             glVertex3fv( d->vertices[ (long) s->tmesh_sequence[ j ] ].xyz);
944           } else {
945             b = (extra_vertex) s->tmesh_sequence[j];
946             glNormal3fv( d->vnormals[(b->ind)].xyz);
947             glVertex3fv( b->vert );
948           }
949         }
950         break;
951       }
952     }
953     glEnd();
954   }
955 }
956
957 /*----------------------------------------------------------------------*/
958
959 static  TStatus
960 PolygonDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
961 {
962   tel_polygon_data p = (tel_polygon_data)data.pdata;
963   if( p->fcolour )  //cmn_freemem( p->fcolour );
964     delete p->fcolour;
965   if( p->vertices )// cmn_freemem( p->vertices );
966     delete[] p->vertices;
967   if( p->vcolours ) //cmn_freemem( p->vcolours );
968     delete[] p->vcolours;
969   if( p->vnormals ) //cmn_freemem( p->vnormals );
970     delete[] p->vnormals;
971   if (p->vtexturecoord) //cmn_freemem( p->vtexturecoord);
972     delete p->vtexturecoord;
973
974   if(p->display)
975   {
976     Tint i, j;
977
978     for( i = 0; i <  p->display->num_of_seq; i++ )
979     {
980       if(p->display->seq[i].tmesh_sequence) {
981         for ( j = 0; j < p->display->seq[i].ts_num ; j++ ) {
982           if ( p->display->seq[i].tmesh_sequence[j] >= (void *)0xffff )
983             free(p->display->seq[i].tmesh_sequence[j]);
984         }
985       }
986       delete[] p->display->seq[i].tmesh_sequence;
987     }
988     delete[] p->display->seq;
989     delete p->display;
990   }
991   if (data.pdata)
992     delete data.pdata;
993   return TSuccess;
994 }
995
996 /*----------------------------------------------------------------------*/
997
998 static  TStatus
999 PolygonPrint( TSM_ELEM_DATA data, Tint n, cmn_key *k )
1000 {
1001   Tint             i;
1002   tel_polygon_data p = (tel_polygon_data)data.pdata;
1003
1004   fprintf( stdout, "TelPolygon. Number of points: %d\n", p->num_vertices );
1005   switch( p->shape_flag )
1006   {
1007   case TEL_SHAPE_UNKNOWN:
1008     fprintf( stdout, "\t\tShape Flag : UNKNOWN\n" );
1009     break;
1010
1011   case TEL_SHAPE_COMPLEX:
1012     fprintf( stdout, "\t\tShape Flag : COMPLEX\n" );
1013     break;
1014
1015   case TEL_SHAPE_CONCAVE:
1016     fprintf( stdout, "\t\tShape Flag : CONCAVE\n" );
1017     break;
1018
1019   case TEL_SHAPE_CONVEX:
1020     fprintf( stdout, "\t\tShape Flag : CONVEX\n" );
1021     break;
1022
1023   }
1024   switch( p->facet_flag )
1025   {
1026   case TEL_FA_NONE:
1027     if( p->fcolour )
1028       fprintf( stdout, "\t\tFacet Flag : COLOUR\n" );
1029     else
1030       fprintf( stdout, "\t\tFacet Flag : NONE\n" );
1031     break;
1032
1033   case TEL_FA_NORMAL:
1034     if( p->fcolour )
1035       fprintf( stdout, "\t\tFacet Flag : COLOURNORMAL\n" );
1036     else
1037       fprintf( stdout, "\t\tFacet Flag : NORMAL\n" );
1038     break;
1039   }
1040   switch( p->vertex_flag )
1041   {
1042   case TEL_VT_NONE:
1043     if( p->vcolours )
1044       fprintf( stdout, "\t\tVertex Flag : COLOUR\n" );
1045     else
1046       fprintf( stdout, "\t\tVertex Flag : NONE\n" );
1047     break;
1048
1049   case TEL_VT_NORMAL:
1050     if( p->vcolours )
1051       fprintf( stdout, "\t\tVertex Flag : COLOURNORMAL\n" );
1052     else
1053       fprintf( stdout, "\t\tVertex Flag : NORMAL\n" );
1054     break;
1055   }
1056   fprintf( stdout, "\t\tFacet Normal : %g %g %g\n", p->fnormal.xyz[0],
1057     p->fnormal.xyz[1],
1058     p->fnormal.xyz[2] );
1059   fprintf( stdout, "\t\tReverse order : %d\n", p->reverse_order);
1060
1061   if( p->fcolour )
1062     fprintf( stdout, "\t\tFacet Colour : %g %g %g\n", p->fcolour->rgb[0],
1063     p->fcolour->rgb[1],
1064     p->fcolour->rgb[2] );
1065   else
1066     fprintf( stdout, "\n\t\tFacet Colour not specified\n" );
1067
1068   if( p->vertices )
1069   {
1070     fprintf( stdout, "\n\t\tVertices : " );
1071     for( i = 0; i < p->num_vertices; i++ )
1072       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
1073       p->vertices[i].xyz[0],
1074       p->vertices[i].xyz[1],
1075       p->vertices[i].xyz[2] );
1076   }
1077
1078   fprintf( stdout, "\n" );
1079   if( p->vcolours )
1080   {
1081     fprintf( stdout, "\n\t\tVertex Colours : " );
1082     for( i = 0; i < p->num_vertices; i++ )
1083       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
1084       p->vcolours[i].rgb[0],
1085       p->vcolours[i].rgb[1],
1086       p->vcolours[i].rgb[2] );
1087   }
1088   else
1089     fprintf( stdout, "\n\t\tVertex Colours not specified\n" );
1090
1091   if( p->vnormals )
1092   {
1093     fprintf( stdout, "\n\t\tVertex Normals : " );
1094     for( i = 0; i < p->num_vertices; i++ )
1095       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
1096       p->vnormals[i].xyz[0],
1097       p->vnormals[i].xyz[1],
1098       p->vnormals[i].xyz[2] );
1099   }
1100   else
1101     fprintf( stdout, "\n\t\tVertex Normals not specified\n" );
1102
1103   if (p->vtexturecoord)
1104   {
1105     fprintf(stdout, "\n\t\tTexture Coordinates : ");
1106     for (i=0; i<p->num_vertices; i++)
1107       fprintf(stdout, "\n\t\t v[%d] = %g %g", i,
1108       p->vtexturecoord[i].xy[0],
1109       p->vtexturecoord[i].xy[1]);
1110   }
1111   else
1112     fprintf( stdout, "\n\t\tTexture Coordinates not specified\n");
1113
1114   fprintf( stdout, "\n" );
1115
1116   return TSuccess;
1117 }
1118
1119 /*----------------------------------------------------------------------*/
1120
1121 static TStatus
1122 PolygonInquire( TSM_ELEM_DATA data, Tint n, cmn_key *k )
1123 {
1124   Tint             i, j;
1125   tel_polygon_data d;
1126   Tint             size_reqd=0;
1127   TStatus          status = TSuccess;
1128   Tchar            *cur_ptr = 0;
1129
1130   d = (tel_polygon_data)data.pdata;
1131
1132   if( d->fcolour )
1133     size_reqd += sizeof( TEL_COLOUR );
1134
1135   if( d->facet_flag == TEL_FA_NORMAL )
1136     size_reqd += sizeof( TEL_POINT );
1137
1138   size_reqd += ( d->num_vertices * sizeof( TEL_POINT ) );
1139
1140   if( d->vcolours )
1141     size_reqd += ( d->num_vertices * sizeof( TEL_COLOUR ) );
1142
1143   if( d->vertex_flag == TEL_VT_NORMAL )
1144     size_reqd += ( d->num_vertices * sizeof( TEL_POINT ) );
1145
1146   for( i = 0; i < n; i++ )
1147   {
1148     switch( k[i]->id )
1149     {
1150     case INQ_GET_SIZE_ID:
1151       {
1152         k[i]->data.ldata = size_reqd;
1153         break;
1154       }
1155
1156     case INQ_GET_CONTENT_ID:
1157       {
1158         TEL_INQ_CONTENT *c;
1159         Teldata         *w;
1160
1161         c = (tel_inq_content)k[i]->data.pdata;
1162         c->act_size = size_reqd;
1163         w = c->data;
1164
1165         cur_ptr = c->buf;
1166         w->fillarea3data.num_points = d->num_vertices;
1167         w->fillarea3data.shpflag = d->shape_flag;
1168
1169         if( c->size >= size_reqd )
1170         {
1171           if( d->facet_flag == TEL_FA_NORMAL )
1172           {
1173             if( d->fcolour )
1174             {
1175               w->fillarea3data.faflag = TEL_FAFLAG_COLOURNORMAL;
1176               w->fillarea3data.gnormal = (tel_point)(c->buf);
1177               *(w->fillarea3data.gnormal) = d->fnormal;
1178               w->fillarea3data.facet_colour_val =
1179                 (tel_colour)(c->buf + sizeof( TEL_POINT ) );
1180               *(w->fillarea3data.facet_colour_val) = *(d->fcolour);
1181               cur_ptr = c->buf + sizeof( TEL_POINT ) +
1182                 sizeof( TEL_COLOUR );
1183             }
1184             else
1185             {
1186               w->fillarea3data.faflag = TEL_FAFLAG_NORMAL;
1187               w->fillarea3data.facet_colour_val = 0;
1188               w->fillarea3data.gnormal = (tel_point)(c->buf);
1189               *(w->fillarea3data.gnormal) = d->fnormal;
1190               cur_ptr = c->buf + sizeof( TEL_POINT );
1191             }
1192           }
1193           else
1194           {
1195             w->fillarea3data.gnormal = 0;
1196             if( d->fcolour )
1197             {
1198               w->fillarea3data.faflag = TEL_FAFLAG_COLOUR;
1199               w->fillarea3data.facet_colour_val = (tel_colour)(c->buf );
1200               *(w->fillarea3data.facet_colour_val) = *(d->fcolour);
1201               cur_ptr = c->buf + sizeof( TEL_COLOUR );
1202             }
1203             else
1204             {
1205               w->fillarea3data.faflag = TEL_FAFLAG_NONE;
1206               w->fillarea3data.facet_colour_val = 0;
1207             }
1208           }
1209
1210           w->fillarea3data.points = (tel_point)cur_ptr;
1211           for( j = 0; j < d->num_vertices; j++ )
1212           {
1213             w->fillarea3data.points[j] = d->vertices[j];
1214           }
1215           cur_ptr += ( d->num_vertices * sizeof( TEL_POINT ) );
1216
1217           if( d->vertex_flag == TEL_VT_NORMAL )
1218           {
1219             if( d->vcolours )
1220             {
1221               w->fillarea3data.vrtflag = TEL_VTFLAG_COLOURNORMAL;
1222               w->fillarea3data.vnormals = (tel_point)(cur_ptr);
1223               for( j = 0; j < d->num_vertices; j++ )
1224               {
1225                 w->fillarea3data.vnormals[j] = d->vnormals[i];
1226               }
1227               cur_ptr += ( d->num_vertices * sizeof( TEL_POINT ) );
1228
1229               w->fillarea3data.colours = (tel_colour)(cur_ptr);
1230
1231               for( j = 0; j < d->num_vertices; j++ )
1232               {
1233                 w->fillarea3data.colours[j] = d->vcolours[i];
1234               }
1235             }
1236             else
1237             {
1238               w->fillarea3data.vrtflag = TEL_VTFLAG_NORMAL;
1239               w->fillarea3data.colours = 0;
1240               w->fillarea3data.vnormals = (tel_point)(cur_ptr);
1241
1242               for( j = 0; j < d->num_vertices; j++ )
1243               {
1244                 w->fillarea3data.vnormals[j] = d->vnormals[i];
1245               }
1246             }
1247           }
1248           else
1249           {
1250             w->fillarea3data.vnormals = 0;
1251             if( d->vcolours )
1252             {
1253               w->fillarea3data.vrtflag = TEL_VTFLAG_COLOUR;
1254               w->fillarea3data.colours = (tel_colour)(cur_ptr);
1255               for( j = 0; j < d->num_vertices; j++ )
1256               {
1257                 w->fillarea3data.colours[j] = d->vcolours[i];
1258               }
1259             }
1260             else
1261             {
1262               w->fillarea3data.vrtflag = TEL_VTFLAG_NONE;
1263               w->fillarea3data.colours = 0;
1264             }
1265           }
1266
1267           status = TSuccess;
1268         }
1269         else
1270           status = TFailure;
1271         break;
1272       }
1273     }
1274   }
1275   return status;
1276 }
1277 /*----------------------------------------------------------------------*/
1278
1279 static void
1280 draw_edges( tel_polygon_data p, tel_colour edge_colour, Tint interior_style )
1281 {
1282   CMN_KEY k, k1, k2, k3, k4;
1283   tel_point  ptr;
1284   Tint    i;
1285   Tint    edge_type, line_type_preserve;
1286   Tfloat  edge_width, line_width_preserve;
1287   GLboolean texture_on;
1288
1289   if (interior_style != TSM_HIDDENLINE)
1290   {
1291     k.id = TelEdgeFlag;
1292     TsmGetAttri( 1, &k );
1293     if( k.data.ldata == TOff )return;
1294   } 
1295
1296   ptr = p->vertices;
1297
1298   LightOff();
1299   texture_on = IsTextureEnabled();
1300   if (texture_on) DisableTexture();
1301
1302   k1.id  = TelPolylineWidth;
1303   k2.id  = TelPolylineType;
1304   k3.id  = TelEdgeType;
1305   k4.id  = TelEdgeWidth;
1306
1307   TsmGetAttri( 4, &k1, &k2, &k3, &k4 );
1308
1309   line_width_preserve = k1.data.fdata;
1310   line_type_preserve  = k2.data.ldata;
1311   edge_type           = k3.data.ldata;
1312   edge_width          = k4.data.fdata;
1313
1314   if( line_width_preserve != edge_width )
1315   {
1316     k.id = TelPolylineWidth;
1317     k.data.fdata = edge_width;
1318     TsmSetAttri( 1, &k );
1319   }
1320   if( line_type_preserve != edge_type )
1321   {
1322     k.id = TelPolylineType;
1323     k.data.ldata = edge_type;
1324     TsmSetAttri( 1, &k );
1325   }
1326
1327   glColor3fv( edge_colour->rgb );
1328
1329   glBegin(GL_LINE_LOOP);
1330   for( i=0; i<p->num_vertices; i++, ptr++ )
1331   {
1332     glVertex3fv( ptr->xyz );
1333   }
1334   glEnd();
1335
1336   if( line_width_preserve != edge_width )
1337   {
1338     k.id = TelPolylineWidth;
1339     k.data.fdata = line_width_preserve;
1340     TsmSetAttri( 1, &k );
1341   }
1342   if( line_type_preserve != edge_type )
1343   {
1344     k.id = TelPolylineType;
1345     k.data.ldata = line_type_preserve;
1346     TsmSetAttri( 1, &k );
1347   }
1348
1349   if (texture_on) EnableTexture();
1350 }
1351 /*----------------------------------------------------------------------*/