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