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