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