0024588: Fix some ICC warning fixes
[occt.git] / src / V3d / V3d_View.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 /***********************************************************************
15
16 FONCTION :
17 ----------
18 Classe V3d_View :
19
20 HISTORIQUE DES MODIFICATIONS   :
21 --------------------------------
22 00-09-92 : GG  ; Creation.
23 02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
24 05-06-97 : FMN ; Correction FitAll()
25 30-06-97 : GG ; Correction + Optimisation de Panning(...)
26 On fait la translation + le zoom en une seule
27 operation au lieu de 2 precedemment qui etait buggee.
28 09-07-97 : FMN ; Correction FitAll() sur le Ratio
29 16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
30 22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
31 15-12-97 : FMN ; Ajout texture mapping
32 17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
33 18-12-97 : FMN ; Ajout mode Ajout
34 24-12-97 : FMN ; Remplacement de math par MathGra
35 24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
36 31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
37 07-01-98 : CAL ; Ajout de la methode DoMapping.
38 07-01-98 : CAL ; Retrait de tous les "this->" inutiles
39 21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
40 27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
41 12-02-98 : GG  ; Reactivation du Redraw dans MustBeResized()
42 23-02-98 : FMN ; Remplacement PI par Standard_PI
43 25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
44 11-03-98 : STT ; S3558
45 19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
46 ne marche pas.
47 08-04-98 : STT ; suppr. S3558
48 10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
49 13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
50 ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
51 16-08-98 : CAL ; S3892. Ajout grilles 3d.
52 09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
53 24-09-98 : CAL ; Ajout d'un parametre a V3d_View::SetPlotter.
54 06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
55 16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
56 06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
57 13-06-98 : FMN ; PRO14896: Correction sur la gestion de la perspective (cf Programming Guinde)
58 29-OCT-98 : DCB : Adding ScreenCopy () method.
59 10-11-99 : GG ; PRO19603 Add Redraw( area ) method
60 IMP130100 : GG
61 -> Don't increase too much the ZSize.
62 -> Initialize correctly the Z clipping and D cueing
63 planes.
64 IMP100701 : SZV ; Add ToPixMap() method
65
66 REMARQUES :
67 -----------
68 About  FitAll() multiple. This probleme is caused by missing
69 precision of transformation matrices. If it is supposed that
70 projection is made in the plane (U,V), there is a difference
71 after several Zoom - compared to the exact value (cf ZoomX).
72 Don't forget that the matrices work in float and not in double.
73 To solve the problem (for lack of a better solution) I make 2 passes.
74
75 ************************************************************************/
76
77 //GER61351  //GG_15/12/99 Add SetBackgroundColor() and BackgroundColor() methods
78
79
80 #define IMP020300 //GG Don't use ZFitAll in during Rotation
81 //      for perf improvment
82
83 #define IMP210600 //GG Avoid to have infinite loop when call Rotation() method
84 //      without call before StartRotation().
85 //      This problem occurs when CTRL MB3 is maintain press betwwen 2 views.
86
87 #define IMP250900 //GG Enable rotation around screen Z axis when
88 //      rotation begin far the center of the screen.
89 //      Thanks to Patrick REGINSTER (SAMTECH)
90 //      GG 21/12/00 Due to a regression on the previous specifications
91 //      this new functionnality is right now deactivated
92 //      by default (see StartRotation(...,zRotationThreshold)
93 //      method.
94
95 #define BUC60952  //GG Enable to rotate around the view axis
96 //      and the required view point
97
98 #define RIC120302 //GG Add a NEW SetWindow method which enable
99 //      to connect a graphic widget and context to OGL.
100
101 #define IMP260302 //GG To avoid conflicting in Window destructor
102 //      nullify this handle in Remove method
103
104 #define OCC280          //SAV fix for FitAll problem in the perspective view.
105
106 #define OCC1188         //SAV Added methods to set background image
107
108 /*----------------------------------------------------------------------*/
109 /*
110 * Includes
111 */
112
113 #include <Standard_TypeMismatch.hxx>
114 #include <Visual3d_ViewManager.hxx>
115 #include <Visual3d_Light.hxx>
116 #include <Image_AlienPixMap.hxx>
117 #include <V3d.hxx>
118 #include <V3d_View.ixx>
119 #include <V3d_BadValue.hxx>
120 #include <V3d_StereoDumpOptions.hxx>
121 #include <Standard_ShortReal.hxx>
122 #include <gp_Dir.hxx>
123 #include <gp_Pln.hxx>
124 #include <TColStd_Array2OfReal.hxx>
125 #include <Visual3d_TransientManager.hxx>
126 #include <Precision.hxx>
127
128 #include <Graphic3d_Structure.hxx>
129 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
130 #include <Graphic3d_MapOfStructure.hxx>
131 #include <Graphic3d_TextureEnv.hxx>
132 #include <Graphic3d_AspectMarker3d.hxx>
133 #include <Graphic3d_GraphicDriver.hxx>
134
135 // S3603
136 #include <Aspect_GenericColorMap.hxx>
137 #include <Aspect_TypeMap.hxx>
138 #include <Aspect_WidthMap.hxx>
139 #include <Aspect_MarkMap.hxx>
140 #include <Aspect_FontMap.hxx>
141 #include <TColStd_HSequenceOfInteger.hxx>
142
143 #define V3d_FLAG_COMPUTATION   0x00000004
144
145 // Perspective
146 #include <OSD_Environment.hxx>
147
148 /*----------------------------------------------------------------------*/
149 /*
150 * Constant
151 */
152
153 #define DEUXPI (2. * M_PI)
154
155 /*----------------------------------------------------------------------*/
156 //-Constructors
157
158 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
159   MyProjModel(V3d_TPM_SCREEN),
160   MyViewer(VM.operator->()),
161   MyActiveLights(),
162   MyViewContext (),
163   myActiveLightsIterator(),
164   SwitchSetFront(Standard_False),  
165   MyTrsf (1, 4, 1, 4),
166   myAutoZFitMode (Standard_True)
167 {
168   myImmediateUpdate = Standard_False;
169   MyView = new Visual3d_View(MyViewer->Viewer());
170
171   // { Begin to retrieve the definition from ViewContext.
172   // Step MyViewContext = MyView->Context() ;
173   // to permit MyView->SetContext to compare
174   // the old and the new context.
175   // No problem for MyViewMapping, MyViewOrientation
176   // as MyView->SetViewMapping and MyView->SetViewOrientation
177   // don't try to optimize the modifications introduced to
178   // viewmapping and vieworientation.
179
180   // Aliasing
181   if ((MyView->Context ()).AliasingIsOn ())
182     MyViewContext.SetAliasingOn ();
183   else
184     MyViewContext.SetAliasingOff ();
185
186   // DepthCueing
187   MyViewContext.SetDepthCueingBackPlane
188     ((MyView->Context ()).DepthCueingBackPlane ());
189   MyViewContext.SetDepthCueingFrontPlane
190     ((MyView->Context ()).DepthCueingFrontPlane ());
191
192   if ((MyView->Context ()).DepthCueingIsOn ())
193     MyViewContext.SetDepthCueingOn ();
194   else
195     MyViewContext.SetDepthCueingOff ();
196
197   // ZClipping
198   MyViewContext.SetZClippingBackPlane
199     ((MyView->Context ()).ZClippingBackPlane ());
200   MyViewContext.SetZClippingFrontPlane
201     ((MyView->Context ()).ZClippingFrontPlane ());
202
203   if ((MyView->Context ()).FrontZClippingIsOn ())
204     MyViewContext.SetFrontZClippingOn ();
205   else
206     MyViewContext.SetFrontZClippingOff ();
207
208   if ((MyView->Context ()).BackZClippingIsOn ())
209     MyViewContext.SetBackZClippingOn ();
210   else
211     MyViewContext.SetBackZClippingOff ();
212
213   // Visualization and Shading Model
214   MyViewContext.SetModel ((MyView->Context ()).Model ());
215   MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
216
217   // Texture Mapping
218   MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
219   MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
220   // } End of retrieval of the definition of ViewContext.
221
222   MyBackground = VM->GetBackgroundColor() ;
223   MyGradientBackground = VM->GetGradientBackground() ;
224
225   // camera init
226   Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
227   aCamera->SetFOVy (45.0);
228   aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
229   aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
230   SetCamera (aCamera);
231
232   SetAxis (0.,0.,0.,1.,1.,1.);
233   SetVisualization (VM->DefaultVisualization());
234   SetShadingModel (VM->DefaultShadingModel());
235   SetSurfaceDetail (VM->DefaultSurfaceDetail());
236   SetTwist (0.);
237   SetAt (0.,0.,0.);
238   SetProj (VM->DefaultViewProj());
239   SetSize (VM->DefaultViewSize());
240   Standard_Real zsize = VM->DefaultViewSize();
241   SetZSize (2.*zsize);
242   SetZClippingDepth (0.);
243   SetZClippingWidth (zsize);
244   SetZCueingDepth (0.);
245   SetZCueingWidth (zsize);
246   SetDepth (VM->DefaultViewSize()/2.0);
247   SetCenter (0.,0.);
248   SetViewMappingDefault();
249   VM->AddView (this);
250   Init();
251   myImmediateUpdate = Standard_True;
252
253   aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
254     ? Graphic3d_Camera::Projection_Orthographic
255     : Graphic3d_Camera::Projection_Perspective);
256
257   MyTransparencyFlag = Standard_False;
258 }
259
260 /*----------------------------------------------------------------------*/
261
262 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
263 MyProjModel(V3d_TPM_SCREEN),
264 MyViewer(theVM.operator->()),
265 MyActiveLights(),
266 MyViewContext (),
267 myActiveLightsIterator(),
268 SwitchSetFront(Standard_False),
269 MyTrsf (1, 4, 1, 4), 
270 myAutoZFitMode (Standard_True)
271 {
272   Handle(Visual3d_View) aFromView = theView->View();
273
274   myImmediateUpdate = Standard_False;
275   MyView = new Visual3d_View (MyViewer->Viewer());
276
277   for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
278   {
279     MyActiveLights.Append (theView->ActiveLight());
280   }
281
282   MyViewContext = aFromView->Context() ;
283
284   SetCamera (new Graphic3d_Camera (theView->Camera()));
285
286   MyBackground = aFromView->Background() ;
287   MyGradientBackground = aFromView->GradientBackground();
288
289   MyView->SetContext (MyViewContext) ;
290
291   SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
292
293   theVM->AddView (this);
294
295   Init();
296
297   myImmediateUpdate = Standard_True;
298 }
299
300 /*----------------------------------------------------------------------*/
301
302 //-Methods, in order
303
304 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
305                           const Handle(V3d_View)& aPreviousView,
306                           const Standard_Integer x1,
307                           const Standard_Integer y1,
308                           const Standard_Integer x2,
309                           const Standard_Integer y2)
310 {
311   if( !MyView->IsDefined() ) {
312     Standard_Real a,b,c,d;
313     aPreviousView->Convert(x1,y1,a,b);
314     aPreviousView->Convert(x2,y2,c,d);
315     MyView->SetWindow(TheWindow) ;
316     FitAll(TheWindow,a,b,c,d);
317     MyView->SetContext(MyViewContext) ;
318     MyView->SetBackground(MyBackground) ;
319     MyViewer->SetViewOn(this) ;
320     MyWindow = TheWindow;
321     MyView->Redraw() ;
322     SetViewMappingDefault();
323   }
324 }
325
326 /*----------------------------------------------------------------------*/
327
328 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
329 {
330   Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
331     "V3d_View::SetWindow, window of view already defined");
332
333   MyView->SetWindow(TheWindow) ;
334   // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
335   // calling Redraw(). Otherwise it is impossible to call certain methods of
336   // V3d_View like Convert() inside the context of Redraw(),
337   // particularly in class NIS_View.
338   MyWindow = TheWindow;
339   // SetWindow carries out SetRatio and modifies
340   MyView->SetContext(MyViewContext) ;
341   MyView->SetBackground(MyBackground) ;
342   MyViewer->SetViewOn(this) ;
343   MyView->Redraw() ;
344 }
345
346 // RIC120302
347 /*----------------------------------------------------------------------*/
348
349 void V3d_View::SetWindow(const Handle(Aspect_Window)&      aWindow,
350                          const Aspect_RenderingContext     aContext,
351                          const Aspect_GraphicCallbackProc& aDisplayCB,
352                          const Standard_Address            aClientData)
353 {
354   Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
355     "V3d_View::SetWindow, "
356     "window of view already defined");
357   // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
358   // calling Redraw(). Otherwise it is impossible to call certain methods of
359   // V3d_View like Convert() inside the context of Redraw(),
360   // particularly in class NIS_View.
361   MyWindow = aWindow;
362   MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
363   MyView->SetContext(MyViewContext) ;
364   MyView->SetBackground(MyBackground) ;
365   MyViewer->SetViewOn(this) ;
366   MyView->Redraw() ;
367 }
368 // RIC120302
369
370 /*----------------------------------------------------------------------*/
371
372 void V3d_View::Remove() const
373 {
374   MyViewer->DelView (this);
375   MyView->Remove();
376   Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
377   aWin.Nullify();
378 }
379
380 /*----------------------------------------------------------------------*/
381
382 void V3d_View::Update() const
383 {
384   if( MyView->IsDefined() )  MyView->Update() ;
385 }
386
387 /*----------------------------------------------------------------------*/
388
389 void V3d_View::Redraw() const
390 {
391   if( MyView->IsDefined() ) MyView->Redraw() ;
392 }
393
394 /*----------------------------------------------------------------------*/
395
396 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
397                       const Standard_Integer width,const Standard_Integer height) const
398 {
399   if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
400 }
401
402 /*----------------------------------------------------------------------*/
403
404 Standard_Boolean V3d_View::IsEmpty() const
405 {
406   Standard_Boolean TheStatus = Standard_True ;
407   if( MyView->IsDefined() ) {
408     Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
409     if( Nstruct > 0 ) TheStatus = Standard_False ;
410   }
411   return (TheStatus) ;
412 }
413
414 /*----------------------------------------------------------------------*/
415
416 void V3d_View::UpdateLights() const
417 {
418   MyView->SetContext(MyViewContext);
419   Update();
420 }
421
422 /*----------------------------------------------------------------------*/
423
424 void V3d_View::DoMapping()
425 {
426   if( MyView->IsDefined() ) {
427     (MyView->Window())->DoMapping() ;
428   }
429 }
430
431 /*----------------------------------------------------------------------*/
432
433 void V3d_View::MustBeResized()
434 {
435   if ( !MyLayerMgr.IsNull() )
436     MyLayerMgr->Resized();
437
438   if( MyView->IsDefined() ) {
439     MyView->Resized() ;
440     MyView->Redraw();
441   }
442 }
443
444 /*----------------------------------------------------------------------*/
445
446 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
447 {
448   Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
449   Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
450   Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
451
452   Quantity_Color C( V1, V2, V3, Type );
453   SetBackgroundColor( C );
454 }
455
456 /*----------------------------------------------------------------------*/
457
458 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
459 {
460   MyBackground.SetColor( Color );
461   if ( MyView->IsDefined() )
462     MyView->SetBackground( MyBackground );
463   //szv: Why?
464   if ( !MyLayerMgr.IsNull() )
465     MyLayerMgr->Resized();
466 }
467
468 /*----------------------------------------------------------------------*/
469
470 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
471 {
472   Quantity_Color C( Name );
473   SetBackgroundColor( C );
474 }
475
476 /*----------------------------------------------------------------------*/
477
478 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
479                                     const Quantity_Color& Color2,
480                                     const Aspect_GradientFillMethod FillStyle,
481                                     const Standard_Boolean status)
482 {
483   MyGradientBackground.SetColors(Color1, Color2, FillStyle);
484   if ( MyView->IsDefined() )
485     MyView->SetGradientBackground( MyGradientBackground, status );
486 }
487
488 /*----------------------------------------------------------------------*/
489
490 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
491                                     const Quantity_NameOfColor Color2,
492                                     const Aspect_GradientFillMethod FillStyle,
493                                     const Standard_Boolean status )
494 {
495   Quantity_Color C1( Color1 );
496   Quantity_Color C2( Color2 );
497   MyGradientBackground.SetColors( C1, C2, FillStyle );
498   if ( MyView->IsDefined() )
499     MyView->SetGradientBackground( MyGradientBackground, status );
500 }
501
502 /*----------------------------------------------------------------------*/
503
504 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
505                                    const Standard_Boolean update)
506 {
507   Quantity_Color Color1, Color2;
508   MyGradientBackground.Colors( Color1, Color2 );
509   MyGradientBackground.SetColors( Color1, Color2, FillStyle );
510   if( MyView->IsDefined() )
511     MyView->SetBgGradientStyle( FillStyle, update ) ;
512 }
513
514 /*----------------------------------------------------------------------*/
515
516 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
517                                    const Aspect_FillMethod FillStyle,
518                                    const Standard_Boolean update )
519 {
520 #ifdef OCC1188
521   if( MyView->IsDefined() )
522     MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
523 #endif
524 }
525
526 /*----------------------------------------------------------------------*/
527
528 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
529                                 const Standard_Boolean update )
530 {
531 #ifdef OCC1188
532   if( MyView->IsDefined() )
533     MyView->SetBgImageStyle( FillStyle, update ) ;
534 #endif
535 }
536
537 /*----------------------------------------------------------------------*/
538
539 void V3d_View::SetAxis(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz)
540 {
541   Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
542
543   D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
544   V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
545   Nx /= D ; Ny /= D ; Nz /= D ;
546   MyDefaultViewPoint.SetCoord(X,Y,Z) ;
547   MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
548 }
549
550 /*----------------------------------------------------------------------*/
551
552 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
553 {
554   MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
555   MyView->SetContext(MyViewContext) ;
556 }
557
558 /*----------------------------------------------------------------------*/
559
560 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
561 {
562   MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
563   MyView->SetContext(MyViewContext) ;
564 }
565
566 /*----------------------------------------------------------------------*/
567
568 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
569 {
570   MyViewContext.SetTextureEnv(ATexture) ;
571   MyView->SetContext(MyViewContext) ;
572 }
573
574 /*----------------------------------------------------------------------*/
575
576 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
577 {
578   MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
579   MyView->SetContext(MyViewContext) ;
580 }
581
582 /*----------------------------------------------------------------------*/
583
584 void V3d_View::SetFront()
585 {
586   gp_Ax3 a = MyViewer->PrivilegedPlane();
587   Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
588
589   a.Direction().Coord(vx,vy,vz);
590   a.YDirection().Coord(xu,yu,zu);
591   a.Location().Coord(xo,yo,zo);
592
593   myCamera->BeginUpdate();
594   myCamera->SetCenter (gp_Pnt (xo, yo, zo));
595   if(SwitchSetFront)
596     myCamera->SetDirection (gp_Dir (vx, vy, vz));
597   else
598     myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
599   myCamera->SetUp (gp_Dir (xu, yu, zu));
600
601   AutoZFit();
602   myCamera->EndUpdate();
603
604   SwitchSetFront = !SwitchSetFront;
605
606   ImmediateUpdate();
607 }
608
609 /*----------------------------------------------------------------------*/
610
611 void V3d_View::Rotate (const Standard_Real ax, 
612                        const Standard_Real ay, 
613                        const Standard_Real az, 
614                        const Standard_Boolean Start)
615 {
616   Standard_Real Ax = ax;
617   Standard_Real Ay = ay;
618   Standard_Real Az = az;
619
620   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
621   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
622   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
623   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
624   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
625   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
626
627   if (Start)
628   {
629     myCamStartOpUp = myCamera->Up();
630     myCamStartOpEye = myCamera->Eye();
631     myCamStartOpCenter = myCamera->Center();
632   }
633
634   myCamera->BeginUpdate();
635   myCamera->SetUp (myCamStartOpUp);
636   myCamera->SetEye (myCamStartOpEye);
637   myCamera->SetCenter (myCamStartOpCenter);
638
639   // rotate camera around 3 initial axes
640   gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
641   gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
642   gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
643   gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
644
645   gp_Trsf aRot[3], aTrsf;
646   aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
647   aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
648   aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
649   aTrsf.Multiply (aRot[0]);
650   aTrsf.Multiply (aRot[1]);
651   aTrsf.Multiply (aRot[2]);
652
653   myCamera->Transform (aTrsf);
654
655   myCamera->EndUpdate();
656
657   AutoZFit();
658
659   ImmediateUpdate();
660 }
661
662 /*----------------------------------------------------------------------*/
663
664 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
665                       const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
666 {
667
668   Standard_Real Ax = ax ;
669   Standard_Real Ay = ay ;
670   Standard_Real Az = az ;
671
672   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
673   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
674   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
675   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
676   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
677   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
678
679   if (Start)
680   {
681     myGravityReferencePoint.SetCoord (X, Y, Z);
682     myCamStartOpUp = myCamera->Up();
683     myCamStartOpEye = myCamera->Eye();
684     myCamStartOpCenter = myCamera->Center();
685   }
686
687   const Graphic3d_Vertex& aVref = myGravityReferencePoint;
688
689   myCamera->BeginUpdate();
690   myCamera->SetUp (myCamStartOpUp);
691   myCamera->SetEye (myCamStartOpEye);
692   myCamera->SetCenter (myCamStartOpCenter);
693
694   // rotate camera around 3 initial axes
695   gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
696
697   gp_Dir aZAxis (myCamera->Direction().Reversed());
698   gp_Dir aYAxis (myCamera->Up());
699   gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 
700
701   gp_Trsf aRot[3], aTrsf;
702   aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
703   aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
704   aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
705   aTrsf.Multiply (aRot[0]);
706   aTrsf.Multiply (aRot[1]);
707   aTrsf.Multiply (aRot[2]);
708
709   myCamera->Transform (aTrsf);
710   myCamera->EndUpdate();
711
712   AutoZFit();
713
714   ImmediateUpdate();
715 }
716
717 /*----------------------------------------------------------------------*/
718
719 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
720 {
721   switch (Axe) {
722   case V3d_X :
723     Rotate(angle,0.,0.,Start);
724     break ;
725   case V3d_Y :
726     Rotate(0.,angle,0.,Start);
727     break ;
728   case V3d_Z :
729     Rotate(0.,0.,angle,Start);
730     break ;
731   }
732 }
733
734 /*----------------------------------------------------------------------*/
735
736 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
737                       const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
738 {
739   Standard_Real Angle = angle ;
740
741   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
742   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
743
744   if (Start)
745   {
746     myGravityReferencePoint.SetCoord (X, Y, Z);
747     myCamStartOpUp = myCamera->Up();
748     myCamStartOpEye = myCamera->Eye();
749     myCamStartOpCenter = myCamera->Center();
750
751     switch (Axe) {
752     case V3d_X :
753       myViewAxis.SetCoord(1.,0.,0.) ;
754       break ;
755     case V3d_Y :
756       myViewAxis.SetCoord(0.,1.,0.) ;
757       break ;
758     case V3d_Z :
759       myViewAxis.SetCoord(0.,0.,1.) ;
760       break ;
761     }
762
763     myCamStartOpUp = myCamera->Up();
764     myCamStartOpEye = myCamera->Eye();
765     myCamStartOpCenter = myCamera->Center();
766   }
767
768   const Graphic3d_Vertex& aVref = myGravityReferencePoint;
769
770   myCamera->BeginUpdate();
771   myCamera->SetUp (myCamStartOpUp);
772   myCamera->SetEye (myCamStartOpEye);
773   myCamera->SetCenter (myCamStartOpCenter);
774
775   // rotate camera around passed axis
776   gp_Trsf aRotation;
777   gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
778   gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
779                   (Axe == V3d_Y) ? 1.0 : 0.0,
780                   (Axe == V3d_Z) ? 1.0 : 0.0);
781
782   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
783   myCamera->Transform (aRotation);
784
785   myCamera->EndUpdate();
786
787   AutoZFit();
788
789   ImmediateUpdate();
790 }
791
792 /*----------------------------------------------------------------------*/
793
794 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
795 {
796   Standard_Real Angle = angle;
797
798   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
799   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
800
801   if( Start ) {
802     myCamStartOpUp = myCamera->Up();
803     myCamStartOpEye = myCamera->Eye();
804     myCamStartOpCenter = myCamera->Center();
805   }
806
807   const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
808   const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
809
810   myCamera->BeginUpdate();
811   myCamera->SetUp (myCamStartOpUp);
812   myCamera->SetEye (myCamStartOpEye);
813   myCamera->SetCenter (myCamStartOpCenter);
814
815   gp_Trsf aRotation;
816   gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
817   gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
818   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
819   myCamera->Transform (aRotation);
820
821   myCamera->EndUpdate();
822
823   AutoZFit();
824
825   ImmediateUpdate();
826 }
827
828 /*----------------------------------------------------------------------*/
829
830 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
831 {
832   Standard_Real Ax = ax;
833   Standard_Real Ay = ay;
834   Standard_Real Az = az;
835
836   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
837   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
838   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
839   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
840   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
841   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
842
843   if( Start ) {
844     myCamStartOpUp = myCamera->Up();
845     myCamStartOpEye = myCamera->Eye();
846     myCamStartOpCenter = myCamera->Center();
847   }
848
849   myCamera->BeginUpdate();
850   myCamera->SetUp (myCamStartOpUp);
851   myCamera->SetEye (myCamStartOpEye);
852   myCamera->SetCenter (myCamStartOpCenter);
853
854   // rotate camera around 3 initial axes
855   gp_Pnt aRCenter = myCamera->Eye();
856   gp_Dir aZAxis (myCamera->Direction().Reversed());
857   gp_Dir aYAxis (myCamera->Up());
858   gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 
859
860   gp_Trsf aRot[3], aTrsf;
861   aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
862   aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
863   aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
864   aTrsf.Multiply (aRot[0]);
865   aTrsf.Multiply (aRot[1]);
866   aTrsf.Multiply (aRot[2]);
867
868   myCamera->Transform (aTrsf);
869   myCamera->EndUpdate();
870
871   AutoZFit();
872
873   ImmediateUpdate();
874 }
875
876 /*----------------------------------------------------------------------*/
877
878 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
879 {
880   switch (Axe) {
881   case V3d_X :
882     Turn(angle,0.,0.,Start);
883     break ;
884   case V3d_Y :
885     Turn(0.,angle,0.,Start);
886     break ;
887   case V3d_Z :
888     Turn(0.,0.,angle,Start);
889     break ;
890   }
891 }
892
893 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
894 {
895   Standard_Real Angle = angle ;
896
897   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
898   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
899
900   if( Start ) {
901     myCamStartOpUp = myCamera->Up();
902     myCamStartOpEye = myCamera->Eye();
903     myCamStartOpCenter = myCamera->Center();
904   }
905
906   myCamera->BeginUpdate();
907   myCamera->SetUp (myCamStartOpUp);
908   myCamera->SetEye (myCamStartOpEye);
909   myCamera->SetCenter (myCamStartOpCenter);
910
911   const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
912
913   gp_Trsf aRotation;
914   gp_Pnt aRCenter = myCamera->Eye();
915   gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
916   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
917   myCamera->Transform (aRotation);
918
919   myCamera->EndUpdate();
920
921   AutoZFit();
922
923   ImmediateUpdate();
924 }
925
926 void V3d_View::SetTwist(const Standard_Real angle)
927 {
928   Standard_Real Angle = angle ;
929   Standard_Boolean TheStatus;
930
931   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
932   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
933
934   gp_Dir aReferencePlane (myCamera->Direction().Reversed());
935   gp_Dir anUp;
936
937   anUp = gp_Dir (0.0, 0.0, 1.0);
938
939   TheStatus = ScreenAxis(aReferencePlane, anUp,
940     myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
941   if( !TheStatus ) {
942     anUp = gp_Dir (0.0, 1.0, 0.0);
943     TheStatus = ScreenAxis(aReferencePlane, anUp,
944       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
945   }
946   if( !TheStatus ) {
947     anUp = gp_Dir (1.0, 0.0, 0.0);
948     TheStatus = ScreenAxis(aReferencePlane, anUp,
949       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
950   }
951
952   V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
953   
954   gp_Pnt aRCenter = myCamera->Center();
955   gp_Dir aZAxis (myCamera->Direction().Reversed());
956
957   gp_Trsf aTrsf;
958   aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
959
960   Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
961   myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
962     
963   myCamera->BeginUpdate();
964   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
965   myCamera->Transform (aTrsf);
966   myCamera->EndUpdate();
967
968   AutoZFit();
969
970   ImmediateUpdate();
971 }
972
973 void V3d_View::SetAutoZFitMode (Standard_Boolean theMode)
974 {
975   myAutoZFitMode = theMode;
976 }
977
978 Standard_Boolean V3d_View::AutoZFitMode () const
979 {
980   return myAutoZFitMode;
981 }
982
983 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
984 {
985   Standard_Real Angle;
986   Angle = Twist();
987
988   myCamera->SetEye (gp_Pnt (X, Y, Z));
989
990   Standard_Boolean update = myImmediateUpdate;
991   myImmediateUpdate = Standard_False;
992
993   SetTwist(Angle);
994
995   AutoZFit();
996
997   myImmediateUpdate = update;
998   ImmediateUpdate();
999 }
1000
1001 void V3d_View::SetDepth(const Standard_Real Depth)
1002 {
1003   V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1004
1005   if( Depth > 0. )
1006   {
1007     // Move eye using center (target) as anchor.
1008     myCamera->SetDistance (Depth);
1009   }
1010   else
1011   { 
1012     // Move the view ref point instead of the eye.
1013     gp_Vec aDir (myCamera->Direction());
1014     gp_Pnt aCameraEye = myCamera->Eye();
1015     gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));      
1016       
1017     myCamera->SetCenter (aCameraCenter);
1018   }
1019
1020   AutoZFit();
1021
1022   ImmediateUpdate();
1023 }
1024
1025
1026 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1027 {
1028   Standard_Real Angle ;
1029
1030   V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1031     "V3d_View::SetProj, null projection vector");
1032
1033   Angle = Twist();
1034
1035   myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1036
1037   Standard_Boolean update = myImmediateUpdate;
1038   myImmediateUpdate = Standard_False;
1039
1040   if( MyProjModel == V3d_TPM_SCREEN ) SetTwist(Angle) ;
1041
1042   AutoZFit();
1043
1044   myImmediateUpdate = update;
1045   ImmediateUpdate();
1046 }
1047
1048 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1049 {
1050   Standard_Real Xpn=0;
1051   Standard_Real Ypn=0;
1052   Standard_Real Zpn=0;
1053
1054   switch (Orientation) {
1055   case V3d_Zpos :
1056     Ypn = 1.;
1057     break;
1058   case V3d_Zneg :
1059     Ypn = -1.;
1060     break;
1061   default:
1062     Zpn = 1.;
1063   }
1064
1065   const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1066   myCamera->BeginUpdate();
1067   myCamera->SetCenter (gp_Pnt (0, 0, 0));
1068   myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1069   myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1070   myCamera->EndUpdate();
1071
1072   AutoZFit();
1073
1074   ImmediateUpdate();
1075 }
1076
1077 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1078 {
1079   Standard_Real Angle;
1080
1081   Angle = Twist();
1082
1083   myCamera->SetCenter (gp_Pnt (X, Y, Z));
1084   Standard_Boolean update = myImmediateUpdate;
1085   myImmediateUpdate = Standard_False;
1086
1087   SetTwist(Angle) ;
1088
1089   AutoZFit();
1090
1091   myImmediateUpdate = update;
1092   ImmediateUpdate();
1093 }
1094
1095 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1096 {
1097   Standard_Boolean TheStatus ;
1098   V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1099     "V3d_View::SetUp, nullUp vector");
1100
1101   gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1102   gp_Dir anUp (Vx, Vy, Vz);
1103
1104   TheStatus = ScreenAxis(aReferencePlane,anUp,
1105     myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1106   if( !TheStatus ) {
1107     anUp = gp_Dir (0.0, 0.0, 1.0);
1108     TheStatus = ScreenAxis(aReferencePlane,anUp,
1109       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1110   }
1111   if( !TheStatus ) {
1112     anUp = gp_Dir (0.0, 1.0, 0.0);
1113     TheStatus = ScreenAxis(aReferencePlane,anUp,
1114       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1115   }
1116   if( !TheStatus ) {
1117     anUp = gp_Dir (1.0, 0.0, 0.0);
1118     TheStatus = ScreenAxis(aReferencePlane,anUp,
1119       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1120   }
1121   V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1122
1123   Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1124   myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1125
1126   myCamera->BeginUpdate();
1127   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1128   AutoZFit();
1129   myCamera->EndUpdate();
1130
1131   ImmediateUpdate();
1132 }
1133
1134 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1135 {
1136   Standard_Boolean TheStatus ;
1137
1138   gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1139   gp_Dir anUp;
1140
1141   const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1142   anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1143
1144   TheStatus = ScreenAxis(aReferencePlane,anUp,
1145     myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1146   if( !TheStatus ) {
1147     anUp = gp_Dir (0.,0.,1.);
1148     TheStatus = ScreenAxis(aReferencePlane,anUp,
1149       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1150   }
1151   if( !TheStatus ) {
1152     anUp = gp_Dir (0.,1.,0.);
1153     TheStatus = ScreenAxis(aReferencePlane,anUp,
1154       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1155   }
1156   if( !TheStatus ) {
1157     anUp = gp_Dir (1.,0.,0.);
1158     TheStatus = ScreenAxis(aReferencePlane,anUp,
1159       myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1160   }
1161   V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1162
1163   Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1164   myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1165
1166   myCamera->BeginUpdate();
1167   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1168   AutoZFit();
1169   myCamera->EndUpdate();
1170
1171   ImmediateUpdate();
1172 }
1173
1174 void V3d_View::SetViewOrientationDefault()
1175 {
1176   MyView->SetViewOrientationDefault() ;
1177
1178   ImmediateUpdate();
1179 }
1180
1181 void V3d_View::ResetViewOrientation()
1182 {
1183   MyView->ViewOrientationReset() ;
1184
1185   ImmediateUpdate();
1186 }
1187
1188 void V3d_View::Reset( const Standard_Boolean update )
1189 {
1190   Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1191
1192   if (!aDefaultCamera.IsNull())
1193   {
1194     myCamera->BeginUpdate();
1195     myCamera->CopyMappingData (aDefaultCamera);
1196     myCamera->CopyOrientationData (aDefaultCamera);
1197     myCamera->EndUpdate();
1198   }
1199
1200   AutoZFit();
1201   SwitchSetFront = Standard_False;
1202
1203   if( !myImmediateUpdate && update ) Update();
1204 }
1205
1206 void V3d_View::Panning(const Standard_Real Dx, const Standard_Real Dy, const Quantity_Factor aZoomFactor, const Standard_Boolean Start)
1207 {
1208   V3d_BadValue_Raise_if( aZoomFactor <= 0.,"V3d_View::Panning, bad zoom factor");
1209
1210   if( Start ) {
1211     myCamStartOpEye = myCamera->Eye();
1212     myCamStartOpCenter = myCamera->Center();
1213     myCamProjectionShift = myCamera->ProjectionShift();
1214   }
1215
1216   myCamera->BeginUpdate();
1217   myCamera->SetEye (myCamStartOpEye);
1218   myCamera->SetCenter (myCamStartOpCenter);
1219   myCamera->SetProjectionShift (myCamProjectionShift);
1220   PanCamera (-Dx, -Dy);
1221   gp_Pnt aViewDims = myCamera->ViewDimensions();
1222   ZoomCamera (aViewDims.X() / aZoomFactor, aViewDims.Y() / aZoomFactor);
1223   myCamera->EndUpdate();
1224
1225   ImmediateUpdate();
1226 }
1227
1228 void V3d_View::SetCenter(const Standard_Integer X, const Standard_Integer Y)
1229 {
1230   Standard_Real x,y;
1231   Convert(X,Y,x,y);
1232   SetCenter(x,y);
1233 }
1234
1235 void V3d_View::SetCenter(const Standard_Real Xc, const Standard_Real Yc)
1236 {
1237   myCamera->SetProjectionShift (gp_Pnt (-Xc, -Yc, 0.0)); 
1238
1239   ImmediateUpdate();
1240 }
1241
1242 void V3d_View::SetSize(const Standard_Real Size)
1243 {
1244   V3d_BadValue_Raise_if(  Size  <= 0.,
1245     "V3d_View::SetSize, Window Size is NULL");
1246
1247   myCamera->BeginUpdate();
1248   myCamera->SetScale (Size);
1249   AutoZFit();
1250   myCamera->EndUpdate();
1251
1252   ImmediateUpdate();
1253 }
1254
1255 void V3d_View::SetZSize(const Standard_Real Size)
1256 {
1257   Standard_Real Zmax = Size/2.;
1258
1259   Standard_Real aDistance = myCamera->Distance();
1260
1261   if( Size <= 0. ) {
1262     Zmax = aDistance;
1263   }
1264
1265   Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1266   Standard_Real Back  = MyViewContext.ZClippingBackPlane();
1267
1268   myCamera->SetZFar (Zmax + aDistance * 2.0);
1269   myCamera->SetZNear (-Zmax + aDistance);
1270
1271   if (MyViewContext.FrontZClippingIsOn()  ||
1272       MyViewContext.BackZClippingIsOn())
1273   {
1274     MyViewContext.SetZClippingFrontPlane (Front);
1275     MyViewContext.SetZClippingBackPlane (Back);
1276     MyView->SetContext (MyViewContext);
1277   }
1278 }
1279
1280 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1281 {
1282   V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1283
1284   if (Start)
1285   {
1286     myCamStartOpEye    = myCamera->Eye();
1287     myCamStartOpCenter = myCamera->Center();
1288   }
1289
1290   Standard_Real aViewWidth  = myCamera->ViewDimensions().X();
1291   Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1292
1293   // ensure that zoom will not be too small or too big
1294   Standard_Real coef = Coef;
1295   if (aViewWidth < coef * Precision::Confusion())
1296   {
1297     coef = aViewWidth / Precision::Confusion();
1298   }
1299   else if (aViewWidth > coef * 1e12)
1300   {
1301     coef = aViewWidth / 1e12;
1302   }
1303   if (aViewHeight < coef * Precision::Confusion())
1304   {
1305     coef = aViewHeight / Precision::Confusion();
1306   }
1307   else if (aViewHeight > coef * 1e12)
1308   {
1309     coef = aViewHeight / 1e12;
1310   }
1311
1312   myCamera->BeginUpdate();
1313   myCamera->SetEye (myCamStartOpEye);
1314   myCamera->SetCenter (myCamStartOpCenter);
1315   myCamera->SetScale (myCamera->Scale() / Coef);
1316   AutoZFit();
1317   myCamera->EndUpdate();
1318
1319   ImmediateUpdate();
1320 }
1321
1322 void V3d_View::SetScale( const Standard_Real Coef )
1323 {
1324   V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1325
1326   Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1327
1328   myCamera->BeginUpdate();
1329   
1330   // Strange behavior for the sake of compatibility.
1331   if (!aDefaultCamera.IsNull())
1332   {
1333     myCamera->SetAspect (aDefaultCamera->Aspect());
1334     Standard_Real aDefaultScale = aDefaultCamera->Scale();
1335     myCamera->SetScale (aDefaultScale / Coef);
1336   } 
1337   else
1338   {
1339     myCamera->SetScale (myCamera->Scale() / Coef);
1340   }
1341
1342   AutoZFit();
1343   myCamera->EndUpdate();
1344
1345   ImmediateUpdate();
1346 }
1347
1348 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1349 {
1350   V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1351
1352   myCamera->BeginUpdate();
1353   myCamera->SetAxialScale (gp_Pnt (Sx, Sy, Sz));
1354   AutoZFit();
1355   myCamera->EndUpdate();
1356 }
1357
1358 void V3d_View::FitAll(const Standard_Real Coef, const Standard_Boolean update)
1359 {
1360   Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1361
1362   // retrieve min / max values for current displayed objects
1363   MyView->MinMaxValues (Xmin, Ymin, Zmin,
1364                         Xmax, Ymax, Zmax);
1365
1366   Standard_Real LIM = ShortRealLast() - 1.0;
1367   if  (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1368     || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM)
1369   {
1370     ImmediateUpdate();
1371     return;
1372   }
1373
1374   myCamera->BeginUpdate();
1375   FitCamera (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1376   myCamera->SetScale (myCamera->Scale() * (1.0 + Coef));
1377   AutoZFit();
1378   myCamera->EndUpdate();
1379
1380   if (myImmediateUpdate || update)
1381   {
1382     Update();
1383   }
1384 }
1385
1386 //===============================================================================================
1387 //function : AutoZFit
1388 //purpose  :
1389 //===============================================================================================
1390 void V3d_View::AutoZFit()
1391 {
1392   if (myAutoZFitMode)
1393   {
1394     ZFitAll();
1395   }
1396 }
1397
1398 void V3d_View::ZFitAll (const Standard_Real theCoeff)
1399 {
1400   V3d_BadValue_Raise_if (theCoeff <= 0.0, "V3d_View::ZFitAll, bad margin coefficient");
1401
1402   Standard_Real aMinMax[6];
1403
1404   MyView->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2], aMinMax[3], aMinMax[4], aMinMax[5]);
1405
1406   gp_Pnt aBMin = gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]);
1407   gp_Pnt aBMax = gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]);
1408
1409   // check bounding box for validness
1410   Standard_Real aLim = (ShortRealLast() - 1.0);
1411   if (Abs (aBMin.X()) > aLim || Abs (aBMin.Y()) > aLim || Abs (aBMin.Z()) > aLim ||
1412       Abs (aBMax.X()) > aLim || Abs (aBMax.Y()) > aLim || Abs (aBMax.Z()) > aLim)
1413   {
1414     SetZSize (0.0);
1415     ImmediateUpdate();
1416     return;
1417   }
1418
1419   // adapt bound points
1420   gp_Pnt aPnts[8] = 
1421     { gp_Pnt (aBMin.X(), aBMin.Y(), aBMin.Z()),
1422       gp_Pnt (aBMin.X(), aBMin.Y(), aBMax.Z()),
1423       gp_Pnt (aBMin.X(), aBMax.Y(), aBMin.Z()),
1424       gp_Pnt (aBMin.X(), aBMax.Y(), aBMax.Z()),
1425       gp_Pnt (aBMax.X(), aBMin.Y(), aBMin.Z()),
1426       gp_Pnt (aBMax.X(), aBMin.Y(), aBMax.Z()),
1427       gp_Pnt (aBMax.X(), aBMax.Y(), aBMin.Z()),
1428       gp_Pnt (aBMax.X(), aBMax.Y(), aBMax.Z()) };
1429
1430   // camera Eye plane
1431   gp_Dir aDir = myCamera->Direction();
1432   gp_Pnt anEye = myCamera->Eye();
1433   gp_Pln aCamPln (anEye, aDir);
1434
1435   Standard_Real aMinDist = RealLast() - 1;
1436   Standard_Real aMaxDist = RealFirst() + 1;
1437
1438   gp_Pnt anAxialScale = myCamera->AxialScale();
1439
1440   // get minimum and maximum distances to the eye plane
1441   for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
1442   {
1443     gp_Pnt aPnt = aPnts[aPntIt];
1444
1445     aPnt = gp_Pnt (aPnt.X() * anAxialScale.X(),
1446                    aPnt.Y() * anAxialScale.Y(),
1447                    aPnt.Z() * anAxialScale.Z());
1448
1449     Standard_Real aDistance = aCamPln.Distance (aPnt);
1450
1451     // check if the camera is intruded into the scene
1452     if (aDir.IsOpposite (gp_Vec (anEye, aPnt), M_PI * 0.5))
1453     {
1454       aDistance *= -1;
1455     }
1456
1457     aMinDist = Min (aDistance, aMinDist);
1458     aMaxDist = Max (aDistance, aMaxDist);
1459   }
1460
1461   // compute depth of bounding box center
1462   Standard_Real aMidDepth  = (aMinDist + aMaxDist) * 0.5;
1463   Standard_Real aHalfDepth = (aMaxDist - aMinDist) * 0.5;
1464
1465   // compute enlarged or shrank near and far z ranges.
1466   Standard_Real aZNear = aMidDepth - aHalfDepth * theCoeff;
1467   Standard_Real aZFar  = aMidDepth + aHalfDepth * theCoeff;
1468
1469   myCamera->BeginUpdate();
1470
1471   if (myCamera->IsOrthographic())
1472   {
1473     myCamera->SetZFar  (myCamera->Distance() * 3.0);
1474     myCamera->SetZNear (0.0);
1475
1476     if (aZNear < 0.0)
1477     {
1478       myCamera->SetDistance (myCamera->Distance() - (aZNear + myCamera->ZNear()) + 10.0);
1479     }
1480   }
1481   else
1482   {
1483     myCamera->SetZFar  (aZFar);
1484     myCamera->SetZNear (aZNear); 
1485   }
1486
1487   myCamera->EndUpdate();
1488
1489   ImmediateUpdate();
1490 }
1491
1492
1493 // Better to use ZFitAll instead. 
1494 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1495                            const Quantity_Coefficient Margin)
1496 {
1497   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1498   Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1499   Standard_Real Dx,Dy,Dz,Size;
1500
1501   Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1502
1503   if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1504     ImmediateUpdate();
1505     return ;
1506   }
1507
1508   MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1509
1510   Standard_Real LIM = ShortRealLast() -1.;
1511   if     (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1512     ||  Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) {
1513       ImmediateUpdate();
1514       return ;
1515     }
1516
1517     if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
1518       ImmediateUpdate();
1519       return ;
1520     }
1521     MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1522     MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1523     Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1524     Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1525     Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1526     MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1527     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1528     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1529     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1530     MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1531     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1532     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1533     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1534     MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1535     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1536     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1537     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1538     MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1539     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1540     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1541     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1542     MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1543     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1544     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1545     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1546     MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1547     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1548     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1549     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1550
1551     // Adjust Z size
1552     Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1553     Dz = 2.*Wmax + Margin * Wmax;
1554
1555     // Compute depth value
1556     Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1557     Dx += Margin * Dx; Dy += Margin * Dy;
1558     Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1559     if( Size > 0. ) {
1560       SetZSize(Size) ;
1561       SetDepth( Aspect * Size / 2.);
1562     }
1563
1564     ImmediateUpdate();
1565 }
1566
1567 void V3d_View::FitAll(const Standard_Real Xmin, const Standard_Real Ymin, const Standard_Real Xmax, const Standard_Real Ymax)
1568 {
1569   FitAll(MyWindow,Xmin,Ymin,Xmax,Ymax);
1570
1571   ImmediateUpdate();
1572 }
1573
1574 void V3d_View::WindowFitAll(const Standard_Integer Xmin, const Standard_Integer Ymin, const Standard_Integer Xmax, const Standard_Integer Ymax)
1575 {
1576   WindowFit(Xmin,Ymin,Xmax,Ymax);
1577 }
1578
1579 void V3d_View::WindowFit(const Standard_Integer Xmin, const Standard_Integer Ymin, const Standard_Integer Xmax, const Standard_Integer Ymax)
1580 {
1581   if (!myCamera->IsOrthographic())
1582   {
1583     // normalize view coordiantes
1584     Standard_Integer aWinWidth, aWinHeight;
1585     MyWindow->Size (aWinWidth, aWinHeight);
1586
1587     // z coordinate of camera center
1588     Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1589
1590     // camera projection coordinate are in NDC which are normalized [-1, 1]
1591     Standard_Real aUMin = (2.0 / aWinWidth) * Xmin - 1.0;
1592     Standard_Real aUMax = (2.0 / aWinWidth) * Xmax - 1.0;
1593     Standard_Real aVMin = (2.0 / aWinHeight) * Ymin - 1.0;
1594     Standard_Real aVMax = (2.0 / aWinHeight) * Ymax - 1.0;
1595
1596     // compute camera panning
1597     gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1598     gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1599     gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1600     gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1601     gp_Vec aPanVec (aPanFrom, aPanTo);
1602
1603     // compute section size
1604     gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1605     gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1606     gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1607     gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1608
1609     Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1610     Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1611
1612     myCamera->BeginUpdate();
1613     PanCamera (aPanVec.X(), -aPanVec.Y());
1614     ZoomCamera (aUSize, aVSize);
1615     AutoZFit();
1616     myCamera->EndUpdate();
1617   }
1618   else
1619   {
1620     Standard_Real x1,y1,x2,y2;
1621     Convert(Xmin,Ymin,x1,y1);
1622     Convert(Xmax,Ymax,x2,y2);
1623
1624     FitAll(x1,y1,x2,y2);
1625   }
1626 }
1627
1628 void V3d_View::SetViewMappingDefault()
1629 {
1630   MyView->SetViewMappingDefault();
1631
1632   ImmediateUpdate();
1633 }
1634
1635 void V3d_View::ResetViewMapping()
1636 {
1637   MyView->ViewMappingReset();
1638
1639   Update();
1640 }
1641
1642 void V3d_View::ConvertToGrid(const Standard_Integer Xp, const Standard_Integer Yp, Standard_Real& Xg, Standard_Real& Yg, Standard_Real& Zg) const
1643 {
1644   Graphic3d_Vertex aVrp;
1645   Standard_Real anX, anY, aZ;
1646   Convert (Xp, Yp, anX, anY, aZ);
1647   aVrp.SetCoord (anX, anY, aZ);
1648
1649   if( MyViewer->Grid()->IsActive() ) {
1650     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1651     aNewVrp.Coord (Xg,Yg,Zg) ;
1652   } else
1653     aVrp.Coord (Xg,Yg,Zg) ;
1654 }
1655
1656 void V3d_View::ConvertToGrid(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Real& Xg, Standard_Real& Yg, Standard_Real& Zg) const
1657 {
1658   if( MyViewer->Grid()->IsActive() ) {
1659     Graphic3d_Vertex aVrp (X,Y,Z) ;
1660     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1661     aNewVrp.Coord(Xg,Yg,Zg) ;
1662   } else {
1663     Xg = X; Yg = Y; Zg = Z;
1664   }
1665 }
1666
1667
1668 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1669 {
1670   Standard_Integer aDxw, aDyw ;
1671
1672   V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1673
1674   MyWindow->Size (aDxw, aDyw);
1675   Standard_Real aValue;
1676   
1677   gp_Pnt aViewDims = myCamera->ViewDimensions();
1678   aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1679
1680   return aValue;
1681 }
1682
1683 void V3d_View::Convert(const Standard_Integer Xp, const Standard_Integer Yp, Standard_Real& Xv, Standard_Real& Yv) const
1684 {
1685   Standard_Integer aDxw, aDyw;
1686
1687   V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1688
1689   MyWindow->Size (aDxw, aDyw);
1690
1691   gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1692   aPoint = myCamera->ConvertProj2View (aPoint);
1693
1694   Xv = aPoint.X();
1695   Yv = aPoint.Y();
1696 }
1697
1698 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1699 {
1700   V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1701
1702   Standard_Integer aDxw, aDyw;
1703   MyWindow->Size (aDxw, aDyw);
1704
1705   gp_Pnt aViewDims = myCamera->ViewDimensions();
1706   Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1707
1708   return aValue;
1709 }
1710
1711 void V3d_View::Convert(const Standard_Real Xv, const Standard_Real Yv, Standard_Integer& Xp, Standard_Integer& Yp) const
1712 {
1713   V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1714
1715   Standard_Integer aDxw, aDyw;
1716   MyWindow->Size (aDxw, aDyw);
1717
1718   gp_Pnt aPoint (Xv, Yv, 0.0);
1719   aPoint = myCamera->ConvertView2Proj (aPoint);
1720   aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1721
1722   Xp = RealToInt (aPoint.X());
1723   Yp = RealToInt (aPoint.Y());
1724 }
1725
1726 void V3d_View::Convert(const Standard_Integer Xp, const Standard_Integer Yp, Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
1727 {
1728   V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1729   Standard_Integer aHeight, aWidth;
1730   MyWindow->Size (aWidth, aHeight);
1731
1732   Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1733   Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1734   Standard_Real  aZ = 2.0 * 0.0 - 1.0;
1735
1736   gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1737
1738   X = aResult.X();
1739   Y = aResult.Y();
1740   Z = aResult.Z();
1741
1742   Graphic3d_Vertex aVrp;
1743   aVrp.SetCoord (X, Y, Z);
1744
1745   if( MyViewer->Grid()->IsActive() ) {
1746     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1747     aNewVrp.Coord (X, Y, Z) ;
1748   }
1749 }
1750
1751 void V3d_View::ConvertWithProj(const Standard_Integer Xp, const Standard_Integer Yp, Standard_Real& X, Standard_Real& Y, Standard_Real& Z, Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
1752 {
1753   V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1754   Standard_Integer aHeight, aWidth;
1755   MyWindow->Size (aWidth, aHeight);
1756
1757   Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1758   Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1759   Standard_Real  aZ = 2.0 * 0.0 - 1.0;
1760
1761   gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1762
1763   X = aResult.X();
1764   Y = aResult.Y();
1765   Z = aResult.Z();
1766
1767   Graphic3d_Vertex aVrp;
1768   aVrp.SetCoord (X, Y, Z);
1769
1770   aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1771
1772   Dx = X - aResult.X();
1773   Dy = Y - aResult.Y();
1774   Dz = Z - aResult.Z();
1775
1776   if( MyViewer->Grid()->IsActive() ) {
1777     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1778     aNewVrp.Coord (X, Y, Z) ;
1779   }
1780 }
1781
1782 void V3d_View::Convert(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Integer& Xp, Standard_Integer& Yp) const
1783 {
1784   V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1785   Standard_Integer aHeight, aWidth;
1786   MyWindow->Size (aWidth, aHeight);
1787
1788   gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
1789
1790   Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1791   Yp = RealToInt ((aPoint.Y() + 1) * 0.5 * aHeight);
1792 }
1793
1794 void V3d_View::Project(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Real &Xp, Standard_Real &Yp) const
1795 {
1796   Standard_Real Zp;
1797   MyView->Projects (X, Y, Z, Xp, Yp, Zp);
1798 }
1799
1800 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,Standard_Real& V1, Standard_Real& V2, Standard_Real& V3) const
1801 {
1802   Quantity_Color C = BackgroundColor() ;
1803   C.Values(V1,V2,V3,Type) ;
1804 }
1805
1806 Quantity_Color V3d_View::BackgroundColor() const
1807 {
1808   return MyBackground.Color() ;
1809 }
1810
1811 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
1812 {
1813   MyGradientBackground.Colors(Color1, Color2);
1814 }
1815
1816 Aspect_GradientBackground V3d_View::GradientBackground() const
1817 {
1818    return MyGradientBackground;
1819 }
1820
1821 Standard_Real V3d_View::Scale() const
1822 {
1823   Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1824
1825   Standard_Real aCameraScale;
1826
1827   // Strange behavior for the sake of compatibility.
1828   if (!aDefaultCamera.IsNull())
1829   {
1830     Standard_Real aDefaultScale = aDefaultCamera->Scale();
1831     aCameraScale = aDefaultScale / myCamera->Scale();
1832   } 
1833   else
1834   {
1835     aCameraScale = myCamera->Scale();
1836   }
1837
1838   return aCameraScale;
1839 }
1840
1841 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1842 {
1843   gp_Pnt anAxialScale = myCamera->AxialScale();
1844   Sx = anAxialScale.X();
1845   Sy = anAxialScale.Y();
1846   Sz = anAxialScale.Z();
1847 }
1848
1849 void V3d_View::Center(Standard_Real& Xc, Standard_Real& Yc) const
1850 {
1851   gp_Pnt aCamProjShift = myCamera->ProjectionShift();
1852
1853   Xc = -aCamProjShift.X();
1854   Yc = -aCamProjShift.Y();
1855 }
1856
1857 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1858 {
1859   gp_Pnt aViewDims = myCamera->ViewDimensions();
1860
1861   Width = aViewDims.X();
1862   Height = aViewDims.Y();
1863 }
1864
1865 Standard_Real V3d_View::ZSize() const
1866 {
1867   gp_Pnt aViewDims = myCamera->ViewDimensions();
1868
1869   return aViewDims.Z();
1870 }
1871
1872 Standard_Integer V3d_View::MinMax(Standard_Real& Umin, Standard_Real& Vmin, Standard_Real& Umax, Standard_Real& Vmax) const
1873 {
1874   Standard_Real Wmin,Wmax,U,V,W ;
1875   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1876   // CAL 6/11/98
1877   Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1878
1879   if( Nstruct ) {
1880     MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1881     MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1882     MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1883     MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1884     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1885     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1886     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1887     MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1888     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1889     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1890     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1891     MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1892     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1893     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1894     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1895     MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1896     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1897     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1898     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1899     MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1900     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1901     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1902     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1903     MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1904     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1905     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1906     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1907   }
1908   return Nstruct ;
1909 }
1910
1911 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin, Standard_Real& Ymin, Standard_Real& Zmin, Standard_Real& Xmax, Standard_Real& Ymax, Standard_Real& Zmax) const
1912 {
1913   // CAL 6/11/98
1914   // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1915   Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1916
1917   if( Nstruct ) {
1918     MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1919   }
1920   return Nstruct ;
1921 }
1922
1923 Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
1924 {
1925   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
1926   Standard_Integer Nstruct,Npoint ;
1927   Graphic3d_MapOfStructure MySetOfStructures;
1928
1929   MyView->DisplayedStructures (MySetOfStructures);
1930   Nstruct = MySetOfStructures.Extent() ;
1931
1932   Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
1933
1934   Npoint = 0 ; X = Y = Z = 0. ;
1935   for (; MyIterator.More(); MyIterator.Next())
1936   {
1937     const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
1938     if (!aStruct->IsEmpty())
1939     {
1940       aStruct->MinMaxValues (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1941
1942       // use camera projection to find gravity point
1943       gp_Pnt aPnts[8] = { 
1944         gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
1945         gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
1946         gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
1947         gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
1948
1949       for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
1950       {
1951         const gp_Pnt& aBndPnt = aPnts[aPntIt];
1952
1953         gp_Pnt aProjected = myCamera->Project (aBndPnt);
1954         const Standard_Real& U = aProjected.X();
1955         const Standard_Real& V = aProjected.Y();
1956         if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
1957         {
1958           Npoint++;
1959           X += aBndPnt.X();
1960           Y += aBndPnt.Y();
1961           Z += aBndPnt.Z();
1962         }
1963       }
1964     }
1965   }
1966   if( Npoint > 0 ) {
1967     X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
1968   }
1969
1970   return Nstruct ;
1971 }
1972
1973 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
1974 {
1975   gp_Pnt aCameraEye = myCamera->Eye();
1976   X = aCameraEye.X();
1977   Y = aCameraEye.Y();
1978   Z = aCameraEye.Z();
1979 }
1980
1981 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
1982 {
1983   Eye (X,Y,Z);
1984 }
1985
1986 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix, const Standard_Integer Ypix, Standard_Real& XP, Standard_Real& YP, Standard_Real& ZP, Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ) const
1987 {
1988   Standard_Real Xo,Yo,Zo;
1989
1990   Convert (Xpix, Ypix, XP, YP, ZP);
1991   if ( Type() == V3d_PERSPECTIVE ) 
1992   {
1993     FocalReferencePoint (Xo,Yo,Zo);
1994     VX = Xo - XP;
1995     VY = Yo - YP;
1996     VZ = Zo - ZP;
1997   }
1998   else 
1999   {
2000     Proj (VX,VY,VZ);
2001   }
2002 }
2003
2004 Standard_Real V3d_View::Depth() const
2005 {
2006   return myCamera->Distance();
2007 }
2008
2009 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2010 {
2011   gp_Dir aCameraDir = myCamera->Direction().Reversed();
2012   Dx = aCameraDir.X();
2013   Dy = aCameraDir.Y();
2014   Dz = aCameraDir.Z();
2015 }
2016
2017 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2018 {
2019   gp_Pnt aCameraCenter = myCamera->Center();
2020   X = aCameraCenter.X();
2021   Y = aCameraCenter.Y();
2022   Z = aCameraCenter.Z();
2023 }
2024
2025 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2026 {
2027   gp_Dir aCameraUp = myCamera->Up();
2028   Vx = aCameraUp.X();
2029   Vy = aCameraUp.Y();
2030   Vz = aCameraUp.Z();
2031 }
2032
2033 Standard_Real V3d_View::Twist() const
2034 {
2035   Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2036   Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2037   Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2038   Standard_Boolean TheStatus ;
2039
2040   gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2041   gp_Dir anUp;
2042
2043   Proj(Xpn,Ypn,Zpn);
2044   anUp = gp_Dir (0.,0.,1.) ;
2045   TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2046   if( !TheStatus ) {
2047     anUp = gp_Dir (0.,1.,0.) ;
2048     TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2049   }
2050   if( !TheStatus ) {
2051     anUp = gp_Dir (1.,0.,0.) ;
2052     TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2053   }
2054   Yaxis.Coord(X0,Y0,Z0) ;
2055
2056   Up(Xup,Yup,Zup) ;
2057   /* Compute Cross Vector From Up & Origin */
2058   pvx = Y0*Zup - Z0*Yup ;
2059   pvy = Z0*Xup - X0*Zup ;
2060   pvz = X0*Yup - Y0*Xup ;
2061   pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2062   sca = X0*Xup + Y0*Yup + Z0*Zup ;
2063   /* Compute Angle */
2064   angle = Sqrt(pvn) ;
2065   if( angle > 1. ) angle = 1. ;
2066   else if( angle < -1. ) angle = -1. ;
2067   angle = asin(angle) ;
2068   if( sca < 0. ) angle = M_PI - angle ;
2069   if( angle > 0. && angle < M_PI ) {
2070     sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2071     if( sca < 0. ) angle = DEUXPI - angle ;
2072   }
2073   return angle ;
2074 }
2075
2076 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2077 {
2078   V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2079   return SM ;
2080 }
2081
2082 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2083 {
2084   V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2085   return SM ;
2086 }
2087
2088 Handle_Graphic3d_TextureEnv V3d_View::TextureEnv() const
2089 {
2090   Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2091   return SM ;
2092 }
2093
2094 V3d_TypeOfVisualization V3d_View::Visualization() const
2095 {
2096   V3d_TypeOfVisualization V =
2097     (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2098   return V ;
2099 }
2100
2101 Standard_Boolean V3d_View::Antialiasing() const
2102 {
2103   Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2104   return A ;
2105 }
2106
2107 Handle(V3d_Viewer) V3d_View::Viewer() const
2108 {
2109   return MyViewer ;
2110 }
2111
2112 Standard_Boolean V3d_View::IfWindow() const
2113 {
2114   Standard_Boolean TheStatus = MyView->IsDefined() ;
2115   return TheStatus ;
2116 }
2117
2118 Handle(Aspect_Window) V3d_View::Window() const
2119 {
2120   return MyWindow;
2121 }
2122
2123 V3d_TypeOfView V3d_View::Type() const
2124 {
2125   return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2126 }
2127
2128 void V3d_View::SetFocale( const Standard_Real focale )
2129 {
2130   if (myCamera->IsOrthographic())
2131   {
2132     return;
2133   }
2134
2135   Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2136
2137   myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2138
2139   ImmediateUpdate();
2140 }
2141
2142 Standard_Real V3d_View::Focale() const
2143 {
2144   if (myCamera->IsOrthographic())
2145   {
2146     return 0.0;
2147   }
2148
2149   return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2150 }
2151
2152 void V3d_View::SetViewingVolume(const Standard_Real Left, const Standard_Real Right,
2153                                 const Standard_Real Bottom, const Standard_Real Top,
2154                                 const Standard_Real ZNear, const Standard_Real ZFar)
2155 {
2156   V3d_BadValue_Raise_if (ZNear >= ZFar, "V3d_View::SetVolume, bad distances");
2157
2158
2159   myCamera->BeginUpdate();
2160
2161   myCamera->SetZFar (ZFar);
2162   myCamera->SetZNear (ZNear);
2163
2164   myCamera->SetScale (Top - Bottom);
2165   myCamera->SetAspect ((Right - Left) / (Top - Bottom));
2166   gp_Pnt aCameraProjShift (-(Left + Right) / 2.0, -(Bottom + Top) / 2.0, 0.0);
2167   myCamera->SetProjectionShift (aCameraProjShift);
2168   if (myCamera->IsOrthographic())
2169   {
2170     myCamera->SetDistance (Abs (ZNear));
2171   }
2172   AutoZFit();
2173   myCamera->EndUpdate();
2174
2175   ImmediateUpdate();
2176 }
2177
2178 Handle(Visual3d_View) V3d_View::View() const
2179 {
2180   return MyView ;
2181 }
2182
2183 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2184 {
2185   Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2186   Standard_Real dx1, dy1, dz1, xx, yy, zz;
2187
2188   Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2189   Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2190   xx = Yup*Zpn - Zup*Ypn;
2191   yy = Zup*Xpn - Xup*Zpn;
2192   zz = Xup*Ypn - Yup*Xpn;
2193   Xaxe.SetCoord (xx, yy, zz);
2194   if (Xaxe.LengthZero()) return Standard_False;
2195   Xaxe.Normalize(); 
2196   Xaxe.Coord(dx1, dy1, dz1);
2197   xx = Ypn*dz1 - Zpn*dy1;
2198   yy = Zpn*dx1 - Xpn*dz1;
2199   zz = Xpn*dy1 - Ypn*dx1;
2200   Yaxe.SetCoord (xx, yy, zz) ;
2201   if (Yaxe.LengthZero()) return Standard_False;
2202   Yaxe.Normalize(); 
2203
2204   Zaxe.SetCoord (Xpn, Ypn, Zpn);
2205   Zaxe.Normalize();
2206   return Standard_True;
2207 }
2208
2209 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2210 {
2211   Graphic3d_Vertex PP ;
2212   Standard_Real X,Y,Z,XX,YY,ZZ ;
2213
2214   // CAL. S3892
2215   Standard_Integer lr, ur, lc, uc;
2216   lr    = Matrix.LowerRow ();
2217   ur    = Matrix.UpperRow ();
2218   lc    = Matrix.LowerCol ();
2219   uc    = Matrix.UpperCol ();
2220   if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2221     P.Coord(X,Y,Z) ;
2222     PP.SetCoord(X,Y,Z) ;
2223     return PP ;
2224   }
2225   P.Coord(X,Y,Z) ;
2226   XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2227     Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2228
2229   YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2230     Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2231
2232   ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2233     Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2234   PP.SetCoord(XX,YY,ZZ) ;
2235   return PP ;
2236 }
2237
2238 void V3d_View::Pan(const Standard_Integer Dx, const Standard_Integer Dy,const Quantity_Factor aZoomFactor)
2239 {
2240   Panning (Convert(Dx), Convert(Dy), aZoomFactor, Standard_True);
2241 }
2242
2243 void V3d_View::Zoom (const Standard_Integer X1,
2244                      const Standard_Integer Y1,
2245                      const Standard_Integer X2,
2246                      const Standard_Integer Y2)
2247 {
2248
2249   Standard_Real dx = Standard_Real (X2-X1);
2250   Standard_Real dy = Standard_Real (Y2-Y1);
2251   if ( dx != 0. || dy != 0. ) {
2252     Standard_Real dzoom = Sqrt(dx*dx + dy*dy) / 100. + 1;
2253     dzoom = (dx > 0) ?  dzoom : 1./dzoom;
2254     SetZoom(dzoom, Standard_True);
2255   }
2256 }
2257
2258 void V3d_View::Zoom (const Standard_Integer X1,
2259                      const Standard_Integer Y1)
2260 {
2261   Standard_Real x,y;
2262   Center(x,y);
2263   Standard_Integer ix,iy;
2264   Convert(x,y,ix,iy);
2265   Zoom(ix,iy,X1,Y1);
2266 }
2267
2268 // Defines the point (pixel) of zooming (for the method ZoomAtPoint()).
2269 void V3d_View::StartZoomAtPoint(const Standard_Integer xpix, const Standard_Integer ypix)
2270 {
2271     MyZoomAtPointX = xpix;
2272     MyZoomAtPointY = ypix;
2273 }
2274
2275 // Zooms the model at a pixel defined by the method StartZoomAtPoint().
2276 void V3d_View::ZoomAtPoint(const Standard_Integer mouseStartX,
2277                            const Standard_Integer mouseStartY,
2278                            const Standard_Integer mouseEndX,
2279                            const Standard_Integer mouseEndY)
2280 {
2281     Standard_Boolean update;
2282     V3d_Coordinate X0, Y0, XS, YS;
2283
2284     // Forbid any update.
2285     update = SetImmediateUpdate(Standard_False);
2286
2287     // Get center point
2288     Center(X0, Y0);
2289
2290     // Pan the point to the center of window.
2291     Convert(MyZoomAtPointX, MyZoomAtPointY, XS, YS);
2292     Panning(X0-XS, Y0-YS);
2293
2294     // Zoom
2295     Standard_Real d = Standard_Real ((mouseEndX + mouseEndY) - (mouseStartX + mouseStartY));
2296
2297     Standard_Real dzoom = fabs(d) / 100.0 + 1.0;
2298     dzoom = (d > 0) ?  dzoom : 1.0 / dzoom;
2299     V3d_BadValue_Raise_if( dzoom <= 0.,"V3d_View::ZoomAtPoint, bad coefficient");
2300
2301     Standard_Real aViewWidth  = myCamera->ViewDimensions().X();
2302     Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2303
2304     // Ensure that zoom will not be too small or too big.
2305     Standard_Real coef = dzoom;
2306     if (aViewWidth < coef * Precision::Confusion())
2307     {
2308       coef = aViewWidth / Precision::Confusion();
2309     }
2310     else if (aViewWidth > coef * 1e12)
2311     {
2312       coef = aViewWidth / 1e12;
2313     }
2314     if (aViewHeight < coef * Precision::Confusion())
2315     {
2316       coef = aViewHeight / Precision::Confusion();
2317     }
2318     else if (aViewHeight > coef * 1e12)
2319     {
2320       coef = aViewHeight / 1e12;
2321     }
2322
2323     V3d_Coordinate Dxv = (XS - X0) / coef;
2324     V3d_Coordinate Dyv = (YS - Y0) / coef;
2325
2326     myCamera->SetScale (myCamera->Scale() / coef);
2327     PanCamera (-Dxv, -Dyv);
2328
2329     AutoZFit();
2330
2331     // Update the view.
2332     SetImmediateUpdate(update);
2333     ImmediateUpdate();
2334 }
2335
2336 void V3d_View::AxialScale (const Standard_Integer Dx,
2337                            const Standard_Integer Dy,
2338                            const V3d_TypeOfAxe Axis)
2339 {
2340   if( Dx != 0. || Dy != 0. ) {
2341     Standard_Real Sx, Sy, Sz;
2342     AxialScale( Sx, Sy, Sz );
2343     Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2344     dscale = (Dx > 0) ?  dscale : 1./dscale;
2345     if( Axis == V3d_X ) Sx = dscale;
2346     if( Axis == V3d_Y ) Sy = dscale;
2347     if( Axis == V3d_Z ) Sz = dscale;
2348     SetAxialScale( Sx, Sy, Sz );
2349   }
2350 }
2351
2352
2353 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2354                       const Standard_Real Xmin,
2355                       const Standard_Real Ymin,
2356                       const Standard_Real Xmax,
2357                       const Standard_Real Ymax)
2358 {
2359   // normalize view coordinates
2360   Standard_Integer aWinWidth, aWinHeight;
2361   aWindow->Size (aWinWidth, aWinHeight);
2362
2363   // compute camera panning
2364   gp_Vec aPanVec ((Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5, 0.0);
2365
2366   // compute section size
2367   gp_Pnt aViewBotLeft (Xmin, Ymin, 0.0);
2368   gp_Pnt aViewTopRight (Xmax, Ymax, 0.0);
2369
2370   Standard_Real aUSize = Abs (Xmax - Xmin);
2371   Standard_Real aVSize = Abs (Ymax - Ymin);
2372
2373   myCamera->BeginUpdate();
2374   myCamera->SetProjectionShift (gp_Pnt (0.0, 0.0, 0.0));
2375   PanCamera (aPanVec.X(), aPanVec.Y());
2376   ZoomCamera (aUSize, aVSize);
2377   myCamera->EndUpdate();
2378
2379   AutoZFit();
2380
2381   Update();
2382 }
2383
2384 #ifdef IMP250900
2385 static Standard_Boolean zRotation = Standard_False;
2386 #endif
2387 void V3d_View::StartRotation(const Standard_Integer X,
2388                              const Standard_Integer Y,
2389                              const Quantity_Ratio zRotationThreshold)
2390 {
2391   sx = X; sy = Y;
2392   Standard_Real x,y;
2393   Size(x,y);
2394   rx = Standard_Real(Convert(x));
2395   ry = Standard_Real(Convert(y));
2396   Gravity(gx,gy,gz);
2397   Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2398 #ifdef IMP250900
2399   zRotation = Standard_False;
2400   if( zRotationThreshold > 0. ) {
2401     Standard_Real dx = Abs(sx - rx/2.);
2402     Standard_Real dy = Abs(sy - ry/2.);
2403     //  if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2404     Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2405     if( dx > dd || dy > dd ) zRotation = Standard_True;
2406   }
2407 #endif
2408
2409 }
2410
2411 void V3d_View::Rotation(const Standard_Integer X,
2412                         const Standard_Integer Y)
2413 {
2414 #ifdef IMP210600
2415   if( rx == 0. || ry == 0. ) {
2416     StartRotation(X,Y);
2417     return;
2418   }
2419 #endif
2420 #ifdef IMP250900
2421   Standard_Real dx=0.,dy=0.,dz=0.;
2422   if( zRotation ) {
2423     dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2424       atan2(sx-rx/2.,ry/2.-sy);
2425   } else {
2426     dx = (Standard_Real(X) - sx) * M_PI / rx;
2427     dy = (sy - Standard_Real(Y)) * M_PI / ry;
2428   }
2429   Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2430 #else
2431   Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2432   Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
2433   Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2434 #endif
2435 #ifdef IMP020300
2436   if( !myImmediateUpdate ) Update();
2437 #else
2438   myImmediateUpdate = Standard_False;
2439   Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2440   ZFitAll (Zmargin);    //Don't do that, perf improvment
2441   myImmediateUpdate = Standard_True;
2442   ImmediateUpdate();
2443 #endif
2444 }
2445
2446 void V3d_View :: SetComputedMode ( const Standard_Boolean aMode )
2447 {
2448   if( aMode ) {
2449     if( myComputedMode ) {
2450       MyView -> SetComputedMode ( Standard_True );
2451       Update ();
2452     }
2453   } else {
2454     MyView -> SetComputedMode ( Standard_False );
2455     Update ();
2456   }
2457 }
2458
2459 Standard_Boolean V3d_View :: ComputedMode () const
2460 {
2461   return MyView -> ComputedMode ();
2462 }
2463
2464 void V3d_View :: SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2465 {
2466   MyView -> SetBackFacingModel ( Visual3d_TypeOfBackfacingModel(aModel) );
2467   Redraw();
2468 }
2469
2470 V3d_TypeOfBackfacingModel V3d_View :: BackFacingModel () const
2471 {
2472   return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2473 }
2474
2475 Standard_Boolean V3d_View::TransientManagerBeginDraw(const Standard_Boolean DoubleBuffer,const Standard_Boolean RetainMode) const
2476 {
2477   return Visual3d_TransientManager::BeginDraw(MyView,DoubleBuffer,RetainMode);
2478 }
2479
2480 void V3d_View::TransientManagerClearDraw() const
2481 {
2482   Visual3d_TransientManager::ClearDraw(MyView);
2483 }
2484
2485 Standard_Boolean V3d_View::TransientManagerBeginAddDraw() const
2486 {
2487   return Visual3d_TransientManager::BeginAddDraw(MyView);
2488 }
2489
2490 void V3d_View::Init()
2491 {
2492   myComputedMode = MyViewer->ComputedMode();
2493   if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
2494     SetComputedMode(Standard_False);
2495   }
2496 }
2497
2498 void V3d_View::SetPlotter(const Handle(Graphic3d_Plotter)& aPlotter)
2499 {
2500   MyPlotter = aPlotter;
2501 }
2502
2503 void V3d_View::Plot()
2504 {
2505   V3d_BadValue_Raise_if( !MyPlotter.IsNull(), "view has no plotter");
2506   MyView->Plot(MyPlotter);
2507 }
2508
2509 #include <Aspect.hxx>
2510 #include <Visual3d_Layer.hxx>
2511
2512 ////////////////////////////////////////////////////////////////
2513 Standard_Boolean V3d_View::Dump (const Standard_CString      theFile,
2514                                  const Graphic3d_BufferType& theBufferType)
2515 {
2516   Standard_Integer aWinWidth, aWinHeight;
2517   MyWindow->Size (aWinWidth, aWinHeight);
2518   Image_AlienPixMap anImage;
2519
2520   return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2521 }
2522
2523 ////////////////////////////////////////////////////////////////
2524 Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
2525                                      const Standard_Integer      theWidth,
2526                                      const Standard_Integer      theHeight,
2527                                      const Graphic3d_BufferType& theBufferType,
2528                                      const Standard_Boolean      theIsForceCentred,
2529                                      const V3d_StereoDumpOptions theStereoOptions)
2530 {
2531   Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
2532
2533   // always prefer hardware accelerated offscreen buffer
2534   Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
2535   Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
2536   Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
2537   Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
2538   if (aPrevFBOPtr != NULL)
2539   {
2540     MyView->FBOGetDimensions (aPrevFBOPtr,
2541                               aPrevFBOVPSizeX, aPrevFBOVPSizeY,
2542                               aPrevFBOSizeXMax, aPrevFBOSizeYMax);
2543     if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
2544     {
2545       MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2546       aFBOPtr = aPrevFBOPtr;
2547     }
2548   }
2549
2550   if (aFBOPtr == NULL)
2551   {
2552     // Try to create hardware accelerated buffer
2553     aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
2554     if (aFBOPtr != NULL)
2555     {
2556       MyView->FBOGetDimensions (aFBOPtr,
2557                                 aFBOVPSizeX,  aFBOVPSizeY,
2558                                 aFBOSizeXMax, aFBOSizeYMax);
2559       // reduce viewport in case of hardware limits
2560       if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
2561       if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
2562       MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2563     }
2564   }
2565   cView->ptrFBO = aFBOPtr;
2566
2567   // If hardware accelerated buffer - try to use onscreen buffer
2568   // Results may be bad!
2569   if (aFBOPtr == NULL)
2570   {
2571     // retrieve window sizes
2572     Standard_Integer aWinWidth, aWinHeight;
2573     MyWindow->Size (aWinWidth, aWinHeight);
2574
2575     // technically we can reduce existing viewport...
2576     // but currently allow only dumping the window itself
2577     if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
2578     {
2579       return Standard_False;
2580     }
2581   }
2582
2583   Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2584
2585   aStoreMapping->Copy (myCamera);
2586   Standard_Real Umin, Vmin, Umax, Vmax;
2587
2588   if (myCamera->IsStereo())
2589   {
2590     switch (theStereoOptions)
2591     {
2592       case V3d_SDO_MONO :
2593         myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2594         break;
2595
2596       case V3d_SDO_LEFT_EYE :
2597         myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2598         break;
2599
2600       case V3d_SDO_RIGHT_EYE :
2601         myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2602         break;
2603     }
2604   }
2605
2606   if (theIsForceCentred)
2607   {
2608     Standard_Real PUmin, PVmin, PUmax, PVmax;
2609     myCamera->WindowLimit (PUmin, PVmin, PUmax, PVmax);
2610
2611     // calculate expansion
2612     Umin = PUmin; Vmin = PVmin; Umax = PUmax; Vmax = PVmax;
2613     Standard_Real oldWidth = (PUmax - PUmin), oldHeight = (PVmax - PVmin);
2614     Standard_Real newWidth = (oldHeight * aFBOVPSizeX) / aFBOVPSizeY;
2615     if (newWidth < oldWidth)
2616     {
2617       Standard_Real newHeight = (oldWidth * aFBOVPSizeY) / aFBOVPSizeX;
2618       // Expand height
2619       Standard_Real delta = 0.5 * (newHeight - oldHeight);
2620       Vmin = PVmin - delta;
2621       Vmax = PVmax + delta;
2622     }
2623     else
2624     {
2625       // Expand width
2626       Standard_Real delta = 0.5 * (newWidth - oldWidth);
2627       Umin = PUmin - delta;
2628       Umax = PUmax + delta;
2629     }
2630
2631     FitAll (Umin, Vmin, Umax, Vmax);
2632   }
2633
2634   //workaround for rendering list of Over and Under Layers
2635   if (!MyLayerMgr.IsNull())
2636   {
2637     MyLayerMgr->Compute();
2638   }
2639
2640   // render immediate structures into back buffer rather than front
2641   Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
2642   const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
2643   Redraw();
2644
2645   if (!aDriver.IsNull())
2646   {
2647     aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
2648   }
2649
2650   myCamera->Copy (aStoreMapping);
2651
2652   Standard_Boolean isSuccess = Standard_True;
2653
2654   // allocate image buffer for dumping
2655   if (theImage.IsEmpty()
2656    || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
2657    || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
2658   {
2659     bool isBigEndian = Image_PixMap::IsBigEndianHost();
2660     Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2661     switch (theBufferType)
2662     {
2663       case Graphic3d_BT_RGB:   aFormat = isBigEndian ? Image_PixMap::ImgRGB  : Image_PixMap::ImgBGR;  break;
2664       case Graphic3d_BT_RGBA:  aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2665       case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2666     }
2667
2668     isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
2669   }
2670   isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
2671
2672   // FBO now useless, free resources
2673   if (aFBOPtr != aPrevFBOPtr)
2674   {
2675     MyView->FBORelease (aFBOPtr);
2676   }
2677   else if (aPrevFBOPtr != NULL)
2678   {
2679     MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
2680   }
2681   cView->ptrFBO = aPrevFBOPtr;
2682   return isSuccess;
2683 }
2684
2685 void V3d_View::ImmediateUpdate() const
2686 {
2687   if (myImmediateUpdate) Update();
2688 }
2689
2690 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2691 {
2692   Standard_Boolean aPreviousMode = myImmediateUpdate;
2693   myImmediateUpdate = theImmediateUpdate;
2694   return aPreviousMode;
2695 }
2696
2697 // =======================================================================
2698 // function : SetCamera
2699 // purpose  :
2700 // =======================================================================
2701 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2702 {
2703   myCamera = theCamera;
2704
2705   MyView->SetCamera (theCamera);
2706 }
2707
2708 // =======================================================================
2709 // function : GetCamera
2710 // purpose  :
2711 // =======================================================================
2712 Handle(Graphic3d_Camera) V3d_View::Camera() const
2713 {
2714   return myCamera;
2715 }
2716
2717 // =======================================================================
2718 // function : FitCamera
2719 // purpose  :
2720 // =======================================================================
2721 void V3d_View::FitCamera (const Standard_Real theXmin,
2722                           const Standard_Real theYmin,
2723                           const Standard_Real theZmin,
2724                           const Standard_Real theXmax,
2725                           const Standard_Real theYmax,
2726                           const Standard_Real theZmax)
2727 {
2728   if (myCamera.IsNull())
2729     return;
2730
2731   // check bounding box for validness
2732   Standard_Real aLim = (ShortRealLast() - 1.0);
2733   if (Abs (theXmin) > aLim || Abs (theYmin) > aLim || Abs (theZmin) > aLim ||
2734       Abs (theXmax) > aLim || Abs (theYmax) > aLim || Abs (theZmax) > aLim)
2735     return;
2736
2737   // place camera center at the geometrical center
2738   // of the passed bounding box
2739   gp_Pnt aCenter ((theXmin + theXmax) * 0.5,
2740                   (theYmin + theYmax) * 0.5,
2741                   (theZmin + theZmax) * 0.5);
2742
2743   // adapt bound points
2744   gp_Pnt aPnts[8] = 
2745     { gp_Pnt (theXmin, theYmin, theZmin),
2746       gp_Pnt (theXmin, theYmin, theZmax),
2747       gp_Pnt (theXmin, theYmax, theZmin),
2748       gp_Pnt (theXmin, theYmax, theZmax),
2749       gp_Pnt (theXmax, theYmin, theZmin),
2750       gp_Pnt (theXmax, theYmin, theZmax),
2751       gp_Pnt (theXmax, theYmax, theZmin),
2752       gp_Pnt (theXmax, theYmax, theZmax) };
2753
2754   Standard_Real aViewMinX = (RealLast() - 1);
2755   Standard_Real aViewMinY = (RealLast() - 1);
2756   Standard_Real aViewMinZ = (RealLast() - 1);
2757   Standard_Real aViewMaxX = (RealFirst() + 1);
2758   Standard_Real aViewMaxY = (RealFirst() + 1);
2759   Standard_Real aViewMaxZ = (RealFirst() + 1);
2760
2761   // find out minimum and maximum values of bounding box
2762   // converted to view space. the limits point out a rectangular
2763   // section parallel to the screen that camera should zoom in.
2764   for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2765   {
2766     gp_Pnt aView = myCamera->ConvertWorld2View (aPnts[aPntIt]);
2767     aViewMinX = Min (aViewMinX, aView.X());
2768     aViewMinY = Min (aViewMinY, aView.Y());
2769     aViewMaxX = Max (aViewMaxX, aView.X());
2770     aViewMaxY = Max (aViewMaxY, aView.Y());
2771     aViewMinZ = Min (aViewMinZ, aView.Z());
2772     aViewMaxZ = Max (aViewMaxZ, aView.Z());
2773   }
2774
2775   // evaluate section size for x1 zoom.
2776   Standard_Real aSectU  = (aViewMaxX - aViewMinX);
2777   Standard_Real aSectV  = (aViewMaxY - aViewMinY);
2778
2779   // zoom camera to front plane of bounding box. the camera
2780   // is set up at the center of bbox, so the depth is half
2781   // space of it in view coordinate space.
2782   Standard_Real aSectDepth = (aViewMaxZ - aViewMinZ) * 0.5;
2783
2784   // re-compute Eye position
2785   gp_Vec aBck = gp_Vec (myCamera->Center(), myCamera->Eye());
2786   gp_Pnt aEye = aCenter.Translated (aBck);
2787
2788   // start camera updates
2789   myCamera->BeginUpdate();
2790
2791   if (myCamera->IsOrthographic())
2792   {
2793     Standard_Real anX = (aViewMaxX + aViewMinX) * 0.5; 
2794     Standard_Real anY = (aViewMaxY + aViewMinY) * 0.5;
2795     myCamera->SetProjectionShift (gp_Pnt (-anX, -anY, 0.0));
2796   }
2797   else
2798   {
2799     myCamera->SetProjectionShift (gp_Pnt (0.0, 0.0, 0.0));
2800     myCamera->SetCenter (aCenter);
2801     myCamera->SetEye (aEye);
2802   }
2803
2804   // zoom camera to fit in the bounding box.
2805   ZoomCamera (aSectU, aSectV, aSectDepth);
2806
2807   // re-evaluate camera
2808   myCamera->EndUpdate();
2809 }
2810
2811 // =======================================================================
2812 // function : ZoomCamera
2813 // purpose  :
2814 // =======================================================================
2815 void V3d_View::ZoomCamera (const Standard_Real theUSize,
2816                            const Standard_Real theVSize,
2817                            const Standard_Real theZDepth)
2818 {
2819   if (myCamera.IsNull())
2820     return;
2821
2822   // compute maximum section size along both directions.
2823   Standard_Real anAspect = myCamera->Aspect();
2824   Standard_Real aSize = Max (theUSize / anAspect, theVSize);
2825
2826   myCamera->BeginUpdate();
2827   myCamera->SetScale (aSize);
2828
2829   if (!myCamera->IsOrthographic())
2830   {
2831     myCamera->SetDistance (myCamera->Distance() + theZDepth);
2832   }
2833
2834   AutoZFit();
2835
2836   myCamera->EndUpdate();
2837 }
2838
2839 // =======================================================================
2840 // function : PanCamera
2841 // purpose  : panning is fun
2842 // =======================================================================
2843 void V3d_View::PanCamera (const Standard_Real theU,
2844                           const Standard_Real theV)
2845 {
2846   if (myCamera.IsNull())
2847     return;
2848
2849   if (myCamera->IsOrthographic())
2850   {
2851     // Projection based panning for compatibility.
2852     myCamera->SetProjectionShift (myCamera->ProjectionShift().
2853       Translated (gp_Vec (-theU, -theV, 0.0)));
2854   } 
2855   else
2856   {
2857     gp_Vec anUp = myCamera->Up();
2858     gp_Vec aSide  = myCamera->Direction().Crossed (anUp);
2859
2860     gp_Vec aPanU = aSide.Scaled (theU);
2861     gp_Vec aPanV = anUp.Scaled (theV);
2862     gp_Pnt aPannedEye (myCamera->Eye());
2863     gp_Pnt aPannedCenter (myCamera->Center());
2864
2865     aPannedEye.Translate (aPanU);
2866     aPannedEye.Translate (aPanV);
2867     aPannedCenter.Translate (aPanU);
2868     aPannedCenter.Translate (aPanV);
2869
2870     myCamera->BeginUpdate();
2871     myCamera->SetEye (aPannedEye);
2872     myCamera->SetCenter (aPannedCenter);
2873     myCamera->EndUpdate();
2874   }
2875
2876   AutoZFit();
2877 }