0024996: Visualization - newly displayed objects are clipped until first
authorduv <duv@opencascade.com>
Thu, 17 Jul 2014 09:46:53 +0000 (13:46 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 17 Jul 2014 09:47:38 +0000 (13:47 +0400)
camera movement

AutoZFit operation now may be applied on Visual3d_View level.
Visual3d_View tracks Graphic3d_Structure updates and call AutoZFit within
Visual3d_View::Redraw if necessary.
In order to get AutoZFit functionality on Visual3d_View level ZfitAll
method moved from V3d_View into Graphic3d_Camera. AutoZFit method and
AutoZFitMode flag now part of Visual3d_View.

Test case for issue CR24996

src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/NIS/NIS_View.cxx
src/V3d/V3d_View.cdl
src/V3d/V3d_View.cxx
src/V3d/V3d_View_3.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d_View.cdl
src/Visual3d/Visual3d_View.cxx
tests/bugs/vis/bug24996 [new file with mode: 0644]
tests/feat/featprism/C4

index 20e5f48..838ae2a 100644 (file)
@@ -966,3 +966,173 @@ void Graphic3d_Camera::LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
 
   theOutMx.Multiply (anAxialScaleMx);
 }
+
+//=============================================================================
+//function : ZFitAll
+//purpose  :
+//=============================================================================
+void Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB)
+{
+  Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
+
+  // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
+  // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
+  // In addition to the graphical boundaries, the usual min max used for fitting perspective
+  // camera. To avoid numeric errors for perspective camera the negative ZNear values are
+  // fixed using tolerance distance, relative to boundaries size. The tolerance distance
+  // should be computed using information on boundaries of primary application actors,
+  // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
+
+  
+  Standard_Real aMinMax[6];    // applicative min max boundaries
+  theMinMax.Get (aMinMax[0], aMinMax[1], aMinMax[2], aMinMax[3], aMinMax[4], aMinMax[5]);
+
+  Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
+  theGraphicBB.Get (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2], aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]);
+
+  // Check if anything can be adjusted
+  Standard_Real aLim = (ShortRealLast() - 1.0);
+  if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
+    Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
+  {
+    // ShortReal precision factor used to add meaningful tolerance to
+    // ZNear, ZFar values in order to avoid equality after type conversion
+    // to ShortReal matrices type.
+    const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
+
+    Standard_Real aZFar  = Distance() * 3.0;
+    Standard_Real aZNear = 0.0;
+
+    if (!IsOrthographic())
+    {
+      if (aZFar < aPrecision)
+      {
+        // Invalid case when both values are negative
+        aZNear = aPrecision;
+        aZFar  = aPrecision * 2.0;
+      }
+      else if (aZNear < Abs (aZFar) * aPrecision)
+      {
+        // Z is less than 0.0, try to fix it using any appropriate z-scale
+        aZNear = Abs (aZFar) * aPrecision;
+      }
+    }
+
+    SetZRange (aZNear, aZFar);
+    return;
+  }
+
+  // Measure depth of boundary points from camera eye
+  gp_Pnt aPntsToMeasure[16] =
+  {
+    gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
+    gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
+    gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
+    gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
+    gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
+    gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
+    gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
+    gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
+
+    gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
+    gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
+    gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
+    gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
+    gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
+    gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
+    gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
+    gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
+  };
+
+  // Camera eye plane
+  gp_Dir aCamDir = Direction();
+  gp_Pnt aCamEye = myEye;
+  gp_Pln aCamPln (aCamEye, aCamDir);
+
+  Standard_Real aModelMinDist   = RealLast();
+  Standard_Real aModelMaxDist   = RealFirst();
+  Standard_Real aGraphicMinDist = RealLast();
+  Standard_Real aGraphicMaxDist = RealFirst();
+
+  const gp_XYZ& anAxialScale = myAxialScale;
+
+  // Get minimum and maximum distances to the eye plane
+  for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
+  {
+    gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
+
+    if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
+    {
+      continue;
+    }
+
+    aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
+      aMeasurePnt.Y() * anAxialScale.Y(),
+      aMeasurePnt.Z() * anAxialScale.Z());
+
+    Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
+
+    // Check if the camera is intruded into the scene
+    if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
+    {
+      aDistance *= -1;
+    }
+
+    Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
+    Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
+    aChangeMinDist = Min (aDistance, aChangeMinDist);
+    aChangeMaxDist = Max (aDistance, aChangeMaxDist);
+  }
+
+  // Compute depth of bounding box center
+  Standard_Real aMidDepth  = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
+  Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
+
+  // ShortReal precision factor used to add meaningful tolerance to
+  // ZNear, ZFar values in order to avoid equality after type conversion
+  // to ShortReal matrices type.
+  const Standard_Real aPrecision = Pow (0.1, ShortRealDigits() - 2);
+
+  // Compute enlarged or shrank near and far z ranges
+  Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
+  Standard_Real aZFar  = aMidDepth + aHalfDepth * theScaleFactor;
+  aZNear              -= aPrecision * 0.5;
+  aZFar               += aPrecision * 0.5;
+
+  if (!IsOrthographic())
+  {
+    if (aZFar >= aPrecision)
+    {
+      // To avoid numeric errors... (See comments in the beginning of the method).
+      // Choose between model distance and graphical distance, as the model boundaries
+      // might be infinite if all structures have infinite flag.
+      const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
+        ? aGraphicMaxDist - aGraphicMinDist : RealLast();
+
+      const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
+        ? aModelMaxDist - aModelMinDist : RealLast();
+
+      const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
+      const Standard_Real aZTolerance =
+        Max (Abs (aMinDepth) * aPrecision, aPrecision);
+
+      if (aZNear < aZTolerance)
+      {
+        aZNear = aZTolerance;
+      }
+    }
+    else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
+    {
+      aZNear = aPrecision;
+      aZFar  = aPrecision * 2.0;
+    }
+  }
+
+  // If range is too small
+  if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
+  {
+    aZFar = aZNear + Abs (aZFar) * aPrecision;
+  }
+
+  SetZRange (aZNear, aZFar);
+}
index 3f15041..cce5ff2 100644 (file)
@@ -28,6 +28,8 @@
 #include <Standard_Macro.hxx>
 #include <Standard_TypeDef.hxx>
 
