0022337: V3d_View::Print crashes in OCCT 6.5.0
[occt.git] / src / OpenGl / OpenGl_polygon.cxx
CommitLineData
7fd59977 1/***********************************************************************
2
3FONCTION :
4----------
5File OpenGl_polygon :
6
7
8REMARQUES:
9----------
10
11Le culling et le backfacing ne marchent pas.
12
13HISTORIQUE DES MODIFICATIONS :
14--------------------------------
15xx-xx-xx : xxx ; Creation.
1611-03-96 : FMN ; Correction warning compilation
1701-04-96 : CAL ; Integration MINSK portage WNT
1828-06-96 : GG ; Auto checking of the polygon facet normal with
19the order of the points (OPTIM)
2009-08-96 : FMN ; Suppression appel glMatrixMode() avant glGetFloatv()
2128-02-97 : FMN ; Suppression OpenGl_telem_light.h
2218-07-97 : FMN ; Ajout desactivation des lights suivant front_lighting_model
2321-07-97 : FMN ; Amelioration des performances OPTIMISATION_FMN
24- suppression calcul inutile sur les front faces
2527-08-97 : FMN ; Correction affichage des edges
26On n'affiche que les edges dans le mode IS_EMPTY
2710-09-97 : FMN ; Amelioration des perfs liees aux lights.
2815-09-97 : PCT ; Ajout coordonnees textures
2924-09-97 : FMN ; Suppression OPTIMISATION_FMN.
3008-12-97 : FMN ; Suppression appel TsmGetAttri inutile.
3131-12-97 : FMN ; Simplification pour le highlight
3215-01-98 : FMN ; Ajout Hidden line
3318-06-98 : CAL ; Correction PRO14340. Patch K4198 et K4199
3408-03-01 : GG ; BUC60823 Avoid crash in the normal computation method
35on 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
83typedef double GLUcoord;
84#endif /* WNT */
85
86#ifdef G003
87extern int g_nDegenerateModel;
88#endif /* G003 */
89
90/*----------------------------------------------------------------------*/
91/*
92* Fonctions statiques
93*/
94
95static TStatus PolygonDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
96static TStatus PolygonAdd( TSM_ELEM_DATA, Tint, cmn_key* );
97static TStatus PolygonDelete( TSM_ELEM_DATA, Tint, cmn_key* );
98static TStatus PolygonPrint( TSM_ELEM_DATA, Tint, cmn_key* );
99static TStatus PolygonInquire( TSM_ELEM_DATA, Tint, cmn_key* );
100
101/*----------------------------------------------------------------------*/
102/*
103* Variables externes
104*/
105
106extern Tint ForbidSetTextureMapping; /* currently defined in tsm/tsm.c */
107
108/*----------------------------------------------------------------------*/
109/*
110* Definition de types
111*/
112
113struct EXTRA_VERTEX
114{
115 GLfloat vert[3];
116 int ind;
117 IMPLEMENT_MEMORY_OPERATORS
118};
119typedef EXTRA_VERTEX* extra_vertex;
120
121struct SEQ_
122{
123 Tint ts_num, ts_alloc;
124 void **tmesh_sequence;
125 GLenum triangle_type; /* FSXXX OPTI */
126 IMPLEMENT_MEMORY_OPERATORS
127};
128
129struct DISPLAY_
130{
131 Tint num_of_seq;
132 Tint num_alloc;
133 SEQ_ *seq;
134 IMPLEMENT_MEMORY_OPERATORS
135};
136
137struct 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};
157typedef TEL_POLYGON_DATA *tel_polygon_data;
158
159static 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
179static void bgntriangulate( tel_polygon_data, void (APIENTRY*)() );
180static void endtriangulate(void);
181static void draw_tmesh( tel_polygon_data, Tint );
182static void draw_polygon( tel_polygon_data, Tint, Tint );
183static void draw_polygon_concav( tel_polygon_data, Tint, Tint );
184
185#if !defined(GLU_VERSION_1_2)
186#define GLUtesselator GLUtriangulatorObj
187void gluTessBeginContour();
188void gluTessBeginPolygon();
189void gluTessEndPolygon();
190void gluTessEndContour();
191#endif
192
193static TStatus (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
194{
195 PolygonDisplay, /* PickTraverse */
196 PolygonDisplay,
197 PolygonAdd,
198 PolygonDelete,
199 PolygonPrint,
200 PolygonInquire
201};
202
203static void draw_edges( tel_polygon_data, tel_colour, Tint);
204
205/*----------------------------------------------------------------------*/
206
207MtblPtr
208TelPolygonInitClass( TelType* el )
209{
210 *el = TelPolygon;
211 return MtdTbl;
212}
213/*----------------------------------------------------------------------*/
214
215static TStatus
216PolygonAdd( 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
332static TStatus
333PolygonDisplay( 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
424default:
425case 0: /* no degeneration */
426 draw_edges ( d, &edge_colour, interior_style );
427 break;
428case 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
437case 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
454static void
455draw_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
537static int seq_increment = INCREMENT;
538
539tel_polygon_data DaTa;
540static GLUtesselator *tripak = 0;
541
542STATIC void APIENTRY
543out_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
581STATIC void APIENTRY
582out_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
628STATIC void APIENTRY
629out_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
675STATIC void APIENTRY
676out_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
722STATIC void APIENTRY
723mycombine( 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
747STATIC void APIENTRY
748out_endtmesh( void )
749{
750 glEnd();
751}
752
753/*----------------------------------------------------------------------*/
754
755STATIC void APIENTRY
756out_error( GLenum error )
757{
758 printf( "POLYGON : %s\n", (char *) gluErrorString(error) );
759}
760
761/*----------------------------------------------------------------------*/
762
763static void
764bgntriangulate(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
789static void
790endtriangulate()
791{
792 DaTa = 0;
793 gluDeleteTess(tripak);
794}
795
796/*----------------------------------------------------------------------*/
797
798static void
799draw_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
892static void
893draw_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
959static TStatus
960PolygonDelete( 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
998static TStatus
999PolygonPrint( 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
1121static TStatus
1122PolygonInquire( 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
1279static void
1280draw_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/*----------------------------------------------------------------------*/