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