0028895: Visualization, V3d_View::SetComputedMode() - HLR calculation is performed...
[occt.git] / src / V3d / V3d_View.cxx
index fbf0cfc..9b1c914 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-/***********************************************************************
-FONCTION :
-----------
-Classe V3d_View :
-HISTORIQUE DES MODIFICATIONS   :
---------------------------------
-00-09-92 : GG  ; Creation.
-02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
-05-06-97 : FMN ; Correction FitAll()
-30-06-97 : GG ; Correction + Optimisation de Panning(...)
-On fait la translation + le zoom en une seule
-operation au lieu de 2 precedemment qui etait buggee.
-09-07-97 : FMN ; Correction FitAll() sur le Ratio
-16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
-22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
-15-12-97 : FMN ; Ajout texture mapping
-17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
-18-12-97 : FMN ; Ajout mode Ajout
-24-12-97 : FMN ; Remplacement de math par MathGra
-24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
-31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
-07-01-98 : CAL ; Ajout de la methode DoMapping.
-07-01-98 : CAL ; Retrait de tous les "this->" inutiles
-21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
-27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
-12-02-98 : GG  ; Reactivation du Redraw dans MustBeResized()
-23-02-98 : FMN ; Remplacement PI par Standard_PI
-25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
-11-03-98 : STT ; S3558
-19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
-ne marche pas.
-08-04-98 : STT ; suppr. S3558
-10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
-13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
-ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
-16-08-98 : CAL ; S3892. Ajout grilles 3d.
-09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
-06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
-16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
-06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
-29-OCT-98 : DCB : Adding ScreenCopy () method.
-REMARQUES :
------------
-About  FitAll() multiple. This probleme is caused by missing
-precision of transformation matrices. If it is supposed that
-projection is made in the plane (U,V), there is a difference
-after several Zoom - compared to the exact value (cf ZoomX).
-Don't forget that the matrices work in float and not in double.
-To solve the problem (for lack of a better solution) I make 2 passes.
-************************************************************************/
-/*----------------------------------------------------------------------*/
-/*
-* Includes
-*/
+#include <V3d_View.hxx>
 
 #include <Aspect_GradientBackground.hxx>
 #include <Aspect_Grid.hxx>
@@ -82,6 +29,8 @@ To solve the problem (for lack of a better solution) I make 2 passes.
 #include <Graphic3d_TextureEnv.hxx>
 #include <Graphic3d_Vector.hxx>
 #include <Image_AlienPixMap.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
 #include <NCollection_Array1.hxx>
 #include <Precision.hxx>
 #include <Quantity_Color.hxx>
@@ -100,18 +49,9 @@ To solve the problem (for lack of a better solution) I make 2 passes.
 #include <V3d_Light.hxx>
 #include <V3d_StereoDumpOptions.hxx>
 #include <V3d_UnMapped.hxx>
-#include <V3d_View.hxx>
 #include <V3d_Viewer.hxx>
 
-#define V3d_FLAG_COMPUTATION   0x00000004
-
-// Perspective
-#include <OSD_Environment.hxx>
-
-/*----------------------------------------------------------------------*/
-/*
-* Constant
-*/
+IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
 
 #define DEUXPI (2. * M_PI)
 
@@ -126,9 +66,9 @@ namespace
 //=============================================================================
 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
 : MyViewer (theViewer.operator->()),
-  MyActiveLights(),
-  myActiveLightsIterator(),
   SwitchSetFront (Standard_False),