+#include <Bnd_Box.hxx>
+
 DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
 
 //! Camera class provides object-oriented approach to setting up projection
@@ -268,6 +270,21 @@ public:
     return myFOVy;
   }
 
+  //! Change Z-min and Z-max planes of projection volume to match the
+  //! displayed objects. The methods ensures that view volume will
+  //! be close by depth range to the displayed objects. Fitting assumes that
+  //! for orthogonal projection the view volume contains the displayed objects
+  //! completely. For zoomed perspective view, the view volume is adjusted such
+  //! that it contains the objects or their parts, located in front of the camera.
+  //! @param theScaleFactor [in] the scale factor for Z-range.
+  //!   The range between Z-min, Z-max projection volume planes
+  //!   evaluated by z fitting method will be scaled using this coefficient.
+  //!   Program error exception is thrown if negative or zero value is passed.
+  //! @param theMinMax [in] applicative min max boundaries.
+  //! @param theScaleFactor [in] real graphical boundaries (not accounting infinite flag).
+
+  void ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB);
+
   //! Change the Near and Far Z-clipping plane positions.
   //! For orthographic projection, theZNear, theZFar can be negative or positive.
   //! For perspective projection, only positive values are allowed.
index 97faf29..bd4c3ba 100644 (file)
@@ -121,7 +121,7 @@ Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
     return Standard_False;
   }
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 
index 593d008..3489ce0 100644 (file)
@@ -244,6 +244,16 @@ is
         ---Level: Public
         ---Purpose: Updates the lights of the view. The view is redrawn.
 
+        AutoZFit (me : mutable);
+        ---Level: Public
+        ---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
+        --          projection volume planes with call to ZFitAll.
+
+        ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
+        ---Level: Public
+        ---Purpose: Change Z-min and Z-max planes of projection volume to match the
+        --          displayed objects. 
+
         --------------------------------------------------------
         ---Category: Methods to modify the Attributes of the view
         --------------------------------------------------------
@@ -413,28 +423,6 @@ is
         returns Boolean from Standard;
          ---Purpose: sets the immediate update mode and returns the previous one.
 
-        SetAutoZFitMode (me : mutable;
-                         theIsOn : Boolean;
-                         theScaleFactor : Real from Standard = 1.0);
-          ---Level: public
-          ---Purpose: Sets the automatic z-fit mode and its parameters.
-          --          The auto z-fit has extra parameters which can controlled from application level
-          --          to ensure that the size of viewing volume will be sufficiently large to cover
-          --          the depth of unmanaged objects, for example, transformation persistent ones.
-          --          @param theScaleFactor [in] the scale factor for Z-range.
-          --          The range between Z-min, Z-max projection volume planes
-          --          evaluated by z fitting method will be scaled using this coefficient.
-          --          Program error exception is thrown if negative or zero value
-          --          is passed.
-
-        AutoZFitMode (me) returns Boolean;
-          ---Level: public
-          ---Purpose: returns TRUE if automatic z-fit mode is turned on.
-
-        AutoZFitScaleFactor (me) returns Real from Standard;
-        ---Level: public
-        ---Purpose: returns scale factor parameter of automatic z-fit mode.
-
         ---------------------------------------------------
         --           Triedron methods
         ---------------------------------------------------
@@ -919,24 +907,6 @@ is
         --          @param theMargin [in] the margin coefficient for view borders.
         --          @param theToUpdate [in] flag to perform view update.
 
-        ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
-        ---Level: Public
-        ---Purpose: Change Z-min and Z-max planes of projection volume to match the
-        --          displayed objects. The methods ensures that view volume will
-        --          be close by depth range to the displayed objects. Fitting assumes that
-        --          for orthogonal projection the view volume contains the displayed objects
-        --          completely. For zoomed perspective view, the view volume is adjusted such
-        --          that it contains the objects or their parts, located in front of the camera.
-        --          @param theScaleFactor [in] the scale factor for Z-range.
-        --                                     The range between Z-min, Z-max projection volume planes
-        --                                     evaluated by z fitting method will be scaled using this coefficient.
-        --                                     Program error exception is thrown if negative or zero value is passed.
-
-        AutoZFit (me : mutable);
-        ---Level: Public
-        ---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
-        --          projection volume planes with call to ZFitAll.
-
         DepthFitAll( me : mutable ;   Aspect : Coefficient = 0.01;
                                       Margin : Coefficient = 0.01 );
         ---Level: Public
