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