+  myZRotation (Standard_False),
+  myTrihedron (new V3d_Trihedron()),
   MyTrsf (1, 4, 1, 4)
 {
   myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
@@ -136,6 +76,8 @@ V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView th
   myView->SetBackground         (theViewer->GetBackgroundColor());
   myView->SetGradientBackground (theViewer->GetGradientBackground());
 
+  ChangeRenderingParams() = theViewer->DefaultRenderingParams();
+
   // camera init
   Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
   aCamera->SetFOVy (45.0);
@@ -148,26 +90,18 @@ V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView th
   myDefaultCamera = new Graphic3d_Camera();
 
   myImmediateUpdate = Standard_False;
-  SetAntialiasingOff();
   SetAutoZFitMode (Standard_True, 1.0);
   SetBackFacingModel (V3d_TOBM_AUTOMATIC);
   SetCamera (aCamera);
   SetAxis (0.,0.,0.,1.,1.,1.);
   SetVisualization (theViewer->DefaultVisualization());
   SetShadingModel (theViewer->DefaultShadingModel());
-  SetSurfaceDetail (theViewer->DefaultSurfaceDetail());
   SetTwist (0.);
   SetAt (0.,0.,0.);
   SetProj (theViewer->DefaultViewProj());
   SetSize (theViewer->DefaultViewSize());
   Standard_Real zsize = theViewer->DefaultViewSize();
   SetZSize (2.*zsize);
-  SetZClippingType (V3d_OFF);
-  SetZClippingDepth (0.);
-  SetZClippingWidth (zsize);
-  SetZCueingOff();
-  SetZCueingDepth (0.);
-  SetZCueingWidth (zsize);
   SetDepth (theViewer->DefaultViewSize() / 2.0);
   SetViewMappingDefault();
   SetViewOrientationDefault();
@@ -182,9 +116,8 @@ V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView th
 //=============================================================================
 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
 : MyViewer (theViewer.operator->()),
-  MyActiveLights(),
-  myActiveLightsIterator(),
   SwitchSetFront(Standard_False),
+  myZRotation (Standard_False),
   MyTrsf (1, 4, 1, 4)
 {
   myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
@@ -232,7 +165,7 @@ void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
     thePreviousView->Convert (theX1, theY1, aU1, aV1);
     thePreviousView->Convert (theX2, theY2, aU2, aV2);
     myView->SetWindow (theWindow);
-    FitAll (theWindow, aU1, aV1, aU2, aV2);
+    FitAll (aU1, aV1, aU2, aV2);
     MyViewer->SetViewOn (this);
     MyWindow = theWindow;
     SetRatio();
@@ -267,6 +200,15 @@ void V3d_View::SetWindow (const Handle(Aspect_Window)&  theWindow,
 //=============================================================================
 void V3d_View::Remove() const
 {
+  if (!MyGrid.IsNull())
+  {
+    MyGrid->Erase();
+  }
+  if (!myTrihedron.IsNull())
+  {
+    myTrihedron->Erase();
+  }
+
   MyViewer->DelView (this);
   myView->Remove();
   Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
@@ -285,7 +227,9 @@ void V3d_View::Update() const
     return;
   }
 
-  myView->Update (Aspect_TOU_ASAP);
+  myView->Update();
+  myView->Compute();
+  myView->Redraw();
 }
 
 //=============================================================================
@@ -300,21 +244,19 @@ void V3d_View::Redraw() const
     return;
   }
 
-  Handle(Graphic3d_GraphicDriver)    aGraphicDriver = MyViewer->Driver();
   Handle(Graphic3d_StructureManager) aStructureMgr  = MyViewer->StructureManager();
   for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
   {
-    if (aGraphicDriver->IsDeviceLost())
+    if (aStructureMgr->IsDeviceLost())
     {
       aStructureMgr->RecomputeStructures();
-      aGraphicDriver->ResetDeviceLostFlag();
     }
 
     AutoZFit();
 
     myView->Redraw();
 
-    if (!aGraphicDriver->IsDeviceLost())
+    if (!aStructureMgr->IsDeviceLost())
     {
       return;
     }
@@ -437,14 +379,11 @@ Standard_Boolean V3d_View::IsEmpty() const
 void V3d_View::UpdateLights() const
 {
   Graphic3d_ListOfCLight aLights;
-
-  for (TColStd_ListIteratorOfListOfTransient anIt (MyActiveLights); anIt.More(); anIt.Next())
+  for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
   {
-    aLights.Append (Handle(V3d_Light)::DownCast (anIt.Value())->Light());
+    aLights.Append (anActiveLightIter.Value()->Light());
   }
-
   myView->SetLights (aLights);
-
   Update();
 }
 
@@ -510,15 +449,6 @@ void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
   }
 }
 