@@ -1693,8 +1663,6 @@ fields
         myViewAxis              : Vector from Graphic3d;
         myGravityReferencePoint : Vertex from Graphic3d;
         myCamProjectionShift    : Pnt from gp;
-        myAutoZFitIsOn          : Boolean from Standard;
-        myAutoZFitScaleFactor   : Real from Standard;
 
 friends
 
index cd35478..0dc3996 100644 (file)
@@ -165,9 +165,7 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
   MyViewContext (),
   myActiveLightsIterator(),
   SwitchSetFront(Standard_False),
-  MyTrsf (1, 4, 1, 4),
-  myAutoZFitIsOn (Standard_True),
-  myAutoZFitScaleFactor (1.0)
+  MyTrsf (1, 4, 1, 4)
 {
   myImmediateUpdate = Standard_False;
   MyView = new Visual3d_View(MyViewer->Viewer());
@@ -287,8 +285,7 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theVi
   MyViewContext = aFromView->Context() ;
 
   SetCamera (new Graphic3d_Camera (theView->Camera()));
-  myAutoZFitIsOn        = theView->AutoZFitMode();
-  myAutoZFitScaleFactor = theView->AutoZFitScaleFactor();
+  View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
 
   MyBackground = aFromView->Background() ;
   MyGradientBackground = aFromView->GradientBackground();
@@ -396,7 +393,7 @@ void V3d_View::Remove() const
 //=============================================================================
 void V3d_View::Update() const
 {
-  if( MyView->IsDefined() )  MyView->Update() ;
+  if( MyView->IsDefined() )  MyView->Update (Aspect_TOU_ASAP) ;
 }
 
 //=============================================================================
@@ -433,6 +430,24 @@ void V3d_View::Invalidate() const
 }
 
 //=============================================================================
+//function : AutoZFit
+//purpose  :
+//=============================================================================
+void V3d_View::AutoZFit()
+{
+  View()->AutoZFit();
+}
+
+//=============================================================================
+//function : ZFitAll
+//purpose  :
+//=============================================================================
+void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
+{
+  View()->ZFitAll (theScaleFactor);
+}
+
+//=============================================================================
 //function : Redraw
 //purpose  :
 //=============================================================================
@@ -676,7 +691,7 @@ void V3d_View::SetFront()
     myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
   myCamera->SetUp (gp_Dir (xu, yu, zu));
 
-  AutoZFit();
+  View()->AutoZFit();
 
   SwitchSetFront = !SwitchSetFront;
 
@@ -730,7 +745,7 @@ void V3d_View::Rotate (const Standard_Real ax,
 
   myCamera->Transform (aTrsf);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -785,7 +800,7 @@ void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Stan
 
   myCamera->Transform (aTrsf);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -861,7 +876,7 @@ void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
   myCamera->Transform (aRotation);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -896,7 +911,7 @@ void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
   myCamera->Transform (aRotation);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -944,7 +959,7 @@ void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standa
 
   myCamera->Transform (aTrsf);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -997,7 +1012,7 @@ void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
   myCamera->Transform (aRotation);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1046,41 +1061,12 @@ void V3d_View::SetTwist(const Standard_Real angle)
   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
   myCamera->Transform (aTrsf);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
 
 //=============================================================================
-//function : SetAutoZFitMode
-//purpose  :
-//=============================================================================
-void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
-{
-  Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
-  myAutoZFitScaleFactor = theScaleFactor;
-  myAutoZFitIsOn = theIsOn;
-}
-
-//=============================================================================
-//function : AutoZFitMode
-//purpose  :
-//=============================================================================
-Standard_Boolean V3d_View::AutoZFitMode() const
-{
-  return myAutoZFitIsOn;
-}
-
-//=============================================================================
-//function : AutoZFitScaleFactor
-//purpose  :
-//=============================================================================
-Standard_Real V3d_View::AutoZFitScaleFactor () const
-{
-  return myAutoZFitScaleFactor;
-}
-
-//=============================================================================
 //function : SetEye
 //purpose  :
 //=============================================================================
@@ -1093,7 +1079,7 @@ void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard
   myCamera->SetEye (gp_Pnt (X, Y, Z));
   SetTwist (aTwistBefore);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   SetImmediateUpdate (wasUpdateEnabled);
 
@@ -1123,7 +1109,7 @@ void V3d_View::SetDepth(const Standard_Real Depth)
     myCamera->SetCenter (aCameraCenter);
   }
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1148,7 +1134,7 @@ void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Sta
     SetTwist(aTwistBefore);
   }
 
-  AutoZFit();
+  View()->AutoZFit();
 
   SetImmediateUpdate (wasUpdateEnabled);
 
