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