Integration of OCCT 6.5.0 from SVN
[occt.git] / src / OpenGl / OpenGl_togl_begin_immediat_mode.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 file OpenGl_togl_begin_immediat_mode.c :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : CAL ; Creation.
15 08-03-96 : FMN ; - Ajout include manquant 
16 01-04-96 : CAL ; Integration MINSK portage WNT
17 15-04-96 : CAL ; Integration travail PIXMAP de Jim ROTH
18 07-05-96 : CAL ; Gestion du minmax calcule en C++
19 voir call_togl_set_minmax
20 Debug temporaire pour ROB, TelRobSetRGB ()
21 12-06-96 : CAL ; Recuperation des attributs lors d'un draw_structure
22 22-07-96 :  GG ; Faire fonctionner correctement le highlight
23 des polygones en mode immediat
24 11-09-96 : FMN ; Ajout appel a TxglWinset dans call_togl_begin_immediat_mode
25 04-11-96 : CAL : Retrait du mode simule, ajout du higlight
26 dans togl_draw_structure
27 06-11-96 : CAL : Retrait du test sur doublebuffer PRO5949
28 16-12-96 : CAL : Ajout d'un glFinish () dans end_immediat_mode
29 21-01-97 : CAL : Gestion du flag <partial> differente pour
30 eviter les comparaisons avec shortrealfirst ou last
31 22-04-97 : FMN ; Correction faute i a la place de j dans util_transform_pt
32 22-04-97 : FMN ; Correction appel util_transform_pt dans togl_set_minmax
33 24-04-97 : FMN ; (PRO4063) Ajout displaylist pour le mode transient
34 25-07-97 : CAL ; Portage WNT (Bool, False, True)
35 30-07-97 : FMN ; Meilleure gestion de la desactivation des lights
36 10-09-97 : FMN ; Meilleure gestion de la desactivation des lights
37 07-10-97 : FMN ; Simplification WNT
38 Ajout glFlush dans call_togl_clear_immediat_mode()
39 26-11-97 : FMN ; Ajout mode Ajout et xor
40 Meilleure gestion display list pour le RetainMode
41 19-12-97 : FMN ; Oublie return dans le call_togl_begin_ajout_mode()
42 22-12-97 : FMN ; Suppression DEBUG_TEMPO_FOR_ROB
43 Correction PRO10217
44 Ajout affichage cadre TelCopyBuffer
45 Ajout LightOff sur le redraw.
46 02-02-98 : CAL ; Correction du bug sur les transformations de structure
47 tracees en mode transient. (PRO10217) (PRO12283)
48 05-02-98 : CAL ; Perfs : mise en place d'un flag identity pour savoir
49 si la matrice de transformation est l'identite.
50 08-04-98 : FMN ; Mailleur traitement du reaffichage d'une vue. Remplacement 
51 de TsmDisplayStructure() par call_func_redraw_all_structs(). 
52 08-07-98 : FMN ; PRO14399: Desactivation animationFlag quand on debute
53 le mode immediat (Transient et Ajout). 
54 30-09-98 : CAL ; Optimisation pour eviter de charger inutilement
55 les matrices de la vue.
56 27-11-98 : CAL ; S4062. Ajout des layers.
57 02.14.100 : JR : Warnings on WNT truncations from double to float
58
59 IMP190100 : GG
60 //                      -> Preserve current attributes because
61 //                      attributes can be changed between
62 //                      begin_immediate_mode() end end_immediate_mode()
63 //                      -> Optimize transformations computation.
64 //          -> Optimize REDRAW in immediat mode.
65 //  19/09/00  -> Avoid to raise in set_linetype() & set_linewith()
66 //        due to a bad call to TsmPutAttri() function.
67
68 BUC60726  GG_040900 Clear the last temporary detected in any case
69
70 BUC60900  GG_180501 Unhilight entity more earlier
71 when clear() is call instead at the next begin().
72
73 ************************************************************************/
74
75
76 #define BUC60863  /*GG_100401 After any view update, made identical 
77 //      the front and back buffer to avoid ghost drawing.
78 //      Minimize flicking.
79 */
80
81 #define IMP150501       /*GG_150501 CADPAK_V2 Enable/Disable Zbuffer  
82 NOTE that the previous and unused "double-buffer"
83 arg is changed to "zbuffer" and enable/disable
84 to use the OpenGl zbuffer capabilities during immediat
85 drawing 
86 */
87
88 #define IMP260601 /*GG Enable correct backing store between 2 different views.
89 */
90
91 #define IMP051001 /*GG Activates the polygon offset for polygon 
92 //      selection fill mode.
93 */
94
95 /*----------------------------------------------------------------------*/
96
97 #define RIC120302       /* GG Enable to use the application display
98 //                      callback at end of traversal
99 */
100
101 /*
102 * Includes
103 */
104
105 #include <OpenGl_tgl_all.hxx>
106 #ifdef IMP051001
107 #include <OpenGl_Extension.hxx>
108 #endif
109 #include <math.h>
110 #include <GL/gl.h>
111 #include <stdio.h>
112
113 #include <InterfaceGraphic_Labels.hxx>
114 #include <InterfaceGraphic_Graphic3d.hxx>
115 #include <InterfaceGraphic_Visual3d.hxx>
116
117 #include <OpenGl_tsm_ws.hxx>
118 #include <OpenGl_txgl.hxx>
119 #include <OpenGl_tgl_tox.hxx>
120 #include <OpenGl_tgl_funcs.hxx>
121 #include <OpenGl_telem_filters.hxx>
122 #include <OpenGl_telem.hxx>
123 #include <OpenGl_telem_util.hxx>
124 #include <OpenGl_telem_view.hxx>
125 #include <OpenGl_LightBox.hxx>
126 #include <OpenGl_animation.hxx>
127 #include <OpenGl_telem_attri.hxx>
128 #include <OpenGl_tgl.hxx>
129 #include <OpenGl_tgl_subrvis.hxx>
130
131 int call_util_osd_getenv( char * , char * , int ) ;
132
133 /*----------------------------------------------------------------------*/
134 /* 
135 * Constantes
136 */
137
138 #define xCOPY
139 #define xTRACE 0
140
141 #if TRACE > 0
142 #include <OpenGl_traces.h>
143 #endif
144
145
146 /*----------------------------------------------------------------------*/
147 /* 
148 * Variables externes
149 */
150
151 /*----------------------------------------------------------------------*/
152 /*
153 * Prototypes fonctions
154 */
155
156 /*----------------------------------------------------------------------*/
157 /*
158 * Prototypes Private functions
159 */
160
161 static void call_util_transform_pt (float *x, float *y, float *z);
162 static int call_util_is_identity ();
163 static void call_util_transpose_mat (float tmat[16], float mat[4][4]);
164
165 /*----------------------------------------------------------------------*/
166 /* 
167 * Variables statiques
168 */
169
170 static int openglNumberOfPoints = 0;
171 static GLint openglViewId = 0;
172 static GLint openglWsId = 0;
173
174 static int identity = 1;
175
176 static int partial = -1;  /* -1 init, 0 complete, 1 partielle */
177
178 static float xm, ym, zm, XM, YM, ZM;
179
180 static float openglMat[4][4] = {
181   {1., 0., 0., 0.},
182   {0., 1., 0., 0.},
183   {0., 0., 1., 0.},
184   {0., 0., 0., 1.},
185 };
186
187 static GLboolean transientOpen = GL_FALSE;
188
189 /*----------------------------------------------------------------------*/
190 /*  Mode Ajout              */
191 /*----------------------------------------------------------------------*/
192
193 int EXPORT call_togl_begin_ajout_mode (
194                                        CALL_DEF_VIEW *aview
195                                        )
196 {
197   CMN_KEY_DATA data;
198
199   TsmGetWSAttri (aview->WsId, WSWindow, &data);
200 #ifdef IMP260601
201   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) != TSuccess) return (0);
202 #else
203   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) == TSuccess)
204 #endif
205
206     if (aview->ViewId == -1) return (0);
207
208   openglWsId = aview->WsId;
209   openglViewId = aview->ViewId;
210
211   /* mise en place des matrices de projection et de mapping */
212   /* TelSetViewIndex (aview->WsId, aview->ViewId); */
213
214 #ifdef TRACE
215   printf ("call_togl_begin_ajout_mode %d %d\n", openglViewId, openglWsId);
216 #endif
217
218   TelMakeFrontAndBackBufCurrent (aview->WsId);
219
220   TsmPushAttri();
221
222   return (1);
223 }
224
225 /*----------------------------------------------------------------------*/
226 void EXPORT call_togl_end_ajout_mode ()
227 {
228
229 #ifdef TRACE
230   printf ("call_togl_end_ajout_mode %d %d\n", openglViewId, openglWsId);
231 #endif
232
233   if (openglViewId != 0) {
234     TelMakeBackBufCurrent (openglWsId);
235   }
236
237   openglViewId = 0;
238   openglWsId = 0;
239
240   identity = 1;
241
242   /* FMN necessaire pour l'affichage sur WNT */
243   glFlush();
244
245   TsmPopAttri();
246
247 }
248
249
250 /*----------------------------------------------------------------------*/
251 /*  Mode Transient              */
252 /*----------------------------------------------------------------------*/
253
254 void EXPORT call_togl_clear_immediat_mode (
255   CALL_DEF_VIEW *aview, Tint aFlush
256   )
257 {
258   CMN_KEY_DATA   data;
259   GLuint listIndex = 0;
260   GLuint retainmode = 0;
261
262   if( transientOpen ) {
263     call_togl_end_immediat_mode(0);
264   } 
265
266 #ifdef IMP260601
267   TsmGetWSAttri (aview->WsId, WSWindow, &data);
268   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) != TSuccess) return;
269 #endif
270   TsmGetWSAttri( aview->WsId, WSRetainMode, &data );
271   retainmode = data.ldata;
272
273 #ifdef TRACE
274   printf("call_togl_clear_immediat_mode. xm %f, ym %f, zm %f, XM %f, YM %f, ZM %f, partial %d retainmode %d\n",xm, ym, zm, XM, YM, ZM, partial, retainmode);
275 #endif
276
277   if (  TelBackBufferRestored () == TOff ) {
278     call_togl_erase_animation_mode();
279     call_func_redraw_all_structs_begin (aview->WsId);
280     if( aview->ptrUnderLayer)
281       call_togl_redraw_layer2d (aview, (CALL_DEF_LAYER *)aview->ptrUnderLayer);
282     call_func_redraw_all_structs_proc (aview->WsId);
283     if( aview->ptrOverLayer)
284       call_togl_redraw_layer2d (aview, (CALL_DEF_LAYER *)aview->ptrOverLayer);
285 #ifdef RIC120302
286     call_subr_displayCB(aview,OCC_REDRAW_WINDOW);
287 #endif
288     call_func_redraw_all_structs_end (aview->WsId, aFlush);
289     /*
290     After a redraw,
291     Made the back identical to the front buffer
292     */
293     if( retainmode && (partial >= 0) )
294       TelCopyBuffers (aview->WsId, GL_FRONT, GL_BACK,
295       xm, ym, zm, XM, YM, ZM, partial);
296 #ifdef TRACE
297     printf(" $$$ REDRAW\n");
298 #endif
299     TelSetBackBufferRestored (TOn);
300   } else if( partial >= 0 ) {
301     /*
302     Restore pixels from the back buffer.
303     */
304     TelCopyBuffers (aview->WsId, GL_BACK, GL_FRONT,
305       xm, ym, zm, XM, YM, ZM, partial);
306   }
307
308   TsmGetWSAttri (aview->WsId, WSTransient, &data);
309   listIndex = (GLuint) data.ldata;
310   if( listIndex != 0 ) {  /* Clear current list contents */
311     glNewList( listIndex, GL_COMPILE_AND_EXECUTE);   
312     glEndList();
313   }
314   partial = -1;
315   XM = YM = ZM = (float ) shortrealfirst ();
316   xm = ym = zm = (float ) shortreallast ();
317 }
318
319 /*----------------------------------------------------------------------*/
320
321 void call_togl_redraw_immediat_mode(
322                                     CALL_DEF_VIEW * aview
323                                     )
324 {
325   CMN_KEY_DATA   data;
326   GLuint listIndex = 0;
327   int retainmode = 0;
328 #ifndef IMP150501
329   GLboolean flag_zbuffer = GL_FALSE;
330 #endif
331
332   TsmGetWSAttri( aview->WsId, WSRetainMode, &data );
333   retainmode = data.ldata;
334
335   TsmGetWSAttri (aview->WsId, WSTransient, &data);
336   listIndex = (GLuint) data.ldata;
337
338   if (retainmode != 0) {
339     if (listIndex != 0) {
340       TelMakeFrontBufCurrent (aview->WsId);
341
342       LightOff();
343       /* mise en place des matrices de projection et de mapping */
344       /* TelSetViewIndex (aview->WsId, aview->ViewId);  */
345
346 #ifdef TRACE
347       printf("call_togl_redraw_immediat_mode::call displaylist(%d) \n",
348         listIndex);
349 #endif
350 #ifdef IMP150501
351       glCallList(listIndex); 
352 #else
353       flag_zbuffer = glIsEnabled(GL_DEPTH_TEST);
354       if (flag_zbuffer) glDisable(GL_DEPTH_TEST);
355       glCallList(listIndex); 
356       if (flag_zbuffer) glEnable(GL_DEPTH_TEST); 
357 #endif
358       /* FMN necessaire pour l'affichage sur WNT */
359       glFlush();
360
361       TelMakeBackBufCurrent (aview->WsId);
362     } 
363   }
364 }
365
366
367 /*----------------------------------------------------------------------*/
368
369 int EXPORT
370 call_togl_begin_immediat_mode
371 (
372  CALL_DEF_VIEW * aview,
373  CALL_DEF_LAYER * anunderlayer,
374  CALL_DEF_LAYER * anoverlayer,
375 #ifdef IMP150501
376  int zbuffer, 
377 #else
378  int doublebuffer,
379 #endif
380  int retainmode
381  )
382 {
383   CMN_KEY_DATA data;
384   GLuint listIndex = 0;
385
386   if (aview->ViewId == -1) return (0);
387
388   TsmGetWSAttri (aview->WsId, WSWindow, &data);
389 #ifdef IMP260601
390   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) != TSuccess) return (0);
391 #else
392   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) == TSuccess)
393 #endif
394
395     openglWsId = aview->WsId;
396   openglViewId = aview->ViewId;
397
398   data.ldata = retainmode;
399   TsmSetWSAttri( aview->WsId, WSRetainMode, &data );
400
401 #ifdef TRACE
402   printf ("call_togl_begin_immediat_mode %d %d RetainMode %d zbuffer %d partial %d\n", openglViewId, openglWsId, retainmode, zbuffer, partial);
403 #endif
404
405   call_togl_clear_immediat_mode(aview,1);
406
407   TelMakeFrontBufCurrent (aview->WsId);
408
409   TsmPushAttri();
410
411 #ifdef COPY
412   if (partial == 1) {
413     glColor3f (1., 0., 0.);
414     glBegin(GL_LINE_LOOP);
415     glVertex3f (xm, ym, zm);
416     glVertex3f (XM, ym, zm);
417     glVertex3f (XM, YM, zm);
418     glVertex3f (xm, YM, zm);
419     glEnd();
420   }
421 #endif
422
423   /* 
424   * RetainMode
425   */
426   if( retainmode ) {
427     TsmGetWSAttri (aview->WsId, WSTransient, &data);
428     listIndex = (GLuint) data.ldata;
429
430     if (listIndex == 0) {
431       listIndex = glGenLists(1);
432 #ifdef TRACE
433       printf("call_togl_begin_immediat_mode::init displaylist() %d \n", listIndex);
434 #endif
435       data.ldata = listIndex;
436       TsmSetWSAttri( aview->WsId, WSTransient, &data );
437     }
438     if (listIndex == 0) return(0);    
439 #ifdef TRACE
440     printf("call_togl_begin_immediat_mode::glNewList() %d \n", listIndex);
441 #endif
442     glNewList(listIndex, GL_COMPILE_AND_EXECUTE);   
443     transientOpen = GL_TRUE;
444   }
445
446 #ifdef IMP150501
447   if( zbuffer ) {
448     glEnable(GL_DEPTH_TEST);
449   } else glDisable(GL_DEPTH_TEST);
450 #endif
451
452   return (1);
453 }
454
455
456 /*----------------------------------------------------------------------*/
457 /*
458 call_togl_end_immediat_mode (synchronize)
459 GLboolean synchronize
460
461 End of immediate graphic primitives in the view.
462 */
463
464 void EXPORT
465 call_togl_end_immediat_mode
466 (
467  int synchronize
468  )
469 {
470
471 #ifdef TRACE
472   printf ("call_togl_end_immediat_mode %d %d %d\n", 
473     synchronize, openglViewId, openglWsId);
474 #endif
475
476 #ifndef BUC60863  /* Don't modify the current minmax !!*/
477   /* Mise ajout MinMax */
478   if ((xm > shortreallast ()) ||
479     (ym > shortreallast ()) ||
480     (zm > shortreallast ()) ||
481     (XM > shortreallast ()) ||
482     (YM > shortreallast ()) ||
483     (ZM > shortreallast ()) ||
484     (xm < shortrealfirst ()) ||
485     (ym < shortrealfirst ()) ||
486     (zm < shortrealfirst ()) ||
487     (XM < shortrealfirst ()) ||
488     (YM < shortrealfirst ()) ||
489     (ZM < shortrealfirst ())) {
490       XM = YM = ZM = (float ) shortreallast ();
491       xm = ym = zm = (float ) shortrealfirst ();
492       partial = 0;
493     }
494   else {
495     if (partial != 0) partial = 1;
496   }
497 #endif  /*BUC60863*/
498
499   if (openglViewId != 0) {
500 #ifdef COPY
501     if (partial == 1) {
502       glColor3f (0., 1., 0.);
503       glBegin(GL_LINE_LOOP);
504       glVertex3f (xm, ym, zm);
505       glVertex3f (XM, ym, zm);
506       glVertex3f (XM, YM, zm);
507       glVertex3f (xm, YM, zm);
508       glEnd();
509     }
510 #endif
511
512     if (transientOpen) {
513       glEndList();
514 #ifdef TRACE
515       printf("--->glEndList() \n");
516 #endif
517       transientOpen = GL_FALSE;
518     }
519
520     TelMakeBackBufCurrent (openglWsId);     
521   }
522
523   /*
524   * Ajout CAL : pour voir quelque chose
525   * avant le prochain begin_immediat_mode
526   */
527   glFinish ();
528
529   openglViewId = 0;
530   openglWsId = 0;
531
532   identity = 1;
533
534   TsmPopAttri();
535
536 }
537
538 /*----------------------------------------------------------------------*/
539 /*
540 call_togl_transform (amatrix, mode)
541 float amatrix[4][4]
542 GLboolean mode
543
544 Set the local transformation for All primitives
545 REPLACE the existante if mode is True or POSTCONCATENATE if GL_FALSE
546 */
547 void EXPORT
548 call_togl_transform ( float amatrix[4][4], int mode )
549 {
550   int i, j;
551   if (mode || identity) {
552     for (i=0; i<4; i++)
553       for (j=0; j<4; j++)
554         openglMat[i][j] = amatrix[i][j];
555   } else
556     TelMultiplymat3 (openglMat, openglMat, amatrix);
557
558   identity = call_util_is_identity ();
559 }
560
561
562 /*
563 call_togl_begin_polyline ()
564
565 Sets the graphic library ready to receive a polyline.
566 */
567
568 void EXPORT
569 call_togl_begin_polyline ()
570 {
571   openglNumberOfPoints  = 0;
572   LightOff();
573   glBegin (GL_LINE_STRIP);
574 }
575
576
577 /*----------------------------------------------------------------------*/
578 /*
579 call_togl_end_polyline ()
580
581 End of the polyline.
582 */
583
584 void EXPORT
585 call_togl_end_polyline ()
586 {
587
588 #ifdef TRACE
589   printf ("call_togl_end_polyline %d %d\n", openglViewId, openglWsId);
590 #endif
591
592   if (openglViewId != 0) glEnd ();
593 }
594
595
596 /*----------------------------------------------------------------------*/
597 /*
598 call_togl_draw (x, y, z)
599 float x;
600 float y;
601 float z;
602
603 Defines a new point in the current primitive.
604 */
605
606 void EXPORT
607 call_togl_draw
608 (
609  float x,
610  float y,
611  float z
612  )
613 {
614
615 #ifdef TRACE
616   printf ("call_togl_draw %d %d\n", openglViewId, openglWsId);
617 #endif
618
619   if (openglViewId != 0) {
620     openglNumberOfPoints ++;
621     call_util_transform_pt (&x, &y, &z);
622     if (x > XM) XM = x;
623     if (y > YM) YM = y;
624     if (z > ZM) ZM = z;
625     if (x < xm) xm = x;
626     if (y < ym) ym = y;
627     if (z < zm) zm = z;
628     glVertex3f (x, y, z);
629     partial = 1;
630   }
631 }
632
633
634 /*----------------------------------------------------------------------*/
635 /*
636 call_togl_move (x, y, z)
637 float x;
638 float y;
639 float z;
640
641 Defines a new point in the current primitive.
642 */
643
644 void EXPORT
645 call_togl_move
646 (
647  float x,
648  float y,
649  float z
650  )
651 {
652
653 #ifdef TRACE
654   printf ("call_togl_move %d %d\n", openglViewId, openglWsId);
655 #endif
656
657   if (openglViewId != 0) {
658     if (openglNumberOfPoints != 0) {
659       call_togl_end_polyline ();
660       call_togl_begin_polyline ();
661     }
662
663     openglNumberOfPoints ++;
664     call_util_transform_pt (&x, &y, &z);
665     if (x > XM) XM = x;
666     if (y > YM) YM = y;
667     if (z > ZM) ZM = z;
668     if (x < xm) xm = x;
669     if (y < ym) ym = y;
670     if (z < zm) zm = z;
671     glVertex3f (x, y, z);
672     partial = 1;
673   }
674 }
675
676
677 /*----------------------------------------------------------------------*/
678 /*
679 call_togl_set_linecolor (r, g, b)
680 float r;
681 float g;
682 float b;
683
684 Sets a new color in the current primitive.
685 */
686
687 void EXPORT
688 call_togl_set_linecolor
689 (
690  float r,
691  float g,
692  float b
693  )
694 {
695
696 #ifdef TRACE
697   printf ("call_togl_set_linecolor %d %d\n", openglViewId, openglWsId);
698 #endif
699
700   if (openglViewId != 0) {
701     TEL_COLOUR color;
702     CMN_KEY key;
703     key.id = TelPolylineColour;
704     color.rgb[0] = r; color.rgb[1] = g; color.rgb[2] = b;
705     key.data.pdata = &color;
706     TsmSetAttri( 1, &key );
707   }
708 }
709
710
711 /*----------------------------------------------------------------------*/
712 /*
713 call_togl_set_linetype (type)
714 long type;
715
716 Sets a new line type in the current primitive.
717 */
718
719 void EXPORT
720 call_togl_set_linetype
721 (
722  long type
723  )
724 {
725 #ifdef TRACE
726   printf ("call_togl_set_linetype %d %d\n", openglViewId, openglWsId);
727 #endif
728
729   if (openglViewId != 0) {
730     CMN_KEY key;
731     key.id = TelPolylineType;
732     key.data.ldata = type;
733     TsmSetAttri( 1, &key);
734   }
735 }
736
737
738 /*----------------------------------------------------------------------*/
739 /*
740 call_togl_set_linewidth (width)
741 float width;
742
743 Sets a new line width in the current primitive.
744 */
745
746 void EXPORT
747 call_togl_set_linewidth
748 (
749  float width
750  )
751 {
752
753 #ifdef TRACE
754   printf ("call_togl_set_linewidth %d %d\n", openglViewId, openglWsId);
755 #endif
756
757   if (openglViewId != 0) {
758     CMN_KEY key;
759     key.id = TelPolylineWidth;
760     key.data.fdata = width;
761     TsmSetAttri( 1, &key);
762   }
763 }
764
765
766 /*----------------------------------------------------------------------*/
767 /*
768 call_togl_draw_structure (aStructureId)
769 int aStructureId
770
771 Draw a structure in the transient view space
772 */
773
774 void EXPORT
775 call_togl_draw_structure
776 (
777  int aStructureId
778  )
779 {
780   Tint    i, num;
781   tsm_node node;
782   register Tint istrsfed = 0;
783   register Tint display = 1;
784   register Tint highl = TOff;
785   register TelType  telem;
786   CMN_KEY   key;
787
788   float mat16[16];
789   GLint mode1;
790   GLint mode2;
791
792 #ifdef TRACE
793   printf ("call_togl_draw_structure %d %d %d\n", openglViewId, openglWsId);
794 #endif
795
796   if (openglViewId == 0) return;
797
798   if (TsmGetStructure (aStructureId, &num, &node) == TFailure || !num) return;
799
800   /*transform_persistence_end();*/
801
802   TsmPushAttriLight (); 
803   TsmPushAttri();
804   TglNamesetPush();
805
806   /* mise en place de la matrice de transformation du trace transient */
807   if (! identity) {
808     call_util_transpose_mat (mat16, openglMat);
809     glGetIntegerv (GL_MATRIX_MODE, &mode1);
810     glMatrixMode (GL_MODELVIEW);
811     glPushMatrix ();
812     glScalef (1., 1., 1.);
813     glMultMatrixf (mat16);
814   }
815
816   for (i = 0; i < num; i++, node = node->next) {
817     telem = node->elem.el;
818 #if TRACE > 0
819     TelTrace(telem,node->elem.data.ldata);
820 #endif
821     switch (telem) {
822       case TelAddNameset:
823       case TelRemoveNameset: {
824         TsmSendMessage (telem, DisplayTraverse, node->elem.data, 0);
825
826         if( TglFilterNameset( openglWsId, InvisFilter ) == TSuccess )
827           display = 0;
828
829         if( TglFilterNameset( openglWsId, HighlFilter ) == TSuccess )
830           highl = TOn;
831
832         break;
833                              }
834
835       case TelCurve:
836       case TelMarker:
837       case TelMarkerSet:
838       case TelPolyline:
839       case TelText: {
840         /* do not send Display message to */
841         /* primitives if they are invisible */
842         if (display) 
843         {
844           LightOff();
845 #ifdef IMP150501
846           glDepthMask(GL_FALSE);
847 #endif
848           key.id = highl;
849           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
850         }
851                     }
852                     break;
853
854       case TelPolygon:
855       case TelPolygonSet:
856       case TelPolygonHoles:
857       case TelPolygonIndices:
858       case TelQuadrangle:
859       case TelParray:  
860       case TelTriangleMesh: {
861         /* do not send Display message to */
862         /* primitives if they are invisible */
863         if (display) 
864         {
865           /* LightOn(); */
866 #ifdef IMP150501
867           glDepthMask(GL_FALSE);
868 #endif
869 #ifdef IMP051001
870           if( highl ) {
871             call_subr_disable_polygon_offset();
872           }
873 #endif
874           key.id = highl;
875           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
876 #ifdef IMP051001
877           if( highl ) {
878             call_subr_enable_polygon_offset();
879           }
880 #endif
881         }
882                             }
883                             break;
884
885       case TelLocalTran3: {
886         tel_matrix3_data  d = ((tel_matrix3_data)(node->elem.data.pdata));
887         istrsfed = 1;
888         call_util_transpose_mat (mat16, d->mat);
889         glGetIntegerv (GL_MATRIX_MODE, &mode2);
890         glMatrixMode (GL_MODELVIEW);
891         glPushMatrix ();
892         glScalef (1., 1., 1.);
893         glMultMatrixf (mat16);
894                           }
895                           break;
896                           /* ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate ) */
897       case TelTransformPersistence:
898         {
899           key.id = openglWsId;
900           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
901           break;
902         }
903         /*ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate ) */
904       default: {
905         key.id = openglWsId;
906         TsmSendMessage (telem, DisplayTraverse, node->elem.data, 0, &key);
907                }
908     }
909   }
910
911   TglNamesetPop();
912   TsmPopAttri();
913   TsmPopAttriLight (); 
914
915   if (istrsfed) {
916     glPopMatrix ();
917     glMatrixMode (mode2);
918   }
919   if (! identity) {
920     glPopMatrix ();
921     glMatrixMode (mode1);
922   }
923
924   return;
925 }
926
927 /*----------------------------------------------------------------------*/
928 /*
929 call_togl_set_minmax (x1, y1, z1, x2, y2, z2)
930 float x1;
931 float y1;
932 float z1;
933 float x2;
934 float y2;
935 float z2;
936
937 Give the boundary box of the transient graphic
938 */
939
940 void EXPORT
941 call_togl_set_minmax (
942                       float x1,
943                       float y1,
944                       float z1,
945                       float x2,
946                       float y2,
947                       float z2
948                       )
949 {
950 #ifdef TRACE
951   printf("call_togl_set_minmax. x1 %f, y1 %f, z1 %f, x2 %f, y2 %f, z2 %f\n",x1, y1, z1, x2, y2, z2);
952 #endif
953   if ((x1 > shortreallast ()) ||
954     (y1 > shortreallast ()) ||
955     (z1 > shortreallast ()) ||
956     (x2 > shortreallast ()) ||
957     (y2 > shortreallast ()) ||
958     (z2 > shortreallast ()) ||
959     (x1 < shortrealfirst ()) ||
960     (y1 < shortrealfirst ()) ||
961     (z1 < shortrealfirst ()) ||
962     (x2 < shortrealfirst ()) ||
963     (y2 < shortrealfirst ()) ||
964     (z2 < shortrealfirst ())) {
965       XM = YM = ZM = (float ) shortreallast ();
966       xm = ym = zm = (float ) shortrealfirst ();
967       partial = 0;
968     }
969   else {
970     call_util_transform_pt (&x1, &y1, &z1);
971     call_util_transform_pt (&x2, &y2, &z2);
972     if (x1 > XM) XM = x1;
973     if (x1 < xm) xm = x1;
974     if (y1 > YM) YM = y1;
975     if (y1 < ym) ym = y1;
976     if (z1 > ZM) ZM = z1;
977     if (z1 < zm) zm = z1;
978
979     if (x2 > XM) XM = x2;
980     if (x2 < xm) xm = x2;
981     if (y2 > YM) YM = y2;
982     if (y2 < ym) ym = y2;
983     if (z2 > ZM) ZM = z2;
984     if (z2 < zm) zm = z2;
985     if (partial != 0) partial = 1;
986   }
987 }
988
989 /*----------------------------------------------------------------------*/
990 /*
991 * Private functions
992 */
993
994 /*----------------------------------------------------------------------*/
995 /*
996 call_util_transform_pt (x, y, z)
997 float *x;
998 float *y;
999 float *z;
1000
1001 Transform the point pt
1002 */
1003
1004 static void call_util_transform_pt
1005 (
1006  float *x,
1007  float *y,
1008  float *z
1009  )
1010 {
1011   int i, j;
1012   float sum = 0.;
1013   float tpt[4], pt[4];
1014
1015   if (! identity) {
1016     pt[0] = *x, pt[1] = *y, pt[2] = *z, pt[3] = 1.0;
1017
1018     for (i = 0; i < 4; i++) {
1019       for (j = 0, sum = 0.0; j < 4; j++)
1020         sum += openglMat[i][j] * pt[j];
1021       tpt[i] = sum;
1022     }
1023
1024     *x = tpt[0], *y = tpt[1], *z = tpt[2];
1025   }
1026 }
1027
1028
1029 /*----------------------------------------------------------------------*/
1030 /*
1031 int call_util_is_identity ()
1032
1033 Returns 1 if openglMat is the identity
1034 */
1035
1036 static int call_util_is_identity
1037 (
1038  )
1039 {
1040   int i, j;
1041   int res = 1;
1042
1043   for (i = 0; res && i < 4; i++)
1044     for (j = 0; res && j < 4; j++)
1045       if (i == j) res = (openglMat[i][j] == 1.);
1046       else        res = (openglMat[i][j] == 0.);
1047
1048 #ifdef TRACE
1049       printf ("La matrice suivante :\n");
1050       for (i = 0; i < 4; i++) {
1051         printf ("\t");
1052         for (j = 0; j < 4; j++)
1053           printf ("%f ", openglMat[i][j]);
1054         printf ("\n");
1055       }
1056       if (res)
1057         printf ("est la matrice identite\n");
1058       else
1059         printf ("n'est pas la matrice identite\n");
1060 #endif
1061
1062       return (res);
1063 }
1064
1065
1066 /*----------------------------------------------------------------------*/
1067 /*
1068 void call_util_transpose_mat (tmat, mat)
1069 float tmat[16];
1070 float mat[4][4];
1071
1072 Transpose mat and returns tmat.
1073 */
1074
1075 static void call_util_transpose_mat (float tmat[16], float mat[4][4]) {
1076   int i, j;
1077
1078   for (i=0; i<4; i++)
1079     for (j=0; j<4; j++)
1080       tmat[j*4+i] = mat[i][j];
1081
1082 #ifdef TRACE
1083   printf ("Transposee :\n");
1084   for (i = 0; i < 4; i++) {
1085     printf ("\t");
1086     for (j = 0; j < 4; j++)
1087       printf ("%f ", tmat[i*4+j]);
1088     printf ("\n");
1089   }
1090 #endif
1091 }