@@ -1190,7 +1176,7 @@ void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
 
   Panning (aPanX, aPanY);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1209,7 +1195,7 @@ void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_
 
   SetTwist (aTwistBefore);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   SetImmediateUpdate (wasUpdateEnabled);
 
@@ -1253,7 +1239,7 @@ void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standar
 
   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1296,7 +1282,7 @@ void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
 
   myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1336,7 +1322,7 @@ void V3d_View::Reset( const Standard_Boolean update )
     myCamera->CopyMappingData (aDefaultCamera);
     myCamera->CopyOrientationData (aDefaultCamera);
 
-    AutoZFit();
+    View()->AutoZFit();
   }
 
   SwitchSetFront = Standard_False;
@@ -1368,7 +1354,7 @@ void V3d_View::SetSize (const Standard_Real theSize)
 
   myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1471,7 +1457,7 @@ void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
   myCamera->SetEye (myCamStartOpEye);
   myCamera->SetCenter (myCamStartOpCenter);
   myCamera->SetScale (myCamera->Scale() / Coef);
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1498,7 +1484,7 @@ void V3d_View::SetScale( const Standard_Real Coef )
     myCamera->SetScale (myCamera->Scale() / Coef);
   }
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -1512,7 +1498,7 @@ void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, co
   V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
 
   myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
-  AutoZFit();
+  View()->AutoZFit();
 }
 
 //=============================================================================
@@ -1538,7 +1524,7 @@ void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean the
     return;
   }
 
-  AutoZFit();
+  View()->AutoZFit();
 
   if (myImmediateUpdate || theToUpdate)
   {
@@ -1547,173 +1533,6 @@ void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean the
 }
 
 //=============================================================================
-//function : AutoZFit
-//purpose  :
-//=============================================================================
-void V3d_View::AutoZFit()
-{
-  if (!AutoZFitMode())
-  {
-    return;
-  }
-
-  ZFitAll (myAutoZFitScaleFactor);
-}
-
-//=============================================================================
-//function : ZFitAll
-//purpose  :
-//=============================================================================
-void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
-{
-  Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
-
-  // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
-  // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
-  // In addition to the graphical boundaries, the usual min max used for fitting perspective
-  // camera. To avoid numeric errors for perspective camera the negative ZNear values are
-  // fixed using tolerance distance, relative to boundaries size. The tolerance distance
-  // should be computed using information on boundaries of primary application actors,
-  // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
-
-  Standard_Real aMinMax[6];    // applicative min max boundaries
-  View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
-                        aMinMax[3], aMinMax[4], aMinMax[5],
-                        Standard_False);
-
-  Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
-  View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
-                        aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
-                        Standard_True);
-
-  // Check if anything can be adjusted
-  Standard_Real aLim = (ShortRealLast() - 1.0);
-  if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
-      Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
-  {
-    SetZSize (0.0);
-    ImmediateUpdate();
-    return;
-  }
-
-  // Measure depth of boundary points from camera eye
-  gp_Pnt aPntsToMeasure[16] =
-  {
-    gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
-    gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
-    gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
-    gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
-    gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
-    gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
-    gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
-    gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
-
-    gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
-    gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
-    gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
-    gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
-    gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
-    gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
-    gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
-    gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
-  };
-
-  // Camera eye plane
-  gp_Dir aCamDir = myCamera->Direction();
-  gp_Pnt aCamEye = myCamera->Eye();
-  gp_Pln aCamPln (aCamEye, aCamDir);
-
-  Standard_Real aModelMinDist   = RealLast();
-  Standard_Real aModelMaxDist   = RealFirst();
-  Standard_Real aGraphicMinDist = RealLast();
-  Standard_Real aGraphicMaxDist = RealFirst();
-
-  const gp_XYZ& anAxialScale = myCamera->AxialScale();
-
-  // Get minimum and maximum distances to the eye plane
-  for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
-  {
-    gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
-
-    if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
-    {
-      continue;
-    }
-
-    aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
-                          aMeasurePnt.Y() * anAxialScale.Y(),
-                          aMeasurePnt.Z() * anAxialScale.Z());
-
-    Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
-
-    // Check if the camera is intruded into the scene
-    if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
-    {
-      aDistance *= -1;
-    }
-
-    Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
-    Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
-    aChangeMinDist = Min (aDistance, aChangeMinDist);
-    aChangeMaxDist = Max (aDistance, aChangeMaxDist);
-  }
-
-  // Compute depth of bounding box center
-  Standard_Real aMidDepth  = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
-  Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
-
-  // ShortReal precision factor used to add meaningful tolerance to
-  // ZNear, ZFar values in order to avoid equality after type conversion
-  // to ShortReal matrices type.
-  const Standard_Real aPrecision = Pow (0.1, ShortRealDigits() - 2);
-
-  // Compute enlarged or shrank near and far z ranges
-  Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
-  Standard_Real aZFar  = aMidDepth + aHalfDepth * theScaleFactor;
-  aZNear              -= aPrecision * 0.5;
-  aZFar               += aPrecision * 0.5;
-
-  if (!myCamera->IsOrthographic())
-  {
-    if (aZFar >= aPrecision)
-    {
-      // To avoid numeric errors... (See comments in the beginning of the method).
-      // Choose between model distance and graphical distance, as the model boundaries
-      // might be infinite if all structures have infinite flag.
-      const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
-        ? aGraphicMaxDist - aGraphicMinDist : RealLast();
-
-      const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
-        ? aModelMaxDist - aModelMinDist : RealLast();
-
-      const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
-      const Standard_Real aZTolerance =
-        Max (Abs (aMinDepth) * aPrecision, aPrecision);
-
-      if (aZNear < aZTolerance)
-      {
-        aZNear = aZTolerance;
-      }
-    }
-    else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
-    {
-      aZNear = aPrecision;
-      aZFar  = aPrecision * 2.0;
-    }
-  }
-
-  // If range is too small
-  if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
-  {
-    aZFar = aZNear + Abs (aZFar) * aPrecision;
-  }
-
-  myCamera->SetZRange (aZNear, aZFar);
-
-  ImmediateUpdate();
-}
-
-//=============================================================================
 //function : DepthFitAll
 //purpose  :
 //=============================================================================