-//=============================================================================
-//function : SetBackgroundColor
-//purpose  :
-//=============================================================================
-void V3d_View::SetBackgroundColor (const Quantity_NameOfColor theName)
-{
-  SetBackgroundColor (Quantity_Color (theName));
-}
-
 //=============================================================================
 //function : SetBgGradientColors
 //purpose  :
@@ -538,21 +468,6 @@ void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
   }
 }
 
-//=============================================================================
-//function : SetBgGradientColors
-//purpose  :
-//=============================================================================
-void V3d_View::SetBgGradientColors (const Quantity_NameOfColor theColor1,
-                                    const Quantity_NameOfColor theColor2,
-                                    const Aspect_GradientFillMethod theFillStyle,
-                                    const Standard_Boolean theToUpdate)
-{
-  Quantity_Color aColor1 (theColor1);
-  Quantity_Color aColor2 (theColor2);
-
-  SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
-}
-
 //=============================================================================
 //function : SetBgGradientStyle
 //purpose  :
@@ -621,15 +536,6 @@ void V3d_View::SetShadingModel (const V3d_TypeOfShadingModel theShadingModel)
   myView->SetShadingModel (static_cast<Graphic3d_TypeOfShadingModel> (theShadingModel));
 }
 
-//=============================================================================
-//function : SetSurfaceDetail
-//purpose  :
-//=============================================================================
-void V3d_View::SetSurfaceDetail (const V3d_TypeOfSurfaceDetail theSurfaceDetail)
-{
-  myView->SetSurfaceDetailType (static_cast<Graphic3d_TypeOfSurfaceDetail> (theSurfaceDetail));
-}
-
 //=============================================================================
 //function : SetTextureEnv
 //purpose  :
@@ -1460,13 +1366,13 @@ void V3d_View::SetZSize (const Standard_Real theSize)
 //function : SetZoom
 //purpose  :
 //=============================================================================
