0022627: Change OCCT memory management defaults
[occt.git] / src / OpenGl / OpenGl_View.cxx
1 // File:      OpenGl_View.cxx
2 // Created:   20 September 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_GlCore11.hxx>
7
8 #include <OpenGl_View.hxx>
9
10 #include <OpenGl_Workspace.hxx>
11 #include <OpenGl_Display.hxx>
12
13 #include <OpenGl_Display.hxx>
14 #include <OpenGl_Trihedron.hxx>
15 #include <OpenGl_GraduatedTrihedron.hxx>
16
17 #include <OpenGl_transform_persistence.hxx>
18
19 #include <GL/glu.h> // gluUnProject()
20
21 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
23
24 /*----------------------------------------------------------------------*/
25
26 static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
27 static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
28 static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
29 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
30 static const OPENGL_EXTRA_REP myDefaultExtra =
31 {
32   //vrp
33   { 0.F, 0.F, 0.F },
34   //vpn
35   { 0.F, 0.F, 1.F },
36   //vup
37   { 0.F, 1.F, 0.F },
38   //map
39   {
40     //window
41     { 0.F, 0.F, 1.F, 1.F },
42     //viewport
43     { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
44     //proj
45     TelParallel,
46     //prp
47     { 0.F, 0.F, 0.F },
48     //vpd
49     0.F,
50     //fpd
51     0.F,
52     //bpd
53     -1.F
54   },
55   //scaleFactors
56   { 1.F, 1.F, 1.F }
57 };
58
59 static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
60 static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
61
62 /*----------------------------------------------------------------------*/
63
64 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
65 : myTextureEnv(0),
66   mySurfaceDetail(Visual3d_TOD_NONE),
67   myBackfacing(0),
68   myBgTexture(myDefaultBgTexture),
69   myBgGradient(myDefaultBgGradient),
70   //myOrientationMatrix(myDefaultMatrix),
71   //myMappingMatrix(myDefaultMatrix),
72   //shield_indicator = TOn,
73   //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
74   //border_indicator = TOff,
75   //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
76   //active_status = TOn,
77   myZClip(myDefaultZClip),
78   myExtra(myDefaultExtra),
79   myFog(myDefaultFog),
80   myVisualization(AContext.Visualization),
81   myIntShadingMethod(TEL_SM_GOURAUD),
82   myAntiAliasing(Standard_False),
83   myAnimationListIndex(0),
84   myAnimationListReady(Standard_False),
85   myTransPers(&myDefaultTransPers),
86   myIsTransPers(Standard_False),
87   myResetFLIST(Standard_False)
88 {
89   // Initialize matrices
90   memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
91   memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
92
93   // Shading method
94   switch (AContext.Model)
95   {
96     case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
97     case 3 : /* VISUAL3D_TOM_VERTEX */
98       myIntShadingMethod = TEL_SM_GOURAUD;
99       break;
100     default :
101       myIntShadingMethod = TEL_SM_FLAT;
102       break;
103   }
104 }
105
106 /*----------------------------------------------------------------------*/
107
108 OpenGl_View::~OpenGl_View ()
109 {
110   if (myAnimationListIndex)
111     glDeleteLists((GLuint)myAnimationListIndex,1);
112
113   if ( myBgTexture.TexId != 0 )
114     glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
115 }
116
117 /*----------------------------------------------------------------------*/
118
119 void OpenGl_View::SetBackfacing (const Standard_Integer AMode)
120 {
121   myBackfacing = AMode;
122   myResetFLIST = Standard_True;
123 }
124
125 /*----------------------------------------------------------------------*/
126
127 //call_togl_setlight
128 void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
129 {
130   myLights.Clear();
131
132   const int nb_lights = AContext.NbActiveLight;
133
134   int i = 0;
135   const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
136   for ( ; i < nb_lights; i++, alight++ )
137   {
138     OpenGl_Light rep;
139
140         switch( alight->LightType )
141     {
142       case 0 : /* TOLS_AMBIENT */
143         rep.type = TLightAmbient;
144         rep.col.rgb[0] = alight->Color.r;
145         rep.col.rgb[1] = alight->Color.g;
146         rep.col.rgb[2] = alight->Color.b;
147         break;
148
149       case 1 : /* TOLS_DIRECTIONAL */
150         rep.type = TLightDirectional;
151         rep.col.rgb[0] = alight->Color.r;
152         rep.col.rgb[1] = alight->Color.g;
153         rep.col.rgb[2] = alight->Color.b;
154         rep.dir[0] = alight->Direction.x;
155         rep.dir[1] = alight->Direction.y;
156         rep.dir[2] = alight->Direction.z;
157         break;
158
159       case 2 : /* TOLS_POSITIONAL */
160         rep.type = TLightPositional;
161         rep.col.rgb[0] = alight->Color.r;
162         rep.col.rgb[1] = alight->Color.g;
163         rep.col.rgb[2] = alight->Color.b;
164         rep.pos[0] = alight->Position.x;
165         rep.pos[1] = alight->Position.y;
166         rep.pos[2] = alight->Position.z;
167         rep.atten[0] = alight->Attenuation[0];
168         rep.atten[1] = alight->Attenuation[1];
169         break;
170
171       case 3 : /* TOLS_SPOT */
172         rep.type = TLightSpot;
173         rep.col.rgb[0] = alight->Color.r;
174         rep.col.rgb[1] = alight->Color.g;
175         rep.col.rgb[2] = alight->Color.b;
176         rep.pos[0] = alight->Position.x;
177         rep.pos[1] = alight->Position.y;
178         rep.pos[2] = alight->Position.z;
179         rep.dir[0] = alight->Direction.x;
180         rep.dir[1] = alight->Direction.y;
181         rep.dir[2] = alight->Direction.z;
182         rep.shine = alight->Concentration;
183         rep.atten[0] = alight->Attenuation[0];
184         rep.atten[1] = alight->Attenuation[1];
185         rep.angle = alight->Angle;
186         break;
187     }
188
189     rep.HeadLight = alight->Headlight;
190
191     myLights.Append(rep);
192   }
193 }
194
195 /*----------------------------------------------------------------------*/
196
197 //call_togl_setplane
198 void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
199 {
200   // clear clipping planes information
201   myClippingPlanes.Clear();
202   // update information 
203   int i = 0;
204   for (; i < AContext.NbActivePlane; i++)
205   {
206     const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
207     if ( aCPlane.Active && aCPlane.PlaneId > 0 )
208     {
209       OPENGL_CLIP_REP aPlane;
210       aPlane.equation[0] = aCPlane.CoefA;
211       aPlane.equation[1] = aCPlane.CoefB;
212       aPlane.equation[2] = aCPlane.CoefC;
213       aPlane.equation[3] = aCPlane.CoefD;
214       myClippingPlanes.Append( aPlane );
215     }
216   }
217 }
218
219 /*----------------------------------------------------------------------*/
220
221 //call_togl_setvisualisation
222 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
223 {
224   myVisualization = AContext.Visualization;
225   // Shading method
226   switch (AContext.Model)
227   {
228     case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
229     case 3 : /* VISUAL3D_TOM_VERTEX */
230       myIntShadingMethod = TEL_SM_GOURAUD;
231       break;
232     default :
233       myIntShadingMethod = TEL_SM_FLAT;
234       break;
235   }
236 }
237
238 /*----------------------------------------------------------------------*/
239
240 //call_togl_cliplimit
241 void OpenGl_View::SetClipLimit (const CALL_DEF_VIEW &ACView)
242 {
243   myZClip.Back.Limit =
244     ( ACView.Context.ZClipBackPlane - ACView.Mapping.BackPlaneDistance ) /
245     ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
246   myZClip.Front.Limit =
247     ( ACView.Context.ZClipFrontPlane - ACView.Mapping.BackPlaneDistance ) /
248     ( ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance );
249   if ( myZClip.Back.Limit < 0.F )
250     myZClip.Back.Limit = 0.F;
251   if ( myZClip.Front.Limit > 1.F )
252     myZClip.Front.Limit = 1.F;
253   if ( myZClip.Back.Limit > myZClip.Front.Limit )
254   {
255     myZClip.Back.Limit = 0.F;
256     myZClip.Front.Limit = 1.F;
257   }
258
259   myZClip.Back.IsOn = (ACView.Context.BackZClipping != 0);
260   myZClip.Front.IsOn = (ACView.Context.FrontZClipping != 0);
261 }
262
263 /*----------------------------------------------------------------------*/
264
265 //call_togl_viewmapping
266 void OpenGl_View::SetMapping (const CALL_DEF_VIEW &ACView)
267 {
268   const float ratio = ACView.DefWindow.dy / ACView.DefWindow.dx;
269   const float r_ratio = ACView.DefWindow.dx / ACView.DefWindow.dy;
270
271   TEL_VIEW_MAPPING Map;
272
273   Map.window.xmin = ACView.Mapping.WindowLimit.um;
274   Map.window.ymin = ACView.Mapping.WindowLimit.vm;
275   Map.window.xmax = ACView.Mapping.WindowLimit.uM;
276   Map.window.ymax = ACView.Mapping.WindowLimit.vM;
277
278   Map.viewport.xmin = 0.F;
279   Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
280   Map.viewport.ymin = 0.F;
281   Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
282   Map.viewport.zmin = 0.F;
283   Map.viewport.zmax = 1.F;
284
285   /* projection type */
286   switch( ACView.Mapping.Projection )
287   {
288     case 0 :
289       Map.proj = TelPerspective;
290       break;
291     case 1 :
292       Map.proj = TelParallel;
293       break;
294   }
295
296   /* projection reference point */
297   Map.prp[0] = ACView.Mapping.ProjectionReferencePoint.x;
298   Map.prp[1] = ACView.Mapping.ProjectionReferencePoint.y;
299   Map.prp[2] = ACView.Mapping.ProjectionReferencePoint.z;
300   if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
301     Map.prp[2] += ACView.Mapping.FrontPlaneDistance;
302
303   /* view plane distance */
304   Map.vpd = ACView.Mapping.ViewPlaneDistance;
305
306   /* back plane distance */
307   Map.bpd = ACView.Mapping.BackPlaneDistance;
308
309   /* front plane distance */
310   Map.fpd = ACView.Mapping.FrontPlaneDistance;
311
312   Tint err_ind = 0;
313
314   /* use user-defined matrix */
315   if ( ACView.Mapping.IsCustomMatrix )
316   {
317     int i, j;
318     for( i = 0; i < 4; i++ )
319       for( j = 0; j < 4; j++ )
320         myMappingMatrix[i][j] = ACView.Mapping.ProjectionMatrix[i][j];
321   }
322   else 
323     TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
324
325   if ( !err_ind )
326     myExtra.map = Map;
327 }
328
329 /*----------------------------------------------------------------------*/
330
331 //call_togl_vieworientation
332 void OpenGl_View::SetOrientation (const CALL_DEF_VIEW &ACView)
333 {
334   Tfloat Vrp[3];
335   Tfloat Vpn[3];
336   Tfloat Vup[3];
337   Tfloat ScaleFactors[3];
338
339   Vrp[0] = ACView.Orientation.ViewReferencePoint.x;
340   Vrp[1] = ACView.Orientation.ViewReferencePoint.y;
341   Vrp[2] = ACView.Orientation.ViewReferencePoint.z;
342
343   Vpn[0] = ACView.Orientation.ViewReferencePlane.x;
344   Vpn[1] = ACView.Orientation.ViewReferencePlane.y;
345   Vpn[2] = ACView.Orientation.ViewReferencePlane.z;
346
347   Vup[0] = ACView.Orientation.ViewReferenceUp.x;
348   Vup[1] = ACView.Orientation.ViewReferenceUp.y;
349   Vup[2] = ACView.Orientation.ViewReferenceUp.z;
350
351   ScaleFactors[0] = ACView.Orientation.ViewScaleX;
352   ScaleFactors[1] = ACView.Orientation.ViewScaleY;
353   ScaleFactors[2] = ACView.Orientation.ViewScaleZ;
354
355   Tint err_ind = 0;
356
357   // use user-defined matrix
358   if ( ACView.Orientation.IsCustomMatrix )
359   {
360     int i, j;
361     for( i = 0; i < 4; i++ )
362       for( j = 0; j < 4; j++ )
363         myOrientationMatrix[i][j] = ACView.Orientation.ModelViewMatrix[i][j];
364   }
365   else
366     TelEvalViewOrientationMatrix( Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix );
367
368   if ( !err_ind )
369   {
370     myExtra.vrp[0] = Vrp[0];
371     myExtra.vrp[1] = Vrp[1];
372     myExtra.vrp[2] = Vrp[2];
373
374     myExtra.vpn[0] = Vpn[0];
375     myExtra.vpn[1] = Vpn[1];
376     myExtra.vpn[2] = Vpn[2];
377
378     myExtra.vup[0] = Vup[0];
379     myExtra.vup[1] = Vup[1];
380     myExtra.vup[2] = Vup[2];
381
382     myExtra.scaleFactors[0] = ScaleFactors[0],
383     myExtra.scaleFactors[1] = ScaleFactors[1],
384     myExtra.scaleFactors[2] = ScaleFactors[2];
385   }
386 }
387
388 /*----------------------------------------------------------------------*/
389
390 void OpenGl_View::SetFog (const CALL_DEF_VIEW &ACView, const Standard_Boolean AFlag)
391 {
392   if( !AFlag )
393   {
394     myFog.IsOn = Standard_False;
395   }
396   else
397   {
398     myFog.IsOn = Standard_True;
399
400     myFog.Front =
401       (ACView.Context.DepthFrontPlane - ACView.Mapping.BackPlaneDistance) /
402       (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
403
404     myFog.Back =
405       (ACView.Context.DepthBackPlane - ACView.Mapping.BackPlaneDistance) /
406       (ACView.Mapping.FrontPlaneDistance - ACView.Mapping.BackPlaneDistance);
407
408     if (myFog.Front < 0.F)
409       myFog.Front = 0.F;
410     else if (myFog.Front > 1.F)
411       myFog.Front = 1.F;
412
413     if (myFog.Back < 0.F)
414       myFog.Back = 0.F;
415     else if (myFog.Back > 1.F)
416       myFog.Back = 1.F;
417
418     if (myFog.Back > myFog.Front)
419     {
420       myFog.Front = 1.F;
421       myFog.Back = 0.F;
422     }
423
424     myFog.Color.rgb[0] = ACView.DefWindow.Background.r;
425     myFog.Color.rgb[1] = ACView.DefWindow.Background.g;
426     myFog.Color.rgb[2] = ACView.DefWindow.Background.b;
427     myFog.Color.rgb[3] = 1.F;
428   }
429 }
430
431 /*----------------------------------------------------------------------*/
432
433 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
434                                   const Standard_Real AScale, const Standard_Boolean AsWireframe)
435 {
436   myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
437 }
438
439 /*----------------------------------------------------------------------*/
440
441 void OpenGl_View::TriedronErase ()
442 {
443   myTrihedron.Nullify();
444 }
445
446 /*----------------------------------------------------------------------*/
447
448 void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
449 {
450   myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
451 }
452
453 /*----------------------------------------------------------------------*/
454
455 void OpenGl_View::GraduatedTrihedronErase ()
456 {
457   myGraduatedTrihedron.Nullify();
458 }
459
460 /*----------------------------------------------------------------------*/
461
462 //transform_persistence_end
463 void OpenGl_View::EndTransformPersistence ()
464 {
465   if ( myIsTransPers )
466   {
467     /* restore matrix */
468     glMatrixMode (GL_PROJECTION);
469     glPopMatrix ();
470     glMatrixMode (GL_MODELVIEW);
471     glPopMatrix ();
472     myIsTransPers = Standard_False;
473   }
474
475
476 /*----------------------------------------------------------------------*/
477
478 //transform_persistence_begin
479 const TEL_TRANSFORM_PERSISTENCE * OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE *ATransPers)
480 {
481   const TEL_TRANSFORM_PERSISTENCE *TransPers_old = myTransPers;
482
483   if ( ATransPers->mode == 0 )
484   {
485     EndTransformPersistence();
486     return TransPers_old;
487   }
488
489   myTransPers = ATransPers;
490
491   GLint viewport[4];
492   glGetIntegerv (GL_VIEWPORT, viewport);
493   GLdouble modelMatrix[4][4];
494   glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
495   GLdouble projMatrix[4][4];
496   glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
497
498   double W = viewport[2];
499   double H = viewport[3];
500
501   if ( myIsTransPers )
502   {
503     /* restore matrix */
504     glMatrixMode (GL_PROJECTION);
505     glPopMatrix ();
506     glMatrixMode (GL_MODELVIEW);
507     glPopMatrix ();
508   }
509   else
510     myIsTransPers = Standard_True;
511
512   glMatrixMode( GL_MODELVIEW );
513   glPushMatrix();
514   glLoadIdentity();
515
516   glMatrixMode( GL_PROJECTION );
517   glPushMatrix();
518   glLoadIdentity();
519
520   /*pre loading matrix*/
521   if( ATransPers->mode & TPF_PAN )
522     /* Annulate translate matrix */
523   {
524     modelMatrix[3][0] = 0.;
525     modelMatrix[3][1] = 0.;
526     modelMatrix[3][2] = 0.;
527     projMatrix[3][0] = 0.;
528     projMatrix[3][1] = 0.;
529     projMatrix[3][2] = 0.;
530   }
531
532   if( ATransPers->mode & TPF_ZOOM )
533     /* Annulate zoom matrix */
534   {
535     const double scaleX = myExtra.scaleFactors[0];
536     const double scaleY = myExtra.scaleFactors[1];
537     const double scaleZ = myExtra.scaleFactors[2];
538
539     for (int i = 0; i < 3; ++i)
540     {
541       modelMatrix[0][i] /= scaleX;
542       modelMatrix[1][i] /= scaleY;
543       modelMatrix[2][i] /= scaleZ;
544     }
545
546     const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
547     projMatrix[0][0] *= det2;
548     projMatrix[1][1] *= det2;
549   }
550
551   if( ATransPers->mode & TPF_ROTATE )
552     /* Annulate rotate matrix */
553   {
554     modelMatrix[0][0] = 1.;
555     modelMatrix[1][1] = 1.;
556     modelMatrix[2][2] = 1.;
557
558     modelMatrix[1][0] = 0.;
559     modelMatrix[2][0] = 0.;
560     modelMatrix[0][1] = 0.;
561     modelMatrix[2][1] = 0.;
562     modelMatrix[0][2] = 0.;
563     modelMatrix[1][2] = 0.;
564   }
565   else if( ATransPers->mode & TPF_RELATIVE_ROTATE )
566     /* Initialize relative rotate matrix*/
567   {
568     modelMatrix[3][0] = 0.;
569     modelMatrix[3][1] = 0.;
570     modelMatrix[3][2] = 0.;
571
572     glMatrixMode( GL_MODELVIEW );
573     glLoadIdentity();
574     glTranslated( ATransPers->pointX, ATransPers->pointY, ATransPers->pointZ );        
575   }
576
577   if( ATransPers->mode == TPF_TRIEDRON )
578   {
579     /* Annulate translation matrix */
580     modelMatrix[3][0] = 0.;
581     modelMatrix[3][1] = 0.;
582     modelMatrix[3][2] = 0.;
583
584     projMatrix[3][0] = 0.;
585     projMatrix[3][1] = 0.;
586     projMatrix[3][2] = 0.;
587
588     const double det2 = 0.002 / ( W > H ? projMatrix[1][1] : projMatrix[0][0]);
589     projMatrix[0][0] *= det2;
590     projMatrix[1][1] *= det2;
591   }
592
593   /* load matrix */
594   glMatrixMode (GL_MODELVIEW);
595   glMultMatrixd ((GLdouble *) modelMatrix);
596
597   glMatrixMode (GL_PROJECTION);
598   glMultMatrixd ((GLdouble *) projMatrix);
599
600   /*post loading matrix*/
601   if( ATransPers->mode == TPF_TRIEDRON )
602   {
603     glMatrixMode( GL_PROJECTION );
604
605         double winx, winy, winz;
606     const GLdouble idenMatrix[4][4] = { {1.,0.,0.,0.}, {0.,1.,0.,0.}, {0.,0.,1.,0.}, {0.,0.,0.,1.} };
607
608     gluUnProject( W/2., H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
609     double W1, H1;
610     W1 = winx;
611     H1 = winy;
612     gluUnProject( -W/2., -H/2., 0., (GLdouble*)idenMatrix, (GLdouble*)projMatrix, (GLint*)viewport, &winx, &winy, &winz);
613     double W2, H2;
614     W2 = winx;
615     H2 = winy;
616
617     if( ATransPers->pointX == 0. && ATransPers->pointY == 0. )
618     {
619       /*center*/
620     }
621     else if( ATransPers->pointX > 0. && ATransPers->pointY > 0. )
622     {
623       /*right upper*/
624       glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
625     }
626     else if( ATransPers->pointX > 0. && ATransPers->pointY < 0. )
627     {
628       /*right lower*/
629       glTranslated( 0.5*(W1 - W2 - ATransPers->pointZ), 0.5*(H2 - H1 + ATransPers->pointZ), 0. );
630     }
631     else if( ATransPers->pointX < 0. && ATransPers->pointY > 0. )
632     {
633       /*left upper*/
634       glTranslated( 0.5*(W2 - W1 + ATransPers->pointZ), 0.5*(H1 - H2 - ATransPers->pointZ), 0. );
635     }
636     else if( ATransPers->pointX < 0 && ATransPers->pointY < 0 )
637     {
638       /*left lower*/
639       glTranslated( -(W1 - W2)/2. + ATransPers->pointZ/2., -(H1-H2)/2. + ATransPers->pointZ/2., 0. );
640     }
641   }
642
643   return TransPers_old;
644 }
645
646 /*----------------------------------------------------------------------*/