b67123ac8597326a613ec53d4a3cc7b26a1fca1d
[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 theOrientation,
1023                         const Standard_Boolean theIsYup)
1024 {
1025   Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1026   if (theIsYup)
1027   {
1028     if (theOrientation == V3d_Ypos
1029      || theOrientation == V3d_Yneg)
1030     {
1031       anUp.SetValues (0.0, 0.0, -1.0);
1032     }
1033   }
1034   else
1035   {
1036     if (theOrientation == V3d_Zpos)
1037     {
1038       anUp.SetValues (0.0, 1.0, 0.0);
1039     }
1040     else if (theOrientation == V3d_Zneg)
1041     {
1042       anUp.SetValues (0.0, -1.0, 0.0);
1043     }
1044   }
1045
1046   const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
1047
1048   // retain camera panning from origin when switching projection
1049   const Handle(Graphic3d_Camera)& aCamera = Camera();
1050   const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1051
1052   aCamera->SetCenter (gp_Pnt (0, 0, 0));
1053   aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1054   aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
1055   aCamera->OrthogonalizeUp();
1056
1057   Panning (anOriginVCS.X(), anOriginVCS.Y());
1058
1059   AutoZFit();
1060
1061   ImmediateUpdate();
1062 }
1063
1064 //=============================================================================
1065 //function : SetAt
1066 //purpose  :
1067 //=============================================================================
1068 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1069 {
1070   Standard_Real aTwistBefore = Twist();
1071
1072   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1073
1074   Camera()->SetCenter (gp_Pnt (X, Y, Z));
1075
1076   SetTwist (aTwistBefore);
1077
1078   AutoZFit();
1079
1080   SetImmediateUpdate (wasUpdateEnabled);
1081
1082   ImmediateUpdate();
1083 }
1084
1085 //=============================================================================
1086 //function : SetUp
1087 //purpose  :
1088 //=============================================================================
1089 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1090 {
1091   Handle(Graphic3d_Camera) aCamera = Camera();
1092
1093   const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1094   const gp_Dir anUp (theVx, theVy, theVz);
1095   if (!screenAxis (aReferencePlane, anUp,     myXscreenAxis, myYscreenAxis, myZscreenAxis)
1096    && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1097    && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1098    && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1099   {
1100     throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1101   }
1102
1103   aCamera->SetUp (gp_Dir (myYscreenAxis));
1104
1105   AutoZFit();
1106
1107   ImmediateUpdate();
1108 }
1109
1110 //=============================================================================
1111 //function : SetUp
1112 //purpose  :
1113 //=============================================================================
1114 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1115 {
1116   Handle(Graphic3d_Camera) aCamera = Camera();
1117
1118   const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1119   const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1120   if (!screenAxis (aReferencePlane, anUp,     myXscreenAxis, myYscreenAxis, myZscreenAxis)
1121    && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1122    && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1123    && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1124   {
1125     throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1126   }
1127
1128   aCamera->SetUp (gp_Dir (myYscreenAxis));
1129
1130   AutoZFit();
1131
1132   ImmediateUpdate();
1133 }
1134
1135 //=============================================================================
1136 //function : SetViewOrientationDefault
1137 //purpose  :
1138 //=============================================================================
1139 void V3d_View::SetViewOrientationDefault()
1140 {
1141   myDefaultCamera->CopyOrientationData (Camera());
1142 }
1143
1144 //=======================================================================
1145 //function : SetViewMappingDefault
1146 //purpose  :
1147 //=======================================================================
1148 void V3d_View::SetViewMappingDefault()
1149 {
1150   myDefaultCamera->CopyMappingData (Camera());
1151 }
1152
1153 //=============================================================================
1154 //function : ResetViewOrientation
1155 //purpose  :
1156 //=============================================================================
1157 void V3d_View::ResetViewOrientation()
1158 {
1159   Camera()->CopyOrientationData (myDefaultCamera);
1160
1161   AutoZFit();
1162
1163   ImmediateUpdate();
1164 }
1165
1166 //=======================================================================
1167 //function : ResetViewMapping
1168 //purpose  :
1169 //=======================================================================
1170 void V3d_View::ResetViewMapping()
1171 {
1172   Camera()->CopyMappingData (myDefaultCamera);
1173
1174   AutoZFit();
1175
1176   ImmediateUpdate();
1177 }
1178
1179 //=============================================================================
1180 //function : Reset
1181 //purpose  :
1182 //=============================================================================
1183 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1184 {
1185   Camera()->Copy (myDefaultCamera);
1186
1187   AutoZFit();
1188
1189   SwitchSetFront = Standard_False;
1190
1191   if (myImmediateUpdate || theToUpdate)
1192   {
1193     Update();
1194   }
1195 }
1196
1197 //=======================================================================
1198 //function : SetCenter
1199 //purpose  :
1200 //=======================================================================
1201 void V3d_View::SetCenter (const Standard_Integer theXp,
1202                           const Standard_Integer theYp)
1203 {
1204   Standard_Real aXv, aYv;
1205   Convert (theXp, theYp, aXv, aYv);
1206   Translate (Camera(), aXv, aYv);
1207
1208   ImmediateUpdate();
1209 }
1210
1211 //=============================================================================
1212 //function : SetSize
1213 //purpose  :
1214 //=============================================================================
1215 void V3d_View::SetSize (const Standard_Real theSize)
1216 {
1217   V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1218
1219   Handle(Graphic3d_Camera) aCamera = Camera();
1220
1221   aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1222
1223   AutoZFit();
1224
1225   ImmediateUpdate();
1226 }
1227
1228 //=============================================================================
1229 //function : SetZSize
1230 //purpose  :
1231 //=============================================================================
1232 void V3d_View::SetZSize (const Standard_Real theSize)
1233 {
1234   Handle(Graphic3d_Camera) aCamera = Camera();
1235
1236   Standard_Real Zmax = theSize / 2.;
1237
1238   Standard_Real aDistance = aCamera->Distance();
1239
1240   if (theSize <= 0.)
1241   {
1242     Zmax = aDistance;
1243   }
1244
1245   // ShortReal precision factor used to add meaningful tolerance to
1246   // ZNear, ZFar values in order to avoid equality after type conversion
1247   // to ShortReal matrices type.
1248   const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1249
1250   Standard_Real aZFar  =  Zmax  + aDistance * 2.0;
1251   Standard_Real aZNear = -Zmax  + aDistance;
1252   aZNear              -= Abs (aZNear) * aPrecision;
1253   aZFar               += Abs (aZFar)  * aPrecision;
1254
1255   if (!aCamera->IsOrthographic())
1256   {
1257     if (aZFar < aPrecision)
1258     {
1259       // Invalid case when both values are negative
1260       aZNear = aPrecision;
1261       aZFar  = aPrecision * 2.0;
1262     }
1263     else if (aZNear < Abs (aZFar) * aPrecision)
1264     {
1265       // Z is less than 0.0, try to fix it using any appropriate z-scale
1266       aZNear = Abs (aZFar) * aPrecision;
1267     }
1268   }
1269
1270   // If range is too small
1271   if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1272   {
1273     aZFar = aZNear + Abs (aZFar) * aPrecision;
1274   }
1275
1276   aCamera->SetZRange (aZNear, aZFar);
1277
1278   if (myImmediateUpdate)
1279   {
1280     Redraw();
1281   }
1282 }
1283
1284 //=============================================================================
1285 //function : SetZoom
1286 //purpose  :
1287 //=============================================================================
1288 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1289 {
1290   V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1291
1292   Handle(Graphic3d_Camera) aCamera = Camera();
1293
1294   if (theToStart)
1295   {
1296     myCamStartOpEye    = aCamera->Eye();
1297     myCamStartOpCenter = aCamera->Center();
1298   }
1299
1300   Standard_Real aViewWidth  = aCamera->ViewDimensions().X();
1301   Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1302
1303   // ensure that zoom will not be too small or too big
1304   Standard_Real aCoef = theCoef;
1305   if (aViewWidth < aCoef * Precision::Confusion())
1306   {
1307     aCoef = aViewWidth / Precision::Confusion();
1308   }
1309   else if (aViewWidth > aCoef * 1e12)
1310   {
1311     aCoef = aViewWidth / 1e12;
1312   }
1313   if (aViewHeight < aCoef * Precision::Confusion())
1314   {
1315     aCoef = aViewHeight / Precision::Confusion();
1316   }
1317   else if (aViewHeight > aCoef * 1e12)
1318   {
1319     aCoef = aViewHeight / 1e12;
1320   }
1321
1322   aCamera->SetEye (myCamStartOpEye);
1323   aCamera->SetCenter (myCamStartOpCenter);
1324   aCamera->SetScale (aCamera->Scale() / aCoef);
1325
1326   AutoZFit();
1327
1328   ImmediateUpdate();
1329 }
1330
1331 //=============================================================================
1332 //function : SetScale
1333 //purpose  :
1334 //=============================================================================
1335 void V3d_View::SetScale( const Standard_Real Coef )
1336 {
1337   V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1338
1339   Handle(Graphic3d_Camera) aCamera = Camera();
1340
1341   Standard_Real aDefaultScale = myDefaultCamera->Scale();
1342   aCamera->SetAspect (myDefaultCamera->Aspect());
1343   aCamera->SetScale (aDefaultScale / Coef);
1344
1345   AutoZFit();
1346
1347   ImmediateUpdate();
1348 }
1349
1350 //=============================================================================
1351 //function : SetAxialScale
1352 //purpose  :
1353 //=============================================================================
1354 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1355 {
1356   V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1357
1358   Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1359
1360   AutoZFit();
1361 }
1362
1363 //=============================================================================
1364 //function : SetRatio
1365 //purpose  :
1366 //=============================================================================
1367 void V3d_View::SetRatio()
1368 {
1369   if (MyWindow.IsNull())
1370   {
1371     return;
1372   }
1373
1374   Standard_Integer aWidth  = 0;
1375   Standard_Integer aHeight = 0;
1376   MyWindow->Size (aWidth, aHeight);
1377   if (aWidth > 0 && aHeight > 0)
1378   {
1379     Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1380                            static_cast<Standard_Real> (aHeight);
1381
1382     Camera()       ->SetAspect (aRatio);
1383     myDefaultCamera->SetAspect (aRatio);
1384   }
1385 }
1386
1387 //=============================================================================
1388 //function : FitAll
1389 //purpose  :
1390 //=============================================================================
1391 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1392 {
1393   FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1394 }
1395
1396 //=============================================================================
1397 //function : FitAll
1398 //purpose  :
1399 //=============================================================================
1400 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1401 {
1402   Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1403
1404   if (myView->NumberOfDisplayedStructures() == 0)
1405   {
1406     return;
1407   }
1408
1409   if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1410   {
1411     return;
1412   }
1413
1414   AutoZFit();
1415
1416   if (myImmediateUpdate || theToUpdate)
1417   {
1418     Update();
1419   }
1420 }
1421
1422 //=============================================================================
1423 //function : DepthFitAll
1424 //purpose  :
1425 //=============================================================================
1426 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1427                            const Standard_Real Margin)
1428 {
1429   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1430   Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1431   Standard_Real Dx,Dy,Dz,Size;
1432
1433   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1434
1435   if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1436     ImmediateUpdate();
1437     return ;
1438   }
1439
1440   Bnd_Box aBox = myView->MinMaxValues();
1441   if (aBox.IsVoid())
1442   {
1443     ImmediateUpdate();
1444     return ;
1445   }
1446     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1447     Project (Xmin,Ymin,Zmin,U,V,W) ;
1448     Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1449     Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1450     Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1451     Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1452     Project (Xmin,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,Zmax,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,Ymin,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 (Xmax,Ymax,Zmin,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,Zmax,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     Project (Xmin,Ymax,Zmin,U,V,W) ;
1473     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1474     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1475     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1476
1477     // Adjust Z size
1478     Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1479     Dz = 2.*Wmax + Margin * Wmax;
1480
1481     // Compute depth value
1482     Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1483     Dx += Margin * Dx; Dy += Margin * Dy;
1484     Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1485     if( Size > 0. ) {
1486       SetZSize(Size) ;
1487       SetDepth( Aspect * Size / 2.);
1488     }
1489
1490     ImmediateUpdate();
1491 }
1492
1493 //=======================================================================
1494 //function : WindowFit
1495 //purpose  :
1496 //=======================================================================
1497 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1498                           const Standard_Integer theMinYp,
1499                           const Standard_Integer theMaxXp,
1500                           const Standard_Integer theMaxYp)
1501 {
1502   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1503
1504   Handle(Graphic3d_Camera) aCamera = Camera();
1505
1506   if (!aCamera->IsOrthographic())
1507   {
1508     // normalize view coordinates
1509     Standard_Integer aWinWidth, aWinHeight;
1510     MyWindow->Size (aWinWidth, aWinHeight);
1511
1512     // z coordinate of camera center
1513     Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1514
1515     // camera projection coordinate are in NDC which are normalized [-1, 1]
1516     Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp  - 1.0;
1517     Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp  - 1.0;
1518     Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1519     Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1520
1521     // compute camera panning
1522     gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1523     gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1524     gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1525     gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1526     gp_Vec aPanVec (aPanFrom, aPanTo);
1527
1528     // compute section size
1529     gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1530     gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1531     gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1532     gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1533
1534     Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1535     Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1536
1537     Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1538     Scale (aCamera, aUSize, aVSize);
1539     AutoZFit();
1540   }
1541   else
1542   {
1543     Standard_Real aX1, aY1, aX2, aY2;
1544     Convert (theMinXp, theMinYp, aX1, aY1);
1545     Convert (theMaxXp, theMaxYp, aX2, aY2);
1546     FitAll (aX1, aY1, aX2, aY2);
1547   }
1548
1549   SetImmediateUpdate (wasUpdateEnabled);
1550
1551   ImmediateUpdate();
1552 }
1553
1554 //=======================================================================
1555 //function : ConvertToGrid
1556 //purpose  :
1557 //=======================================================================
1558 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1559                              const Standard_Integer Yp,
1560                              Standard_Real& Xg,
1561                              Standard_Real& Yg,
1562                              Standard_Real& Zg) const
1563 {
1564   Graphic3d_Vertex aVrp;
1565   Standard_Real anX, anY, aZ;
1566   Convert (Xp, Yp, anX, anY, aZ);
1567   aVrp.SetCoord (anX, anY, aZ);
1568
1569   if( MyViewer->Grid()->IsActive() ) {
1570     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1571     aNewVrp.Coord (Xg,Yg,Zg) ;
1572   } else
1573     aVrp.Coord (Xg,Yg,Zg) ;
1574 }
1575
1576 //=======================================================================
1577 //function : ConvertToGrid
1578 //purpose  :
1579 //=======================================================================
1580 void V3d_View::ConvertToGrid(const Standard_Real X,
1581                              const Standard_Real Y,
1582                              const Standard_Real Z,
1583                              Standard_Real& Xg,
1584                              Standard_Real& Yg,
1585                              Standard_Real& Zg) const
1586 {
1587   if( MyViewer->Grid()->IsActive() ) {
1588     Graphic3d_Vertex aVrp (X,Y,Z) ;
1589     Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1590     aNewVrp.Coord(Xg,Yg,Zg) ;
1591   } else {
1592     Xg = X; Yg = Y; Zg = Z;
1593   }
1594 }
1595
1596 //=======================================================================
1597 //function : Convert
1598 //purpose  :
1599 //=======================================================================
1600 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1601 {
1602   Standard_Integer aDxw, aDyw ;
1603
1604   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1605
1606   MyWindow->Size (aDxw, aDyw);
1607   Standard_Real aValue;
1608
1609   gp_Pnt aViewDims = Camera()->ViewDimensions();
1610   aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1611
1612   return aValue;
1613 }
1614
1615 //=======================================================================
1616 //function : Convert
1617 //purpose  :
1618 //=======================================================================
1619 void V3d_View::Convert(const Standard_Integer Xp,
1620                        const Standard_Integer Yp,
1621                        Standard_Real& Xv,
1622                        Standard_Real& Yv) const
1623 {
1624   Standard_Integer aDxw, aDyw;
1625
1626   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1627
1628   MyWindow->Size (aDxw, aDyw);
1629
1630   gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1631   aPoint = Camera()->ConvertProj2View (aPoint);
1632
1633   Xv = aPoint.X();
1634   Yv = aPoint.Y();
1635 }
1636
1637 //=======================================================================
1638 //function : Convert
1639 //purpose  :
1640 //=======================================================================
1641 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1642 {
1643   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1644
1645   Standard_Integer aDxw, aDyw;
1646   MyWindow->Size (aDxw, aDyw);
1647
1648   gp_Pnt aViewDims = Camera()->ViewDimensions();
1649   Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1650
1651   return aValue;
1652 }
1653
1654 //=======================================================================
1655 //function : Convert
1656 //purpose  :
1657 //=======================================================================
1658 void V3d_View::Convert(const Standard_Real Xv,
1659                        const Standard_Real Yv,
1660                        Standard_Integer& Xp,
1661                        Standard_Integer& Yp) const
1662 {
1663   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1664
1665   Standard_Integer aDxw, aDyw;
1666   MyWindow->Size (aDxw, aDyw);
1667
1668   gp_Pnt aPoint (Xv, Yv, 0.0);
1669   aPoint = Camera()->ConvertView2Proj (aPoint);
1670   aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1671
1672   Xp = RealToInt (aPoint.X());
1673   Yp = RealToInt (aPoint.Y());
1674 }
1675
1676 //=======================================================================
1677 //function : Convert
1678 //purpose  :
1679 //=======================================================================
1680 void V3d_View::Convert(const Standard_Integer Xp,
1681                        const Standard_Integer Yp,
1682                        Standard_Real& X,
1683                        Standard_Real& Y,
1684                        Standard_Real& Z) const
1685 {
1686   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1687   Standard_Integer aHeight, aWidth;
1688   MyWindow->Size (aWidth, aHeight);
1689
1690   Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1691   Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1692   Standard_Real  aZ = 2.0 * 0.0 - 1.0;
1693
1694   gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1695
1696   X = aResult.X();
1697   Y = aResult.Y();
1698   Z = aResult.Z();
1699 }
1700
1701 //=======================================================================
1702 //function : ConvertWithProj
1703 //purpose  :
1704 //=======================================================================
1705 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1706                                const Standard_Integer theYp,
1707                                Standard_Real& theX,
1708                                Standard_Real& theY,
1709                                Standard_Real& theZ,
1710                                Standard_Real& theDx,
1711                                Standard_Real& theDy,
1712                                Standard_Real& theDz) const
1713 {
1714   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1715   Standard_Integer aHeight = 0, aWidth = 0;
1716   MyWindow->Size (aWidth, aHeight);
1717
1718   const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1719   const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1720   const Standard_Real  aZ = 2.0 * 0.0 - 1.0;
1721
1722   const Handle(Graphic3d_Camera)& aCamera = Camera();
1723   const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1724   const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1725
1726   theX = aResult1.X();
1727   theY = aResult1.Y();
1728   theZ = aResult1.Z();
1729   Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1730                             theY - aResult2.Y(),
1731                             theZ - aResult2.Z());
1732   aNormDir.Normalize();
1733
1734   theDx = aNormDir.x();
1735   theDy = aNormDir.y();
1736   theDz = aNormDir.z();
1737 }
1738
1739 //=======================================================================
1740 //function : Convert
1741 //purpose  :
1742 //=======================================================================
1743 void V3d_View::Convert(const Standard_Real X,
1744                        const Standard_Real Y,
1745                        const Standard_Real Z,
1746                        Standard_Integer& Xp,
1747                        Standard_Integer& Yp) const
1748 {
1749   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1750   Standard_Integer aHeight, aWidth;
1751   MyWindow->Size (aWidth, aHeight);
1752
1753   gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1754
1755   Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1756   Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1757 }
1758
1759 //=======================================================================
1760 //function : Project
1761 //purpose  :
1762 //=======================================================================
1763 void V3d_View::Project (const Standard_Real theX,
1764                         const Standard_Real theY,
1765                         const Standard_Real theZ,
1766                         Standard_Real& theXp,
1767                         Standard_Real& theYp) const
1768 {
1769   Standard_Real aZp;
1770   Project (theX, theY, theZ, theXp, theYp, aZp);
1771 }
1772
1773 //=======================================================================
1774 //function : Project
1775 //purpose  :
1776 //=======================================================================
1777 void V3d_View::Project (const Standard_Real theX,
1778                         const Standard_Real theY,
1779                         const Standard_Real theZ,
1780                         Standard_Real& theXp,
1781                         Standard_Real& theYp,
1782                         Standard_Real& theZp) const
1783 {
1784   Handle(Graphic3d_Camera) aCamera = Camera();
1785
1786   gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1787   Standard_Real aXSize = aViewSpaceDimensions.X();
1788   Standard_Real aYSize = aViewSpaceDimensions.Y();
1789   Standard_Real aZSize = aViewSpaceDimensions.Z();
1790
1791   gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1792
1793   // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1794   theXp = aPoint.X() * aXSize * 0.5;
1795   theYp = aPoint.Y() * aYSize * 0.5;
1796   theZp = aPoint.Z() * aZSize * 0.5;
1797 }
1798
1799 //=======================================================================
1800 //function : BackgroundColor
1801 //purpose  :
1802 //=======================================================================
1803 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1804                                Standard_Real& V1,
1805                                Standard_Real& V2,
1806                                Standard_Real& V3) const
1807 {
1808   Quantity_Color C = BackgroundColor() ;
1809   C.Values(V1,V2,V3,Type) ;
1810 }
1811
1812 //=======================================================================
1813 //function : BackgroundColor
1814 //purpose  :
1815 //=======================================================================
1816 Quantity_Color V3d_View::BackgroundColor() const
1817 {
1818   return myView->Background().Color() ;
1819 }
1820
1821 //=======================================================================
1822 //function : GradientBackgroundColors
1823 //purpose  :
1824 //=======================================================================
1825 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1826 {
1827   myView->GradientBackground().Colors (theColor1, theColor2);
1828 }
1829
1830 //=======================================================================
1831 //function : GradientBackground
1832 //purpose  :
1833 //=======================================================================
1834 Aspect_GradientBackground V3d_View::GradientBackground() const
1835 {
1836   return myView->GradientBackground();
1837 }
1838
1839 //=======================================================================
1840 //function : Scale
1841 //purpose  :
1842 //=======================================================================
1843 Standard_Real V3d_View::Scale() const
1844 {
1845   return myDefaultCamera->Scale() / Camera()->Scale();
1846 }
1847
1848 //=======================================================================
1849 //function : AxialScale
1850 //purpose  :
1851 //=======================================================================
1852 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1853 {
1854   gp_Pnt anAxialScale = Camera()->AxialScale();
1855   Sx = anAxialScale.X();
1856   Sy = anAxialScale.Y();
1857   Sz = anAxialScale.Z();
1858 }
1859
1860 //=======================================================================
1861 //function : Size
1862 //purpose  :
1863 //=======================================================================
1864 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1865 {
1866   gp_Pnt aViewDims = Camera()->ViewDimensions();
1867
1868   Width = aViewDims.X();
1869   Height = aViewDims.Y();
1870 }
1871
1872 //=======================================================================
1873 //function : ZSize
1874 //purpose  :
1875 //=======================================================================
1876 Standard_Real V3d_View::ZSize() const
1877 {
1878   gp_Pnt aViewDims = Camera()->ViewDimensions();
1879
1880   return aViewDims.Z();
1881 }
1882
1883 //=======================================================================
1884 //function : MinMax
1885 //purpose  :
1886 //=======================================================================
1887 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1888                                   Standard_Real& Vmin,
1889                                   Standard_Real& Umax,
1890                                   Standard_Real& Vmax) const
1891 {
1892   Standard_Real Wmin,Wmax,U,V,W ;
1893   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1894   // CAL 6/11/98
1895   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1896
1897   if( Nstruct ) {
1898     Bnd_Box aBox = myView->MinMaxValues();
1899     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1900     Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1901     Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1902     Project (Xmin,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,Zmax,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,Ymin,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 (Xmax,Ymax,Zmin,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,Zmax,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     Project (Xmin,Ymax,Zmin,U,V,W) ;
1923     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1924     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1925     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1926   }
1927   return Nstruct ;
1928 }
1929
1930 //=======================================================================
1931 //function : MinMax
1932 //purpose  :
1933 //=======================================================================
1934 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1935                                   Standard_Real& Ymin,
1936                                   Standard_Real& Zmin,
1937                                   Standard_Real& Xmax,
1938                                   Standard_Real& Ymax,
1939                                   Standard_Real& Zmax) const
1940 {
1941   // CAL 6/11/98
1942   // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1943   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1944
1945   if( Nstruct ) {
1946     Bnd_Box aBox = myView->MinMaxValues();
1947     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1948   }
1949   return Nstruct ;
1950 }
1951
1952 //=======================================================================
1953 //function : Gravity
1954 //purpose  :
1955 //=======================================================================
1956 void V3d_View::Gravity (Standard_Real& theX,
1957                         Standard_Real& theY,
1958                         Standard_Real& theZ) const
1959 {
1960   Graphic3d_MapOfStructure aSetOfStructures;
1961   myView->DisplayedStructures (aSetOfStructures);
1962
1963   Standard_Boolean hasSelection = Standard_False;
1964   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1965        aStructIter.More(); aStructIter.Next())
1966   {
1967     if (aStructIter.Key()->IsHighlighted()
1968      && aStructIter.Key()->IsVisible())
1969     {
1970       hasSelection = Standard_True;
1971       break;
1972     }
1973   }
1974
1975   Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1976   Standard_Integer aNbPoints = 0;
1977   gp_XYZ aResult (0.0, 0.0, 0.0);
1978   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1979        aStructIter.More(); aStructIter.Next())
1980   {
1981     const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
1982     if (!aStruct->IsVisible()
1983       || aStruct->IsInfinite()
1984       || (hasSelection && !aStruct->IsHighlighted()))
1985     {
1986       continue;
1987     }
1988
1989     const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
1990     if (!aBox.IsValid())
1991     {
1992       continue;
1993     }
1994
1995     // skip transformation-persistent objects
1996     if (!aStruct->TransformPersistence().IsNull())
1997     {
1998       continue;
1999     }
2000
2001     // use camera projection to find gravity point
2002     Xmin = aBox.CornerMin().x();
2003     Ymin = aBox.CornerMin().y();
2004     Zmin = aBox.CornerMin().z();
2005     Xmax = aBox.CornerMax().x();
2006     Ymax = aBox.CornerMax().y();
2007     Zmax = aBox.CornerMax().z();
2008     gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2009     {
2010       gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2011       gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2012       gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2013       gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2014     };
2015
2016     for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2017     {
2018       const gp_Pnt& aBndPnt    = aPnts[aPntIt];
2019       const gp_Pnt  aProjected = Camera()->Project (aBndPnt);
2020       if (Abs (aProjected.X()) <= 1.0
2021        && Abs (aProjected.Y()) <= 1.0)
2022       {
2023         aResult += aBndPnt.XYZ();
2024         ++aNbPoints;
2025       }
2026     }
2027   }
2028
2029   if (aNbPoints == 0)
2030   {
2031     // fallback - just use bounding box of entire scene
2032     Bnd_Box aBox = myView->MinMaxValues();
2033     if (!aBox.IsVoid())
2034     {
2035       aBox.Get (Xmin, Ymin, Zmin,
2036                 Xmax, Ymax, Zmax);
2037       gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2038       {
2039         gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2040         gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2041         gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2042         gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2043       };
2044
2045       for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2046       {
2047         const gp_Pnt& aBndPnt = aPnts[aPntIt];
2048         aResult += aBndPnt.XYZ();
2049         ++aNbPoints;
2050       }
2051     }
2052   }
2053
2054   if (aNbPoints > 0)
2055   {
2056     aResult /= aNbPoints;
2057   }
2058   theX = aResult.X();
2059   theY = aResult.Y();
2060   theZ = aResult.Z();
2061 }
2062
2063 //=======================================================================
2064 //function : Eye
2065 //purpose  :
2066 //=======================================================================
2067 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2068 {
2069   gp_Pnt aCameraEye = Camera()->Eye();
2070   X = aCameraEye.X();
2071   Y = aCameraEye.Y();
2072   Z = aCameraEye.Z();
2073 }
2074
2075 //=============================================================================
2076 //function : ProjReferenceAxe
2077 //purpose  :
2078 //=============================================================================
2079 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2080                                 const Standard_Integer Ypix,
2081                                 Standard_Real& XP,
2082                                 Standard_Real& YP,
2083                                 Standard_Real& ZP,
2084                                 Standard_Real& VX,
2085                                 Standard_Real& VY,
2086                                 Standard_Real& VZ) const
2087 {
2088   Standard_Real Xo,Yo,Zo;
2089
2090   Convert (Xpix, Ypix, XP, YP, ZP);
2091   if ( Type() == V3d_PERSPECTIVE ) 
2092   {
2093     FocalReferencePoint (Xo,Yo,Zo);
2094     VX = Xo - XP;
2095     VY = Yo - YP;
2096     VZ = Zo - ZP;
2097   }
2098   else 
2099   {
2100     Proj (VX,VY,VZ);
2101   }
2102 }
2103
2104 //=============================================================================
2105 //function : Depth
2106 //purpose  :
2107 //=============================================================================
2108 Standard_Real V3d_View::Depth() const
2109 {
2110   return Camera()->Distance();
2111 }
2112
2113 //=============================================================================
2114 //function : Proj
2115 //purpose  :
2116 //=============================================================================
2117 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2118 {
2119   gp_Dir aCameraDir = Camera()->Direction().Reversed();
2120   Dx = aCameraDir.X();
2121   Dy = aCameraDir.Y();
2122   Dz = aCameraDir.Z();
2123 }
2124
2125 //=============================================================================
2126 //function : At
2127 //purpose  :
2128 //=============================================================================
2129 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2130 {
2131   gp_Pnt aCameraCenter = Camera()->Center();
2132   X = aCameraCenter.X();
2133   Y = aCameraCenter.Y();
2134   Z = aCameraCenter.Z();
2135 }
2136
2137 //=============================================================================
2138 //function : Up
2139 //purpose  :
2140 //=============================================================================
2141 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2142 {
2143   gp_Dir aCameraUp = Camera()->Up();
2144   Vx = aCameraUp.X();
2145   Vy = aCameraUp.Y();
2146   Vz = aCameraUp.Z();
2147 }
2148
2149 //=============================================================================
2150 //function : Twist
2151 //purpose  :
2152 //=============================================================================
2153 Standard_Real V3d_View::Twist() const
2154 {
2155   gp_Vec Xaxis, Yaxis, Zaxis;
2156   const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2157   if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2158    && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2159    && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2160   {
2161     //
2162   }
2163
2164   // Compute Cross Vector From Up & Origin
2165   const gp_Dir aCameraUp = Camera()->Up();
2166   const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2167
2168   // compute Angle
2169   Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2170   if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2171   {
2172     anAngle = M_PI - anAngle;
2173   }
2174   if (anAngle > 0.0
2175    && anAngle < M_PI)
2176   {
2177     const gp_Dir aProjDir = Camera()->Direction().Reversed();
2178     if (aP.Dot (aProjDir.XYZ()) < 0.0)
2179     {
2180       anAngle = DEUXPI - anAngle;
2181     }
2182   }
2183   return anAngle;
2184 }
2185
2186 //=============================================================================
2187 //function : ShadingModel
2188 //purpose  :
2189 //=============================================================================
2190 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2191 {
2192   return myView->ShadingModel();
2193 }
2194
2195 //=============================================================================
2196 //function : TextureEnv
2197 //purpose  :
2198 //=============================================================================
2199 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2200 {
2201   return myView->TextureEnv();
2202 }
2203
2204 //=============================================================================
2205 //function : Visualization
2206 //purpose  :
2207 //=============================================================================
2208 V3d_TypeOfVisualization V3d_View::Visualization() const
2209 {
2210   return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2211 }
2212
2213 //=============================================================================
2214 //function : IfWindow
2215 //purpose  :
2216 //=============================================================================
2217 Standard_Boolean V3d_View::IfWindow() const
2218 {
2219   return myView->IsDefined();
2220 }
2221
2222 //=============================================================================
2223 //function : Type
2224 //purpose  :
2225 //=============================================================================
2226 V3d_TypeOfView V3d_View::Type() const
2227 {
2228   return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2229 }
2230
2231 //=============================================================================
2232 //function : SetFocale
2233 //purpose  :
2234 //=============================================================================
2235 void V3d_View::SetFocale( const Standard_Real focale )
2236 {
2237   Handle(Graphic3d_Camera) aCamera = Camera();
2238
2239   if (aCamera->IsOrthographic())
2240   {
2241     return;
2242   }
2243
2244   Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2245
2246   aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2247
2248   ImmediateUpdate();
2249 }
2250
2251 //=============================================================================
2252 //function : Focale
2253 //purpose  :
2254 //=============================================================================
2255 Standard_Real V3d_View::Focale() const
2256 {
2257   Handle(Graphic3d_Camera) aCamera = Camera();
2258
2259   if (aCamera->IsOrthographic())
2260   {
2261     return 0.0;
2262   }
2263
2264   return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2265 }
2266
2267 //=============================================================================
2268 //function : screenAxis
2269 //purpose  :
2270 //=============================================================================
2271 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2272                                        gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2273 {
2274   theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2275   if (theXaxe.Magnitude() <= gp::Resolution())
2276   {
2277     return Standard_False;
2278   }
2279   theXaxe.Normalize();
2280
2281   theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2282   if (theYaxe.Magnitude() <= gp::Resolution())
2283   {
2284     return Standard_False;
2285   }
2286   theYaxe.Normalize();
2287
2288   theZaxe = theVpn.XYZ();
2289   theZaxe.Normalize();
2290   return Standard_True;
2291 }
2292
2293 //=============================================================================
2294 //function : TrsPoint
2295 //purpose  :
2296 //=============================================================================
2297 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2298 {
2299   // CAL. S3892
2300   const Standard_Integer lr = theMat.LowerRow();
2301   const Standard_Integer ur = theMat.UpperRow();
2302   const Standard_Integer lc = theMat.LowerCol();
2303   const Standard_Integer uc = theMat.UpperCol();
2304   if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2305   {
2306     return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2307   }
2308
2309   Standard_Real X, Y, Z;
2310   thePnt.Coord (X,Y,Z);
2311   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);
2312   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);
2313   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);
2314   return gp_XYZ (XX, YY, ZZ);
2315 }
2316
2317 //=======================================================================
2318 //function : Pan
2319 //purpose  :
2320 //=======================================================================
2321 void V3d_View::Pan (const Standard_Integer theDXp,
2322                     const Standard_Integer theDYp,
2323                     const Standard_Real    theZoomFactor,
2324                     const Standard_Boolean theToStart)
2325 {
2326   Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2327 }
2328
2329 //=======================================================================
2330 //function : Panning
2331 //purpose  :
2332 //=======================================================================
2333 void V3d_View::Panning (const Standard_Real theDXv,
2334                         const Standard_Real theDYv,
2335                         const Standard_Real theZoomFactor,
2336                         const Standard_Boolean theToStart)
2337 {
2338   Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2339
2340   Handle(Graphic3d_Camera) aCamera = Camera();
2341
2342   if (theToStart)
2343   {
2344     myCamStartOpEye    = aCamera->Eye();
2345     myCamStartOpCenter = aCamera->Center();
2346   }
2347
2348   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2349
2350   gp_Pnt aViewDims = aCamera->ViewDimensions();
2351
2352   aCamera->SetEye (myCamStartOpEye);
2353   aCamera->SetCenter (myCamStartOpCenter);
2354   Translate (aCamera, -theDXv, -theDYv);
2355   Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2356
2357   SetImmediateUpdate (wasUpdateEnabled);
2358
2359   ImmediateUpdate();
2360 }
2361
2362 //=======================================================================
2363 //function : Zoom
2364 //purpose  :
2365 //=======================================================================
2366 void V3d_View::Zoom (const Standard_Integer theXp1,
2367                      const Standard_Integer theYp1,
2368                      const Standard_Integer theXp2,
2369                      const Standard_Integer theYp2)
2370 {
2371   Standard_Integer aDx = theXp2 - theXp1;
2372   Standard_Integer aDy = theYp2 - theYp1;
2373   if (aDx != 0 || aDy != 0)
2374   {
2375     Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2376     aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2377     SetZoom (aCoeff, Standard_True);
2378   }
2379 }
2380
2381 //=======================================================================
2382 //function : StartZoomAtPoint
2383 //purpose  :
2384 //=======================================================================
2385 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2386                                  const Standard_Integer theYp)
2387 {
2388   MyZoomAtPointX = theXp;
2389   MyZoomAtPointY = theYp;
2390 }
2391
2392 //=======================================================================
2393 //function : ZoomAtPoint
2394 //purpose  :
2395 //=======================================================================
2396 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2397                             const Standard_Integer theMouseStartY,
2398                             const Standard_Integer theMouseEndX,
2399                             const Standard_Integer theMouseEndY)
2400 {
2401   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2402
2403   // zoom
2404   Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2405   Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2406   aDZoom = (aDxy > 0.0) ?  aDZoom : 1.0 / aDZoom;
2407
2408   V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2409
2410   Handle(Graphic3d_Camera) aCamera = Camera();
2411
2412   Standard_Real aViewWidth  = aCamera->ViewDimensions().X();
2413   Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2414
2415   // ensure that zoom will not be too small or too big.
2416   Standard_Real aCoef = aDZoom;
2417   if (aViewWidth < aCoef * Precision::Confusion())
2418   {
2419     aCoef = aViewWidth / Precision::Confusion();
2420   }
2421   else if (aViewWidth > aCoef * 1e12)
2422   {
2423     aCoef = aViewWidth / 1e12;
2424   }
2425   if (aViewHeight < aCoef * Precision::Confusion())
2426   {
2427     aCoef = aViewHeight / Precision::Confusion();
2428   }
2429   else if (aViewHeight > aCoef * 1e12)
2430   {
2431     aCoef = aViewHeight / 1e12;
2432   }
2433
2434   Standard_Real aZoomAtPointXv = 0.0;
2435   Standard_Real aZoomAtPointYv = 0.0;
2436   Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2437
2438   Standard_Real aDxv = aZoomAtPointXv / aCoef;
2439   Standard_Real aDyv = aZoomAtPointYv / aCoef;
2440
2441   aCamera->SetScale (aCamera->Scale() / aCoef);
2442   Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2443
2444   AutoZFit();
2445
2446   SetImmediateUpdate (wasUpdateEnabled);
2447
2448   ImmediateUpdate();
2449 }
2450
2451 //=============================================================================
2452 //function : AxialScale
2453 //purpose  :
2454 //=============================================================================
2455 void V3d_View::AxialScale (const Standard_Integer Dx,
2456                            const Standard_Integer Dy,
2457                            const V3d_TypeOfAxe Axis)
2458 {
2459   if( Dx != 0. || Dy != 0. ) {
2460     Standard_Real Sx, Sy, Sz;
2461     AxialScale( Sx, Sy, Sz );
2462     Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2463     dscale = (Dx > 0) ?  dscale : 1./dscale;
2464     if( Axis == V3d_X ) Sx = dscale;
2465     if( Axis == V3d_Y ) Sy = dscale;
2466     if( Axis == V3d_Z ) Sz = dscale;
2467     SetAxialScale( Sx, Sy, Sz );
2468   }
2469 }
2470
2471 //=============================================================================
2472 //function : FitAll
2473 //purpose  :
2474 //=============================================================================
2475 void V3d_View::FitAll(const Standard_Real theXmin,
2476                       const Standard_Real theYmin,
2477                       const Standard_Real theXmax,
2478                       const Standard_Real theYmax)
2479 {
2480   Handle(Graphic3d_Camera) aCamera = Camera();
2481   Standard_Real anAspect = aCamera->Aspect();
2482
2483   Standard_Real aFitSizeU  = Abs (theXmax - theXmin);
2484   Standard_Real aFitSizeV  = Abs (theYmax - theYmin);
2485   Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2486   if (aFitAspect >= anAspect)
2487   {
2488     aFitSizeV = aFitSizeU / anAspect;
2489   }
2490   else
2491   {
2492     aFitSizeU = aFitSizeV * anAspect;
2493   }
2494
2495   Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2496   Scale (aCamera, aFitSizeU, aFitSizeV);
2497
2498   AutoZFit();
2499
2500   ImmediateUpdate();
2501 }
2502
2503 //=============================================================================
2504 //function : StartRotation
2505 //purpose  :
2506 //=============================================================================
2507 void V3d_View::StartRotation(const Standard_Integer X,
2508                              const Standard_Integer Y,
2509                              const Standard_Real zRotationThreshold)
2510 {
2511   sx = X; sy = Y;
2512   Standard_Real x,y;
2513   Size(x,y);
2514   rx = Standard_Real(Convert(x));
2515   ry = Standard_Real(Convert(y));
2516   Gravity(gx,gy,gz);
2517   Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2518   myZRotation = Standard_False;
2519   if( zRotationThreshold > 0. ) {
2520     Standard_Real dx = Abs(sx - rx/2.);
2521     Standard_Real dy = Abs(sy - ry/2.);
2522     //  if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2523     Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2524     if( dx > dd || dy > dd ) myZRotation = Standard_True;
2525   }
2526
2527 }
2528
2529 //=============================================================================
2530 //function : Rotation
2531 //purpose  :
2532 //=============================================================================
2533 void V3d_View::Rotation(const Standard_Integer X,
2534                         const Standard_Integer Y)
2535 {
2536   if( rx == 0. || ry == 0. ) {
2537     StartRotation(X,Y);
2538     return;
2539   }
2540   Standard_Real dx=0.,dy=0.,dz=0.;
2541   if( myZRotation ) {
2542     dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2543       atan2(sx-rx/2.,ry/2.-sy);
2544   } else {
2545     dx = (Standard_Real(X) - sx) * M_PI / rx;
2546     dy = (sy - Standard_Real(Y)) * M_PI / ry;
2547   }
2548
2549   Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2550 }
2551
2552 //=============================================================================
2553 //function : SetComputedMode
2554 //purpose  :
2555 //=============================================================================
2556 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2557 {
2558   if (theMode)
2559   {
2560     if (myComputedMode)
2561     {
2562       myView->SetComputedMode (Standard_True);
2563     }
2564   }
2565   else
2566   {
2567     myView->SetComputedMode (Standard_False);
2568   }
2569 }
2570
2571 //=============================================================================
2572 //function : ComputedMode
2573 //purpose  :
2574 //=============================================================================
2575 Standard_Boolean V3d_View::ComputedMode() const
2576 {
2577   return myView->ComputedMode();
2578 }
2579
2580 //=============================================================================
2581 //function : SetBackFacingModel
2582 //purpose  :
2583 //=============================================================================
2584 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2585 {
2586   myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2587   Redraw();
2588 }
2589
2590 //=============================================================================
2591 //function : BackFacingModel
2592 //purpose  :
2593 //=============================================================================
2594 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2595 {
2596   return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2597 }
2598
2599 //=============================================================================
2600 //function : Init
2601 //purpose  :
2602 //=============================================================================
2603 void V3d_View::Init()
2604 {
2605   myComputedMode = MyViewer->ComputedMode();
2606   if (!myComputedMode || !MyViewer->DefaultComputedMode())
2607   {
2608     SetComputedMode (Standard_False);
2609   }
2610 }
2611
2612 //=============================================================================
2613 //function : Dump
2614 //purpose  :
2615 //=============================================================================
2616 Standard_Boolean V3d_View::Dump (const Standard_CString      theFile,
2617                                  const Graphic3d_BufferType& theBufferType)
2618 {
2619   Standard_Integer aWinWidth, aWinHeight;
2620   MyWindow->Size (aWinWidth, aWinHeight);
2621   Image_AlienPixMap anImage;
2622
2623   return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2624 }
2625
2626 //=============================================================================
2627 //function : ToPixMap
2628 //purpose  :
2629 //=============================================================================
2630 Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
2631                                      const V3d_ImageDumpOptions& theParams)
2632 {
2633   Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2634   if (aTargetSize.x() != 0
2635    && aTargetSize.y() != 0)
2636   {
2637     // allocate image buffer for dumping
2638     if (theImage.IsEmpty()
2639      || theImage.SizeX() != Standard_Size(aTargetSize.x())
2640      || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2641     {
2642       Image_Format aFormat = Image_Format_UNKNOWN;
2643       switch (theParams.BufferType)
2644       {
2645         case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
2646         case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
2647         case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
2648         case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
2649       }
2650
2651       if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2652       {
2653         Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2654                                                                  + " for view dump", Message_Fail);
2655         return Standard_False;
2656       }
2657     }
2658   }
2659   if (theImage.IsEmpty())
2660   {
2661     Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2662     return Standard_False;
2663   }
2664   aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2665   aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2666
2667   Handle(Standard_Transient) aFBOPtr;
2668   Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2669   Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2670
2671   bool isTiling = false;
2672   if (theParams.TileSize > 0)
2673   {
2674     if (aFBOVPSize.x() > theParams.TileSize
2675      || aFBOVPSize.y() > theParams.TileSize)
2676     {
2677       aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2678       aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2679       isTiling = true;
2680     }
2681   }
2682
2683   Graphic3d_Vec2i aPrevFBOVPSize;
2684   if (!aPrevFBOPtr.IsNull())
2685   {
2686     Graphic3d_Vec2i aPrevFBOSizeMax;
2687     myView->FBOGetDimensions (aPrevFBOPtr,
2688                               aPrevFBOVPSize.x(),  aPrevFBOVPSize.y(),
2689                               aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2690     if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2691      && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2692     {
2693       aFBOPtr = aPrevFBOPtr;
2694     }
2695   }
2696
2697   if (aFBOPtr.IsNull())
2698   {
2699     Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2700     Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2701     if (theParams.TileSize > aMaxTexSizeX
2702      || theParams.TileSize > aMaxTexSizeY)
2703     {
2704       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2705                                                                  + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Fail);
2706       return Standard_False;
2707     }
2708
2709     if (aFBOVPSize.x() > aMaxTexSizeX
2710      || aFBOVPSize.y() > aMaxTexSizeY)
2711     {
2712       if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2713       {
2714         Message::DefaultMessenger ()->Send (TCollection_AsciiString ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applyed."), Message_Warning);
2715       }
2716       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2717                                                                  + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Info);
2718       aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2719       aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
2720       isTiling = true;
2721     }
2722
2723     // Try to create hardware accelerated buffer
2724     aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2725   }
2726   myView->SetFBO (aFBOPtr);
2727
2728   if (aFBOPtr.IsNull())
2729   {
2730     // try to use on-screen buffer
2731     Graphic3d_Vec2i aWinSize;
2732     MyWindow->Size (aWinSize.x(), aWinSize.y());
2733     if (aFBOVPSize.x() != aWinSize.x()
2734      || aFBOVPSize.y() != aWinSize.y())
2735     {
2736       isTiling = true;
2737     }
2738     aFBOVPSize = aWinSize;
2739
2740     Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2741   }
2742
2743   // backup camera parameters
2744   Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2745   Handle(Graphic3d_Camera) aCamera = Camera();
2746   aStoreMapping->Copy (aCamera);
2747   if (aCamera->IsStereo())
2748   {
2749     switch (theParams.StereoOptions)
2750     {
2751       case V3d_SDO_MONO:
2752       {
2753         aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2754         break;
2755       }
2756       case V3d_SDO_LEFT_EYE:
2757       {
2758         aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2759         break;
2760       }
2761       case V3d_SDO_RIGHT_EYE:
2762       {
2763         aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2764         break;
2765       }
2766       case V3d_SDO_BLENDED:
2767       {
2768         break; // dump as is
2769       }
2770     }
2771   }
2772   if (theParams.ToAdjustAspect)
2773   {
2774     aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2775   }
2776   AutoZFit();
2777
2778   // render immediate structures into back buffer rather than front
2779   const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2780
2781   Standard_Boolean isSuccess = Standard_True;
2782   if (!isTiling)
2783   {
2784     if (!aFBOPtr.IsNull())
2785     {
2786       myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2787     }
2788     Redraw();
2789     isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2790   }
2791   else
2792   {
2793     Image_PixMap aTilePixMap;
2794     aTilePixMap.SetTopDown (theImage.IsTopDown());
2795
2796     Graphic3d_Vec2i anOffset (0, 0);
2797     for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2798     {
2799       anOffset.x() = 0;
2800       for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2801       {
2802         Graphic3d_CameraTile aTileUncropped;
2803         aTileUncropped.Offset    = anOffset;
2804         aTileUncropped.TotalSize = aTargetSize;
2805         aTileUncropped.TileSize  = aFBOVPSize;
2806         const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2807         if (aTile.TileSize.x() < 1
2808          || aTile.TileSize.y() < 1)
2809         {
2810           continue;
2811         }
2812
2813         const Standard_Integer aLeft   = aTile.Offset.x();
2814         Standard_Integer       aBottom = aTile.Offset.y();
2815         if (theImage.IsTopDown())
2816         {
2817           const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2818           aBottom = aTargetSize.y() - aTop;
2819         }
2820         aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2821                                + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2822                                  aTile.TileSize.x(), aTile.TileSize.y(),
2823                                  theImage.SizeRowBytes());
2824
2825         if (!aFBOPtr.IsNull())
2826         {
2827           aCamera->SetTile (aTile);
2828           myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2829         }
2830         else
2831         {
2832           // no API to resize viewport of on-screen buffer - render uncropped
2833           aCamera->SetTile (aTileUncropped);
2834         }
2835         Redraw();
2836         isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2837         if (!isSuccess)
2838         {
2839           break;
2840         }
2841       }
2842       if (!isSuccess)
2843       {
2844         break;
2845       }
2846     }
2847   }
2848
2849   // restore state
2850   myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2851   aCamera->Copy (aStoreMapping);
2852   if (aFBOPtr != aPrevFBOPtr)
2853   {
2854     myView->FBORelease (aFBOPtr);
2855   }
2856   else if (!aPrevFBOPtr.IsNull())
2857   {
2858     myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2859   }
2860   myView->SetFBO (aPrevFBOPtr);
2861   return isSuccess;
2862 }
2863
2864 //=============================================================================
2865 //function : ImmediateUpdate
2866 //purpose  :
2867 //=============================================================================
2868 void V3d_View::ImmediateUpdate() const
2869 {
2870   if (myImmediateUpdate)
2871   {
2872     Update();
2873   }
2874 }
2875
2876 //=============================================================================
2877 //function : SetImmediateUpdate
2878 //purpose  :
2879 //=============================================================================
2880 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2881 {
2882   Standard_Boolean aPreviousMode = myImmediateUpdate;
2883   myImmediateUpdate = theImmediateUpdate;
2884   return aPreviousMode;
2885 }
2886
2887 // =======================================================================
2888 // function : SetCamera
2889 // purpose  :
2890 // =======================================================================
2891 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2892 {
2893   myView->SetCamera (theCamera);
2894
2895   ImmediateUpdate();
2896 }
2897
2898 // =======================================================================
2899 // function : GetCamera
2900 // purpose  :
2901 // =======================================================================
2902 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2903 {
2904   return myView->Camera();
2905 }
2906
2907 // =======================================================================
2908 // function : FitMinMax
2909 // purpose  : Internal
2910 // =======================================================================
2911 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2912                                       const Bnd_Box& theBox,
2913                                       const Standard_Real theMargin,
2914                                       const Standard_Real theResolution,
2915                                       const Standard_Boolean theToEnlargeIfLine) const
2916 {
2917   // Check bounding box for validness
2918   if (theBox.IsVoid())
2919   {
2920     return Standard_False; // bounding box is out of bounds...
2921   }
2922
2923   // Apply "axial scaling" to the bounding points.
2924   // It is not the best approach to make this scaling as a part of fit all operation,
2925   // but the axial scale is integrated into camera orientation matrix and the other
2926   // option is to perform frustum plane adjustment algorithm in view camera space,
2927   // which will lead to a number of additional world-view space conversions and
2928   // loosing precision as well.
2929   gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2930   gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2931
2932   if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
2933   {
2934     return Standard_False; // nothing to fit all
2935   }
2936
2937   // Prepare camera frustum planes.
2938   NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
2939   theCamera->Frustum (aFrustumPlane.ChangeValue (1),
2940                       aFrustumPlane.ChangeValue (2),
2941                       aFrustumPlane.ChangeValue (3),
2942                       aFrustumPlane.ChangeValue (4),
2943                       aFrustumPlane.ChangeValue (5),
2944                       aFrustumPlane.ChangeValue (6));
2945
2946   // Prepare camera up, side, direction vectors.
2947   gp_Dir aCamUp  = theCamera->OrthogonalizedUp();
2948   gp_Dir aCamDir = theCamera->Direction();
2949   gp_Dir aCamSide = aCamDir ^ aCamUp;
2950
2951   // Prepare scene bounding box parameters.
2952   gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
2953
2954   NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
2955   aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
2956   aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
2957   aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
2958   aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
2959   aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
2960   aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
2961   aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
2962   aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
2963
2964   // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
2965   // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
2966   // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
2967   // set up perspective-correct camera projection matching the bounding box.
2968   // These steps support non-asymmetric transformations of view-projection space provided by camera.
2969   // The zooming can be done by calculating view plane size matching the bounding box at center of
2970   // the bounding box. The only limitation here is that the scale of camera should define size of
2971   // its view plane passing through the camera center, and the center of camera should be on the
2972   // same line with the center of bounding box.
2973
2974   // The following method is applied:
2975   // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
2976   // 2) Determine new location of frustum planes, "matching" the bounding box.
2977   // 3) Determine new camera projection vector using the normalized asymmetry.
2978   // 4) Determine new zooming in view space.
2979
2980   // 1. Determine normalized projection asymmetry (if any).
2981   Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
2982                          - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
2983   Standard_Real anAssymY = Tan (( aCamUp)  .Angle (aFrustumPlane (3).Axis().Direction()))
2984                          - Tan ((-aCamUp)  .Angle (aFrustumPlane (4).Axis().Direction()));
2985
2986   // 2. Determine how far should be the frustum planes placed from center
2987   //    of bounding box, in order to match the bounding box closely.
2988   NCollection_Array1<Standard_Real> aFitDistance (1, 6);
2989   aFitDistance.ChangeValue (1) = 0.0;
2990   aFitDistance.ChangeValue (2) = 0.0;
2991   aFitDistance.ChangeValue (3) = 0.0;
2992   aFitDistance.ChangeValue (4) = 0.0;
2993   aFitDistance.ChangeValue (5) = 0.0;
2994   aFitDistance.ChangeValue (6) = 0.0;
2995
2996   for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
2997   {
2998     // Measure distances from center of bounding box to its corners towards the frustum plane.
2999     const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3000
3001     Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3002
3003     for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3004     {
3005       aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3006     }
3007   }
3008   // The center of camera is placed on the same line with center of bounding box.
3009   // The view plane section crosses the bounding box at its center.
3010   // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3011   // into view section size between the point and the frustum plane.
3012   //       proj
3013   //       /|\   right half of frame     //
3014   //        |                           //
3015   //  point o<--  distance * coeff  -->//---- (view plane section)
3016   //         \                        //
3017   //      (distance)                 // 
3018   //                ~               //
3019   //                 (distance)    //
3020   //                           \/\//
3021   //                            \//
3022   //                            //
3023   //                      (frustum plane)
3024   aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan (  aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3025   aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3026   aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan (  aCamUp   .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3027   aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp)  .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3028   aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan (  aCamDir  .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3029   aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3030
3031   Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3032   Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3033   Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3034
3035   // 3. Place center of camera on the same line with center of bounding
3036   //    box applying corresponding projection asymmetry (if any).
3037   Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3038   Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3039   Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3040   Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3041   gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3042   gp_Vec aTranslateUp   = gp_Vec (aCamUp)   * anOffsetYv;
3043   gp_Pnt aCamNewCenter  = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3044
3045   gp_Trsf aCenterTrsf;
3046   aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3047   theCamera->Transform (aCenterTrsf);
3048   theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3049
3050   // Bounding box collapses to a point or thin line going in depth of the screen
3051   if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3052   {
3053     if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3054     {
3055       return Standard_True; // This is just one point or line and zooming has no effect.
3056     }
3057
3058     // Looking along line and "theToEnlargeIfLine" is requested.
3059     // Fit view to see whole scene on rotation.
3060     aViewSizeXv = aViewSizeZv;
3061     aViewSizeYv = aViewSizeZv;
3062   }
3063
3064   Scale (theCamera, aViewSizeXv, aViewSizeYv);
3065
3066   const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3067
3068   Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3069
3070   return Standard_True;
3071 }
3072
3073 // =======================================================================
3074 // function : Scale
3075 // purpose  : Internal
3076 // =======================================================================
3077 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3078                       const Standard_Real theSizeXv,
3079                       const Standard_Real theSizeYv) const
3080 {
3081   Standard_Real anAspect = theCamera->Aspect();
3082   if (anAspect > 1.0)
3083   {
3084     theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3085   }
3086   else
3087   {
3088     theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3089   }
3090 }
3091
3092 // =======================================================================
3093 // function : Translate
3094 // purpose  : Internal
3095 // =======================================================================
3096 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3097                           const Standard_Real theDXv,
3098                           const Standard_Real theDYv) const
3099 {
3100   const gp_Pnt& aCenter = theCamera->Center();
3101   const gp_Dir& aDir = theCamera->Direction();
3102   const gp_Dir& anUp = theCamera->Up();
3103   gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3104
3105   gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3106   gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3107   gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3108   gp_Trsf aPanTrsf;
3109   aPanTrsf.SetTranslation (aCameraPan);
3110
3111   theCamera->Transform (aPanTrsf);
3112 }
3113
3114 // =======================================================================
3115 // function : DiagnosticInformation
3116 // purpose  :
3117 // =======================================================================
3118 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3119                                       Graphic3d_DiagnosticInfo theFlags) const
3120 {
3121   myView->DiagnosticInformation (theDict, theFlags);
3122 }
3123
3124 //=======================================================================
3125 //function : StatisticInformation
3126 //purpose  :
3127 //=======================================================================
3128 void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3129 {
3130   myView->StatisticInformation (theDict);
3131 }
3132
3133 // =======================================================================
3134 // function : StatisticInformation
3135 // purpose  :
3136 // =======================================================================
3137 TCollection_AsciiString V3d_View::StatisticInformation() const
3138 {
3139   return myView->StatisticInformation();
3140 }
3141
3142 //=============================================================================
3143 //function : RenderingParams
3144 //purpose  :
3145 //=============================================================================
3146 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3147 {
3148   return myView->RenderingParams();
3149 }
3150
3151 //=============================================================================
3152 //function : ChangeRenderingParams
3153 //purpose  :
3154 //=============================================================================
3155 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3156 {
3157   return myView->ChangeRenderingParams();
3158 }