0022819: Redesign of OpenGl driver
[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     // After a redraw,
290     // Made the back identical to the front buffer.
291     // Always perform full copy (partial update optimization is useless on mordern hardware)!
292     if (retainmode)
293       TelCopyBuffers (aview->WsId, GL_FRONT, GL_BACK, xm, ym, zm, XM, YM, ZM, 0);
294 #ifdef TRACE
295     printf(" $$$ REDRAW\n");
296 #endif
297     TelSetBackBufferRestored (TOn);
298   } else if( partial >= 0 ) {
299     // Restore pixels from the back buffer.
300     // Always perform full copy (partial update optimization is useless on mordern hardware)!
301     TelCopyBuffers (aview->WsId, GL_BACK, GL_FRONT, xm, ym, zm, XM, YM, ZM, 0);
302   }
303
304   TsmGetWSAttri (aview->WsId, WSTransient, &data);
305   listIndex = (GLuint) data.ldata;
306   if( listIndex != 0 ) {  /* Clear current list contents */
307     glNewList( listIndex, GL_COMPILE_AND_EXECUTE);   
308     glEndList();
309   }
310   partial = -1;
311   XM = YM = ZM = (float ) shortrealfirst ();
312   xm = ym = zm = (float ) shortreallast ();
313 }
314
315 /*----------------------------------------------------------------------*/
316
317 void call_togl_redraw_immediat_mode(
318                                     CALL_DEF_VIEW * aview
319                                     )
320 {
321   CMN_KEY_DATA   data;
322   GLuint listIndex = 0;
323   int retainmode = 0;
324 #ifndef IMP150501
325   GLboolean flag_zbuffer = GL_FALSE;
326 #endif
327
328   TsmGetWSAttri( aview->WsId, WSRetainMode, &data );
329   retainmode = data.ldata;
330
331   TsmGetWSAttri (aview->WsId, WSTransient, &data);
332   listIndex = (GLuint) data.ldata;
333
334   if (retainmode != 0) {
335     if (listIndex != 0) {
336       TelMakeFrontBufCurrent (aview->WsId);
337
338       LightOff();
339       /* mise en place des matrices de projection et de mapping */
340       /* TelSetViewIndex (aview->WsId, aview->ViewId);  */
341
342 #ifdef TRACE
343       printf("call_togl_redraw_immediat_mode::call displaylist(%d) \n",
344         listIndex);
345 #endif
346 #ifdef IMP150501
347       glCallList(listIndex); 
348 #else
349       flag_zbuffer = glIsEnabled(GL_DEPTH_TEST);
350       if (flag_zbuffer) glDisable(GL_DEPTH_TEST);
351       glCallList(listIndex); 
352       if (flag_zbuffer) glEnable(GL_DEPTH_TEST); 
353 #endif
354       /* FMN necessaire pour l'affichage sur WNT */
355       glFlush();
356
357       TelMakeBackBufCurrent (aview->WsId);
358     } 
359   }
360 }
361
362
363 /*----------------------------------------------------------------------*/
364
365 int EXPORT
366 call_togl_begin_immediat_mode
367 (
368  CALL_DEF_VIEW * aview,
369  CALL_DEF_LAYER * anunderlayer,
370  CALL_DEF_LAYER * anoverlayer,
371 #ifdef IMP150501
372  int zbuffer, 
373 #else
374  int doublebuffer,
375 #endif
376  int retainmode
377  )
378 {
379   CMN_KEY_DATA data;
380   GLuint listIndex = 0;
381
382   if (aview->ViewId == -1) return (0);
383
384   TsmGetWSAttri (aview->WsId, WSWindow, &data);
385 #ifdef IMP260601
386   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) != TSuccess) return (0);
387 #else
388   if (TxglWinset (call_thedisplay, (WINDOW) data.ldata) == TSuccess)
389 #endif
390
391     openglWsId = aview->WsId;
392   openglViewId = aview->ViewId;
393
394   data.ldata = retainmode;
395   TsmSetWSAttri( aview->WsId, WSRetainMode, &data );
396
397 #ifdef TRACE
398   printf ("call_togl_begin_immediat_mode %d %d RetainMode %d zbuffer %d partial %d\n", openglViewId, openglWsId, retainmode, zbuffer, partial);
399 #endif
400
401   call_togl_clear_immediat_mode(aview,1);
402
403   TelMakeFrontBufCurrent (aview->WsId);
404
405   TsmPushAttri();
406
407 #ifdef COPY
408   if (partial == 1) {
409     glColor3f (1., 0., 0.);
410     glBegin(GL_LINE_LOOP);
411     glVertex3f (xm, ym, zm);
412     glVertex3f (XM, ym, zm);
413     glVertex3f (XM, YM, zm);
414     glVertex3f (xm, YM, zm);
415     glEnd();
416   }
417 #endif
418
419   /* 
420   * RetainMode
421   */
422   if( retainmode ) {
423     TsmGetWSAttri (aview->WsId, WSTransient, &data);
424     listIndex = (GLuint) data.ldata;
425
426     if (listIndex == 0) {
427       listIndex = glGenLists(1);
428 #ifdef TRACE
429       printf("call_togl_begin_immediat_mode::init displaylist() %d \n", listIndex);
430 #endif
431       data.ldata = listIndex;
432       TsmSetWSAttri( aview->WsId, WSTransient, &data );
433     }
434     if (listIndex == 0) return(0);    
435 #ifdef TRACE
436     printf("call_togl_begin_immediat_mode::glNewList() %d \n", listIndex);
437 #endif
438     glNewList(listIndex, GL_COMPILE_AND_EXECUTE);   
439     transientOpen = GL_TRUE;
440   }
441
442 #ifdef IMP150501
443   if( zbuffer ) {
444     glEnable(GL_DEPTH_TEST);
445   } else glDisable(GL_DEPTH_TEST);
446 #endif
447
448   return (1);
449 }
450
451
452 /*----------------------------------------------------------------------*/
453 /*
454 call_togl_end_immediat_mode (synchronize)
455 GLboolean synchronize
456
457 End of immediate graphic primitives in the view.
458 */
459
460 void EXPORT
461 call_togl_end_immediat_mode
462 (
463  int synchronize
464  )
465 {
466
467 #ifdef TRACE
468   printf ("call_togl_end_immediat_mode %d %d %d\n", 
469     synchronize, openglViewId, openglWsId);
470 #endif
471
472 #ifndef BUC60863  /* Don't modify the current minmax !!*/
473   /* Mise ajout MinMax */
474   if ((xm > shortreallast ()) ||
475     (ym > shortreallast ()) ||
476     (zm > shortreallast ()) ||
477     (XM > shortreallast ()) ||
478     (YM > shortreallast ()) ||
479     (ZM > shortreallast ()) ||
480     (xm < shortrealfirst ()) ||
481     (ym < shortrealfirst ()) ||
482     (zm < shortrealfirst ()) ||
483     (XM < shortrealfirst ()) ||
484     (YM < shortrealfirst ()) ||
485     (ZM < shortrealfirst ())) {
486       XM = YM = ZM = (float ) shortreallast ();
487       xm = ym = zm = (float ) shortrealfirst ();
488       partial = 0;
489     }
490   else {
491     if (partial != 0) partial = 1;
492   }
493 #endif  /*BUC60863*/
494
495   if (openglViewId != 0) {
496 #ifdef COPY
497     if (partial == 1) {
498       glColor3f (0., 1., 0.);
499       glBegin(GL_LINE_LOOP);
500       glVertex3f (xm, ym, zm);
501       glVertex3f (XM, ym, zm);
502       glVertex3f (XM, YM, zm);
503       glVertex3f (xm, YM, zm);
504       glEnd();
505     }
506 #endif
507
508     if (transientOpen) {
509       glEndList();
510 #ifdef TRACE
511       printf("--->glEndList() \n");
512 #endif
513       transientOpen = GL_FALSE;
514     }
515
516     TelMakeBackBufCurrent (openglWsId);     
517   }
518
519   /*
520   * Ajout CAL : pour voir quelque chose
521   * avant le prochain begin_immediat_mode
522   */
523   glFinish ();
524
525   openglViewId = 0;
526   openglWsId = 0;
527
528   identity = 1;
529
530   TsmPopAttri();
531
532 }
533
534 /*----------------------------------------------------------------------*/
535 /*
536 call_togl_transform (amatrix, mode)
537 float amatrix[4][4]
538 GLboolean mode
539
540 Set the local transformation for All primitives
541 REPLACE the existante if mode is True or POSTCONCATENATE if GL_FALSE
542 */
543 void EXPORT
544 call_togl_transform ( float amatrix[4][4], int mode )
545 {
546   int i, j;
547   if (mode || identity) {
548     for (i=0; i<4; i++)
549       for (j=0; j<4; j++)
550         openglMat[i][j] = amatrix[i][j];
551   } else
552     TelMultiplymat3 (openglMat, openglMat, amatrix);
553
554   identity = call_util_is_identity ();
555 }
556
557
558 /*
559 call_togl_begin_polyline ()
560
561 Sets the graphic library ready to receive a polyline.
562 */
563
564 void EXPORT
565 call_togl_begin_polyline ()
566 {
567   openglNumberOfPoints  = 0;
568   LightOff();
569   glBegin (GL_LINE_STRIP);
570 }
571
572
573 /*----------------------------------------------------------------------*/
574 /*
575 call_togl_end_polyline ()
576
577 End of the polyline.
578 */
579
580 void EXPORT
581 call_togl_end_polyline ()
582 {
583
584 #ifdef TRACE
585   printf ("call_togl_end_polyline %d %d\n", openglViewId, openglWsId);
586 #endif
587
588   if (openglViewId != 0) glEnd ();
589 }
590
591
592 /*----------------------------------------------------------------------*/
593 /*
594 call_togl_draw (x, y, z)
595 float x;
596 float y;
597 float z;
598
599 Defines a new point in the current primitive.
600 */
601
602 void EXPORT
603 call_togl_draw
604 (
605  float x,
606  float y,
607  float z
608  )
609 {
610
611 #ifdef TRACE
612   printf ("call_togl_draw %d %d\n", openglViewId, openglWsId);
613 #endif
614
615   if (openglViewId != 0) {
616     openglNumberOfPoints ++;
617     call_util_transform_pt (&x, &y, &z);
618     if (x > XM) XM = x;
619     if (y > YM) YM = y;
620     if (z > ZM) ZM = z;
621     if (x < xm) xm = x;
622     if (y < ym) ym = y;
623     if (z < zm) zm = z;
624     glVertex3f (x, y, z);
625     partial = 1;
626   }
627 }
628
629
630 /*----------------------------------------------------------------------*/
631 /*
632 call_togl_move (x, y, z)
633 float x;
634 float y;
635 float z;
636
637 Defines a new point in the current primitive.
638 */
639
640 void EXPORT
641 call_togl_move
642 (
643  float x,
644  float y,
645  float z
646  )
647 {
648
649 #ifdef TRACE
650   printf ("call_togl_move %d %d\n", openglViewId, openglWsId);
651 #endif
652
653   if (openglViewId != 0) {
654     if (openglNumberOfPoints != 0) {
655       call_togl_end_polyline ();
656       call_togl_begin_polyline ();
657     }
658
659     openglNumberOfPoints ++;
660     call_util_transform_pt (&x, &y, &z);
661     if (x > XM) XM = x;
662     if (y > YM) YM = y;
663     if (z > ZM) ZM = z;
664     if (x < xm) xm = x;
665     if (y < ym) ym = y;
666     if (z < zm) zm = z;
667     glVertex3f (x, y, z);
668     partial = 1;
669   }
670 }
671
672
673 /*----------------------------------------------------------------------*/
674 /*
675 call_togl_set_linecolor (r, g, b)
676 float r;
677 float g;
678 float b;
679
680 Sets a new color in the current primitive.
681 */
682
683 void EXPORT
684 call_togl_set_linecolor
685 (
686  float r,
687  float g,
688  float b
689  )
690 {
691
692 #ifdef TRACE
693   printf ("call_togl_set_linecolor %d %d\n", openglViewId, openglWsId);
694 #endif
695
696   if (openglViewId != 0) {
697     TEL_COLOUR color;
698     CMN_KEY key;
699     key.id = TelPolylineColour;
700     color.rgb[0] = r; color.rgb[1] = g; color.rgb[2] = b;
701     key.data.pdata = &color;
702     TsmSetAttri( 1, &key );
703   }
704 }
705
706
707 /*----------------------------------------------------------------------*/
708 /*
709 call_togl_set_linetype (type)
710 long type;
711
712 Sets a new line type in the current primitive.
713 */
714
715 void EXPORT
716 call_togl_set_linetype
717 (
718  long type
719  )
720 {
721 #ifdef TRACE
722   printf ("call_togl_set_linetype %d %d\n", openglViewId, openglWsId);
723 #endif
724
725   if (openglViewId != 0) {
726     CMN_KEY key;
727     key.id = TelPolylineType;
728     key.data.ldata = type;
729     TsmSetAttri( 1, &key);
730   }
731 }
732
733
734 /*----------------------------------------------------------------------*/
735 /*
736 call_togl_set_linewidth (width)
737 float width;
738
739 Sets a new line width in the current primitive.
740 */
741
742 void EXPORT
743 call_togl_set_linewidth
744 (
745  float width
746  )
747 {
748
749 #ifdef TRACE
750   printf ("call_togl_set_linewidth %d %d\n", openglViewId, openglWsId);
751 #endif
752
753   if (openglViewId != 0) {
754     CMN_KEY key;
755     key.id = TelPolylineWidth;
756     key.data.fdata = width;
757     TsmSetAttri( 1, &key);
758   }
759 }
760
761
762 /*----------------------------------------------------------------------*/
763 /*
764 call_togl_draw_structure (aStructureId)
765 int aStructureId
766
767 Draw a structure in the transient view space
768 */
769
770 void EXPORT
771 call_togl_draw_structure
772 (
773  int aStructureId
774  )
775 {
776   Tint    i, num;
777   tsm_node node;
778   register Tint istrsfed = 0;
779   register Tint display = 1;
780   register Tint highl = TOff;
781   register TelType  telem;
782   CMN_KEY   key;
783
784   float mat16[16];
785   GLint mode1;
786   GLint mode2;
787
788 #ifdef TRACE
789   printf ("call_togl_draw_structure %d %d %d\n", openglViewId, openglWsId);
790 #endif
791
792   if (openglViewId == 0) return;
793
794   if (TsmGetStructure (aStructureId, &num, &node) == TFailure || !num) return;
795
796   /*transform_persistence_end();*/
797
798   TsmPushAttriLight (); 
799   TsmPushAttri();
800   TglNamesetPush();
801
802   /* mise en place de la matrice de transformation du trace transient */
803   if (! identity) {
804     call_util_transpose_mat (mat16, openglMat);
805     glGetIntegerv (GL_MATRIX_MODE, &mode1);
806     glMatrixMode (GL_MODELVIEW);
807     glPushMatrix ();
808     glScalef (1., 1., 1.);
809     glMultMatrixf (mat16);
810   }
811
812   for (i = 0; i < num; i++, node = node->next) {
813     telem = node->elem.el;
814 #if TRACE > 0
815     TelTrace(telem,node->elem.data.ldata);
816 #endif
817     switch (telem) {
818       case TelAddNameset:
819       case TelRemoveNameset: {
820         TsmSendMessage (telem, DisplayTraverse, node->elem.data, 0);
821
822         if( TglFilterNameset( openglWsId, InvisFilter ) == TSuccess )
823           display = 0;
824
825         if( TglFilterNameset( openglWsId, HighlFilter ) == TSuccess )
826           highl = TOn;
827
828         break;
829                              }
830
831       case TelCurve:
832       case TelMarker:
833       case TelMarkerSet:
834       case TelPolyline:
835       case TelText: {
836         /* do not send Display message to */
837         /* primitives if they are invisible */
838         if (display) 
839         {
840           LightOff();
841 #ifdef IMP150501
842           glDepthMask(GL_FALSE);
843 #endif
844           key.id = highl;
845           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
846         }
847                     }
848                     break;
849
850       case TelPolygon:
851       case TelPolygonSet:
852       case TelPolygonHoles:
853       case TelPolygonIndices:
854       case TelQuadrangle:
855       case TelParray:  
856       case TelTriangleMesh: {
857         /* do not send Display message to */
858         /* primitives if they are invisible */
859         if (display) 
860         {
861           /* LightOn(); */
862 #ifdef IMP150501
863           glDepthMask(GL_FALSE);
864 #endif
865 #ifdef IMP051001
866           if( highl ) {
867             call_subr_disable_polygon_offset();
868           }
869 #endif
870           key.id = highl;
871           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
872 #ifdef IMP051001
873           if( highl ) {
874             call_subr_enable_polygon_offset();
875           }
876 #endif
877         }
878                             }
879                             break;
880
881       case TelLocalTran3: {
882         tel_matrix3_data  d = ((tel_matrix3_data)(node->elem.data.pdata));
883         istrsfed = 1;
884         call_util_transpose_mat (mat16, d->mat);
885         glGetIntegerv (GL_MATRIX_MODE, &mode2);
886         glMatrixMode (GL_MODELVIEW);
887         glPushMatrix ();
888         glScalef (1., 1., 1.);
889         glMultMatrixf (mat16);
890                           }
891                           break;
892                           /* ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate ) */
893       case TelTransformPersistence:
894         {
895           key.id = openglWsId;
896           TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
897           break;
898         }
899         /*ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate ) */
900       default: {
901         key.id = openglWsId;
902         TsmSendMessage (telem, DisplayTraverse, node->elem.data, 1, &key);
903                }
904     }
905   }
906
907   TglNamesetPop();
908   TsmPopAttri();
909   TsmPopAttriLight (); 
910
911   if (istrsfed) {
912     glPopMatrix ();
913     glMatrixMode (mode2);
914   }
915   if (! identity) {
916     glPopMatrix ();
917     glMatrixMode (mode1);
918   }
919
920   return;
921 }
922
923 /*----------------------------------------------------------------------*/
924 /*
925 call_togl_set_minmax (x1, y1, z1, x2, y2, z2)
926 float x1;
927 float y1;
928 float z1;
929 float x2;
930 float y2;
931 float z2;
932
933 Give the boundary box of the transient graphic
934 */
935
936 void EXPORT
937 call_togl_set_minmax (
938                       float x1,
939                       float y1,
940                       float z1,
941                       float x2,
942                       float y2,
943                       float z2
944                       )
945 {
946 #ifdef TRACE
947   printf("call_togl_set_minmax. x1 %f, y1 %f, z1 %f, x2 %f, y2 %f, z2 %f\n",x1, y1, z1, x2, y2, z2);
948 #endif
949   if ((x1 > shortreallast ()) ||
950     (y1 > shortreallast ()) ||
951     (z1 > shortreallast ()) ||
952     (x2 > shortreallast ()) ||
953     (y2 > shortreallast ()) ||
954     (z2 > shortreallast ()) ||
955     (x1 < shortrealfirst ()) ||
956     (y1 < shortrealfirst ()) ||
957     (z1 < shortrealfirst ()) ||
958     (x2 < shortrealfirst ()) ||
959     (y2 < shortrealfirst ()) ||
960     (z2 < shortrealfirst ())) {
961       XM = YM = ZM = (float ) shortreallast ();
962       xm = ym = zm = (float ) shortrealfirst ();
963       partial = 0;
964     }
965   else {
966     call_util_transform_pt (&x1, &y1, &z1);
967     call_util_transform_pt (&x2, &y2, &z2);
968     if (x1 > XM) XM = x1;
969     if (x1 < xm) xm = x1;
970     if (y1 > YM) YM = y1;
971     if (y1 < ym) ym = y1;
972     if (z1 > ZM) ZM = z1;
973     if (z1 < zm) zm = z1;
974
975     if (x2 > XM) XM = x2;
976     if (x2 < xm) xm = x2;
977     if (y2 > YM) YM = y2;
978     if (y2 < ym) ym = y2;
979     if (z2 > ZM) ZM = z2;
980     if (z2 < zm) zm = z2;
981     if (partial != 0) partial = 1;
982   }
983 }
984
985 /*----------------------------------------------------------------------*/
986 /*
987 * Private functions
988 */
989
990 /*----------------------------------------------------------------------*/
991 /*
992 call_util_transform_pt (x, y, z)
993 float *x;
994 float *y;
995 float *z;
996
997 Transform the point pt
998 */
999
1000 static void call_util_transform_pt
1001 (
1002  float *x,
1003  float *y,
1004  float *z
1005  )
1006 {
1007   int i, j;
1008   float sum = 0.;
1009   float tpt[4], pt[4];
1010
1011   if (! identity) {
1012     pt[0] = *x, pt[1] = *y, pt[2] = *z, pt[3] = 1.0;
1013
1014     for (i = 0; i < 4; i++) {
1015       for (j = 0, sum = 0.0; j < 4; j++)
1016         sum += openglMat[i][j] * pt[j];
1017       tpt[i] = sum;
1018     }
1019
1020     *x = tpt[0], *y = tpt[1], *z = tpt[2];
1021   }
1022 }
1023
1024
1025 /*----------------------------------------------------------------------*/
1026 /*
1027 int call_util_is_identity ()
1028
1029 Returns 1 if openglMat is the identity
1030 */
1031
1032 static int call_util_is_identity
1033 (
1034  )
1035 {
1036   int i, j;
1037   int res = 1;
1038
1039   for (i = 0; res && i < 4; i++)
1040     for (j = 0; res && j < 4; j++)
1041       if (i == j) res = (openglMat[i][j] == 1.);
1042       else        res = (openglMat[i][j] == 0.);
1043
1044 #ifdef TRACE
1045       printf ("La matrice suivante :\n");
1046       for (i = 0; i < 4; i++) {
1047         printf ("\t");
1048         for (j = 0; j < 4; j++)
1049           printf ("%f ", openglMat[i][j]);
1050         printf ("\n");
1051       }
1052       if (res)
1053         printf ("est la matrice identite\n");
1054       else
1055         printf ("n'est pas la matrice identite\n");
1056 #endif
1057
1058       return (res);
1059 }
1060
1061
1062 /*----------------------------------------------------------------------*/
1063 /*
1064 void call_util_transpose_mat (tmat, mat)
1065 float tmat[16];
1066 float mat[4][4];
1067
1068 Transpose mat and returns tmat.
1069 */
1070
1071 static void call_util_transpose_mat (float tmat[16], float mat[4][4]) {
1072   int i, j;
1073
1074   for (i=0; i<4; i++)
1075     for (j=0; j<4; j++)
1076       tmat[j*4+i] = mat[i][j];
1077
1078 #ifdef TRACE
1079   printf ("Transposee :\n");
1080   for (i = 0; i < 4; i++) {
1081     printf ("\t");
1082     for (j = 0; j < 4; j++)
1083       printf ("%f ", tmat[i*4+j]);
1084     printf ("\n");
1085   }
1086 #endif
1087 }