-void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
+void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
 {
-  V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
+  V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
 
   Handle(Graphic3d_Camera) aCamera = Camera();
 
-  if (Start)
+  if (theToStart)
   {
     myCamStartOpEye    = aCamera->Eye();
     myCamStartOpCenter = aCamera->Center();
@@ -1476,27 +1382,27 @@ void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
   Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
 
   // ensure that zoom will not be too small or too big
-  Standard_Real coef = Coef;
-  if (aViewWidth < coef * Precision::Confusion())
+  Standard_Real aCoef = theCoef;
+  if (aViewWidth < aCoef * Precision::Confusion())
   {
-    coef = aViewWidth / Precision::Confusion();
+    aCoef = aViewWidth / Precision::Confusion();
   }
-  else if (aViewWidth > coef * 1e12)
+  else if (aViewWidth > aCoef * 1e12)
   {
-    coef = aViewWidth / 1e12;
+    aCoef = aViewWidth / 1e12;
   }
-  if (aViewHeight < coef * Precision::Confusion())
+  if (aViewHeight < aCoef * Precision::Confusion())
   {
-    coef = aViewHeight / Precision::Confusion();
+    aCoef = aViewHeight / Precision::Confusion();
   }
-  else if (aViewHeight > coef * 1e12)
+  else if (aViewHeight > aCoef * 1e12)
   {
-    coef = aViewHeight / 1e12;
+    aCoef = aViewHeight / 1e12;
   }
 
   aCamera->SetEye (myCamStartOpEye);
   aCamera->SetCenter (myCamStartOpCenter);
-  aCamera->SetScale (aCamera->Scale() / Coef);
+  aCamera->SetScale (aCamera->Scale() / aCoef);
 
   AutoZFit();
 
@@ -1563,7 +1469,7 @@ void V3d_View::SetRatio()
 //function : FitAll
 //purpose  :
 //=============================================================================
-void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
+void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
 {
   FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
 }
@@ -1572,7 +1478,7 @@ void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Bool
 //function : FitAll
 //purpose  :
 //=============================================================================
-void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
+void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
 {
   Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
 
@@ -1598,8 +1504,8 @@ void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMarg
 //function : DepthFitAll
 //purpose  :
 //=============================================================================
-void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
-                           const Quantity_Coefficient Margin)
+void V3d_View::DepthFitAll(const Standard_Real Aspect,
+                           const Standard_Real Margin)
 {
   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
   Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
@@ -1665,18 +1571,6 @@ void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
     ImmediateUpdate();
 }
 
-//=============================================================================
-//function : FitAll
-//purpose  :
-//=============================================================================
-void V3d_View::FitAll(const Standard_Real theMinXv,
-                      const Standard_Real theMinYv,
-                      const Standard_Real theMaxXv,
-                      const Standard_Real theMaxYv)
-{
-  FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
-}
-
 //=============================================================================
 //function : WindowFitAll
 //purpose  :
@@ -2186,21 +2080,31 @@ void V3d_View::Gravity (Standard_Real& theX,
   {
     const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
     if (!aStruct->IsVisible()
-    || (hasSelection && !aStruct->IsHighlighted())
-    ||  aStruct->IsEmpty())
+      || aStruct->IsInfinite()
+      || (hasSelection && !aStruct->IsHighlighted()))
+    {
+      continue;
+    }
+
+    const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
+    if (!aBox.IsValid())
     {
       continue;
     }
 
-    Bnd_Box aBox = aStruct->MinMaxValues();
-    if (aBox.IsVoid() || aStruct->IsInfinite())
+    // skip transformation-persistent objects
+    if (!aStruct->TransformPersistence().IsNull())
     {
       continue;
     }
 
     // use camera projection to find gravity point
-    aBox.Get (Xmin, Ymin, Zmin,
-              Xmax, Ymax, Zmax);
+    Xmin = aBox.CornerMin().x();
+    Ymin = aBox.CornerMin().y();
+    Zmin = aBox.CornerMin().z();
+    Xmax = aBox.CornerMax().x();
+    Ymax = aBox.CornerMax().y();
+    Zmax = aBox.CornerMax().z();
     gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
     {
       gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
@@ -2224,21 +2128,10 @@ void V3d_View::Gravity (Standard_Real& theX,
 
   if (aNbPoints == 0)
   {
-    for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
-         aStructIter.More(); aStructIter.Next())
+    // fallback - just use bounding box of entire scene
+    Bnd_Box aBox = myView->MinMaxValues();
+    if (!aBox.IsVoid())
     {
-      const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
-      if (aStruct->IsEmpty())
-      {
-        continue;
-      }
-
-      Bnd_Box aBox = aStruct->MinMaxValues();
-      if (aBox.IsVoid() || aStruct->IsInfinite())
-      {
-        continue;
-      }
-
       aBox.Get (Xmin, Ymin, Zmin,
                 Xmax, Ymax, Zmax);
       gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
@@ -2418,15 +2311,6 @@ V3d_TypeOfShadingModel V3d_View::ShadingModel() const
   return static_cast<V3d_TypeOfShadingModel> (myView->ShadingModel());
 }
 
-//=============================================================================
-//function : SurfaceDetail
-//purpose  :
-//=============================================================================
-V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
-{
-  return static_cast<V3d_TypeOfSurfaceDetail> (myView->SurfaceDetailType());
-}
-
 //=============================================================================
 //function : TextureEnv
 //purpose  :
@@ -2445,15 +2329,6 @@ V3d_TypeOfVisualization V3d_View::Visualization() const
   return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
 }
 
-//=============================================================================
-//function : Antialiasing
-//purpose  :
-//=============================================================================
-Standard_Boolean V3d_View::Antialiasing() const
-{
-  return myView->IsAntialiasingEnabled();
-}
-
 //=============================================================================
 //function : Viewer
 //purpose  :
@@ -2569,33 +2444,24 @@ Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Gra
 //function : TrsPoint
 //purpose  :
 //=============================================================================
-Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
+gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
 {
-  Graphic3d_Vertex PP ;
-  Standard_Real X,Y,Z,XX,YY,ZZ ;
-
   // CAL. S3892
-  Standard_Integer lr, ur, lc, uc;
-  lr    = Matrix.LowerRow ();
-  ur    = Matrix.UpperRow ();
-  lc    = Matrix.LowerCol ();
-  uc    = Matrix.UpperCol ();
-  if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
-    P.Coord(X,Y,Z) ;
-    PP.SetCoord(X,Y,Z) ;
-    return PP ;
+  const Standard_Integer lr = theMat.LowerRow();
+  const Standard_Integer ur = theMat.UpperRow();
+  const Standard_Integer lc = theMat.LowerCol();
+  const Standard_Integer uc = theMat.UpperCol();
+  if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
+  {
+    return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
   }
-  P.Coord(X,Y,Z) ;
-  XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
-    Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
 
-  YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
-    Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
-
-  ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
-    Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
-  PP.SetCoord(XX,YY,ZZ) ;
-  return PP ;
+  Standard_Real X, Y, Z;
+  thePnt.Coord (X,Y,Z);
+  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);
+  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);
+  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);
+  return gp_XYZ (XX, YY, ZZ);
 }
 
 //=======================================================================
@@ -2604,7 +2470,7 @@ Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Ar
 //=======================================================================
 void V3d_View::Pan (const Standard_Integer theDXp,
                     const Standard_Integer theDYp,
-                    const Quantity_Factor  theZoomFactor,
+                    const Standard_Real    theZoomFactor,
                     const Standard_Boolean theToStart)
 {
   Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
@@ -2616,7 +2482,7 @@ void V3d_View::Pan (const Standard_Integer theDXp,
 //=======================================================================
 void V3d_View::Panning (const Standard_Real theDXv,
                         const Standard_Real theDYv,
-                        const Quantity_Factor theZoomFactor,
+                        const Standard_Real theZoomFactor,
                         const Standard_Boolean theToStart)
 {
   Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
@@ -2719,8 +2585,8 @@ void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
   Standard_Real aZoomAtPointYv = 0.0;
   Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
 
-  V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
-  V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
+  Standard_Real aDxv = aZoomAtPointXv / aCoef;
+  Standard_Real aDyv = aZoomAtPointYv / aCoef;
 
   aCamera->SetScale (aCamera->Scale() / aCoef);
   Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
@@ -2756,32 +2622,27 @@ void V3d_View::AxialScale (const Standard_Integer Dx,
 //function : FitAll
 //purpose  :
 //=============================================================================
-void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
-                      const Standard_Real Xmin,
-                      const Standard_Real Ymin,
-                      const Standard_Real Xmax,
-                      const Standard_Real Ymax)
+void V3d_View::FitAll(const Standard_Real theXmin,
+                      const Standard_Real theYmin,
+                      const Standard_Real theXmax,
+                      const Standard_Real theYmax)
 {
-  Standard_Integer aWinWidth, aWinHeight;
-  aWindow->Size (aWinWidth, aWinHeight);
+  Handle(Graphic3d_Camera) aCamera = Camera();
+  Standard_Real anAspect = aCamera->Aspect();
 
-  Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
-  Standard_Real aFitSizeU  = Abs (Xmax - Xmin);
-  Standard_Real aFitSizeV  = Abs (Ymax - Ymin);
+  Standard_Real aFitSizeU  = Abs (theXmax - theXmin);
+  Standard_Real aFitSizeV  = Abs (theYmax - theYmin);
   Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
-  if (aFitAspect >= aWinAspect)
+  if (aFitAspect >= anAspect)
   {
-    aFitSizeV = aFitSizeU / aWinAspect;
+    aFitSizeV = aFitSizeU / anAspect;
   }
   else
   {
-    aFitSizeU = aFitSizeV * aWinAspect;
+    aFitSizeU = aFitSizeV * anAspect;
   }
 
-  Handle(Graphic3d_Camera) aCamera = Camera();
-
-  aCamera->SetAspect (aWinAspect);
-  Translate (aCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
+  Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
   Scale (aCamera, aFitSizeU, aFitSizeV);
 
   AutoZFit();
@@ -2793,10 +2654,9 @@ void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
 //function : StartRotation
 //purpose  :
 //=============================================================================
-static Standard_Boolean zRotation = Standard_False;
 void V3d_View::StartRotation(const Standard_Integer X,
                              const Standard_Integer Y,
-                             const Quantity_Ratio zRotationThreshold)
+                             const Standard_Real zRotationThreshold)
 {
   sx = X; sy = Y;
   Standard_Real x,y;
@@ -2805,13 +2665,13 @@ void V3d_View::StartRotation(const Standard_Integer X,
   ry = Standard_Real(Convert(y));
   Gravity(gx,gy,gz);
   Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
-  zRotation = Standard_False;
+  myZRotation = Standard_False;
   if( zRotationThreshold > 0. ) {
     Standard_Real dx = Abs(sx - rx/2.);
     Standard_Real dy = Abs(sy - ry/2.);
-    //  if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
+    //  if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
     Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
-    if( dx > dd || dy > dd ) zRotation = Standard_True;
+    if( dx > dd || dy > dd ) myZRotation = Standard_True;
   }
 
 }
@@ -2828,7 +2688,7 @@ void V3d_View::Rotation(const Standard_Integer X,
     return;
   }
   Standard_Real dx=0.,dy=0.,dz=0.;
-  if( zRotation ) {
+  if( myZRotation ) {
     dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
       atan2(sx-rx/2.,ry/2.-sy);
   } else {
@@ -2850,13 +2710,11 @@ void V3d_View::SetComputedMode (const Standard_Boolean theMode)
     if (myComputedMode)
     {
       myView->SetComputedMode (Standard_True);
-      Update();
     }
   }
   else
   {
     myView->SetComputedMode (Standard_False);
-    Update();
   }
 }
 
@@ -2931,71 +2789,117 @@ Standard_Boolean V3d_View::Dump (const Standard_CString      theFile,
 //purpose  :
 //=============================================================================
 Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
-                                     const Standard_Integer      theWidth,
-                                     const Standard_Integer      theHeight,
-                                     const Graphic3d_BufferType& theBufferType,
-                                     const Standard_Boolean      theToKeepAspect,
-                                     const V3d_StereoDumpOptions theStereoOptions)
-{
-  // always prefer hardware accelerated offscreen buffer
-  Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
-  Graphic3d_PtrFrameBuffer aPrevFBOPtr = myView->FBO();
-  Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
-  Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
-  if (aPrevFBOPtr != NULL)
+                                     const V3d_ImageDumpOptions& theParams)
+{
+  Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
+  if (aTargetSize.x() != 0
+   && aTargetSize.y() != 0)
+  {
+    // allocate image buffer for dumping
+    if (theImage.IsEmpty()
+     || theImage.SizeX() != Standard_Size(aTargetSize.x())
+     || theImage.SizeY() != Standard_Size(aTargetSize.y()))
+    {
+      Image_Format aFormat = Image_Format_UNKNOWN;
+      switch (theParams.BufferType)
+      {
+        case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
+        case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
+        case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
+        case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
+      }
+
+      if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
+      {
+        Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
+                                                                 + " for view dump", Message_Fail);
+        return Standard_False;
+      }
+    }
+  }
+  if (theImage.IsEmpty())
   {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
+    return Standard_False;
+  }
+  aTargetSize.x() = (Standard_Integer )theImage.SizeX();
+  aTargetSize.y() = (Standard_Integer )theImage.SizeY();
+
+  Handle(Standard_Transient) aFBOPtr;
+  Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
+  Graphic3d_Vec2i aFBOVPSize = aTargetSize;
+
+  bool isTiling = false;
+  if (theParams.TileSize > 0)
+  {
+    if (aFBOVPSize.x() > theParams.TileSize
+     || aFBOVPSize.y() > theParams.TileSize)
+    {
+      aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
+      aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
+      isTiling = true;
+    }
+  }
+
+  Graphic3d_Vec2i aPrevFBOVPSize;
+  if (!aPrevFBOPtr.IsNull())
+  {
+    Graphic3d_Vec2i aPrevFBOSizeMax;
     myView->FBOGetDimensions (aPrevFBOPtr,
-                              aPrevFBOVPSizeX, aPrevFBOVPSizeY,
-                              aPrevFBOSizeXMax, aPrevFBOSizeYMax);
-    if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
+                              aPrevFBOVPSize.x(),  aPrevFBOVPSize.y(),
+                              aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
+    if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
+     && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
     {
-      myView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
       aFBOPtr = aPrevFBOPtr;
     }
   }
 
-  if (aFBOPtr == NULL)
+  if (aFBOPtr.IsNull())
   {
-    // Try to create hardware accelerated buffer
-    aFBOPtr = myView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
-    if (aFBOPtr != NULL)
+    Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize);
+    if (theParams.TileSize > aMaxTexSize)
     {
-      myView->FBOGetDimensions (aFBOPtr,
-                                aFBOVPSizeX,  aFBOVPSizeY,
-                                aFBOSizeXMax, aFBOSizeYMax);
-      // reduce viewport in case of hardware limits
-      if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
-      if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
-      myView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
+      Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
+                                                                 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail);
+      return Standard_False;
     }
+
+    if (aFBOVPSize.x() > aMaxTexSize
+     || aFBOVPSize.y() > aMaxTexSize)
+    {
+      aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize);
+      aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize);
+      isTiling = true;
+    }
+
+    // Try to create hardware accelerated buffer
+    aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
   }
   myView->SetFBO (aFBOPtr);
 
-  // If hardware accelerated buffer - try to use onscreen buffer
-  // Results may be bad!
-  if (aFBOPtr == NULL)
+  if (aFBOPtr.IsNull())
   {
-    // retrieve window sizes
-    Standard_Integer aWinWidth, aWinHeight;
-    MyWindow->Size (aWinWidth, aWinHeight);
-
-    // technically we can reduce existing viewport...
-    // but currently allow only dumping the window itself
-    if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
+    // try to use on-screen buffer
+    Graphic3d_Vec2i aWinSize;
+    MyWindow->Size (aWinSize.x(), aWinSize.y());
+    if (aFBOVPSize.x() != aWinSize.x()
+     || aFBOVPSize.y() != aWinSize.y())
     {
-      return Standard_False;
+      isTiling = true;
     }
+    aFBOVPSize = aWinSize;
+
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
   }
 
+  // backup camera parameters
   Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
-
   Handle(Graphic3d_Camera) aCamera = Camera();
-
   aStoreMapping->Copy (aCamera);
-
   if (aCamera->IsStereo())
   {
-    switch (theStereoOptions)
+    switch (theParams.StereoOptions)
     {
       case V3d_SDO_MONO:
       {
@@ -3018,57 +2922,95 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
       }
     }
   }
-
-  // render immediate structures into back buffer rather than front
-  const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
-
-  const Standard_Boolean toAutoUpdate = myImmediateUpdate;
-  myImmediateUpdate = Standard_False;
-  AutoZFit();
-  myImmediateUpdate = toAutoUpdate;
-
-  if (theToKeepAspect)
+  if (theParams.ToAdjustAspect)
   {
-    aCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
+    aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
   }
+  AutoZFit();
 
-  Redraw();
-
-  myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
-
-  aCamera->Copy (aStoreMapping);
+  // render immediate structures into back buffer rather than front
+  const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
 
   Standard_Boolean isSuccess = Standard_True;
-
-  // allocate image buffer for dumping
-  if (theImage.IsEmpty()
-   || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
-   || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
+  if (!isTiling)
   {
-    bool isBigEndian = Image_PixMap::IsBigEndianHost();
-    Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
-    switch (theBufferType)
+    if (!aFBOPtr.IsNull())
     {
-      case Graphic3d_BT_RGB:   aFormat = isBigEndian ? Image_PixMap::ImgRGB  : Image_PixMap::ImgBGR;  break;
-      case Graphic3d_BT_RGBA:  aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
-      case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
+      myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
     }
+    Redraw();
+    isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
+  }
+  else
+  {
+    Image_PixMap aTilePixMap;
+    aTilePixMap.SetTopDown (theImage.IsTopDown());
 
-    isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
+    Graphic3d_Vec2i anOffset (0, 0);
+    for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
+    {
+      anOffset.x() = 0;
+      for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
+      {
+        Graphic3d_CameraTile aTile;
+        aTile.Offset    = anOffset;
+        aTile.TotalSize = aTargetSize;
+        aTile.TileSize  = aFBOVPSize;
+        if (!aFBOPtr.IsNull())
+        {
+          // crop corners in case of FBO
+          // (no API to resize viewport of on-screen buffer - keep uncropped in this case)
+          aTile = aTile.Cropped();
+        }
+        if (aTile.TileSize.x() < 1
+         || aTile.TileSize.y() < 1)
+        {
+          continue;
+        }
+
+        const Standard_Integer aLeft   = aTile.Offset.x();
+        Standard_Integer       aBottom = aTile.Offset.y();
+        if (theImage.IsTopDown())
+        {
+          const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
+          aBottom = aTargetSize.y() - aTop;
+        }
+        aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
+                               + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
+                                 aTile.TileSize.x(), aTile.TileSize.y(),
+                                 theImage.SizeRowBytes());
+
+        aCamera->SetTile (aTile);
+        if (!aFBOPtr.IsNull())
+        {
+          myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
+        }
+        Redraw();
+        isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
+        if (!isSuccess)
+        {
+          break;
+        }
+      }
+      if (!isSuccess)
+      {
+        break;
+      }
+    }
   }
-  isSuccess = isSuccess && myView->BufferDump (theImage, theBufferType);
 
-  // FBO now useless, free resources
+  // restore state
+  myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
+  aCamera->Copy (aStoreMapping);
   if (aFBOPtr != aPrevFBOPtr)
   {
     myView->FBORelease (aFBOPtr);
   }
-  else if (aPrevFBOPtr != NULL)
+  else if (!aPrevFBOPtr.IsNull())
   {
-    myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
+    myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
   }
   myView->SetFBO (aPrevFBOPtr);
-
   return isSuccess;
 }
 
@@ -3189,10 +3131,10 @@ Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
   // 4) Determine new zooming in view space.
 
   // 1. Determine normalized projection asymmetry (if any).
-  Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction()))
-                         - Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction()));
-  Standard_Real anAssymY = Tan ( aCamUp.Angle   (aFrustumPlane (3).Axis().Direction()))
-                         - Tan (-aCamUp.Angle   (aFrustumPlane (4).Axis().Direction()));
+  Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
+                         - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
+  Standard_Real anAssymY = Tan (( aCamUp)  .Angle (aFrustumPlane (3).Axis().Direction()))
+                         - Tan ((-aCamUp)  .Angle (aFrustumPlane (4).Axis().Direction()));
 
   // 2. Determine how far should be the frustum planes placed from center
   //    of bounding box, in order to match the bounding box closely.