@@ -1858,7 +1677,7 @@ void V3d_View::WindowFit (const Standard_Integer theMinXp,
 
     Translate (myCamera, aPanVec.X(), -aPanVec.Y());
     Scale (myCamera, aUSize, aVSize);
-    AutoZFit();
+    View()->AutoZFit();
   }
   else
   {
@@ -2811,7 +2630,7 @@ void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
   myCamera->SetScale (myCamera->Scale() / aCoef);
   Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   SetImmediateUpdate (wasUpdateEnabled);
 
@@ -2867,7 +2686,7 @@ void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
   myCamera->SetAspect (aWinAspect);
   Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
   Scale (myCamera, aFitSizeU, aFitSizeV);
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -3104,7 +2923,7 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
 
   const Standard_Boolean toAutoUpdate = myImmediateUpdate;
   myImmediateUpdate = Standard_False;
-  AutoZFit();
+  View()->AutoZFit();
   myImmediateUpdate = toAutoUpdate;
 
   if (theToKeepAspect)
index 2aca022..558fe3e 100644 (file)
@@ -68,7 +68,7 @@ void V3d_View::Move(const Standard_Real Dx, const Standard_Real Dy, const Standa
     + Dz * gp_Pnt (ZX, ZY, ZZ).XYZ()
     );
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -86,7 +86,7 @@ void V3d_View::Move(const Standard_Real Length, const Standard_Boolean Start) {
 
   myCamera->SetEye (myCamera->Eye().XYZ() + Length * gp_Pnt (Vx, Vy, Vz).XYZ());
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -142,7 +142,7 @@ void V3d_View::Translate(const Standard_Real Dx, const Standard_Real Dy, const S
     - Dz * gp_Pnt (ZX, ZY, ZZ).XYZ()
     );
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
@@ -190,7 +190,7 @@ void V3d_View::Translate(const Standard_Real theLength, const Standard_Boolean t
   gp_Pnt aNewCenter (myCamStartOpCenter.XYZ() - gp_Pnt (aVx, aVy, aVz).XYZ() * theLength);
   myCamera->SetCenter (aNewCenter);
 
-  AutoZFit();
+  View()->AutoZFit();
 
   ImmediateUpdate();
 }
index 63e4264..bdd04f9 100644 (file)
@@ -2480,7 +2480,7 @@ static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const
 
   if (theArgsNb == 1)
   {
-    aCurrentView->ZFitAll();
+    aCurrentView->View()->ZFitAll();
     aCurrentView->Redraw();
     return 0;
   }
@@ -2492,7 +2492,7 @@ static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const
     aScale = Draw::Atoi (theArgVec[1]);
   }
 
-  aCurrentView->ZFitAll (aScale);
+  aCurrentView->View()->ZFitAll (aScale);
   aCurrentView->Redraw();
 
   return 0;
@@ -2851,7 +2851,7 @@ static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, cons
     return 1;
   }
 
-  V3dView->ZFitAll();
+  V3dView->View()->ZFitAll();
 
   return 0;
 }
@@ -5671,7 +5671,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
     return 1;
   }
 
-  Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
+  Standard_Real aScale = aCurrentView->View()->AutoZFitScaleFactor();
 
   if (theArgsNb > 3)
   {
@@ -5682,7 +5682,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
   if (theArgsNb < 2)
   {
     theDi << "Auto z-fit mode: " << "\n"
-          << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
+          << "On: " << (aCurrentView->View()->AutoZFitMode() ? "enabled" : "disabled") << "\n"
           << "Scale: " << aScale << "\n";
     return 0;
   }
@@ -5694,8 +5694,8 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
     aScale = Draw::Atoi (theArgVec[2]);
   }
 
-  aCurrentView->SetAutoZFitMode (isOn, aScale);
-  aCurrentView->AutoZFit();
+  aCurrentView->View()->SetAutoZFitMode (isOn, aScale);
+  aCurrentView->View()->AutoZFit();
   aCurrentView->Redraw();
 
   return 0;
@@ -5810,7 +5810,7 @@ static int VChangeCamera (Draw_Interpretor& theDi, Standard_Integer theArgsNb, c
     return 1;
   }
 
