0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_triedron.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_triedron : gestion du triedre non zoomable.
6
7 REMARQUES:
8 ---------- 
9
10 Algorithme :
11 o dimensions et origine du triedre sont recalcules a chaque fois, en
12 fonction de la taille (u,v = largeur-hauteur) de la fenetre =>
13 il est inutile ici de jouer sur le facteur d'echelle.
14 o on n'inhibe que les translations, car on veut conserver les
15 transformations d'orientations.
16
17
18 HISTORIQUE DES MODIFICATIONS   :
19 --------------------------------
20 08-12-98 : BGN ; Creation.
21
22
23 ************************************************************************/
24
25 #define BUC60851  /* GG 15/03/01 Avoid to raise after the second creation
26 of the trihedron
27 */
28
29 #define BUC61045        /* 25/10/01 SAV ; added functionality to control gl lighting 
30 from higher API */
31
32
33 #define QTOCC_PATCH   /* Active QtOPENCASCADE patches */
34
35 /*----------------------------------------------------------------------*/
36 /*
37 * Includes
38 */ 
39
40 #include <OpenGl_tgl_all.hxx>
41 #include <OpenGl_tgl_tox.hxx>
42
43
44 #include <stddef.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <math.h> /* pour M_PI */
48
49 #include <OpenGl_LightBox.hxx>
50 #include <OpenGl_TextureBox.hxx>
51 #include <OpenGl_tgl_tox.hxx>
52
53 #include <OpenGl_tsm_ws.hxx>  /* pour TsmGetWSAttri */
54 #include <OpenGl_telem_view.hxx>  /* pour tel_view_data */
55 #include <InterfaceGraphic_Graphic3d.hxx>  /* pour CALL_DEF_STRUCTURE */
56 #include <InterfaceGraphic_Aspect.hxx>  /* pour CALL_DEF_VIEW  */
57 #include <InterfaceGraphic_Visual3d.hxx>
58
59 #include <OpenGl_transform_persistence.hxx>
60
61 #ifdef HAVE_GL2PS
62 #include <gl2ps.h>
63 #endif
64
65 #ifdef HAVE_CONFIG_H
66 #include <config.h>
67 #endif
68 #ifdef HAVE_STRING_H
69 #include <string.h>
70 #endif
71
72 #include <OpenGl_TextRender.hxx>
73 /*----------------------------------------------------------------------*/
74 /*
75 * Constantes
76 */ 
77
78 #define NO_DEBUG
79 #define NO_PRINT
80 #define NO_PRINT_MATRIX
81
82 /* on trouve que 10 vues sera suffisant */
83 #define GROW_SIZE_NZ_WKS   10
84
85 /* pour l'instant on ne travaille que sur le triedre */
86 /* on augmentera le define quand on developpera les struc. non zoomables*/
87 #define GROW_SIZE_NZ_STRUC  1 
88
89 /* Identificateur du Triedre Non Zommable dans la liste des structures */
90 # define TRIEDRON_ID -100
91
92 /*----------------------------------------------------------------------*/
93 /*
94 * Definition de types
95 */ 
96 typedef struct
97 {
98   float aXColor[3];
99   float aYColor[3];
100   float aZColor[3];
101   float aRatio;
102   float aDiametr;
103   int   aNbFacettes;
104 } ZBUF_STRUCT;
105
106
107 /* donnees des structures non zoomables liees a une wks (=une vue) */
108 typedef struct
109 {
110   int   NZStrucID; /* = TRIEDRON_ID ou astructure->Id de Graphic3d sinon.*/
111   int   aPos;
112   float aColor[3];
113   float aScale;
114   int   isWireframe;
115   CALL_DEF_STRUCTURE * astructure;
116   ZBUF_STRUCT* aZBufParam;
117 } NZ_STRUC_DATA;
118
119
120
121 /* liste des wks (=vues) concernees par les structures non zoomables */
122 typedef struct
123 {
124   int   nz_wks; /* = id de la wks  */
125   int   triedron_on; /* =0 si le triedre non zoomable n'est pas defini */
126   int   nz_struc_count; /* nb de structures non zoomables de la vue */
127   int   nz_struc_size;
128   NZ_STRUC_DATA *nz_struc;
129 } NZ_WKS;
130
131
132 typedef  struct
133 {
134   TEL_VIEW_REP    vrep;
135 } TEL_VIEW_DATA, *tel_view_data; /* Internal data stored for every view rep */
136
137 /*----------------------------------------------------------------------*/
138 /*
139 * Variables statiques
140 */
141
142 static NZ_WKS *nz_wks = NULL;
143 static int     nz_wks_count = 0;
144 static int     nz_wks_size = 0;
145
146 /* Default parameters for ZBUFFER triheron */
147 static float theXColor[] = { 1.0, 0.0, 0.0 };
148 static float theYColor[] = { 0.0, 1.0, 0.0 };
149 static float theZColor[] = { 0.0, 0.0, 1.0 };
150 static float theRatio = 0.8f;
151 static float theDiametr = 0.05f;
152 static int   theNBFacettes = 12;
153
154 /*----------------------------------------------------------------------*/
155 /*----------------------------------------------------------------------*/
156 /*
157 * Fonctions privees
158 */
159
160
161
162 /*----------------------------------------------------------------------*/
163 /*
164 * recherche de la wks NZWksID concernee par les structures non zoomables;
165 * creation de l'element wks s'il n'existe pas.
166 */
167 static int find_nz_wks(int NZWksID, int alloc)
168 {
169   int i;
170
171   /* recherche la wks dans la liste si elle existe */
172   for (i=0; i<nz_wks_count; i++)
173     if (nz_wks[i].nz_wks == NZWksID)
174       return i;
175
176   if (!alloc) return -1;
177
178   /* la wks n'existe pas => on fait de la place si il n'y en a plus */
179   if (nz_wks_count == nz_wks_size) {      
180 #ifdef BUC60851
181     if( nz_wks_size > 0 ) {
182       nz_wks_size += GROW_SIZE_NZ_WKS;
183       nz_wks =  (NZ_WKS *) realloc(nz_wks, nz_wks_size * sizeof(NZ_WKS)); 
184     } else {
185       nz_wks_size = GROW_SIZE_NZ_WKS;
186       nz_wks = (NZ_WKS *) malloc(nz_wks_size * sizeof(NZ_WKS));
187     }
188 #else
189     nz_wks_size += GROW_SIZE_NZ_WKS;
190     nz_wks =  (NZ_WKS *) realloc(nz_wks, nz_wks_size * sizeof(NZ_WKS));
191 #endif
192     if (nz_wks == NULL) return -1;
193   }
194
195   nz_wks[nz_wks_count].nz_wks = NZWksID;
196   nz_wks[nz_wks_count].triedron_on = 0;
197   nz_wks[nz_wks_count].nz_struc = NULL;
198   nz_wks[nz_wks_count].nz_struc_size = 0;
199   nz_wks[nz_wks_count].nz_struc_count = 0;
200
201   return nz_wks_count++;
202 }
203
204 /*-----------------------------------------------------------------*/
205 /*
206 * recherche de la structure non zoomable NZStrucID dans la liste
207 * de la wks NZWksIdx ;
208 * creation de l'element structure non zoomable s'il n'existe pas.
209 */
210 static int find_nz_struc(int NZWksIdx, int NZStrucID, int alloc)
211 {
212   int i;
213   NZ_STRUC_DATA *nz_struc;
214
215
216   /* recherche la structure non zoomable dans la liste de la wks */
217   nz_struc = nz_wks[NZWksIdx].nz_struc;
218   for (i=0; i<nz_wks[NZWksIdx].nz_struc_count; i++)
219     if (nz_struc[i].NZStrucID == NZStrucID)
220       return i;
221
222   if (!alloc) return -1;
223
224   /* la structure non zoomable n'existe pas => on la cree */
225   if (nz_wks[NZWksIdx].nz_struc_count == nz_wks[NZWksIdx].nz_struc_size) {
226 #ifdef BUC60851
227     if( nz_wks[NZWksIdx].nz_struc_size > 0 ) {
228       nz_wks[NZWksIdx].nz_struc_size += GROW_SIZE_NZ_STRUC;
229       nz_wks[NZWksIdx].nz_struc = 
230         (NZ_STRUC_DATA *)  realloc(nz_wks[NZWksIdx].nz_struc, 
231         nz_wks[NZWksIdx].nz_struc_size * sizeof(NZ_STRUC_DATA));
232     } else {
233       nz_wks[NZWksIdx].nz_struc_size = GROW_SIZE_NZ_STRUC;
234       nz_wks[NZWksIdx].nz_struc = 
235         (NZ_STRUC_DATA *)  malloc( nz_wks[NZWksIdx].nz_struc_size * sizeof(NZ_STRUC_DATA));
236     }
237 #else
238     nz_wks[NZWksIdx].nz_struc_size += GROW_SIZE_NZ_STRUC;
239     nz_wks[NZWksIdx].nz_struc = (NZ_STRUC_DATA *)  realloc(nz_wks[NZWksIdx].nz_struc, nz_wks[NZWksIdx].nz_struc_size * sizeof(NZ_STRUC_DATA));
240 #endif
241     if (nz_wks[NZWksIdx].nz_struc == NULL) return -1;
242
243     nz_wks[NZWksIdx].nz_struc[nz_wks[NZWksIdx].nz_struc_count].aZBufParam = NULL;
244   }
245
246   return nz_wks[NZWksIdx].nz_struc_count++;
247 }
248
249
250 /*----------------------------------------------------------------------*/
251
252 /*
253 * affichage d'un triedre non zoomable a partir des index dans les tables
254 * des structures non zoomables.
255 *
256 * Triedre = Objet non Zoomable :
257 * on recalcule ses dimensions et son origine en fonction de la taille
258 * de la fenetre; on positionne selon le choix de l'init;
259 * et on inhibe seulement les translations.
260 *
261 */
262
263
264
265
266 TStatus call_triedron_redraw (
267                               int      nz_wks_entry,
268                               int      nz_struc_entry,
269                               GLdouble U,
270                               GLdouble V
271                               )
272 {
273   GLdouble modelMatrix[4][4];
274   GLdouble projMatrix[4][4];
275
276   GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
277   GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
278   GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
279   GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
280   GLfloat TriedronColor[3] = { 1.0, 1.0, 1.0 }; /* def = blanc */
281
282   GLfloat TriedronWidth = 1.0;
283   GLfloat TriedronScale = (float)0.1 ;
284   GLint   TriedronPosition = 0; /* def = Aspect_TOTP_CENTER */
285
286   GLdouble L, l, rayon ;
287   GLdouble minUV;
288   int      ii;
289 #ifdef PRINT_MATRIX 
290   int      jj;
291 #endif
292   int      NbFacettes;
293   double   Angle;
294   GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
295
296   GLuint fontBase = 0;
297   GLint mode;
298
299 #ifdef QTOCC_PATCH /* PCD 10/02/08 */
300   /* Fix to problem with clipping planes chopping off pieces of the triedron */
301   GLint max_plane=0;
302   GLboolean* isPlaneActive;
303   glGetIntegerv( GL_MAX_CLIP_PLANES, &max_plane);
304   isPlaneActive= new GLboolean[max_plane];
305   /* Backup the clip planes.         */
306   for (ii = 0; ii < max_plane ; ii++) {
307     isPlaneActive[ii] = glIsEnabled(GL_CLIP_PLANE0 + ii);
308     glDisable(GL_CLIP_PLANE0 + ii);
309   }
310 #endif
311
312   /* 
313   * Lecture des Init. du Triedre 
314   */
315
316   TriedronColor[0] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[0];
317   TriedronColor[1] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[1];
318   TriedronColor[2] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[2];
319   TriedronScale = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aScale;
320   TriedronPosition = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aPos;
321
322
323   /* 
324   * Calcul des axes => on inhibe le zoom.
325   */
326
327   /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
328   /* de la dimension la plus petite de la window.                    */ 
329   if ( U < V )  minUV = U;
330   else minUV = V;
331   L = minUV * (double) TriedronScale ;
332
333   /* Position de l'origine */
334   TriedronOrigin[0]= 0.0; 
335   TriedronOrigin[1]= 0.0;
336   TriedronOrigin[2]= 0.0; 
337
338   /* Position des Axes */
339   TriedronAxeX[0] = TriedronOrigin[0] + L ;
340   TriedronAxeX[1] = TriedronOrigin[1] + 0.0;
341   TriedronAxeX[2] = TriedronOrigin[2] + 0.0;
342
343   TriedronAxeY[0] = TriedronOrigin[0] + 0.0;
344   TriedronAxeY[1] = TriedronOrigin[1] + L ;
345   TriedronAxeY[2] = TriedronOrigin[2] + 0.0;
346
347   TriedronAxeZ[0] = TriedronOrigin[0] + 0.0;
348   TriedronAxeZ[1] = TriedronOrigin[1] + 0.0;
349   TriedronAxeZ[2] = TriedronOrigin[2] + L ;
350
351   /*
352   * On inhibe les translations; on conserve les autres transformations.
353   */
354
355   /* on lit les matrices de transformation et de projection de la vue */
356   /* pour annuler les translations (dernieres colonnes des matrices). */
357   glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
358   glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
359
360 #ifdef PRINT_MATRIX 
361   printf ("\n--- call_triedron_redraw : avant transfo projMatrix= ");
362   for (ii = 0; ii<4 ; ii++) {
363     printf ("\n ");
364     for (jj = 0; jj<4 ; jj++) {
365       printf ("  %f  ", projMatrix[ii][jj] );
366     }
367   }
368   printf ("\n--- call_triedron_redraw : avant transfo  modelMatrix= ");
369   for (ii = 0; ii<4 ; ii++) {
370     printf ("\n ");
371     for (jj = 0; jj<4 ; jj++) {
372       printf ("  %f  ", modelMatrix[ii][jj] );
373     }
374   }
375 #endif
376
377
378   /* on annule la translation qui peut etre affectee a la vue */
379   modelMatrix[3][0] = 0. ;
380   modelMatrix[3][1] = 0. ;
381   modelMatrix[3][2] = 0. ; 
382   projMatrix[3][0] = 0. ;
383   projMatrix[3][1] = 0. ;
384   projMatrix[3][2] = 0. ; 
385
386
387   /* sauvegarde du contexte des matrices avant chargement */
388   glMatrixMode (GL_MODELVIEW);
389   glPushMatrix ();
390   glLoadIdentity ();
391   glLoadMatrixd( (GLdouble *) modelMatrix);
392   glMatrixMode ( GL_PROJECTION );
393   glPushMatrix ();
394   glLoadIdentity();
395   glLoadMatrixd( (GLdouble *) projMatrix);
396
397
398 #ifdef PRINT_MATRIX 
399   printf ("\n\n\n--- call_triedron_redraw :  APRES transfo projMatrix= ");
400   for (ii = 0; ii<4 ; ii++) {
401     printf ("\n ");
402     for (jj = 0; jj<4 ; jj++) {
403       printf ("  %f  ", projMatrix[ii][jj] );
404     }
405   }
406   printf ("\n--- call_triedron_redraw : APRES transfo  modelMatrix= ");
407   for (ii = 0; ii<4 ; ii++) {
408     printf ("\n ");
409     for (jj = 0; jj<4 ; jj++) {
410       printf ("  %f  ", modelMatrix[ii][jj] );
411     }
412   }
413 #endif
414
415
416   /*
417   * Positionnement de l'origine du triedre selon le choix de l'init
418   */
419
420   /* on fait uniquement une translation de l'origine du Triedre */
421
422   switch (TriedronPosition) {
423
424        case 0 : /* Aspect_TOTP_CENTER */
425          break;
426
427        case 1 : /* Aspect_TOTP_LEFT_LOWER */
428          glTranslated( -U/2. + L , -V/2. + L , 0. );
429          break;
430
431        case 2  : /*Aspect_TOTP_LEFT_UPPER */
432          glTranslated( -U/2. + L , +V/2. - L -L/3. , 0. );
433          break;
434
435        case 3 : /* Aspect_TOTP_RIGHT_LOWER */
436          glTranslated( U/2. - L -L/3. , -V/2. + L , 0. );
437          break;
438
439        case 4  : /* Aspect_TOTP_RIGHT_UPPER */
440          glTranslated( U/2. - L -L/3. , +V/2. - L -L/3. , 0. );
441          break;
442
443        default :
444          break;
445
446   }
447
448 #ifdef PRINT 
449   printf ("\n--- call_triedron_redraw :  TriedronOrigin= %f %f %f\n",
450     TriedronOrigin[0], TriedronOrigin[1], TriedronOrigin[2]);
451   printf ("\n---                      :  TriedronAxeX= %f %f %f \n",
452     TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
453   printf ("\n---                      :  TriedronAxeY= %f %f %f \n",
454     TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2] );
455   printf ("\n---                      :  TriedronAxeZ= %f %f %f \n",
456     TriedronAxeZ[0], TriedronAxeZ[1], TriedronAxeZ[2]);
457   printf ("\n---                      : TriedronScale= %f \n",TriedronScale);
458   printf ("\n---                      : 1/echelle = ( %f %f %f %f ) \n",
459     modelMatrix[0][0],modelMatrix[1][1],modelMatrix[2][2],modelMatrix[3][3]);
460 #endif
461
462
463   /* 
464   * Creation du triedre 
465   */
466   glColor3fv (TriedronColor);
467
468   glGetIntegerv( GL_RENDER_MODE, &mode );
469
470 #ifdef HAVE_GL2PS
471   if( mode==GL_RENDER )
472     glLineWidth( TriedronWidth );
473   else if( mode==GL_FEEDBACK )
474     gl2psLineWidth( TriedronWidth );
475 #else
476         glLineWidth( TriedronWidth );
477 #endif 
478
479 #ifdef QTOCC_PATCH /* Fotis Sioutis 2007-11-14 15:06 
480   I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode 
481   changes colors depending on the state of the view. This behaviour can be easily 
482   corrected by altering call_triedron_redraw function in OpenGl_triedron.c of TKOpengl.
483   The only change needed is to erase the LightOff() function that is called before the 
484   Axis name drawing and move this function call just before the initial axis drawing.
485   Below is the code portion with the modification.I don't know if this is considered to 
486   be a bug but anyway i believe it might help some of you out there.*/
487   LightOff();
488 #endif
489
490   /* dessin des axes */
491   glBegin(GL_LINES);
492   glVertex3dv( TriedronOrigin );
493   glVertex3dv( TriedronAxeX );
494
495   glVertex3dv( TriedronOrigin );
496   glVertex3dv( TriedronAxeY );
497
498   glVertex3dv( TriedronOrigin );
499   glVertex3dv( TriedronAxeZ );
500   glEnd();
501
502
503   /* fleches au bout des axes (= cones de la couleur demandee) */
504   l = L - L/4. ; /* distance a l'origine */
505   rayon = L/30. ; /* rayon de la base du cone */
506   NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
507   Angle = 2. * M_PI/ NbFacettes;
508
509   /* solution FILAIRE des cones au bout des axes : une seule ligne */
510   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
511   /* (la couleur est deja initialisee dans TriedronColor) */
512   /* FIN de la solution FILAIRE CHOISIE pour les cones des axes */
513
514   /* fleche en X */
515   glBegin(GL_TRIANGLE_FAN);
516   glVertex3dv( TriedronAxeX );
517   TriedronCoord[0] = TriedronOrigin[0] + l ;
518   ii = NbFacettes;
519   while (ii >= 0 ) {
520     TriedronCoord[1] = TriedronOrigin[1] + ( rayon * sin(ii * Angle) );
521     TriedronCoord[2] = TriedronOrigin[2] + ( rayon * cos(ii * Angle) );
522     glVertex3dv( TriedronCoord );
523     ii--;
524   }
525   glEnd();
526
527   /* fleche en Y */
528   glBegin(GL_TRIANGLE_FAN);
529   glVertex3dv( TriedronAxeY );
530   TriedronCoord[1] = TriedronOrigin[1] + l ;
531   ii = NbFacettes;
532   while (ii >= 0 ) {
533     TriedronCoord[0] = TriedronOrigin[0] + (rayon * cos(ii * Angle) );
534     TriedronCoord[2] = TriedronOrigin[2] + (rayon * sin(ii * Angle) );
535     glVertex3dv( TriedronCoord );
536     ii--;
537   }
538   glEnd();
539
540   /* fleche en Z */
541   glBegin(GL_TRIANGLE_FAN);
542   glVertex3dv( TriedronAxeZ );
543   TriedronCoord[2] = TriedronOrigin[2] + l ;
544   ii = NbFacettes;
545   while (ii >= 0 ) {
546     TriedronCoord[0] = TriedronOrigin[0] + ( rayon * sin(ii * Angle) );
547     TriedronCoord[1] = TriedronOrigin[1] + ( rayon * cos(ii * Angle) );
548     glVertex3dv( TriedronCoord );
549     ii--;
550   }
551   glEnd();
552
553   /* dessin de l'origine */
554   TriedronCoord[0] = TriedronOrigin[0] + rayon ;
555   TriedronCoord[1] = TriedronOrigin[1] + 0.0 ;
556   TriedronCoord[2] = TriedronOrigin[2] + 0.0 ;
557   ii = 24 ;
558   Angle = 2. * M_PI/ii ;
559   glBegin(GL_LINE_LOOP);
560   while (ii >= 0 ) {
561     TriedronCoord[0] = TriedronOrigin[0] + ( rayon * sin(ii * Angle) );
562     TriedronCoord[1] = TriedronOrigin[1] + ( rayon * cos(ii * Angle) );
563     glVertex3dv( TriedronCoord );
564     ii--;
565   }  
566   glEnd();
567
568   LightOff();
569
570   /* 
571   * Noms des axes et de l'origine
572   */
573
574   /* init de la fonte */
575
576   OpenGl_TextRender* textRender=OpenGl_TextRender::instance();
577
578   /* Axe X */
579   TriedronCoord[0] = TriedronOrigin[0] + ( L + rayon ) ;
580   TriedronCoord[1] = TriedronOrigin[1] + 0.0;
581   TriedronCoord[2] = TriedronOrigin[2] - rayon ;
582   textRender->RenderText(L"X", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2] );
583
584   /* Axe Y */
585   TriedronCoord[0] = TriedronOrigin[0] + rayon ;
586   TriedronCoord[1] = TriedronOrigin[1] + ( L + 3.0 * rayon ) ;
587   TriedronCoord[2] = TriedronOrigin[2] + ( 2.0 * rayon );
588   textRender->RenderText(L"Y", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
589
590   /* Axe Z */
591   TriedronCoord[0] = TriedronOrigin[0] + ( - 2.0 * rayon ) ;
592   TriedronCoord[1] = TriedronOrigin[1] +  rayon/2. ;
593   TriedronCoord[2] = TriedronOrigin[2] + ( L + 3.0 * rayon ) ;
594   textRender->RenderText(L"Z", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
595
596 #ifdef QTOCC_PATCH /* PCD 10/02/08 */
597   /* Recover the clip planes */
598   glGetIntegerv( GL_MAX_CLIP_PLANES, &max_plane);
599   for (ii = 0; ii <max_plane ; ii++) {
600     if (isPlaneActive[ii]) { 
601       glEnable(GL_CLIP_PLANE0 + ii);
602     }
603   } 
604   free(isPlaneActive);
605
606 #endif
607
608   /* 
609   * restauration du contexte des matrices
610   */
611   glMatrixMode (GL_PROJECTION);
612   glPopMatrix ();
613   glMatrixMode (GL_MODELVIEW);
614   glPopMatrix ();
615
616
617   return (TSuccess);
618
619 }
620
621
622
623
624 /*******************************************************
625 *  Draws ZBUFFER trihedron mode
626 *******************************************************/
627 TStatus call_zbuffer_triedron_redraw (
628                                       int      nz_wks_entry,
629                                       int      nz_struc_entry,
630                                       GLdouble U,
631                                       GLdouble V
632                                       )
633 {
634   GLdouble modelMatrix[4][4];
635   GLdouble projMatrix[4][4];
636
637   GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
638   GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
639   GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
640   GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
641   GLfloat TriedronColor[3] = { 1.0, 1.0, 1.0 }; /* def = blanc */
642
643   GLfloat TriedronScale = (float)0.1 ;
644   GLint   TriedronPosition = 0; /* def = Aspect_TOTP_CENTER */
645
646   GLdouble L, l, rayon ;
647   GLdouble minUV;
648   int      NbFacettes = 12;
649   double   Angle;
650   GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
651
652   GLuint fontBase = 0;
653
654   GLuint startList;
655   GLUquadricObj* aQuadric;
656   GLfloat aXColor[] = { 1.0, 0.0, 0.0, 0.6f };
657   GLfloat aYColor[] = { 0.0, 1.0, 0.0, 0.6f };
658   GLfloat aZColor[] = { 0.0, 0.0, 1.0, 0.6f };
659   GLdouble aConeDiametr;
660   GLdouble aConeLength;
661   GLdouble aCylinderDiametr;
662   GLdouble aCylinderLength;
663   GLboolean aIsDepthEnabled;
664 #ifndef BUG
665   GLboolean aIsDepthMaskEnabled;
666 #endif
667   GLint   aViewPort[4];  /* to store view port coordinates */
668   GLdouble aWinCoord[3];
669   GLboolean isWithinView;
670   GLdouble aLengthReduce = 0.8;
671   GLdouble aAxisDiametr = 0.05;
672   ZBUF_STRUCT* aParam;
673
674 #ifdef QTOCC_PATCH 
675   GLint df;                                       /* PCD 17/06/07 */      
676   GLfloat aNULLColor[] = { 0.0, 0.0, 0.0, 0.0f }; /* FS 21/01/08 */
677   /* Fix to problem with clipping planes chopping off pieces of the triedron   */
678   int i;
679   GLint max_plane=0;
680   GLboolean* isPlaneActive;
681   glGetIntegerv( GL_MAX_CLIP_PLANES, &max_plane);
682   isPlaneActive = new GLboolean[max_plane];
683   /* Backup the clip planes. */
684   for (i = 0; i < max_plane ; i++) {
685     isPlaneActive[i] = glIsEnabled(GL_CLIP_PLANE0 + i);
686     glDisable(GL_CLIP_PLANE0 + i);
687   }
688 #endif
689
690   /* 
691   * Lecture des Init. du Triedre 
692   */
693
694   TriedronColor[0] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[0];
695   TriedronColor[1] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[1];
696   TriedronColor[2] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[2];
697   TriedronScale = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aScale;
698   TriedronPosition = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aPos;
699
700   if (nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aZBufParam != NULL) {
701     aParam = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aZBufParam;
702     aXColor[0] = aParam->aXColor[0];
703     aXColor[1] = aParam->aXColor[1];
704     aXColor[2] = aParam->aXColor[2];
705
706     aYColor[0] = aParam->aYColor[0];
707     aYColor[1] = aParam->aYColor[1];
708     aYColor[2] = aParam->aYColor[2];
709
710     aZColor[0] = aParam->aZColor[0];
711     aZColor[1] = aParam->aZColor[1];
712     aZColor[2] = aParam->aZColor[2];
713
714     aLengthReduce = aParam->aRatio;
715     aAxisDiametr = aParam->aDiametr;
716     NbFacettes = aParam->aNbFacettes;
717   }
718
719   /* 
720   * Calcul des axes => on inhibe le zoom.
721   */
722
723   /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
724   /* de la dimension la plus petite de la window.                    */ 
725   if ( U < V )  minUV = U;
726   else minUV = V;
727   L = minUV * (double) TriedronScale ;
728
729   /* Position de l'origine */
730   TriedronOrigin[0]= 0.0; 
731   TriedronOrigin[1]= 0.0;
732   TriedronOrigin[2]= 0.0; 
733
734   /* Position des Axes */
735   TriedronAxeX[0] = TriedronOrigin[0] + L ;
736   TriedronAxeX[1] = TriedronOrigin[1] + 0.0;
737   TriedronAxeX[2] = TriedronOrigin[2] + 0.0;
738
739   TriedronAxeY[0] = TriedronOrigin[0] + 0.0;
740   TriedronAxeY[1] = TriedronOrigin[1] + L ;
741   TriedronAxeY[2] = TriedronOrigin[2] + 0.0;
742
743   TriedronAxeZ[0] = TriedronOrigin[0] + 0.0;
744   TriedronAxeZ[1] = TriedronOrigin[1] + 0.0;
745   TriedronAxeZ[2] = TriedronOrigin[2] + L ;
746
747   /* Check position in the ViewPort */
748   glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
749   glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
750
751   glGetIntegerv(GL_VIEWPORT, aViewPort);
752   gluProject(TriedronOrigin[0], TriedronOrigin[1], TriedronOrigin[2],
753     (GLdouble *)modelMatrix, (GLdouble *)projMatrix, aViewPort,
754     &aWinCoord[0], &aWinCoord[1], &aWinCoord[2]);
755
756 #ifdef QTOCC_PATCH /* PCD 29/09/2008 */
757   /* Simple code modification recommended by Fotis Sioutis and Peter Dolbey  */
758   /* to remove the irritating default behaviour of triedrons using V3d_ZBUFFER   */
759   /* which causes the glyph to jump around the screen when the origin moves offscreen. */
760   isWithinView = GL_FALSE;
761 #else
762   /* Original code */
763   isWithinView = !((aWinCoord[0]<aViewPort[0]) || (aWinCoord[0]>aViewPort[2]) ||
764     (aWinCoord[1]<aViewPort[1]) || (aWinCoord[1]>aViewPort[3]));
765 #endif
766
767   if (!isWithinView) {
768     /* Annulate translation matrix */
769     modelMatrix[3][0] = 0. ;
770     modelMatrix[3][1] = 0. ;
771     modelMatrix[3][2] = 0. ; 
772     projMatrix[3][0] = 0. ;
773     projMatrix[3][1] = 0. ;
774     projMatrix[3][2] = 0. ; 
775
776     /* save matrix */
777     glMatrixMode (GL_MODELVIEW);
778     glPushMatrix ();
779     glLoadIdentity ();
780     glLoadMatrixd( (GLdouble *) modelMatrix);
781     glMatrixMode ( GL_PROJECTION );
782     glPushMatrix ();
783     glLoadIdentity();
784     glLoadMatrixd( (GLdouble *) projMatrix);
785
786
787     /*
788     * Define position in the view
789     */
790     switch (TriedronPosition) {
791       case 0 :  /* Aspect_TOTP_CENTER */
792         break;
793
794       case 1 :  /* Aspect_TOTP_LEFT_LOWER */
795         glTranslated( -U/2. + L , -V/2. + L , 0. );
796         break;
797
798       case 2  : /* Aspect_TOTP_LEFT_UPPER */
799         glTranslated( -U/2. + L , +V/2. - L -L/3. , 0. );
800         break;
801
802       case 3 :  /* Aspect_TOTP_RIGHT_LOWER */
803         glTranslated( U/2. - L -L/3. , -V/2. + L , 0. );
804         break;
805
806       case 4  :  /* Aspect_TOTP_RIGHT_UPPER */
807         glTranslated( U/2. - L -L/3. , +V/2. - L -L/3. , 0. );
808         break;
809
810       default :
811         break;
812
813     }
814     L *= aLengthReduce;
815   }
816
817
818   /* 
819   * Creation the trihedron
820   */
821
822 #define COLOR_REDUCE      0.3f
823 #define CYLINDER_LENGTH   0.75f
824 #ifdef BUG
825 #define ALPHA_REDUCE      0.4f
826 #else
827 #define ALPHA_REDUCE      1.0f
828 #endif
829
830   startList = glGenLists(4);
831   aQuadric = gluNewQuadric();
832
833   aCylinderLength = L * CYLINDER_LENGTH;
834   aCylinderDiametr = L * aAxisDiametr;
835   aConeDiametr = aCylinderDiametr * 2;
836   aConeLength = L * (1 - CYLINDER_LENGTH);
837   /* Correct for owerlapping */
838   /*    aCylinderLength += aConeLength - 1.2*aCylinderDiametr*aConeLength/aConeDiametr;*/
839
840   aIsDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
841 #ifndef BUG
842
843 #ifdef QTOCC_PATCH  /*PCD 02/07/07   */
844   /* GL_DEPTH_WRITEMASK is not a valid argument to glIsEnabled, the  */
845   /* original code is shown to be broken when run under an OpenGL debugger  */
846   /* like GLIntercept. This is the correct way to retrieve the mask value.  */
847   glGetBooleanv(GL_DEPTH_WRITEMASK, &aIsDepthMaskEnabled); 
848 #else
849   aIsDepthMaskEnabled = glIsEnabled(GL_DEPTH_WRITEMASK);
850 #endif
851
852 #endif 
853
854   /* Create cylinder for axis */
855   gluQuadricDrawStyle(aQuadric, GLU_FILL); /* smooth shaded */
856   gluQuadricNormals(aQuadric, GLU_FLAT);
857   /* Axis */
858   glNewList(startList, GL_COMPILE);
859   gluCylinder(aQuadric, aCylinderDiametr, aCylinderDiametr, aCylinderLength, NbFacettes, 1);
860   glEndList();
861   /* Cone */
862   glNewList(startList + 1, GL_COMPILE);
863   gluCylinder(aQuadric, aConeDiametr, 0, aConeLength, NbFacettes, 1);
864   glEndList();
865   /* Central sphere */
866   glNewList(startList + 2, GL_COMPILE);
867 #ifdef QTOCC_PATCH
868   gluSphere(aQuadric, aCylinderDiametr * 2, NbFacettes, NbFacettes);
869 #else
870   gluSphere(aQuadric, aCylinderDiametr, NbFacettes, NbFacettes);
871 #endif
872   glEndList();
873   /* End disk */
874   gluQuadricOrientation(aQuadric,GLU_INSIDE); /*szv*/
875   glNewList(startList + 3, GL_COMPILE);
876   gluDisk(aQuadric, aCylinderDiametr, aConeDiametr, NbFacettes, 1/*szv:2*/);
877   glEndList();
878
879 #ifdef QTOCC_PATCH
880   /* Store previous attributes */
881   glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
882   LightOn();
883 #else
884   LightOn();
885
886   /* Store previous attributes */
887   glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
888 #endif
889
890   glCullFace(GL_BACK);
891   glEnable(GL_CULL_FACE);
892
893 #ifdef QTOCC_PATCH /*Fotis Sioutis | 2008-01-21 10:55 
894   In the function call_zbuffer_triedron_redraw of TKOpengl, 
895   the z buffered trihedron changes colors in case there 
896   is an object in the scene that has an explicit material 
897   attached to it.In the trihedron display loop, 
898   GL_COLOR_MATERIAL is enabled, but only the GL_DIFFUSE 
899   parameter is utilized in glColorMaterial(...).
900   This causes the last ambient,specular and emission values 
901   used, to stay at the stack and applied to the trihedron
902   (which causes the color change).
903   A fix is proposed , to change GL_DIFFUSE to 
904   GL_AMBIENT_AND_DIFFUSE in glColorMaterial call in 
905   line 946.The above of course will leave unchanged 
906   the SPECULAR and EMISSION values.
907   Another proposal which would fix 100% the problem 
908   is to use glMaterial instead of glColor on the trihedron 
909   drawing loop.               */
910   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aNULLColor);
911   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, aNULLColor);
912   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, aNULLColor);
913
914   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.);
915 #endif
916
917   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
918   glEnable(GL_COLOR_MATERIAL);
919
920   if (!aIsDepthEnabled)  {
921     glEnable(GL_DEPTH_TEST);
922 #ifndef BUG
923     glClear(GL_DEPTH_BUFFER_BIT);
924 #endif
925   }
926 #ifdef BUG
927   if (!(aIsDepthEnabled && isWithinView))
928     glClear(GL_DEPTH_BUFFER_BIT);
929 #endif
930 #ifndef BUG
931   if (!aIsDepthMaskEnabled)  {
932     /* This is how the depthmask needs to be re-enabled...*/
933     glDepthMask(GL_TRUE);
934     /* ...and not this stuff below */
935   }
936 #endif
937
938   glMatrixMode(GL_MODELVIEW);
939 #ifdef QTOCC_PATCH /* PCD 17/06/07  */
940   glGetIntegerv (GL_DEPTH_FUNC, &df); 
941 #else
942   /*szv:if (isWithinView) {*/
943   glDepthFunc(GL_GREATER);
944   glPushMatrix();
945   glPushMatrix();
946   glPushMatrix();
947
948   glColor4f(TriedronColor[0]*COLOR_REDUCE, 
949     TriedronColor[1]*COLOR_REDUCE, 
950     TriedronColor[2]*COLOR_REDUCE,
951     ALPHA_REDUCE);
952   glCallList(startList+2);
953
954   /* Z axis */
955   glColor4f(aZColor[0]*COLOR_REDUCE, 
956     aZColor[1]*COLOR_REDUCE, 
957     aZColor[2]*COLOR_REDUCE,
958     ALPHA_REDUCE);
959   glCallList(startList);
960   glTranslated(0, 0, L * CYLINDER_LENGTH);
961   glCallList(startList + 3);
962   glCallList(startList + 1);
963   glPopMatrix();    
964
965   /* X axis */
966   glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
967   glColor4f(aXColor[0]*COLOR_REDUCE, 
968     aXColor[1]*COLOR_REDUCE, 
969     aXColor[2]*COLOR_REDUCE,
970     ALPHA_REDUCE);
971   glCallList(startList);
972   glTranslated(0, 0, L * CYLINDER_LENGTH);
973   glCallList(startList + 3);
974   glCallList(startList + 1);
975   glPopMatrix();    
976
977   /* Y axis */
978   glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
979   glColor4f(aYColor[0]*COLOR_REDUCE, 
980     aYColor[1]*COLOR_REDUCE, 
981     aYColor[2]*COLOR_REDUCE,
982     ALPHA_REDUCE);
983   glCallList(startList);
984   glTranslated(0, 0, L * CYLINDER_LENGTH);
985   glCallList(startList + 3);
986   glCallList(startList + 1);
987   glPopMatrix();
988
989   glDepthFunc(GL_LESS);
990   /*szv:}*/
991 #endif
992
993 #ifdef QTOCC_PATCH
994   for (i = 0; i < 2; i++) /* PCD 11/02/08 Two pass method */
995   {
996     if (i == 0) /*  First pass  */
997     {                          
998       glDepthFunc(GL_ALWAYS); 
999     }
1000     else
1001     {
1002       glDepthFunc(GL_LEQUAL); 
1003     }
1004 #endif
1005
1006     glPushMatrix();
1007     glPushMatrix();
1008     glPushMatrix();
1009
1010     glColor3fv(TriedronColor);
1011     glCallList(startList+2);
1012
1013     /* Z axis */
1014     glColor4fv(aZColor);
1015     glCallList(startList);
1016     glTranslated(0, 0, L * CYLINDER_LENGTH);
1017     glCallList(startList + 3);
1018     glCallList(startList + 1);
1019     glPopMatrix();    
1020
1021     /* X axis */
1022     glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
1023     glColor4fv(aXColor);
1024     glCallList(startList);
1025     glTranslated(0, 0, L * CYLINDER_LENGTH);
1026     glCallList(startList + 3);
1027     glCallList(startList + 1);
1028     glPopMatrix();    
1029
1030     /* Y axis */
1031     glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
1032     glColor4fv(aYColor);
1033     glCallList(startList);
1034     glTranslated(0, 0, L * CYLINDER_LENGTH);
1035     glCallList(startList + 3);
1036     glCallList(startList + 1);
1037     glPopMatrix();
1038
1039 #ifdef QTOCC_PATCH
1040   }
1041 #endif
1042
1043   if (!aIsDepthEnabled) 
1044     glDisable(GL_DEPTH_TEST);
1045 #ifndef BUG
1046   if (!aIsDepthMaskEnabled)
1047
1048 #ifdef QTOCC_PATCH /*PCD 02/07/07   */
1049     glDepthMask(GL_FALSE);
1050 #else
1051     glDisable(GL_DEPTH_WRITEMASK);
1052 #endif
1053
1054 #endif
1055   glDisable(GL_CULL_FACE);
1056   glDisable(GL_COLOR_MATERIAL);
1057
1058   gluDeleteQuadric(aQuadric);
1059   glColor3fv (TriedronColor);
1060
1061 #ifdef QTOCC_PATCH /* PCD 11/02/08 */
1062   /* Always write the text */
1063   glDepthFunc(GL_ALWAYS); 
1064 #endif
1065
1066   glPopAttrib();
1067
1068   /* fleches au bout des axes (= cones de la couleur demandee) */
1069   l = L - L/4. ; /* distance a l'origine */
1070   rayon = L/30. ; /* rayon de la base du cone */
1071   Angle = 2. * M_PI/ NbFacettes;
1072
1073   glDeleteLists(startList, 4); 
1074
1075   LightOff();
1076
1077   /* 
1078   * origine names
1079   */
1080
1081   /* init font */
1082
1083   OpenGl_TextRender* textRender=OpenGl_TextRender::instance();
1084
1085   /* Axe X */
1086   TriedronCoord[0] = TriedronOrigin[0] + ( L + rayon ) ;
1087   TriedronCoord[1] = TriedronOrigin[1] + 0.0;
1088   TriedronCoord[2] = TriedronOrigin[2] - rayon ;
1089   textRender->RenderText(L"X", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
1090
1091   /* Axe Y */
1092   TriedronCoord[0] = TriedronOrigin[0] + rayon ;
1093   TriedronCoord[1] = TriedronOrigin[1] + ( L + 3.0 * rayon ) ;
1094   TriedronCoord[2] = TriedronOrigin[2] + ( 2.0 * rayon );
1095   textRender->RenderText(L"Y", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
1096
1097   /* Axe Z */
1098   TriedronCoord[0] = TriedronOrigin[0] + ( - 2.0 * rayon ) ;
1099   TriedronCoord[1] = TriedronOrigin[1] +  rayon/2. ;
1100   TriedronCoord[2] = TriedronOrigin[2] + ( L + 3.0 * rayon ) ;
1101   textRender->RenderText(L"Z", fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
1102
1103 #ifdef QTOCC_PATCH 
1104   /*PCD 17/06/07    */
1105   glDepthFunc(df);
1106
1107   /* PCD 10/02/08  */
1108   /* Recover the clip planes */ 
1109   glGetIntegerv( GL_MAX_CLIP_PLANES, &max_plane);
1110   for (i = 0; i < max_plane ; i++) {
1111     if (isPlaneActive[i]) { 
1112       glEnable(GL_CLIP_PLANE0 + i);
1113     }
1114   }
1115   free(isPlaneActive);
1116 #endif
1117
1118   if (!isWithinView) { /* restore matrix */
1119     glMatrixMode (GL_PROJECTION);
1120     glPopMatrix ();
1121     glMatrixMode (GL_MODELVIEW);
1122     glPopMatrix ();
1123   }
1124
1125   return (TSuccess);
1126
1127 }
1128
1129
1130 /*----------------------------------------------------------------------*/
1131
1132 /*----------------------------------------------------------------------*/
1133 /*
1134 * Fonctions publiques 
1135 */
1136
1137
1138 /*
1139 * initialisation d'un triedre non zoomable dans une vue.
1140 * ou modification des valeurs deja initialisees.
1141 */
1142
1143 TStatus call_triedron_init (
1144                             CALL_DEF_VIEW * aview, 
1145                             int aPosition, 
1146                             float r,
1147                             float g,
1148                             float b, 
1149                             float aScale,
1150                             int asWireframe 
1151                             )
1152
1153 {
1154
1155   int nz_wks_entry;
1156   int nz_struc_entry;
1157   ZBUF_STRUCT* aParam;
1158
1159
1160 #ifdef PRINT
1161   printf("\n----------- call_triedron_init  r = %f, g = %f, b = %f",
1162     r, g, b);
1163   printf(", aScale = %f, aPosition = %d \n", aScale, aPosition );
1164 #endif
1165
1166   if (aview->WsId == -1) return(TFailure);
1167   if (aview->ViewId == -1) return(TFailure);
1168 #ifdef PRINT
1169   printf(", aview->WsId=%d  aview->ViewId=%d \n",aview->WsId,aview->ViewId);
1170 #endif
1171
1172
1173
1174   /* recherche du num de la liste de structures non zoomables de la wks */
1175   /* creation sinon */
1176   nz_wks_entry = find_nz_wks(aview->WsId, 1);
1177   if (nz_wks_entry == -1) return TFailure;
1178
1179   /* recherche du Triedre s'il existe; creation sinon */
1180   nz_struc_entry = find_nz_struc(nz_wks_entry, TRIEDRON_ID, 1);
1181   if (nz_struc_entry == -1) return TFailure;
1182
1183   /* mise a jour du Triedre */
1184   nz_wks[nz_wks_entry].triedron_on = 1;
1185   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].NZStrucID = TRIEDRON_ID;
1186   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].astructure = NULL;
1187   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aPos = aPosition;
1188   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[0] = r;
1189   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[1] = g;
1190   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[2] = b;
1191   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aScale = aScale;
1192   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].isWireframe = asWireframe;
1193
1194   nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aZBufParam = new ZBUF_STRUCT();
1195   if (nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aZBufParam == NULL) return TFailure;
1196
1197   aParam = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aZBufParam;
1198   aParam->aXColor[0] = theXColor[0];
1199   aParam->aXColor[1] = theXColor[1];
1200   aParam->aXColor[2] = theXColor[2];
1201
1202   aParam->aYColor[0] = theYColor[0];
1203   aParam->aYColor[1] = theYColor[1];
1204   aParam->aYColor[2] = theYColor[2];
1205
1206   aParam->aZColor[0] = theZColor[0];
1207   aParam->aZColor[1] = theZColor[1];
1208   aParam->aZColor[2] = theZColor[2];
1209
1210   aParam->aRatio = theRatio;
1211   aParam->aDiametr = theDiametr;
1212   aParam->aNbFacettes = theNBFacettes;
1213
1214
1215 #ifdef DEBUG
1216   printf("nz_wks_entry=%d nz_struc_entry=%d \n",nz_wks_entry,nz_struc_entry);
1217   printf("ajout ok\n");
1218 #endif
1219   return (TSuccess);
1220
1221 }
1222
1223 /*----------------------------------------------------------------------*/
1224
1225 /*
1226 * affichage d'un triedre non zoomable dans la wks  awsid 
1227 *
1228 * Triedre = Objet non Zoomable;
1229 * on cree cette fonction pour pouvoir travailler par les structures 
1230 * utilisees par les fonctions Tsm* et TEL_VIEW_REP
1231 *
1232 */
1233
1234 TStatus call_triedron_redraw_from_wsid (
1235                                         Tint awsid
1236                                         )
1237
1238 {
1239
1240   TStatus   status = TSuccess;
1241   int       nz_wks_entry;
1242   int       nz_struc_entry;
1243   int    save_texture_state;
1244   GLdouble  U, V ; /* largeur,hauteur de la fenetre */
1245
1246   CMN_KEY_DATA    key;
1247   tel_view_data   vptr;
1248
1249   if ( awsid == -1) return (TFailure );
1250
1251 #ifdef BUC61045
1252   /* check if GL_LIGHTING should be disabled
1253   no enabling 'cause it will be done (if necessary: kinda Polygon types ) 
1254   during redrawing structures 
1255   */
1256   TsmGetWSAttri (awsid, WSGLLight, &key );
1257   if ( key.ldata == TOff )
1258     glDisable( GL_LIGHTING );
1259 #endif
1260
1261   /* recherche du numero de la liste de structures non zoomables de la wks */
1262 #ifdef PRINT
1263   printf("\n----------- call_triedron_redraw_from_WSID : appel find_nz_wks \n");
1264 #endif
1265   nz_wks_entry = find_nz_wks(awsid, 0);
1266   /* si on ne l'a pas trouve, il n'y a rien a faire */
1267   if (nz_wks_entry == -1) return (TSuccess);
1268
1269   /* recherche du Triedre */
1270 #ifdef PRINT
1271   printf("\n----------- call_triedron_redraw_from_WSID : appel find_nz_struc \n");
1272 #endif
1273   nz_struc_entry = find_nz_struc(nz_wks_entry, TRIEDRON_ID, 0);
1274   /* si on ne l'a pas trouve, il n'y a rien a faire */
1275   if (nz_struc_entry == -1) return (TSuccess);
1276   /* si il est "off" il n'y a rien a faire */
1277   if (nz_wks[nz_wks_entry].triedron_on == 0) return (TSuccess);
1278
1279
1280   /* recherche de la dimension de la fenetre                   */
1281   /* (car la taille des axes du treiedre en sera 1 proportion) */
1282   TsmGetWSAttri (awsid, WSViews, &key );
1283   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
1284   if ( !vptr ) return TFailure; /* no view defined yet */
1285   U = vptr->vrep.extra.map.window.xmax - vptr->vrep.extra.map.window.xmin;
1286   V = vptr->vrep.extra.map.window.ymax - vptr->vrep.extra.map.window.ymin;
1287
1288   /* sauvegarde du contexte (on reste dans le buffer courant) */
1289   save_texture_state = IsTextureEnabled();
1290   DisableTexture();
1291
1292   /* affichage du Triedre Non Zoomable */
1293   transform_persistence_end();
1294   if (nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].isWireframe)
1295     status = call_triedron_redraw (nz_wks_entry, nz_struc_entry, U, V);
1296   else
1297     status = call_zbuffer_triedron_redraw (nz_wks_entry, nz_struc_entry, U, V);
1298
1299   /* restauration du contexte */
1300   if (save_texture_state) EnableTexture();
1301
1302   return status;
1303
1304 }
1305
1306 /*----------------------------------------------------------------------*/
1307
1308 /*
1309 * affichage d'un triedre non zoomable dans la vue aview 
1310 *
1311 * Triedre = Objet non Zoomable;
1312 * on cree cette fonction pour pouvoir utiliser CALL_DEF_VIEW
1313 *
1314 */
1315
1316 TStatus call_triedron_redraw_from_view (
1317                                         CALL_DEF_VIEW * aview
1318                                         )
1319 {
1320
1321   TStatus   status = TSuccess;
1322   int       nz_wks_entry;
1323   int       nz_struc_entry;
1324   int    save_texture_state;
1325   GLdouble  U, V ; /* largeur,hauteur de la fenetre */
1326
1327
1328
1329   if (aview->WsId == -1) return (TFailure );
1330   if (aview->ViewId == -1) return (TFailure);
1331 #ifdef PRINT
1332   printf("\n call_triedron_redraw_from_VIEW aview->WsId=%d  aview->ViewId=%d \n",aview->WsId,aview->ViewId);
1333 #endif
1334
1335
1336   /* recherche du numero de la liste de structures non zoomables de la wks */
1337 #ifdef PRINT
1338   printf("\n----------- call_triedron_redraw_from_VIEW : appel find_nz_wks \n");
1339 #endif
1340   nz_wks_entry = find_nz_wks(aview->WsId, 0);
1341   /* si on ne l'a pas trouve, il n'y a rien a faire */
1342   if (nz_wks_entry == -1) return (TSuccess);
1343
1344   /* recherche du Triedre */
1345 #ifdef PRINT
1346   printf("\n----------- call_triedron_redraw_from_VIEW : appel find_nz_struc \n");
1347 #endif
1348   nz_struc_entry = find_nz_struc(nz_wks_entry, TRIEDRON_ID, 0);
1349   /* si on ne l'a pas trouve, il n'y a rien a faire */
1350   if (nz_struc_entry == -1) return (TSuccess);
1351   /* si il est "off" il n'y a rien a faire */
1352   if (nz_wks[nz_wks_entry].triedron_on == 0) return (TSuccess);
1353
1354
1355   /* recherche de la dimension de la fenetre                   */
1356   /* (car la taille des axes du treiedre en sera 1 proportion) */
1357   U = aview->Mapping.WindowLimit.uM - aview->Mapping.WindowLimit.um ;
1358   V = aview->Mapping.WindowLimit.vM - aview->Mapping.WindowLimit.vm ;
1359
1360   /* sauvegarde du contexte et ecriture en front buffer */
1361   save_texture_state = IsTextureEnabled();
1362   DisableTexture();
1363   glDrawBuffer (GL_FRONT);
1364
1365   /* affichage du Triedre Non Zoomable */
1366   transform_persistence_end();
1367   status = call_triedron_redraw (nz_wks_entry, nz_struc_entry, U, V);
1368
1369   /* necessaire pour WNT */
1370   glFlush();
1371
1372   /* restauration du contexte */
1373   if (save_texture_state) EnableTexture();
1374   glDrawBuffer (GL_BACK); 
1375
1376   return status;
1377
1378 }
1379
1380 /*----------------------------------------------------------------------*/
1381
1382 /*
1383 * destruction du triedre non zoomable d'une vue.
1384 */
1385
1386 TStatus call_triedron_erase (
1387                              CALL_DEF_VIEW * aview
1388                              )
1389
1390 {
1391   int   nz_wks_entry;
1392   int i;
1393
1394
1395 #ifdef PRINT
1396   printf("\n----------- call_triedron_erase  " );
1397 #endif
1398
1399   if (aview->WsId == -1) return(TFailure);
1400   if (aview->ViewId == -1) return(TFailure);
1401 #ifdef PRINT
1402   printf(", aview->WsId=%d  aview->ViewId=%d \n",aview->WsId,aview->ViewId);
1403 #endif
1404
1405
1406   /* recherche du num de la liste de structures non zoomables de la wks */
1407   /* si on ne l'a pas trouve, il n'y a rien a faire                     */
1408   nz_wks_entry = find_nz_wks(aview->WsId, 0);
1409   if (nz_wks_entry == -1) return TSuccess;
1410
1411
1412   /* 
1413   * destruction du Triedre puis de toute la wks
1414   */
1415   /* (aujourd'hui il n'y a pas d'autre structure graphique dans la table */
1416   /* de la wks => on detruit tout ;                                      */
1417   /* si on ajoutait d'autres structures non zoomables, il faudrait       */
1418   /* selectionner et detruire uniquement l'element Triedre en cherchant  */
1419   /* s'il existe via une variable nz_struc_entry ).                      */
1420   for (i = 0; i < nz_wks[nz_wks_entry].nz_struc_count; i++) {
1421     if (nz_wks[nz_wks_entry].nz_struc[i].aZBufParam != NULL) 
1422       free(nz_wks[nz_wks_entry].nz_struc[i].aZBufParam);
1423   }
1424
1425   if (nz_wks[nz_wks_entry].nz_struc != NULL) {
1426     free(nz_wks[nz_wks_entry].nz_struc);
1427   }
1428
1429   if (nz_wks_count == 1) {
1430     free(nz_wks);
1431     nz_wks_count = 0;
1432     nz_wks_size = 0;
1433   }
1434   else { /* il y a au moins 2 wks definies */
1435     memcpy(&nz_wks[nz_wks_entry],
1436       &nz_wks[nz_wks_entry+1],
1437       (nz_wks_count - nz_wks_entry - 1)*sizeof(NZ_WKS));
1438     nz_wks_count--;
1439   }
1440
1441
1442 #ifdef DEBUG
1443   printf("nz_wks_entry=%d   nz_wks_count=%d   nz_wks_size=%d\n",
1444     nz_wks_entry,  nz_wks_count, nz_wks_size );
1445   printf("erase ok\n");
1446 #endif
1447
1448   return (TSuccess);
1449 }
1450
1451 /*----------------------------------------------------------------------*/
1452
1453
1454 /*
1455 * gestion d'un echo de designation du triedre non zoomable d' une vue.
1456 */
1457 TStatus call_triedron_echo (
1458                             CALL_DEF_VIEW * aview,
1459                             int aType
1460                             )
1461
1462 {
1463   return (TSuccess);
1464 }
1465
1466
1467 /*----------------------------------------------------------------------*/
1468
1469 /*
1470 * initialisation of zbuffer trihedron
1471 */
1472 extern TStatus  call_ztriedron_setup (
1473                                       float* xcolor,
1474                                       float* ycolor,
1475                                       float* zcolor,
1476                                       float  sizeratio,
1477                                       float  axisdiameter,
1478                                       int    nbfacettes)
1479 {
1480   theXColor[0] = xcolor[0];
1481   theXColor[1] = xcolor[1];
1482   theXColor[2] = xcolor[2];
1483
1484   theYColor[0] = ycolor[0];
1485   theYColor[1] = ycolor[1];
1486   theYColor[2] = ycolor[2];
1487
1488   theZColor[0] = zcolor[0];
1489   theZColor[1] = zcolor[1];
1490   theZColor[2] = zcolor[2];
1491
1492   theRatio = sizeratio;
1493   theDiametr = axisdiameter;
1494   theNBFacettes = nbfacettes;
1495
1496   return (TSuccess);
1497 }
1498