0022962: Invalid realization of reading and writing material in STEP.
[occt.git] / src / OpenGl / OpenGl_funcs.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_funcs :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : xxx ; Creation.
15 20-02-96 : FMN ; Suppression code inutile:
16 11-03-96 : FMN ; Correction warning compilation
17 01-04-96 : CAL ; Integration MINSK portage WNT
18 13-06-96 : CAL ; Gestion de la transparence dans redraw_all_structs
19 09-07-97 : FMN ; Verification calcul matrice orientation et projection.
20 Je n'ai verifie que le mode parallele pas le mode perspective.
21 18-07-97 : FMN ; Desactivation des lights au demarrage
22 05-08-97 : PCT ; Support texture mapping
23 19-08-97 : PCT ; ajout reflexion
24 23-12-97 : FMN ; Suppression TelBackInteriorStyle, TelBackInteriorStyleIndex
25 et TelBackInteriorShadingMethod
26 13-01-98 : FMN ; Oublie printf
27 03-03-98 : FMN ; Suppression variable externe TglWhetherPerspective 
28 13-03-98 : FMN ; Suppression variable externe TglUpdateView0
29 17-03-98 : FMN ; Ajout mode animation
30 - deplacement TelSetViewIndex de OpenGl_execstruct.c ici.
31 - gestion du mode animation.
32 29-04-98 : FMN ; Mode animation
33 - ajout TsmPushAttri et TsmPopAttri necessaire pour
34 sauvegarder la point de vue.
35 - ajout init de la var TglActiveWs
36 08-07-98 : FMN ; Mode animation: ajout print debug
37 27-11-98 : CAL ; S4062. AJout des layers.
38 30-11-98 : FMN ; S3819 : Textes toujours visibles
39 14-12-98 : BGN ; (S3989, Phase "triedre") ajout du reaffichage
40 du triedre .
41 05-01-99 : CAL ; Warning WNT
42 22-03-04 : SAN ; OCC4895 High-level interface for controlling polygon offsets
43
44 ************************************************************************/
45
46 #define G003    /* EUG 20-09-99 ; Animation management
47 */
48
49
50 /*----------------------------------------------------------------------*/
51 /*
52 * Includes
53 */
54
55 #include <stdio.h>
56 #include <stdlib.h>
57
58 #include <OpenGl_tgl_all.hxx>
59 #include <OpenGl_cmn_varargs.hxx>
60 #include <OpenGl_tsm.hxx>
61 #include <OpenGl_tsm_ws.hxx>
62 #include <OpenGl_telem.hxx>
63 #include <OpenGl_telem_view.hxx>
64 #include <OpenGl_telem_util.hxx>
65 #include <OpenGl_telem_attri.hxx>
66 #include <OpenGl_tgl_funcs.hxx>
67 #include <OpenGl_telem_util.hxx> 
68 #include <OpenGl_LightBox.hxx>
69 #include <OpenGl_TextureBox.hxx>
70 #include <OpenGl_animation.hxx>
71
72 #include <InterfaceGraphic_Graphic3d.hxx>
73 #include <OpenGl_telem.hxx>
74 #include <InterfaceGraphic_Visual3d.hxx>
75 #include <OpenGl_trsf_stack.hxx>
76 #include <OpenGl_triedron.hxx>
77 #include <OpenGl_graduatedtrihedron.hxx>
78
79 #ifdef G003
80 # include <OpenGl_degeneration.hxx>
81 #endif  /* G003 */
82
83 #if defined(WNT)
84 #include <GL/glu.h>
85 #endif
86
87 #include <OSD_FontAspect.hxx>
88 /*----------------------------------------------------------------------*/
89 /*
90 * Constantes
91 */
92
93 #define NO_PRINT
94 #define NO_DEBUG
95 #define NO_DEBUG_ANIMATION
96
97 #define EPSI 0.0001
98
99 /*----------------------------------------------------------------------*/
100 /*
101 * Variables externes
102 */
103
104 tsm_trsf_stack trsf_stack = NULL;
105 tsm_trsf_stack cur_trsf_stack = NULL;
106
107 Tint    ForbidSetTextureMapping;    /* valid only during traversal */
108 Tint    SecondPassNeeded;           /* valid only during traversal */
109 Tint    SecondPassDo;               /* valid only during traversal */
110
111 #ifdef G003
112 extern GLboolean g_fUpdateAM;
113 extern GLboolean g_fList;
114 int    g_nBackfacing;
115 #endif  /* G003 */
116
117
118 /*----------------------------------------------------------------------*/
119 /*
120 * Prototypes
121 */
122
123 static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
124                                    float *ox, float *oy, float *oz );
125 static void call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c);
126
127 #ifdef DEBUG
128 static void pr_matrix( matrix3 mat );
129 #endif
130
131 /*----------------------------------------------------------------------*/
132 /*
133 * Fonctions externes
134 */
135
136 void
137 call_func_set_text_style(int lid)
138 {
139   CMN_KEY  key;
140
141   key.data.ldata = lid;
142   TsmAddToStructure( TelTextStyle, 1, &key );
143   return;
144 }
145
146 /*----------------------------------------------------------------------*/
147
148 void
149 call_func_set_text_display_type(int lid)
150 {
151   CMN_KEY  key;
152
153   key.data.ldata = lid;
154   TsmAddToStructure( TelTextDisplayType, 1, &key );
155   return;
156 }
157
158 /*----------------------------------------------------------------------*/
159
160
161 /*----------------------------------------------------------------------*/
162
163 void
164 call_func_label(Tint lid)
165 {
166   CMN_KEY  key;
167
168   key.data.ldata = lid;
169   TsmAddToStructure( TelLabel, 1, &key );
170   return;
171 }
172
173 /*----------------------------------------------------------------------*/
174
175 void
176 call_func_appl_data(void *ptr)
177 {
178   CMN_KEY  key;
179
180   key.data.pdata = ptr;
181   TsmAddToStructure( TelApplicationData, 1, &key );
182   return;
183 }
184
185 /*----------------------------------------------------------------------*/
186
187 void
188 call_func_set_view_ind(Tint vid)
189 {
190   CMN_KEY  key;
191
192   key.data.ldata = vid;
193   TsmAddToStructure( TelViewIndex, 1, &key );
194   return;
195 }
196
197 /*----------------------------------------------------------------------*/
198
199 void
200 call_func_set_local_tran3( Tmatrix3  mat, TComposeType  mode )
201 {
202   CMN_KEY  key;
203
204   key.id = mode;
205   key.data.pdata = mat;
206   TsmAddToStructure( TelLocalTran3, 1, &key );
207   return;
208 }
209
210 /*----------------------------------------------------------------------*/
211
212 void
213 call_func_set_linewidth( Tfloat  lw )
214 {
215   CMN_KEY  key;
216
217   key.data.fdata = lw;
218   TsmAddToStructure( TelPolylineWidth, 1, &key );
219   return;
220 }
221
222 /*----------------------------------------------------------------------*/
223
224 void
225 call_func_set_linetype( Tint  lt )
226 {
227   CMN_KEY  key;
228
229   key.data.ldata = lt;
230   TsmAddToStructure( TelPolylineType, 1, &key );
231   return;
232 }
233
234 /*----------------------------------------------------------------------*/
235
236 void
237 call_func_set_edge_type( Tint  lt )
238 {
239   CMN_KEY  key;
240
241   key.data.ldata = lt;
242   TsmAddToStructure( TelEdgeType, 1, &key );
243   return;
244 }
245
246 /*----------------------------------------------------------------------*/
247
248 void
249 call_func_set_int_style( Tint  is )
250 {
251   CMN_KEY  key;
252
253   key.data.ldata = is;
254   TsmAddToStructure( TelInteriorStyle, 1, &key );
255   return;
256 }
257
258 /*----------------------------------------------------------------------*/
259
260 void
261 call_func_set_edge_flag( Tint st )
262 {
263   CMN_KEY  key;
264
265   key.data.ldata = st;
266   TsmAddToStructure( TelEdgeFlag, 1, &key );
267
268   return;
269 }
270
271 /*----------------------------------------------------------------------*/
272
273 void
274 call_func_set_edgewidth( Tfloat  ew )
275 {
276   CMN_KEY  key;
277
278   key.data.fdata = ew;
279   TsmAddToStructure( TelEdgeWidth, 1, &key );
280   return;
281 }
282
283 /*----------------------------------------------------------------------*/
284
285 void
286 call_func_set_int_style_ind( Tint  ind )
287 {
288   CMN_KEY  key;
289
290   key.data.ldata = ind;
291   TsmAddToStructure( TelInteriorStyleIndex, 1, &key );
292   return;
293 }
294
295 /*----------------------------------------------------------------------*/
296
297 void
298 call_func_set_face_disting_mode( Tint  mode )
299 {
300   CMN_KEY  key;
301
302   key.data.ldata = mode;
303   TsmAddToStructure( TelFaceDistinguishingMode, 1, &key );
304   return;
305 }
306
307 /*----------------------------------------------------------------------*/
308
309 void
310 call_func_set_face_cull_mode( Tint  mode )
311 {
312   CMN_KEY  key;
313
314   key.data.ldata = mode;
315   TsmAddToStructure( TelFaceCullingMode, 1, &key );
316   return;
317 }
318
319 /*----------------------------------------------------------------------*/
320
321 void
322 call_func_set_marker_type( Tint type )
323 {
324   CMN_KEY  key;
325
326   key.data.ldata = type;
327   TsmAddToStructure( TelPolymarkerType, 1, &key );
328
329   return;
330 }
331
332 /*----------------------------------------------------------------------*/
333
334 void
335 call_func_set_marker_size( Tfloat size )
336 {
337   CMN_KEY  key;
338
339   key.data.fdata = size;
340   TsmAddToStructure( TelPolymarkerSize, 1, &key );
341
342   return;
343 }
344
345 /*----------------------------------------------------------------------*/
346
347 void
348 call_func_exec_struct(Tint stid)
349 {
350   CMN_KEY  key;
351
352   key.data.ldata = stid;
353   TsmAddToStructure( TelExecuteStructure, 1, &key );
354   return;
355 }
356
357 /*----------------------------------------------------------------------*/
358
359 void
360 call_func_init_tgl()
361 {
362   TelHookOnAllClasses();
363   return;
364 }
365
366 /*----------------------------------------------------------------------*/
367
368 void                            /* Ignoring priority */
369 call_func_post_struct( Tint ws, Tint stid, Tfloat priority )
370 {
371   CMN_KEY_DATA k;
372
373   k.ldata = stid;
374   TsmSetWSAttri( ws, WSViewStid, &k );
375   return;
376 }
377
378 /*----------------------------------------------------------------------*/
379
380 void
381 call_func_set_int_shad_meth(Tint mtd)
382 {
383   CMN_KEY  key;
384
385   key.data.ldata = mtd;
386   TsmAddToStructure( TelInteriorShadingMethod, 1, &key );
387   return;
388 }
389
390 /*----------------------------------------------------------------------*/
391
392 void
393 call_func_set_refl_eqn( Tint  eqn )
394 {
395   CMN_KEY  key;
396
397   key.data.ldata = eqn;
398   TsmAddToStructure( TelInteriorReflectanceEquation, 1, &key );
399   return;
400 }
401
402 /*----------------------------------------------------------------------*/
403
404 void
405 call_func_set_back_refl_eqn( Tint  eqn )
406 {
407   CMN_KEY  key;
408
409   key.data.ldata = eqn;
410   TsmAddToStructure( TelBackInteriorReflectanceEquation, 1, &key );
411   return;
412 }
413
414 /*----------------------------------------------------------------------*/
415
416 void
417 call_func_set_text_font( Tchar *font )
418 {
419   CMN_KEY  key;
420
421
422   key.data.pdata = font;
423   TsmAddToStructure( TelTextFont, 1, &key );
424   return;
425 }
426
427 /*----------------------------------------------------------------------*/
428
429 void
430 call_func_set_char_space( Tfloat sp )
431 {
432   CMN_KEY  key;
433
434   key.data.fdata = sp;
435   TsmAddToStructure( TelCharacterSpacing, 1, &key );
436   return;
437 }
438
439 /*----------------------------------------------------------------------*/
440
441 void
442 call_func_set_char_expan( Tfloat exp )
443 {
444   CMN_KEY  key;
445
446   key.data.fdata = exp;
447   TsmAddToStructure( TelCharacterExpansionFactor, 1, &key );
448   return;
449 }
450
451 /*----------------------------------------------------------------------*/
452
453
454
455 void
456 call_func_set_text_zoomable( Tint flag )
457 {
458   CMN_KEY  key;
459
460   key.data.ldata = flag;
461   TsmAddToStructure( TelTextZoomable, 1, &key );
462   return;
463 }
464
465 /*----------------------------------------------------------------------*/
466
467
468 void
469 call_func_set_text_angle( Tfloat angl )
470 {
471   CMN_KEY  key;
472
473   key.data.ldata = angl;
474   TsmAddToStructure( TelTextAngle, 1, &key );
475   return;
476 }
477
478 /*----------------------------------------------------------------------*/
479
480
481 void
482 call_func_set_text_fontaspect( OSD_FontAspect fontaspect )
483 {
484   CMN_KEY  key;
485
486   key.data.ldata = fontaspect;
487   TsmAddToStructure( TelTextFontAspect, 1, &key );
488   return;
489 }
490
491
492
493 /*----------------------------------------------------------------------*/
494
495 /* OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets */
496 void call_func_set_polygon_offset_params( Tint mode, Tfloat factor, Tfloat units )
497 {
498   CMN_KEY  key;
499   TEL_POFFSET_PARAM  param;
500
501   param.mode   = mode;
502   param.factor = factor;
503   param.units  = units;
504
505   key.data.pdata = &param;
506   TsmAddToStructure( TelPolygonOffset, 1, &key );
507 }
508 /* OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets */
509
510 /*----------------------------------------------------------------------*/
511
512 void
513 call_func_set_pick_id(Tint pid)
514 {
515   CMN_KEY  key;
516
517   key.data.ldata = pid;
518   TsmAddToStructure( TelPickId, 1, &key );
519   return;
520 }
521 /*----------------------------------------------------------------------*/
522
523 static void redraw_all_structs( Tint wsid, Tint vstid )
524 {
525   CMN_KEY_DATA   k;
526   GLint blend_dst, blend_src;
527   GLboolean blend_state;    
528   GLint zbuff_f;
529   GLboolean zbuff_state, zbuff_w;
530
531   /* Est-il necessaire de faire de la transparence ? */
532   TsmGetWSAttri( wsid, WSTransparency, &k );
533   TelSetTransparency( k.ldata );
534
535   /* ajout PCT pour gestion des textures */
536   TsmGetWSAttri(wsid, WSSurfaceDetail, &k);
537   switch (k.ldata)
538   {
539     /* TOD_NONE */
540   case 0:
541     ForbidSetTextureMapping = 1;
542     SecondPassNeeded = 0;
543     SecondPassDo = 0;
544     DisableTexture();
545     TsmDisplayStructure( vstid, wsid );
546     break;
547
548     /* TOD_ENVIRONMENT */
549   case 1:
550     ForbidSetTextureMapping = 1;
551     SecondPassNeeded = 0;
552     SecondPassDo = 0;
553     TsmGetWSAttri(wsid, WSTextureEnv, &k);
554     SetCurrentTexture(k.ldata);
555     EnableTexture();
556     TsmDisplayStructure( vstid, wsid );
557     DisableTexture();
558     break;
559
560     /* TOD_ALL */
561   case 2:
562     /* premiere passe */
563     ForbidSetTextureMapping = 0;
564     SecondPassNeeded = 0;
565     SecondPassDo = 0;
566     TsmDisplayStructure( vstid, wsid );
567     DisableTexture();
568
569     /* deuxieme passe */
570     if (SecondPassNeeded)
571     {
572       SecondPassDo = 1;
573       TsmGetWSAttri(wsid, WSTextureEnv, &k);
574       SetCurrentTexture(k.ldata);
575       EnableTexture();
576
577       /* sauvegarde de quelques parametres OpenGL */
578       glGetBooleanv(GL_DEPTH_WRITEMASK, &zbuff_w);
579       glGetIntegerv(GL_DEPTH_FUNC, &zbuff_f);
580       glGetIntegerv(GL_BLEND_DST, &blend_dst); 
581       glGetIntegerv(GL_BLEND_SRC, &blend_src);    
582       zbuff_state = glIsEnabled(GL_DEPTH_TEST);
583       blend_state = glIsEnabled(GL_BLEND);
584
585
586       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
587       glEnable(GL_BLEND);
588
589       glDepthFunc(GL_EQUAL);
590       glDepthMask(GL_FALSE);
591       glEnable(GL_DEPTH_TEST);
592
593       ForbidSetTextureMapping = 1;
594       TsmDisplayStructure(vstid, wsid );
595       DisableTexture();
596
597       /* restauration des parametres OpenGL */
598       glBlendFunc(blend_src, blend_dst);
599       if (!blend_state) glDisable(GL_BLEND);
600
601       glDepthFunc(zbuff_f);
602       glDepthMask(zbuff_w);
603       if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
604     }
605     break;
606   }  
607 }
608
609 /*----------------------------------------------------------------------*/
610
611 void
612 call_func_redraw_all_structs( Tint wsid, Tint swap )
613 {
614   call_func_redraw_all_structs_begin (wsid);
615   call_func_redraw_all_structs_proc (wsid);
616   call_func_redraw_all_structs_end (wsid, swap);
617   return;
618 }
619
620 /*----------------------------------------------------------------------*/
621
622 void
623 call_func_set_anno_char_ht( Tfloat h )
624 {
625   CMN_KEY  key;
626
627   key.data.fdata = h;
628   TsmAddToStructure( TelTextHeight, 1, &key );
629   return;
630 }
631
632 /*----------------------------------------------------------------------*/
633
634 void /* unimplemented */
635 call_func_set_anno_char_up_vec( Tfloat path[2] )
636 {
637   return;
638 }
639
640 /*----------------------------------------------------------------------*/
641
642 void /* unimplemented */
643 call_func_set_anno_path( Tint path )
644 {
645   return;
646 }
647
648 /*----------------------------------------------------------------------*/
649
650
651 void /* unimplemented */
652 call_func_set_anno_align( Tint hor, Tint ver )
653 {
654   /*OCC7456 abd 14.12.2004 Text alingnment attributes  */
655   CMN_KEY  k;
656   TEL_ALIGN_DATA data;
657   data.Hmode = hor;
658   data.Vmode = ver;
659   k.data.pdata = &data;
660
661   TsmAddToStructure( TelTextAlign, 1, &k );
662   /*OCC7456 abd 14.12.2004 Text alingnment attributes  */
663
664   return;
665 }
666
667 /*----------------------------------------------------------------------*/
668
669 void
670 call_func_anno_text_rel3( tel_point pt, Techar *str )
671 {
672   CMN_KEY  k[2];
673
674   k[0].id = TEXT_ATTACH_PT_ID;
675   k[0].data.pdata = pt;
676   k[1].id = TEXT_STRING_ID;
677   k[1].data.pdata = str;
678   TsmAddToStructure( TelText, 2, &k[0], &k[1] );
679
680   return;
681 }
682
683 /*----------------------------------------------------------------------*/
684
685 void
686 call_func_dcue_ind(Tint dcid)
687 {
688   CMN_KEY  key;
689
690   key.data.ldata = dcid;
691   TsmAddToStructure( TelDepthCueIndex, 1, &key );
692   return;
693 }
694
695 /*----------------------------------------------------------------------*/
696
697 void
698 call_func_set_texture_id(Tint dcid)
699 {
700   CMN_KEY  key;
701
702   key.data.ldata = dcid;
703   TsmAddToStructure( TelTextureId, 1, &key );
704   return;
705 }
706
707 /*----------------------------------------------------------------------*/
708
709 void
710 call_func_set_do_texturemap(Tint dcid)
711 {
712   CMN_KEY  key;
713
714   key.data.ldata = dcid;
715   TsmAddToStructure( TelDoTextureMap, 1, &key );
716   return;
717 }
718
719 /*----------------------------------------------------------------------*/
720
721 #define EPSI 0.0001
722
723 #ifdef DEBUG
724 static void
725 pr_matrix( matrix3 mat )
726 {
727   printf( "%1.12f %1.12f %1.12f %1.12f\n", mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
728   printf( "%1.12f %1.12f %1.12f %1.12f\n", mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
729   printf( "%1.12f %1.12f %1.12f %1.12f\n", mat[2][0], mat[2][1], mat[2][2], mat[2][3] );
730   printf( "%1.12f %1.12f %1.12f %1.12f\n", mat[3][0], mat[3][1], mat[3][2], mat[3][3] );
731   printf( "\n" );
732   return;
733 }
734 #endif
735
736 /*
737 *  Evaluates orientation matrix.
738 */
739 /* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
740 void call_func_eval_ori_matrix3 (
741                                  point3  *vrp,               /* view reference point */
742                                  vec3    *vpn,               /* view plane normal    */
743                                  vec3    *vup,               /* view up vector       */
744                                  int     *err_ind, 
745                                  float   mout[4][4]) /* OUT view orientation matrix  */
746 {
747
748   /* Translate to VRP then change the basis.
749   * The old basis is: e1 = < 1, 0, 0>, e2 = < 0, 1, 0>, e3 = < 0, 0, 1>.
750   * The new basis is: ("x" means cross product)
751   *  e3' = VPN / |VPN|
752   *  e1' = VUP x VPN / |VUP x VPN|
753   *  e2' = e3' x e1'
754   * Therefore the transform from old to new is x' = TAx, where:
755   *
756   *       | e1'x e2'x e3'x 0 |         |   1      0      0      0 |
757   *   A = | e1'y e2'y e3'y 0 |,    T = |   0      1      0      0 |
758   *       | e1'z e2'z e3'z 0 |         |   0      0      1      0 |
759   *       |  0    0    0   1 |         | -vrp.x -vrp.y -vrp.z   1 |
760   *
761   */
762
763   /*
764   * These ei's are really ei primes.
765   */
766   register float      (*m)[4][4];
767   point3      e1, e2, e3, e4;
768   double      s, v;
769
770   /*
771   * e1' = VUP x VPN / |VUP x VPN|, but do the division later.
772   */
773   e1.x = vup->delta_y * vpn->delta_z - vup->delta_z * vpn->delta_y;
774   e1.y = vup->delta_z * vpn->delta_x - vup->delta_x * vpn->delta_z;
775   e1.z = vup->delta_x * vpn->delta_y - vup->delta_y * vpn->delta_x;
776   s = sqrt( e1.x * e1.x + e1.y * e1.y + e1.z * e1.z);
777   e3.x = vpn->delta_x;
778   e3.y = vpn->delta_y;
779   e3.z = vpn->delta_z;
780   v = sqrt( e3.x * e3.x + e3.y * e3.y + e3.z * e3.z);
781   /*
782   * Check for vup and vpn colinear (zero dot product).
783   */
784   if ((s > -EPSI) && (s < EPSI))
785     *err_ind = 2;
786   else
787     /*
788     * Check for a normal vector not null.
789     */
790     if ((v > -EPSI) && (v < EPSI))
791       *err_ind = 3;
792     else {
793       /*
794       * Normalize e1
795       */
796       e1.x /= ( float )s;
797       e1.y /= ( float )s;
798       e1.z /= ( float )s;
799       /*
800       * e3 = VPN / |VPN|
801       */
802       e3.x /= ( float )v;
803       e3.y /= ( float )v;
804       e3.z /= ( float )v;
805       /*
806       * e2 = e3 x e1
807       */
808       e2.x = e3.y * e1.z - e3.z * e1.y;
809       e2.y = e3.z * e1.x - e3.x * e1.z;
810       e2.z = e3.x * e1.y - e3.y * e1.x;
811       /*
812       * Add the translation
813       */
814       e4.x = -( e1.x * vrp->x + e1.y * vrp->y + e1.z * vrp->z);
815       e4.y = -( e2.x * vrp->x + e2.y * vrp->y + e2.z * vrp->z);
816       e4.z = -( e3.x * vrp->x + e3.y * vrp->y + e3.z * vrp->z);
817       /*
818       * Homogeneous entries
819       *
820       *  | e1.x  e2.x  e3.x  0.0 |   | 1  0  0  0 |
821       *  | e1.y  e2.y  e3.y  0.0 | * | 0  1  0  0 |
822       *  | e1.z  e2.z  e3.z  0.0 |   | a  b  1  c |
823       *  | e4.x  e4.y  e4.z  1.0 |   | 0  0  0  1 |
824       */
825
826       m = (float (*)[4][4])mout;
827
828       (*m)[0][0] = e1.x;
829       (*m)[0][1] = e2.x;
830       (*m)[0][2] = e3.x;
831       (*m)[0][3] = ( float )0.0;
832
833       (*m)[1][0] = e1.y;
834       (*m)[1][1] = e2.y;
835       (*m)[1][2] = e3.y;
836       (*m)[1][3] = ( float )0.0;
837
838       (*m)[2][0] = e1.z;
839       (*m)[2][1] = e2.z;
840       (*m)[2][2] = e3.z;
841       (*m)[2][3] = ( float )0.0;
842
843       (*m)[3][0] = e4.x;
844       (*m)[3][1] = e4.y;
845       (*m)[3][2] = e4.z;
846       (*m)[3][3] = ( float )1.0;
847
848       *err_ind = 0;
849
850 #ifdef DEBUG
851       printf( "\n->call_func_eval_ori_matrix3 \n" );
852       printf( "orientation_matrix :\n" );
853       pr_matrix(mout);
854 #endif
855     }
856 }
857
858 /*----------------------------------------------------------------------*/
859 /*
860 *  Evaluates mapping matrix.
861 */
862 /* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
863 void call_func_eval_map_matrix3(
864                                 view_map3 *Map, 
865                                 int *err_ind, 
866                                 matrix3 mat)
867 {
868   int i, j;
869   matrix3 Tpar, Spar;
870   matrix3 Tper, Sper;
871   matrix3 Shear;
872   matrix3 Scale;
873   matrix3 Tprp;
874   matrix3 aux_mat1, aux_mat2, aux_mat3;
875   point3 Prp;
876
877   *err_ind = 0;
878   for (i=0; i<4; i++)
879     for (j=0; j<4; j++)
880       Spar[i][j] = Sper[i][j] = aux_mat1[i][j] = aux_mat2[i][j] =
881       aux_mat3[i][j] = Tper[i][j] = Tpar[i][j] = Tprp[i][j] =
882       Shear[i][j] = Scale[i][j] = ( float )(i == j);
883
884   Prp.x = Map->proj_ref_point.x;
885   Prp.y = Map->proj_ref_point.y;
886   Prp.z = Map->proj_ref_point.z;
887
888   /*
889   * Type Parallele
890   */    
891   if (Map->proj_type == TYPE_PARAL)
892   {
893     float umid, vmid;
894     point3 temp;
895
896 #ifdef FMN
897     float    cx, cy, gx, gy, xsf, ysf, zsf;
898     float    fpd, bpd;
899     float    dopx, dopy, dopz;
900     matrix3  tmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
901     { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
902     { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
903     { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
904     matrix3  smat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
905     { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
906     { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
907     { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
908     matrix3 shmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
909     { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
910     { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
911     { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
912     matrix3 tshmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
913     { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
914     { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
915     { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
916
917     /* centers */
918     cx = Map->win.x_min + Map->win.x_max, cx /= ( float )2.0;
919     cy = Map->win.y_min + Map->win.y_max, cy /= ( float )2.0;
920
921     gx = 2.0/ (Map->win.x_max - Map->win.x_min);
922     gy = 2.0/ (Map->win.y_max - Map->win.y_min);
923
924     tmat[0][3] = -cx;
925     tmat[1][3] = -cy;
926     tmat[2][3] = (Map->front_plane + Map->back_plane)/(Map->front_plane - Map->back_plane);
927
928     smat[0][0] = gx;
929     smat[1][1] = gy;
930     smat[2][2] = -2./(Map->front_plane - Map->back_plane);
931
932     /* scale factors */
933     dopx = cx - Prp.x;
934     dopy = cy - Prp.y;
935     dopz = - Prp.z;
936
937     /* map matrix */
938     shmat[0][2] = -(dopx/dopz);
939     shmat[1][2] = -(dopy/dopz);
940
941     /* multiply to obtain mapping matrix */
942     call_util_mat_mul( tmat, shmat, tshmat );
943     call_util_mat_mul( smat, tshmat, mat );
944
945 #ifdef DEBUG
946     printf( "\n->call_func_eval_map_matrix3 FMN\n" );
947     printf("prp %f %f %f \n", Prp.x, Prp.y, Prp.z);
948     printf("vpd fpd bpd %f %f %f \n", Map->view_plane, Map->front_plane, Map->back_plane);
949     printf("window limits %f %f %f %f\n", Map->win.x_min, Map->win.x_max, 
950       Map->win.y_min, Map->win.y_max);
951     printf( "mapping_matrix :\n" );
952     pr_matrix(mat);
953 #endif
954     return;         
955 #endif
956
957     /* CAL */
958     Map->proj_vp.z_min = ( float )0.0;
959     Map->proj_vp.z_max = ( float )1.0;
960     /* CAL */
961
962     /* Shear matrix calculation */
963     umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0;
964     vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0;
965     if(Prp.z == Map->view_plane){
966       /* Projection reference point is on the view plane */
967       *err_ind = 1;
968       return;
969     }
970     Shear[2][0] = ( float )(-1.0) * ((Prp.x-umid)/(Prp.z-Map->view_plane));
971     Shear[2][1] = ( float )(-1.0) * ((Prp.y-vmid)/(Prp.z-Map->view_plane));
972
973     /*
974     * Calculate the lower left coordinate of the view plane
975     * after the Shearing Transformation.
976     */
977     call_util_apply_trans2(Map->win.x_min, Map->win.y_min,
978       Map->view_plane, Shear, &(temp.x), &(temp.y), &(temp.z));
979
980     /* Translate the back plane to the origin */
981     Tpar[3][0] = ( float )(-1.0) * temp.x;
982     Tpar[3][1] = ( float )(-1.0) * temp.y;
983     Tpar[3][2] = ( float )(-1.0) * Map->back_plane;
984
985     call_util_mat_mul(Shear, Tpar, aux_mat1);
986
987     /* Calculation of Scaling transformation */
988     Spar[0][0] = ( float )1.0 / (Map->win.x_max - Map->win.x_min);
989     Spar[1][1] = ( float )1.0 / (Map->win.y_max - Map->win.y_min);
990     Spar[2][2] = ( float )1.0 / (Map->front_plane - Map->back_plane );
991     call_util_mat_mul (aux_mat1, Spar, aux_mat2);
992     /* Atlast we transformed view volume to NPC */
993
994     /* Translate and scale the view plane to projection view port */
995     if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
996       Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
997       Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
998       Map->proj_vp.x_min > Map->proj_vp.x_max ||
999       Map->proj_vp.y_min > Map->proj_vp.y_max ||
1000       Map->proj_vp.z_min > Map->proj_vp.z_max){
1001         *err_ind = 1;
1002         return;
1003       }
1004       for(i=0; i<4; i++)
1005         for(j=0; j<4; j++)
1006           aux_mat1[i][j] = (float)(i==j);
1007       aux_mat1[0][0] = Map->proj_vp.x_max-Map->proj_vp.x_min;
1008       aux_mat1[1][1] = Map->proj_vp.y_max-Map->proj_vp.y_min;
1009       aux_mat1[2][2] = Map->proj_vp.z_max-Map->proj_vp.z_min;
1010       aux_mat1[3][0] = Map->proj_vp.x_min;
1011       aux_mat1[3][1] = Map->proj_vp.y_min;
1012       aux_mat1[3][2] = Map->proj_vp.z_min;
1013       call_util_mat_mul (aux_mat2, aux_mat1, mat);
1014
1015 #ifdef DEBUG
1016       printf( "\n->call_func_eval_map_matrix3 - ORTHOGRAPHIC projection\n" );
1017       printf("prp %f %f %f \n", Prp.x, Prp.y, Prp.z);
1018       printf("vpd fpd bpd %f %f %f \n", Map->view_plane, Map->front_plane, Map->back_plane);
1019       printf("window limits %f %f %f %f\n", Map->win.x_min, Map->win.x_max, 
1020         Map->win.y_min, Map->win.y_max);
1021       printf( "mapping_matrix :\n" );
1022       pr_matrix(mat);
1023 #endif
1024
1025       return;         
1026   } 
1027
1028   /*
1029   * Type Perspective
1030   */    
1031   else if (Map->proj_type == TYPE_PERSPECT)
1032   {
1033     float umid, vmid;
1034     float B, F, V;
1035     float Zvmin;
1036
1037     /* CAL */
1038     Map->proj_vp.z_min = ( float )0.0;
1039     Map->proj_vp.z_max = ( float )1.0;
1040     /* CAL */
1041
1042     B = Map->back_plane;
1043     F = Map->front_plane;
1044     V = Map->view_plane;
1045
1046     if(Prp.z == Map->view_plane){
1047       /* Centre of Projection is on the view plane */
1048       *err_ind = 1;
1049       return;
1050     }
1051     if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
1052       Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
1053       Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
1054       Map->proj_vp.x_min > Map->proj_vp.x_max ||
1055       Map->proj_vp.y_min > Map->proj_vp.y_max ||
1056       Map->proj_vp.z_min > Map->proj_vp.z_max ||
1057       F < B){
1058         *err_ind = 1;
1059         return;
1060       }
1061
1062       /* This is the transformation to move VRC to Center Of Projection */
1063       Tprp[3][0] = ( float )(-1.0)*Prp.x;
1064       Tprp[3][1] = ( float )(-1.0)*Prp.y;
1065       Tprp[3][2] = ( float )(-1.0)*Prp.z;
1066
1067       /* Calculation of Shear matrix */
1068       umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0-Prp.x;
1069       vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0-Prp.y;
1070       Shear[2][0] = ( float )(-1.0)*umid/(Map->view_plane-Prp.z);
1071       Shear[2][1] = ( float )(-1.0)*vmid/(Map->view_plane-Prp.z);
1072       call_util_mat_mul(Tprp, Shear, aux_mat3);
1073
1074       /* Scale the view volume to canonical view volume
1075       * Centre of projection at origin.
1076       * 0 <= N <= -1, -0.5 <= U <= 0.5, -0.5 <= V <= 0.5
1077       */
1078       Scale[0][0] =  (( float )(-1.0)*Prp.z+V)/
1079         ((Map->win.x_max-Map->win.x_min)*(( float )(-1.0)*Prp.z+B));
1080       Scale[1][1] =  (( float )(-1.0)*Prp.z+V)/
1081         ((Map->win.y_max-Map->win.y_min)*(( float )(-1.0)*Prp.z+B));
1082       Scale[2][2] =  ( float )(-1.0) / (( float )(-1.0)*Prp.z+B);
1083
1084       call_util_mat_mul(aux_mat3, Scale, aux_mat1);
1085
1086       /*
1087       * Transform the Perspective view volume into
1088       * Parallel view volume.
1089       * Lower left coordinate: (-0.5,-0.5, -1)
1090       * Upper right coordinate: (0.5, 0.5, 1.0)
1091       */
1092       Zvmin = ( float )(-1.0*(-1.0*Prp.z+F)/(-1.0*Prp.z+B));
1093       aux_mat2[2][2] = ( float )1.0/(( float )1.0+Zvmin);
1094       aux_mat2[2][3] = ( float )(-1.0);
1095       aux_mat2[3][2] = ( float )(-1.0)*Zvmin*aux_mat2[2][2];
1096       aux_mat2[3][3] = ( float )0.0;
1097       call_util_mat_mul(aux_mat1, aux_mat2, Shear);
1098
1099       for(i=0; i<4; i++)
1100         for(j=0; j<4; j++)
1101           aux_mat1[i][j] = aux_mat2[i][j] = (float)(i==j);
1102
1103       /* Translate and scale the view plane to projection view port */
1104       aux_mat2[0][0] = (Map->proj_vp.x_max-Map->proj_vp.x_min);
1105       aux_mat2[1][1] = (Map->proj_vp.y_max-Map->proj_vp.y_min);
1106       aux_mat2[2][2] = (Map->proj_vp.z_max-Map->proj_vp.z_min);
1107       aux_mat2[3][0] = aux_mat2[0][0]/( float )2.0+Map->proj_vp.x_min;
1108       aux_mat2[3][1] = aux_mat2[1][1]/( float )2.0+Map->proj_vp.y_min;
1109       aux_mat2[3][2] = aux_mat2[2][2]+Map->proj_vp.z_min;
1110       call_util_mat_mul (Shear, aux_mat2, mat);
1111
1112 #ifdef DEBUG
1113       printf( "\n->call_func_eval_map_matrix3 - PERSPECTIVE projection\n" );
1114       printf("prp %f %f %f \n", Prp.x, Prp.y, Prp.z);
1115       printf("vpd fpd bpd %f %f %f \n", Map->view_plane, Map->front_plane, Map->back_plane);
1116       printf("window limits %f %f %f %f\n", Map->win.x_min, Map->win.x_max, 
1117         Map->win.y_min, Map->win.y_max);
1118       printf("viewport limits %f %f %f %f %f %f\n", Map->proj_vp.x_min, Map->proj_vp.x_max, 
1119         Map->proj_vp.y_min, Map->proj_vp.y_max,
1120         Map->proj_vp.z_min, Map->proj_vp.z_max);
1121       printf( "mapping_matrix :\n" );
1122       pr_matrix(mat);
1123 #endif
1124
1125       return;
1126   }
1127   else
1128     *err_ind = 1;
1129 }
1130
1131 /*----------------------------------------------------------------------*/
1132
1133 static void
1134 call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
1135                        float *ox, float *oy, float *oz )
1136 {
1137   float temp;
1138   *ox = ix*mat[0][0]+iy*mat[1][0]+iz*mat[2][0]+mat[3][0];
1139   *oy = ix*mat[0][1]+iy*mat[1][1]+iz*mat[2][1]+mat[3][1];
1140   *oz = ix*mat[0][2]+iy*mat[1][2]+iz*mat[2][2]+mat[3][2];
1141   temp = ix * mat[0][3]+iy * mat[1][3]+iz * mat[2][3]+mat[3][3];
1142   *ox /= temp;
1143   *oy /= temp;
1144   *oz /= temp;
1145 }
1146
1147 /*----------------------------------------------------------------------*/
1148
1149 static void
1150 call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
1151 {
1152   int i, j, k;
1153
1154   for (i=0; i<4; i++)
1155     for (j=0; j<4; j++)
1156       for (mat_c[i][j] = ( float )0.0,k=0; k<4; k++)
1157         mat_c[i][j] += mat_a[i][k] * mat_b[k][j];
1158 }
1159
1160 /*----------------------------------------------------------------------*/
1161
1162 void
1163 call_func_redraw_all_structs_begin( Tint wsid )
1164 {
1165
1166   static Tmatrix3 identity = {
1167     {( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0},
1168     {( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0},
1169     {( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0},
1170     {( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0}
1171   };
1172
1173   /*
1174   * Gestion de la pile des transformations pour les structures
1175   * connectees dans la vue <wsid>
1176   */
1177   if (trsf_stack == NULL) {
1178     trsf_stack = (tsm_trsf_stack) malloc (sizeof (TSM_TRSF_STACK));
1179     trsf_stack->next = NULL;
1180     trsf_stack->prev = NULL;
1181     matcpy (trsf_stack->LocalTran3, identity);
1182     cur_trsf_stack = trsf_stack;
1183   }
1184
1185   TelClearViews(wsid);
1186
1187   /* Par defaut on desactive les lumieres */
1188   LightOff();
1189
1190   return;
1191 }
1192
1193 /*----------------------------------------------------------------------*/
1194
1195 void
1196 call_func_redraw_all_structs_proc( Tint wsid )
1197 {
1198
1199   CMN_KEY        kk;
1200   CMN_KEY_DATA   k;
1201 #ifdef G003
1202   CMN_KEY_DATA   kbf;
1203 #endif  /* G003 */
1204   Tint           vstid;
1205
1206   TsmGetWSAttri( wsid, WSViewStid, &k );
1207 #ifdef G003
1208   TsmGetWSAttri ( wsid, WSBackfacing, &kbf );
1209   g_nBackfacing = kbf.ldata;
1210
1211   if ( g_nBackfacing > 0 )
1212
1213     glDisable ( GL_CULL_FACE );
1214
1215   else if ( g_nBackfacing < 0 ) {
1216
1217     glEnable   ( GL_CULL_FACE );
1218     glCullFace ( GL_BACK      );
1219
1220   }  /* end if */
1221 #endif  /* G003 */
1222   vstid = k.ldata;
1223   if( vstid != -1 )
1224   {
1225
1226 #ifdef PRINT
1227     printf("OpenGl_funcs::call_func_redraw_all_structs:TsmPushAttri \n");
1228 #endif
1229     TsmPushAttri(); /* save previous graphics context */
1230
1231     TglActiveWs = wsid; /* Indispensable precedemment dans TsmDisplayStructure */
1232     /* Avec le mode Ajout cette init n'etait plus faite */
1233
1234     /* mise en place des matrices de projection et de mapping */
1235     kk.id = TelViewIndex;
1236     kk.data.ldata = vstid;
1237     TsmSetAttri( 1, &kk );
1238     TelSetViewIndex (wsid, vstid);
1239 #ifdef G003
1240     if ( g_fUpdateAM ) goto forceRedraw;
1241 #endif  /* G003 */
1242     /* Mode animation */
1243     if (animationFlag)
1244     {
1245       if ((listIndexFlag) && (listIndexView == vstid))
1246       {
1247 #ifdef DEBUG_ANIMATION
1248         printf("call_func_redraw_all_structs::glCallList1 \n");
1249 #endif
1250         glCallList(listIndex);
1251       }
1252       else
1253       {
1254 #ifdef G003
1255         if ( !g_fList ) {
1256
1257           g_fList = GL_TRUE;
1258           goto forceRedraw;
1259
1260         }  /* end if */
1261 #endif  /* G003 */
1262
1263 #ifdef DEBUG_ANIMATION
1264         printf("call_func_redraw_all_structs::glNewList \n");
1265 #endif
1266         glNewList(listIndex, GL_COMPILE_AND_EXECUTE);
1267         redraw_all_structs( wsid, vstid );
1268 #ifdef DEBUG_ANIMATION
1269         printf("call_func_redraw_all_structs::glEndList \n");
1270 #endif
1271         glEndList();
1272         listIndexFlag = GL_TRUE;
1273         listIndexView = vstid;
1274       }    
1275     }
1276     /* Mode normal */
1277     else
1278     {
1279       /* Optimisation si displaylist est toujours valable */
1280       if ((listIndexFlag) && (listIndexView == vstid))
1281       {
1282 #ifdef DEBUG_ANIMATION
1283         printf("call_func_redraw_all_structs::glCallList2 \n");
1284 #endif
1285         glCallList(listIndex);
1286       }
1287       else
1288       {
1289 #ifdef DEBUG_ANIMATION
1290         printf("call_func_redraw_all_structs::redraw_all_structs \n");
1291 #endif
1292
1293 #ifdef G003
1294 forceRedraw:
1295 #endif  /* G003 */
1296         redraw_all_structs( wsid, vstid );
1297       }    
1298     } /* Mode Animation */
1299
1300 #ifdef PRINT
1301     printf("OpenGl_funcs::call_func_redraw_all_structs:TsmPopAttri \n");
1302 #endif
1303     /* restore previous graphics context; before update lights */
1304     TsmPopAttri();
1305
1306
1307
1308     /* affichage de Triedre Non Zoomable de la vue s'il existe */
1309 #ifdef PRINT
1310     printf("call_func_redraw_all_structS => CALL_TRIEDRON... \n");
1311 #endif
1312     call_triedron_redraw_from_wsid (wsid);
1313     call_graduatedtrihedron_redraw(wsid);
1314
1315
1316   } /* Test vue valide */
1317
1318   return;
1319 }
1320
1321 /*----------------------------------------------------------------------*/
1322
1323 void
1324 call_func_redraw_all_structs_end( Tint wsid, Tint swap )
1325 {
1326
1327   /*    CMN_KEY      kk;*/
1328   CMN_KEY_DATA   k;
1329   Tint           vstid;
1330
1331   TsmGetWSAttri( wsid, WSViewStid, &k );
1332   vstid = k.ldata;
1333   if( vstid != -1 )
1334   {
1335
1336     /* On swap les buffers */
1337     TsmGetWSAttri( wsid, WSDbuff, &k );
1338     if( (k.ldata == TOn) && (swap) )
1339       TelSwapBuffers( wsid );
1340     else
1341       TelFlush(0);
1342
1343   } /* Test vue valide */
1344
1345   /*
1346   * Mise a jour de l'update_state
1347   */
1348   k.ldata = TDone;
1349   TsmSetWSAttri( wsid, WSUpdateState, &k );
1350
1351   return;
1352 }
1353
1354 #ifdef G003
1355 void call_func_set_degenerate_model ( Tint model, Tfloat skipRatio ) {
1356
1357   CMN_KEY      key;
1358   DEGENERATION deg;
1359
1360   deg.mode      = model;
1361   deg.skipRatio = skipRatio;
1362
1363   key.data.pdata = &deg;
1364   TsmAddToStructure ( TelDegenerationMode, 1, &key );
1365
1366 }  /* end call_func_set_degenerate_model */
1367 #endif  /* G003 */
1368
1369
1370 void
1371 call_func_set_transform_persistence( Tint mode, Tfloat x, Tfloat y, Tfloat z )
1372 {
1373   CMN_KEY  key;
1374   TEL_TRANSFORM_PERSISTENCE  pers;
1375
1376   pers.mode   = mode;
1377
1378   pers.pointX = x;
1379   pers.pointY = y;
1380   pers.pointZ = z;
1381
1382   key.data.pdata = &pers;
1383   TsmAddToStructure( TelTransformPersistence, 1, &key );
1384   return;
1385 }
1386 /* ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate ) */