-  ViewerTest::CurrentView()->AutoZFit();
+  ViewerTest::CurrentView()->View()->AutoZFit();
   ViewerTest::CurrentView()->Redraw();
 
   return 0;
index 7f919c7..aaa5a88 100644 (file)
@@ -390,7 +390,8 @@ is
        ---Purpose:
        --          After this call, each view is mapped in an unique window.
 
-       Update ( me     : mutable )
+       Update ( me     : mutable;
+    theUpdateMode  : TypeOfUpdate from Aspect )
                is static;
        ---Level: Public
        ---Purpose: Updates screen in function of modifications of
@@ -406,6 +407,38 @@ is
        --          the structures.
        ---Category: Methods to modify the class definition
 
+  SetAutoZFitMode (me : mutable;
+                   theIsOn : Boolean;
+                   theScaleFactor : Real from Standard = 1.0);
+    ---Level: public
+    ---Purpose: Sets the automatic z-fit mode and its parameters.
+    --          The auto z-fit has extra parameters which can controlled from application level
+    --          to ensure that the size of viewing volume will be sufficiently large to cover
+    --          the depth of unmanaged objects, for example, transformation persistent ones.
+    --          @param theScaleFactor [in] the scale factor for Z-range.
+    --          The range between Z-min, Z-max projection volume planes
+    --          evaluated by z fitting method will be scaled using this coefficient.
+    --          Program error exception is thrown if negative or zero value
+    --          is passed.
+
+  AutoZFitMode (me) returns Boolean;
+    ---Level: public
+    ---Purpose: returns TRUE if automatic z-fit mode is turned on.
+
+  AutoZFitScaleFactor (me) returns Real from Standard;
+  ---Level: public
+  ---Purpose: returns scale factor parameter of automatic z-fit mode.
+
+  AutoZFit (me : mutable);
+  ---Level: Public
+  ---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
+  --          projection volume planes with call to ZFitAll.
+
+  ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
+  ---Level: Public
+  ---Purpose: Change Z-min and Z-max planes of projection volume to match the
+  --          displayed objects. 
+
        ViewMappingReset ( me   : mutable )
                is static;
        ---Level: Public
@@ -1205,6 +1238,11 @@ fields
 
   myDefaultCamera  : Camera_Handle from Graphic3d;
 
+  myAutoZFitIsOn          : Boolean from Standard;
+  myAutoZFitScaleFactor   : Real from Standard;
+
+  myStructuresUpdated     : Boolean from Standard;
+
 friends
 
   class ViewManager from Visual3d
index c844753..5f57e4f 100644 (file)
 
 //-Constructors
 
-Visual3d_View::Visual3d_View (const Handle(Visual3d_ViewManager)& AManager):
-MyContext (),
-MyTOCOMPUTESequence (),
-MyCOMPUTEDSequence (),
-MyDisplayedStructure ()
+Visual3d_View::Visual3d_View (const Handle(Visual3d_ViewManager)& AManager) :
+  MyContext (),
+  MyTOCOMPUTESequence (),
+  MyCOMPUTEDSequence (),
+  MyDisplayedStructure (),
+  myAutoZFitIsOn (Standard_True),
+  myAutoZFitScaleFactor (1.0),
+  myStructuresUpdated (Standard_True)
 {
 
         MyPtrViewManager        = AManager.operator->();
@@ -409,8 +412,7 @@ void Visual3d_View::SetRatio()
   }
 
   MyViewManager->SetUpdateMode (UpdateMode);
-  if (UpdateMode == Aspect_TOU_ASAP)
-    Update();
+  Update (UpdateMode);
 }
 
 void Visual3d_View::UpdateLights()
@@ -487,8 +489,8 @@ void Visual3d_View::SetBackground (const Aspect_Background& ABack) {
 
         MyGraphicDriver->Background (MyCView);
 
-        if (MyPtrViewManager && MyViewManager->UpdateMode () == Aspect_TOU_ASAP)
-          Update ();
+        if (MyPtrViewManager)
+          Update (MyViewManager->UpdateMode());
 
 }
 