@@ -3232,12 +3174,12 @@ Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
   //                            \//
   //                            //
   //                      (frustum plane)
-  aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
-  aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
-  aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp.Angle   (aFrustumPlane (3).Axis().Direction())), 2.0));
-  aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan (-aCamUp.Angle   (aFrustumPlane (4).Axis().Direction())), 2.0));
-  aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir.Angle  (aFrustumPlane (5).Axis().Direction())), 2.0));
-  aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan (-aCamDir.Angle  (aFrustumPlane (6).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan (  aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan (  aCamUp   .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp)  .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan (  aCamDir  .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
+  aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
 
   Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
   Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
@@ -3272,7 +3214,11 @@ Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
     aViewSizeYv = aViewSizeZv;
   }
 
-  Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
+  Scale (theCamera, aViewSizeXv, aViewSizeYv);
+
+  const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
+
+  Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
 
   return Standard_True;
 }
@@ -3335,3 +3281,31 @@ void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
 {
   myView->SetCullingEnabled (theToClip);
 }
+
+// =======================================================================
+// function : DiagnosticInformation
+// purpose  :
+// =======================================================================
+void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+                                      Graphic3d_DiagnosticInfo theFlags) const
+{
+  myView->DiagnosticInformation (theDict, theFlags);
+}
+
+//=============================================================================
+//function : RenderingParams
+//purpose  :
+//=============================================================================
+const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
+{
+  return myView->RenderingParams();
+}
+
+//=============================================================================
+//function : ChangeRenderingParams
+//purpose  :
+//=============================================================================
+Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
+{
+  return myView->ChangeRenderingParams();
+}