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