@@ -506,42 +508,61 @@ void Visual3d_View::SetGradientBackground(const Aspect_GradientBackground& ABack
   MyGraphicDriver->GradientBackground(MyCView, aCol1, aCol2, MyGradientBackground.BgGradientFillMethod());
 
   if ( update )
-     Update ();
-  else if (MyPtrViewManager && MyViewManager->UpdateMode () == Aspect_TOU_ASAP)
-    Update();
+  {
+     Update (Aspect_TOU_ASAP);
+  }
+  else if (MyPtrViewManager)
+  {
+    Update (MyViewManager->UpdateMode());
+  }
 }
 
 void Visual3d_View::SetBackgroundImage( const Standard_CString FileName,
                                         const Aspect_FillMethod FillStyle,
                                         const Standard_Boolean update )
 {
-  if ( IsDeleted() )
+  if (IsDeleted())
+  {
     return;
-  if ( !IsDefined() )
+  }
+  if (!IsDefined())
+  {
     Visual3d_ViewDefinitionError::Raise ("Window not defined");
+  }
 
   MyGraphicDriver->BackgroundImage( FileName, MyCView, FillStyle );
 
-  if ( update )
-    Update();
-  else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
-    Update();
+  if (update)
+  {
+    Update (Aspect_TOU_ASAP);
+  }
+  else
+  {
+    Update (MyViewManager->UpdateMode());
+  }
 }
 
 void Visual3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
                                      const Standard_Boolean update )
 {
-  if ( IsDeleted() )
+  if (IsDeleted())
+  {
     return;
-  if ( !IsDefined() )
+  }
+  if (!IsDefined())
+  {
     Visual3d_ViewDefinitionError::Raise ("Window not defined");
+  }
 
   MyGraphicDriver->SetBgImageStyle( MyCView, FillStyle );
 
-  if ( update )
-    Update();
-  else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
-    Update();
+  if (update)
+  {
+    Update (Aspect_TOU_ASAP);
+  } else
+  {
+    Update (MyViewManager->UpdateMode());
+  }
 }
 
 Aspect_Background Visual3d_View::Background () const {
@@ -553,17 +574,26 @@ Aspect_Background Visual3d_View::Background () const {
 void Visual3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
                                         const Standard_Boolean update )
 {
-  if ( IsDeleted() )
+  if (IsDeleted())
+  {
     return;
-  if ( !IsDefined() )
+  }
+
+  if (!IsDefined())
+  {
     Visual3d_ViewDefinitionError::Raise ("Window not defined");
+  }
 
   MyGraphicDriver->SetBgGradientStyle( MyCView, FillStyle );
 
-  if ( update )
-    Update();
-  else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
-    Update();
+  if (update)
+  {
+    Update (Aspect_TOU_ASAP);
+  }
+  else
+  {
+    Update (MyViewManager->UpdateMode());
+  }
 
 }
 
@@ -598,10 +628,7 @@ void Visual3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
 
   MyGraphicDriver->SetCamera (MyCView);
 
-  if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
-  {
-    Update();
-  }
+  Update (MyViewManager->UpdateMode());
 }
 
 // =======================================================================
@@ -634,10 +661,7 @@ void Visual3d_View::ViewOrientationReset ()
     MyCView.Context.Camera->CopyOrientationData (myDefaultCamera);
   }
 
-  if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
-  {
-    Update();
-  }
+  Update (MyViewManager->UpdateMode());
 }
 
 // =======================================================================
@@ -669,10 +693,7 @@ void Visual3d_View::ViewMappingReset ()
     MyCView.Context.Camera->CopyMappingData (myDefaultCamera);
   }
 
-  if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
-  {
-    Update();
-  }
+  Update (MyViewManager->UpdateMode());
 }
 
 void Visual3d_View::SetContext (const Visual3d_ContextView& CTX) {
@@ -872,7 +893,7 @@ Standard_Integer Length = FooSequence.Length ();
                 if (Length != 0) FooSequence.Clear ();
         }
 
-        if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
+        Update (MyViewManager->UpdateMode());
 
 }
 
@@ -957,7 +978,7 @@ Standard_Boolean BZBuffer       = ZBufferIsActivated ();
                         SetZBufferActivity (0);
         }
 
-        if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
+        Update (MyViewManager->UpdateMode());
 
 }
 
@@ -1008,7 +1029,7 @@ void Visual3d_View::Deactivate () {
                     }
                 }
 
-                if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
+                Update (MyViewManager->UpdateMode());
 
                 // No action currently possible in the view
                 MyCView.Active  = 0;
@@ -1082,6 +1103,12 @@ void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
       }
     }
 
+    if (myStructuresUpdated)
+    {
+      AutoZFit();
+      myStructuresUpdated = Standard_False;
+    }
+
     MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
     if (!MyGraphicDriver->IsDeviceLost())
     {
@@ -1118,12 +1145,17 @@ void Visual3d_View::Invalidate()
   MyGraphicDriver->Invalidate (MyCView);
 }
 
