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