-void Visual3d_View::Update()
+void Visual3d_View::Update (Aspect_TypeOfUpdate theUpdateMode)
 {
-  IsInitialized = Standard_True;
-  Compute ();
+  myStructuresUpdated = Standard_True;
 
-  Redraw (MyViewManager->UnderLayer(), MyViewManager->OverLayer(), 0, 0, 0, 0);
+  if (theUpdateMode == Aspect_TOU_ASAP)
+  {
+    IsInitialized = Standard_True;
+    Compute ();
+
+    Redraw (MyViewManager->UnderLayer(), MyViewManager->OverLayer(), 0, 0, 0, 0);
+  }
 }
 
 void Visual3d_View::Update (const Handle(Visual3d_Layer)& theUnderLayer,
@@ -1132,9 +1164,83 @@ void Visual3d_View::Update (const Handle(Visual3d_Layer)& theUnderLayer,
   IsInitialized = Standard_True;
   Compute ();
 
+  myStructuresUpdated = Standard_True;
+
   Redraw (theUnderLayer, theOverLayer, 0, 0, 0, 0);
 }
 
+//=============================================================================
+//function : SetAutoZFitMode
+//purpose  :
+//=============================================================================
+void Visual3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
+{
+  Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
+  myAutoZFitScaleFactor = theScaleFactor;
+  myAutoZFitIsOn = theIsOn;
+}
+
+//=============================================================================
+//function : AutoZFitMode
+//purpose  :
+//=============================================================================
+Standard_Boolean Visual3d_View::AutoZFitMode() const
+{
+  return myAutoZFitIsOn;
+}
+
+//=============================================================================
+//function : AutoZFitScaleFactor
+//purpose  :
+//=============================================================================
+Standard_Real Visual3d_View::AutoZFitScaleFactor () const
+{
+  return myAutoZFitScaleFactor;
+}
+
+//=============================================================================
+//function : AutoZFit
+//purpose  :
+//=============================================================================
+void Visual3d_View::AutoZFit()
+{
+  if (!AutoZFitMode())
+  {
+    return;
+  }
+
+  ZFitAll (myAutoZFitScaleFactor);
+}
+
+//=============================================================================
+//function : ZFitAll
+//purpose  :
+//=============================================================================
+void Visual3d_View::ZFitAll (const Standard_Real theScaleFactor)
+{
+  Standard_Real aMinMax[6];    // applicative min max boundaries
+  MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
+    aMinMax[3], aMinMax[4], aMinMax[5],
+    Standard_False);
+
+  Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
+  MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
+    aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
+    Standard_True);
+
+  Bnd_Box aMinMaxBox;
+  Bnd_Box aGraphicBox;
+
+  aMinMaxBox.Update (aMinMax[0], aMinMax[1], aMinMax[2],
+    aMinMax[3], aMinMax[4], aMinMax[5]);
+
+  aGraphicBox.Update (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
+    aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]);
+
+  const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
+  aCamera->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
+}
+
 Visual3d_TypeOfAnswer Visual3d_View::AcceptDisplay (const Handle(Graphic3d_Structure)& AStructure) const {
 
 // Return type of visualization of the view
@@ -1390,7 +1496,7 @@ Standard_Integer Index = IsComputed (AStructure);
                 AStructure->CalculateBoundBox();
                 MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), AStructure->DisplayPriority());
                 MyDisplayedStructure.Add (AStructure);
-                if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
+                Update (AnUpdateMode);
         }
 
         if (Answer == Visual3d_TOA_COMPUTE) {
@@ -1405,7 +1511,7 @@ Standard_Integer OldStructId =
                     if (! IsDisplayed (AStructure)) {
                         MyDisplayedStructure.Add (AStructure);
                         MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure()), AStructure->DisplayPriority ());
-                        if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
+                        Update (AnUpdateMode);
                     }
                     return;
                 }
@@ -1429,7 +1535,7 @@ Standard_Integer OldStructId =
                                                         Identification ();
                             MyDisplayedStructure.Add (AStructure);
                             MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (NewIndex)->CStructure()), AStructure->DisplayPriority ());
-                            if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
+                            Update (AnUpdateMode);
                         }
                         return;
                     }
@@ -1517,7 +1623,7 @@ Standard_Boolean ComputeShading = ((ViewType == Visual3d_TOV_SHADING) &&
                 if (! IsDisplayed (AStructure))
                         MyDisplayedStructure.Add (AStructure);
                 MyGraphicDriver->DisplayStructure (MyCView, *(TheStructure->CStructure()), AStructure->DisplayPriority ());
-                if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
+                Update (AnUpdateMode);
             }
         } // Visual3d_TOA_COMPUTE
 }
@@ -1575,7 +1681,7 @@ Standard_Integer Index = IsComputed (AStructure);
                     // else is impossible
                 }
                 MyDisplayedStructure.Remove (AStructure);
-                if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
+                Update (AnUpdateMode);
         }
 
 }
@@ -2794,7 +2900,7 @@ void Visual3d_View :: SetComputedMode ( const Standard_Boolean aMode )
 
   }  // end while
 
-  if (  MyViewManager -> UpdateMode () == Aspect_TOU_ASAP  ) Update ();
+  Update (MyViewManager->UpdateMode());
 
  }  // end else
 
diff --git a/tests/bugs/vis/bug24996 b/tests/bugs/vis/bug24996
new file mode 100644 (file)
index 0000000..95635f7
--- /dev/null
@@ -0,0 +1,23 @@
+puts "============"
+puts "CR24996"
+puts "============"
+puts ""
+#######################################################################
+#  Visualization - newly displayed objects are clipped until first camera movement
+#######################################################################
+
+box b1 0  0 0 1 2 3
+box b2 3  2 1 1 2 3
+box b3 5 -4 0 1 2 3
+
+vinit
+vclear
+vaxo
+vsetdispmode 0
+vdisplay b1
+vfit
+vzoom 0.25
+vdisplay b2 b3
+
+set anImage ${imagedir}/${casename}.png
+vdump ${anImage}
index a482cd9..fddcf6e 100644 (file)
@@ -17,4 +17,4 @@ if { [catch { featperform prism result face face } ] != 0 } {
   puts "Error in featperform"
 }
 
-set square 82351.1
+set square 103218