0027793: Visualization - object drifts at zoom within Graphic3d_TMF_TriedronPers...
authorkgv <kgv@opencascade.com>
Tue, 23 Aug 2016 14:11:49 +0000 (17:11 +0300)
committerabv <abv@opencascade.com>
Fri, 26 Aug 2016 06:46:43 +0000 (09:46 +0300)
Graphic3d_TransformPers now takes Graphic3d_Camera definition as argument
for methods applying transformation.

Graphic3d_TransformPers::Apply() now computes Graphic3d_TMF_TriedronPers
transformation in the following way:
- The object is moved onto Z focus distance.
- The object is expected to be defined in pixels.
- The Z coordinate on anchor point is used as offset from the view corner in pixels.
- It is now possible to define not only corners of the view, but also middle of the side.
- Graphic3d_TMF_TriedronPers now works with perspective projection.

OpenGl_LayerList::ChangeLayer() - fixed removing of the element in old ZLayer.

OpenGl_Layer::BoundingBox() now takes into account bounding box
of Graphic3d_TMF_TriedronPers presentations for Z-fit operation.

28 files changed:
dox/dev_guides/upgrade/upgrade.md
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_CView.cxx
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/Graphic3d/Graphic3d_TransformPers.hxx
src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx
src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.hxx
src/OpenGl/OpenGl_BVHTreeSelector.cxx
src/OpenGl/OpenGl_BVHTreeSelector.hxx
src/OpenGl/OpenGl_GraduatedTrihedron.cxx
src/OpenGl/OpenGl_Layer.cxx
src/OpenGl/OpenGl_Layer.hxx
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/SelectMgr/SelectMgr_BaseFrustum.cxx
src/SelectMgr/SelectMgr_BaseFrustum.hxx
src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.cxx
src/SelectMgr/SelectMgr_SelectableObjectTrsfPersSet.hxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/V3d/V3d_View.cxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug26344
tests/bugs/vis/bug27793 [new file with mode: 0644]

index aa5655b..b433110 100644 (file)
@@ -1031,6 +1031,12 @@ Applications should explicitly enable deprecated functionality by setting OpenGl
 but being aware that this functionality is likely to be removed in a next OCCT release.
 Thus the recommended way to generate vector image of a 3D model or scene is to use application-level solution independent from OpenGL.
 
+@subsection upgrade_710_trsfpers Transformation persistence
+
+The behavior of transformation persistence flags Graphic3d_TMF_ZoomPers and Graphic3d_TMF_TriedronPers have been changed to be consistent with textured fixed-size 2D text.
+Object with these flags is considered to be defined in pixel units, and presentation is no more scaled depending on view height.
+Applications that need to scale such objects depending on viewport size should update them manually.
+
 @subsection upgrade_710_removed Removed features
 
 The following obsolete features have been removed:
index 5040ac5..2c914e1 100644 (file)
@@ -71,6 +71,14 @@ public:
   //! Return structure visibility flag
   bool IsVisible() const { return visible != 0; }
 
+  //! Return structure visibility considering both View Affinity and global visibility state.
+  bool IsVisible (const Standard_Integer theViewId) const
+  {
+    return visible != 0
+        && (ViewAffinity.IsNull()
+         || ViewAffinity->IsVisible (theViewId));
+  }
+
   //! Set z layer ID to display the structure in specified layer
   void SetZLayer (const Graphic3d_ZLayerId theLayerIndex) { myZLayer = theLayerIndex; }
 
index 4fcf838..fe40e84 100644 (file)
@@ -432,7 +432,7 @@ void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructur
 // function : MinMaxValues
 // purpose  :
 // =======================================================================
-Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
+Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
 {
   Bnd_Box aResult;
 
@@ -453,14 +453,18 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIgnoreInfinit
                                                  aCamera,
                                                  aWinWidth,
                                                  aWinHeight,
-                                                 theToIgnoreInfiniteFlag);
+                                                 theToIncludeAuxiliary);
     combineBox (aResult, aBox);
   }
 
   Standard_Integer aMaxZLayer = ZLayerMax();
   for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
   {
-    Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId, aCamera, aWinWidth, aWinHeight, theToIgnoreInfiniteFlag);
+    Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId,
+                                                 aCamera,
+                                                 aWinWidth,
+                                                 aWinHeight,
+                                                 theToIncludeAuxiliary);
     combineBox (aResult, aBox);
   }
 
@@ -487,12 +491,12 @@ Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
   Standard_Real aMaxCoef = 1.0;
   for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
   {
-    aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight, Standard_False));
+    aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight));
   }
 
   for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
   {
-    aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight, Standard_False));
+    aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight));
   }
 
   return aMaxCoef;
@@ -519,12 +523,8 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
   {
     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
-    if (!aStructure->IsVisible() || aStructure->IsEmpty())
-    {
-      continue;
-    }
-    else if (!aStructure->CStructure()->ViewAffinity.IsNull()
-          && !aStructure->CStructure()->ViewAffinity->IsVisible (aViewId))
+    if (aStructure->IsEmpty()
+    || !aStructure->CStructure()->IsVisible (aViewId))
     {
       continue;
     }
@@ -554,7 +554,7 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
     {
       const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
       const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
-      aStructure->TransformPersistence().Apply (aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
+      aStructure->TransformPersistence().Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
     }
 
     // To prevent float overflow at camera parameters calculation and further
index 089af32..b9e768f 100644 (file)
@@ -135,17 +135,18 @@ public:
                                                Handle(Graphic3d_Structure)& theComputedStruct) const;
 
   //! Returns the bounding box of all structures displayed in the view.
-  //! If <theToIgnoreInfiniteFlag> is TRUE, then the boundary box
-  //! also includes minimum and maximum limits of graphical elements
-  //! forming parts of infinite structures.
-  Standard_EXPORT Bnd_Box MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
+  //! If theToIncludeAuxiliary is TRUE, then the boundary box also includes minimum and maximum limits
+  //! of graphical elements forming parts of infinite and other auxiliary structures.
+  //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
+  //! @return computed bounding box
+  Standard_EXPORT Bnd_Box MinMaxValues (const Standard_Boolean theToIncludeAuxiliary = Standard_False) const;
 
   //! Returns the coordinates of the boundary box of all structures in the set <theSet>.
   //! If <theToIgnoreInfiniteFlag> is TRUE, then the boundary box
   //! also includes minimum and maximum limits of graphical elements
   //! forming parts of infinite structures.
   Standard_EXPORT Bnd_Box MinMaxValues (const Graphic3d_MapOfStructure& theSet,
-                                        const Standard_Boolean theToIgnoreInfiniteFlag = Standard_False) const;
+                                        const Standard_Boolean theToIncludeAuxiliary = Standard_False) const;
 
   //! Returns the structure manager handle which manage structures associated with this view.
   const Handle(Graphic3d_StructureManager)& StructureManager() const { return myStructureManager; }
@@ -322,11 +323,17 @@ public:
   virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const = 0;
 
   //! Returns the bounding box of all structures displayed in the Z layer.
+  //! @param theLayerId            layer identifier
+  //! @param theCamera             camera definition
+  //! @param theWindowWidth        viewport width  (for applying transformation-persistence)
+  //! @param theWindowHeight       viewport height (for applying transformation-persistence)
+  //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
+  //! @return computed bounding box
   virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
                                                 const Handle(Graphic3d_Camera)& theCamera,
                                                 const Standard_Integer          theWindowWidth,
                                                 const Standard_Integer          theWindowHeight,
-                                                const Standard_Boolean          theToIgnoreInfiniteFlag) const = 0;
+                                                const Standard_Boolean          theToIncludeAuxiliary) const = 0;
 
   //! Remove Z layer from the specified view. All structures
   //! displayed at the moment in layer will be displayed in default layer
@@ -473,8 +480,7 @@ private:
   virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
                                                         const Handle(Graphic3d_Camera)& theCamera,
                                                         const Standard_Integer          theWindowWidth,
-                                                        const Standard_Integer          theWindowHeight,
-                                                        const Standard_Boolean          theToIgnoreInfiniteFlag) const = 0;
+                                                        const Standard_Integer          theWindowHeight) const = 0;
 
 protected:
 
index 5696abc..2288278 100644 (file)
@@ -270,7 +270,7 @@ void Graphic3d_Camera::SetScale (const Standard_Real theScale)
     case Projection_MonoLeftEye  :
     case Projection_MonoRightEye :
     {
-      Standard_Real aDistance = theScale * 0.5 / Tan(myFOVy * M_PI / 360.0);
+      Standard_Real aDistance = theScale * 0.5 / Tan(DTR_HALF * myFOVy);
       SetDistance (aDistance);
     }
 
@@ -297,7 +297,7 @@ Standard_Real Graphic3d_Camera::Scale() const
     // case Projection_MonoLeftEye  :
     // case Projection_MonoRightEye :
     default :
-      return Distance() * 2.0 * Tan (myFOVy * M_PI / 360.0);
+      return Distance() * 2.0 * Tan (DTR_HALF * myFOVy);
   }
 }
 
@@ -627,10 +627,10 @@ gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
 // function : ViewDimensions
 // purpose  :
 // =======================================================================
-gp_XYZ Graphic3d_Camera::ViewDimensions() const
+gp_XYZ Graphic3d_Camera::ViewDimensions (const Standard_Real theZValue) const
 {
   // view plane dimensions
-  Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * Distance() * Tan (DTR_HALF * myFOVy));
+  Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * theZValue * Tan (DTR_HALF * myFOVy));
   Standard_Real aSizeX, aSizeY;
   if (myAspect > 1.0)
   {
index ca91801..dfb90bb 100644 (file)
@@ -386,7 +386,16 @@ public:
   //! Calculate view plane size at center (target) point
   //! and distance between ZFar and ZNear planes.
   //! @return values in form of gp_Pnt (Width, Height, Depth).
-  Standard_EXPORT gp_XYZ ViewDimensions() const;
+  gp_XYZ ViewDimensions() const
+  {
+    return ViewDimensions (Distance());
+  }
+
+  //! Calculate view plane size at center point with specified Z offset
+  //! and distance between ZFar and ZNear planes.
+  //! @param theZValue [in] the distance from the eye in eye-to-center direction
+  //! @return values in form of gp_Pnt (Width, Height, Depth).
+  Standard_EXPORT gp_XYZ ViewDimensions (const Standard_Real theZValue) const;
 
   //! Calculate WCS frustum planes for the camera projection volume.
   //! Frustum is a convex volume determined by six planes directing
index f64417d..f2f620b 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <Bnd_Box.hxx>
 #include <BVH_Box.hxx>
+#include <Graphic3d_Camera.hxx>
 #include <Graphic3d_TransformUtils.hxx>
 #include <Graphic3d_TransModeFlags.hxx>
 #include <NCollection_Mat4.hxx>
@@ -44,26 +45,30 @@ public:
 public:
 
   //! Apply transformation to bounding box of presentation.
+  //! @param theCamera [in] camera definition
   //! @param theProjection [in] the projection transformation matrix.
   //! @param theWorldView [in] the world view transformation matrix.
   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
   //! @param theBoundingBox [in/out] the bounding box to transform.
   template<class T>
-  void Apply (const NCollection_Mat4<T>& theProjection,
+  void Apply (const Handle(Graphic3d_Camera)& theCamera,
+              const NCollection_Mat4<T>& theProjection,
               const NCollection_Mat4<T>& theWorldView,
               const Standard_Integer theViewportWidth,
               const Standard_Integer theViewportHeight,
               Bnd_Box& theBoundingBox) const;
 
   //! Apply transformation to bounding box of presentation
+  //! @param theCamera [in] camera definition
   //! @param theProjection [in] the projection transformation matrix.
   //! @param theWorldView [in] the world view transformation matrix.
   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
   //! @param theBoundingBox [in/out] the bounding box to transform.
   template<class T>
-  void Apply (const NCollection_Mat4<T>& theProjection,
+  void Apply (const Handle(Graphic3d_Camera)& theCamera,
+              const NCollection_Mat4<T>& theProjection,
               const NCollection_Mat4<T>& theWorldView,
               const Standard_Integer theViewportWidth,
               const Standard_Integer theViewportHeight,
@@ -72,19 +77,22 @@ public:
   //! Compute transformation.
   //! Computed matrix can be applied to model world transformation
   //! of an object to implement effect of transformation persistence.
+  //! @param theCamera [in] camera definition
   //! @param theProjection [in] the projection transformation matrix.
   //! @param theWorldView [in] the world view transformation matrix.
   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
   //! @return transformation matrix to be applied to model world transformation of an object.
   template<class T>
-  NCollection_Mat4<T> Compute (const NCollection_Mat4<T>& theProjection,
+  NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
+                               const NCollection_Mat4<T>& theProjection,
                                const NCollection_Mat4<T>& theWorldView,
                                const Standard_Integer theViewportWidth,
                                const Standard_Integer theViewportHeight) const;
 
   template<class T>
-  void Apply (NCollection_Mat4<T>& theProjection,
+  void Apply (const Handle(Graphic3d_Camera)& theCamera,
+              NCollection_Mat4<T>& theProjection,
               NCollection_Mat4<T>& theWorldView,
               const Standard_Integer theViewportWidth,
               const Standard_Integer theViewportHeight) const;
@@ -95,7 +103,8 @@ public:
 // purpose  : Apply transformation to world view and projection matrices.
 // =======================================================================
 template<class T>
-void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
+void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
+                                     NCollection_Mat4<T>& theProjection,
                                      NCollection_Mat4<T>& theWorldView,
                                      const Standard_Integer theViewportWidth,
                                      const Standard_Integer theViewportHeight) const
@@ -105,6 +114,53 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
     return;
   }
 
+  if (Flags == Graphic3d_TMF_TriedronPers)
+  {
+    // reset Z focus for trihedron persistence
+    const Standard_Real aFocus = theCamera->IsOrthographic()
+                               ? theCamera->Distance()
+                               : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
+                                ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
+                                : Standard_Real(theCamera->ZFocus()));
+
+    // scale factor to pixels
+    const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
+    const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(theViewportHeight);
+
+    // offset from the corner
+    const Standard_Real anOffset = Point.z() * aScale;
+
+    const gp_Dir aForward (theCamera->Center().XYZ() - theCamera->Eye().XYZ());
+    gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
+    if (Point.x() != 0.0)
+    {
+      const gp_Dir aSide = aForward.Crossed (theCamera->Up());
+      if (Point.x() > 0.0)
+      {
+        aCenter += aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
+      }
+      else
+      {
+        aCenter -= aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffset);
+      }
+    }
+    if (Point.y() != 0.0)
+    {
+      if (Point.y() > 0.0)
+      {
+        aCenter += theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
+      }
+      else
+      {
+        aCenter -= theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffset);
+      }
+    }
+
+    Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
+    Graphic3d_TransformUtils::Scale     (theWorldView, T(aScale),      T(aScale),      T(aScale));
+    return;
+  }
+
   if (Flags & Graphic3d_TMF_2d)
   {
     T aLeft   = -static_cast<T> (theViewportWidth  / 2);
@@ -158,8 +214,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
     }
 
     // Prevent zooming.
-    if ((Flags == Graphic3d_TMF_TriedronPers)
-     || (Flags & Graphic3d_TMF_ZoomPers))
+    if ((Flags & Graphic3d_TMF_ZoomPers) != 0)
     {
       const T aSize = static_cast<T> (1.0);
       const Standard_Integer aViewport[4] = { 0, 0, theViewportHeight, theViewportHeight };
@@ -189,7 +244,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
     }
 
     // Prevent translation by nullifying translation component.
-    if ((Flags & Graphic3d_TMF_PanPers) || Flags == Graphic3d_TMF_TriedronPers)
+    if ((Flags & Graphic3d_TMF_PanPers) != 0)
     {
       theWorldView .SetValue (0, 3, static_cast<T> (0.0));
       theWorldView .SetValue (1, 3, static_cast<T> (0.0));
@@ -215,35 +270,7 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
       theWorldView.SetValue (2, 2, static_cast<T> (1.0));
     }
 
-    if (Flags == Graphic3d_TMF_TriedronPers)
-    {
-      if (Point.x() != 0.0 && Point.y() != 0.0)
-      {
-        NCollection_Mat4<T> anUnviewMat;
-
-        if (!(theProjection).Inverted (anUnviewMat))
-        {
-          Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse projection matrix.");
-        }
-
-        NCollection_Vec4<T> aProjMax (static_cast<T> ( 1.0), static_cast<T> ( 1.0), static_cast<T> (0.0), static_cast<T> (1.0));
-        NCollection_Vec4<T> aProjMin (static_cast<T> (-1.0), static_cast<T> (-1.0), static_cast<T> (0.0), static_cast<T> (1.0));
-        NCollection_Vec4<T> aViewMax = anUnviewMat * aProjMax;
-        NCollection_Vec4<T> aViewMin = anUnviewMat * aProjMin;
-
-        aViewMax /= aViewMax.w();
-        aViewMin /= aViewMin.w();
-
-        T aMoveX = static_cast<T> (0.5) * (aViewMax.x() - aViewMin.x() - static_cast<T> (Point.z()));
-        T aMoveY = static_cast<T> (0.5) * (aViewMax.y() - aViewMin.y() - static_cast<T> (Point.z()));
-
-        aMoveX = (Point.x() > 0.0) ? aMoveX : -aMoveX;
-        aMoveY = (Point.y() > 0.0) ? aMoveY : -aMoveY;
-
-        Graphic3d_TransformUtils::Translate<T> (theProjection, aMoveX, aMoveY, static_cast<T> (0.0));
-      }
-    }
-    else if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
+    if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
     {
       NCollection_Mat4<T> anUnviewMat;
 
@@ -266,12 +293,18 @@ void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
 // purpose  : Apply transformation to bounding box of presentation.
 // =======================================================================
 template<class T>
-void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
+void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
+                                     const NCollection_Mat4<T>& theProjection,
                                      const NCollection_Mat4<T>& theWorldView,
                                      const Standard_Integer theViewportWidth,
                                      const Standard_Integer theViewportHeight,
                                      Bnd_Box& theBoundingBox) const
 {
+  if (theBoundingBox.IsVoid())
+  {
+    return;
+  }
+
   T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
 
   theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
@@ -280,7 +313,7 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
   typename BVH_Box<T, 4>::BVH_VecNt aMax (aXmax, aYmax, aZmax, static_cast<T> (1.0));
   BVH_Box<T, 4> aBBox (aMin, aMax);
 
-  Apply (theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
+  Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
 
   theBoundingBox = Bnd_Box();
   theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
@@ -292,15 +325,16 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
 // purpose  : Apply transformation to bounding box of presentation.
 // =======================================================================
 template<class T>
-void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
+void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
+                                     const NCollection_Mat4<T>& theProjection,
                                      const NCollection_Mat4<T>& theWorldView,
                                      const Standard_Integer theViewportWidth,
                                      const Standard_Integer theViewportHeight,
                                      BVH_Box<T, 4>& theBoundingBox) const
 {
-  NCollection_Mat4<T> aTPers = Compute (theProjection, theWorldView, theViewportWidth, theViewportHeight);
-
-  if (aTPers.IsIdentity())
+  NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
+  if (aTPers.IsIdentity()
+  || !theBoundingBox.IsValid())
   {
     return;
   }
@@ -333,7 +367,8 @@ void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
 // purpose  : Compute transformation.
 // =======================================================================
 template<class T>
-NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>& theProjection,
+NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
+                                                      const NCollection_Mat4<T>& theProjection,
                                                       const NCollection_Mat4<T>& theWorldView,
                                                       const Standard_Integer theViewportWidth,
                                                       const Standard_Integer theViewportHeight) const
@@ -353,7 +388,7 @@ NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>&
   NCollection_Mat4<T> aProjection (theProjection);
   NCollection_Mat4<T> aWorldView (theWorldView);
 
-  Apply (aProjection, aWorldView, theViewportWidth, theViewportHeight);
+  Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
 
   return anUnviewMat * (aProjection * aWorldView);
 }
index e351367..c1c880a 100644 (file)
@@ -133,7 +133,8 @@ const OpenGl_Structure* OpenGl_BVHClipPrimitiveTrsfPersSet::GetStructureById (St
 // purpose  :
 //=======================================================================
 const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
-  OpenGl_BVHClipPrimitiveTrsfPersSet::BVH (const OpenGl_Mat4& theProjectionMatrix,
+  OpenGl_BVHClipPrimitiveTrsfPersSet::BVH (const Handle(Graphic3d_Camera)& theCamera,
+                                           const OpenGl_Mat4& theProjectionMatrix,
                                            const OpenGl_Mat4& theWorldViewMatrix,
                                            const Standard_Integer theViewportWidth,
                                            const Standard_Integer theViewportHeight,
@@ -154,7 +155,7 @@ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
 
     HBndBox4f aBoundingBox = new Graphic3d_BndBox4f;
     *aBoundingBox = aStructure->BoundingBox();
-     aStructure->TransformPersistence.Apply (theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, *aBoundingBox);
+     aStructure->TransformPersistence.Apply (theCamera, theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, *aBoundingBox);
 
     myStructBoxes.Add (aBoundingBox);
   }
index d838a0e..c800e4c 100644 (file)
@@ -76,7 +76,8 @@ public:
   }
 
   //! Returns BVH tree for the given world view projection (builds it if necessary).
-  const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& BVH (const OpenGl_Mat4& theProjectionMatrix,
+  const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& BVH (const Handle(Graphic3d_Camera)& theCamera,
+                                                                   const OpenGl_Mat4& theProjectionMatrix,
                                                                    const OpenGl_Mat4& theWorldViewMatrix,
                                                                    const Standard_Integer theViewportWidth,
                                                                    const Standard_Integer theViewportHeight,
index 0699286..66492f3 100644 (file)
@@ -40,6 +40,7 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
 
   myIsProjectionParallel = theCamera->IsOrthographic();
 
+  myCamera             = theCamera;
   myProjectionMat      = theCamera->ProjectionMatrixF();
   myWorldViewMat       = theCamera->OrientationMatrixF();
   myWorldViewProjState = theCamera->WorldViewProjState();
index 4824dda..39824c9 100644 (file)
@@ -46,6 +46,9 @@ public:
   //! Must be called at the beginning of each BVH tree traverse loop.
   Standard_EXPORT void CacheClipPtsProjections();
 
+  //! Return the camera definition.
+  const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
+
   //! Returns current projection matrix.
   const OpenGl_Mat4& ProjectionMatrix() const
   {
@@ -115,6 +118,8 @@ protected:
   OpenGl_Vec4 myClipPlanes[PlanesNB];      //!< Plane equations
   OpenGl_Vec4 myClipVerts[ClipVerticesNB]; //!< Vertices
 
+  Handle(Graphic3d_Camera) myCamera; //!< camera definition
+
   // for caching clip points projections onto viewing area normals once per traverse
   // ORDER: TOP, BOTTOM, LEFT, RIGHT, NEAR, FAR
   Standard_ShortReal myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
index 94dd4cb..cd12dfb 100755 (executable)
@@ -424,7 +424,7 @@ void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theW
   const Standard_Integer aHeight = theWorkspace->Height();
 
   // Take into account Transform Persistence
-  aContext->ModelWorldState.SetCurrent (aTransMode.Compute (aProjection, aWorldView, aWidth, aHeight));
+  aContext->ModelWorldState.SetCurrent (aTransMode.Compute (theWorkspace->View()->Camera(), aProjection, aWorldView, aWidth, aHeight));
   aContext->ApplyModelViewMatrix();
 
   anAxis.Arrow.Render (theWorkspace);
index bc624cf..330ce25 100644 (file)
@@ -61,6 +61,10 @@ void OpenGl_Layer::Add (const OpenGl_Structure* theStruct,
   if (theStruct->IsAlwaysRendered())
   {
     theStruct->MarkAsNotCulled();
+    if (!isForChangePriority)
+    {
+      myAlwaysRenderedMap.Add (theStruct);
+    }
   }
   else if (!isForChangePriority)
   {
@@ -101,12 +105,23 @@ bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct,
       aStructures.Swap (anIndex, aStructures.Size());
       aStructures.RemoveLast();
 
-      if (!theStruct->IsAlwaysRendered()
-       && !isForChangePriority)
+      if (!isForChangePriority)
       {
-        if (!myBVHPrimitives.Remove (theStruct))
+        if (theStruct->IsAlwaysRendered())
         {
-          myBVHPrimitivesTrsfPers.Remove (theStruct);
+          const Standard_Integer anIndex2 = myAlwaysRenderedMap.FindIndex (theStruct);
+          if (anIndex2 != 0)
+          {
+            myAlwaysRenderedMap.Swap (myAlwaysRenderedMap.Size(), anIndex2);
+            myAlwaysRenderedMap.RemoveLast();
+          }
+        }
+        else
+        {
+          if (!myBVHPrimitives.Remove (theStruct))
+          {
+            myBVHPrimitivesTrsfPers.Remove (theStruct);
+          }
         }
       }
       --myNbStructures;
@@ -128,18 +143,40 @@ void OpenGl_Layer::InvalidateBVHData() const
   myIsBVHPrimitivesNeedsReset = Standard_True;
 }
 
+//! Calculate a finite bounding box of infinite object as its middle point.
+inline Graphic3d_BndBox4f centerOfinfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
+{
+  // bounding borders of infinite line has been calculated as own point in center of this line
+  const Graphic3d_Vec4 aDiagVec = theBndBox.CornerMax() - theBndBox.CornerMin();
+  return aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f
+       ? Graphic3d_BndBox4f ((theBndBox.CornerMin() + theBndBox.CornerMax()) * 0.5f)
+       : Graphic3d_BndBox4f();
+}
+
+//! Return true if at least one vertex coordinate out of float range.
+inline bool isInfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
+{
+  return Abs (theBndBox.CornerMax().x()) >= ShortRealLast()
+      || Abs (theBndBox.CornerMax().y()) >= ShortRealLast()
+      || Abs (theBndBox.CornerMax().z()) >= ShortRealLast()
+      || Abs (theBndBox.CornerMin().x()) >= ShortRealLast()
+      || Abs (theBndBox.CornerMin().y()) >= ShortRealLast()
+      || Abs (theBndBox.CornerMin().z()) >= ShortRealLast();
+}
+
 // =======================================================================
 // function : BoundingBox
 // purpose  :
 // =======================================================================
-const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer          theViewId,
-                                                     const Handle(Graphic3d_Camera)& theCamera,
-                                                     const Standard_Integer          theWindowWidth,
-                                                     const Standard_Integer          theWindowHeight,
-                                                     const Standard_Boolean          theToIgnoreInfiniteFlag) const
+Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer          theViewId,
+                                              const Handle(Graphic3d_Camera)& theCamera,
+                                              const Standard_Integer          theWindowWidth,
+                                              const Standard_Integer          theWindowHeight,
+                                              const Standard_Boolean          theToIncludeAuxiliary) const
 {
-  const Standard_Integer aBoxId = theToIgnoreInfiniteFlag == 0 ? 0 : 1;
-
+  const Standard_Integer aBoxId = !theToIncludeAuxiliary ? 0 : 1;
+  const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
+  const Graphic3d_Mat4& aWorldViewMat  = theCamera->OrientationMatrixF();
   if (myIsBoundingBoxNeedsReset[aBoxId])
   {
     // Recompute layer bounding box
@@ -152,12 +189,7 @@ const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer
       for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
       {
         const OpenGl_Structure* aStructure = aStructures.FindKey (aStructIdx);
-        if (!aStructure->IsVisible())
-        {
-          continue;
-        }
-        else if (!aStructure->ViewAffinity.IsNull()
-              && !aStructure->ViewAffinity->IsVisible (theViewId))
+        if (!aStructure->IsVisible (theViewId))
         {
           continue;
         }
@@ -166,7 +198,8 @@ const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer
         // but adds transform persistence point in a bounding box of layer (only zoom pers. objects).
         if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
         {
-          if (!theToIgnoreInfiniteFlag && (aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
+          if (!theToIncludeAuxiliary
+           && (aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers) != 0)
           {
             BVH_Vec4f aTPPoint (static_cast<float> (aStructure->TransformPersistence.Point.x()),
                                 static_cast<float> (aStructure->TransformPersistence.Point.y()),
@@ -178,66 +211,86 @@ const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer
           }
           // Panning and 2d persistence apply changes to projection or/and its translation components.
           // It makes them incompatible with z-fitting algorithm. Ignored by now.
-          else if (!theToIgnoreInfiniteFlag
-           || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_2d)
-           || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_PanPers)
-           || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_TriedronPers))
+          else if (!theToIncludeAuxiliary
+                || (aStructure->TransformPersistence.Flags & (Graphic3d_TMF_2d | Graphic3d_TMF_PanPers | Graphic3d_TMF_TriedronPers)) != 0)
           {
             continue;
           }
         }
 
         Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
+        if (!aBox.IsValid())
+        {
+          continue;
+        }
 
         if (aStructure->IsInfinite
-        && !theToIgnoreInfiniteFlag)
+        && !theToIncludeAuxiliary)
         {
-          const Graphic3d_Vec4 aDiagVec = aBox.CornerMax() - aBox.CornerMin();
-          if (aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f)
-          {
-            // bounding borders of infinite line has been calculated as own point in center of this line
-            aBox = Graphic3d_BndBox4f ((aBox.CornerMin() + aBox.CornerMax()) * 0.5f);
-          }
-          else
-          {
-            aBox = Graphic3d_BndBox4f (Graphic3d_Vec4 (ShortRealFirst(), ShortRealFirst(), ShortRealFirst(), 1.0f),
-                                       Graphic3d_Vec4 (ShortRealLast(),  ShortRealLast(),  ShortRealLast(),  1.0f));
-          }
+          // include center of infinite object
+          aBox = centerOfinfiniteBndBox (aBox);
         }
 
         if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
         {
-          const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
-          const Graphic3d_Mat4& aWorldViewMat  = theCamera->OrientationMatrixF();
-
-          aStructure->TransformPersistence.Apply (aProjectionMat,
+          aStructure->TransformPersistence.Apply (theCamera,
+                                                  aProjectionMat,
                                                   aWorldViewMat,
                                                   theWindowWidth,
                                                   theWindowHeight,
                                                   aBox);
         }
 
-        // To prevent float overflow at camera parameters calculation and further
-        // rendering, bounding boxes with at least one vertex coordinate out of
-        // float range are skipped by view fit algorithms
-        if (Abs (aBox.CornerMax().x()) >= ShortRealLast()
-         || Abs (aBox.CornerMax().y()) >= ShortRealLast()
-         || Abs (aBox.CornerMax().z()) >= ShortRealLast()
-         || Abs (aBox.CornerMin().x()) >= ShortRealLast()
-         || Abs (aBox.CornerMin().y()) >= ShortRealLast()
-         || Abs (aBox.CornerMin().z()) >= ShortRealLast())
+        // skip too big boxes to prevent float overflow at camera parameters calculation
+        if (!isInfiniteBndBox (aBox))
         {
-          continue;
+          myBoundingBox[aBoxId].Combine (aBox);
         }
-
-        myBoundingBox[aBoxId].Combine (aBox);
       }
     }
 
     myIsBoundingBoxNeedsReset[aBoxId] = false;
   }
 
-  return myBoundingBox[aBoxId];
+  if (!theToIncludeAuxiliary
+    || myAlwaysRenderedMap.IsEmpty())
+  {
+    return myBoundingBox[aBoxId];
+  }
+
+  // add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit
+  Graphic3d_BndBox4f aResBox = myBoundingBox[aBoxId];
+  for (NCollection_IndexedMap<const OpenGl_Structure*>::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next())
+  {
+    const OpenGl_Structure* aStructure = aStructIter.Value();
+    if (!aStructure->IsVisible (theViewId))
+    {
+      continue;
+    }
+    else if ((aStructure->TransformPersistence.Flags & Graphic3d_TMF_TriedronPers) == 0)
+    {
+      continue;
+    }
+
+    Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
+    if (!aBox.IsValid())
+    {
+      continue;
+    }
+
+    aStructure->TransformPersistence.Apply (theCamera,
+                                            aProjectionMat,
+                                            aWorldViewMat,
+                                            theWindowWidth,
+                                            theWindowHeight,
+                                            aBox);
+    if (!isInfiniteBndBox (aBox))
+    {
+      aResBox.Combine (aBox);
+    }
+  }
+
+  return aResBox;
 }
 
 // =======================================================================
@@ -247,8 +300,7 @@ const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer
 Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integer          theViewId,
                                                             const Handle(Graphic3d_Camera)& theCamera,
                                                             Standard_Integer                theWindowWidth,
-                                                            Standard_Integer                theWindowHeight,
-                                                            Standard_Boolean                /*theToIgnoreInfiniteFlag*/) const
+                                                            Standard_Integer                theWindowHeight) const
 {
   if (NbOfTransformPersistenceObjects() == 0)
   {
@@ -266,23 +318,19 @@ Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integ
     for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
     {
       OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructures.FindKey (aStructIdx));
-      if (!aStructure->IsVisible())
-      {
-        continue;
-      }
-      else if (!aStructure->ViewAffinity.IsNull()
-            && !aStructure->ViewAffinity->IsVisible (theViewId))
+      if (!aStructure->IsVisible (theViewId)
+       || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers) == 0)
       {
         continue;
       }
 
-      if (!(aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
+      Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
+      if (!aBox.IsValid())
       {
         continue;
       }
 
-      Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
-      aStructure->TransformPersistence.Apply (aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
+      aStructure->TransformPersistence.Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
 
       const BVH_Vec4f&       aCornerMin           = aBox.CornerMin();
       const BVH_Vec4f&       aCornerMax           = aBox.CornerMax();
@@ -399,36 +447,48 @@ void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) cons
 }
 
 // =======================================================================
-// function : renderTraverse
+// function : updateBVH
 // purpose  :
 // =======================================================================
-void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_Layer::updateBVH() const
 {
-  if (myIsBVHPrimitivesNeedsReset)
+  if (!myIsBVHPrimitivesNeedsReset)
+  {
+    return;
+  }
+
+  myBVHPrimitives.Clear();
+  myBVHPrimitivesTrsfPers.Clear();
+  myIsBVHPrimitivesNeedsReset = Standard_False;
+  for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
   {
-    myBVHPrimitives.Clear();
-    myBVHPrimitivesTrsfPers.Clear();
-    myIsBVHPrimitivesNeedsReset = Standard_False;
-    for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
+    for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
     {
-      for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
+      const OpenGl_Structure* aStruct = aStructIter.Value();
+      if (aStruct->IsAlwaysRendered())
       {
-        const OpenGl_Structure* aStruct = aStructIter.Value();
-
-        if (aStruct->IsAlwaysRendered())
-          continue;
+        continue;
+      }
 
-        if (aStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
-        {
-          myBVHPrimitives.Add (aStruct);
-        }
-        else
-        {
-          myBVHPrimitivesTrsfPers.Add (aStruct);
-        }
+      if (aStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
+      {
+        myBVHPrimitives.Add (aStruct);
+      }
+      else
+      {
+        myBVHPrimitivesTrsfPers.Add (aStruct);
       }
     }
   }
+}
+
+// =======================================================================
+// function : renderTraverse
+// purpose  :
+// =======================================================================
+void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  updateBVH();
 
   OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
   traverse (aSelector);
@@ -441,13 +501,8 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
     for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
     {
       const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
-      if (!aStruct->IsVisible()
-        || aStruct->IsCulled())
-      {
-        continue;
-      }
-      else if (!aStruct->ViewAffinity.IsNull()
-            && !aStruct->ViewAffinity->IsVisible (aViewId))
+      if (aStruct->IsCulled()
+      || !aStruct->IsVisible (aViewId))
       {
         continue;
       }
@@ -487,7 +542,7 @@ void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
       const Standard_Integer aViewportWidth         = theSelector.ViewportWidth();
       const Standard_Integer aViewportHeight        = theSelector.ViewportHeight();
 
-      aBVHTree = myBVHPrimitivesTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
+      aBVHTree = myBVHPrimitivesTrsfPers.BVH (theSelector.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
     }
     else
     {
index 09d8b16..78eeb6e 100644 (file)
@@ -99,18 +99,23 @@ public:
   }
 
   //! Returns layer bounding box.
-  const Graphic3d_BndBox4f& BoundingBox (const Standard_Integer          theViewId,
-                                         const Handle(Graphic3d_Camera)& theCamera,
-                                         const Standard_Integer          theWindowWidth,
-                                         const Standard_Integer          theWindowHeight,
-                                         const Standard_Boolean          theToIgnoreInfiniteFlag) const;
+  //! @param theViewId             view index to consider View Affinity in structure
+  //! @param theCamera             camera definition
+  //! @param theWindowWidth        viewport width  (for applying transformation-persistence)
+  //! @param theWindowHeight       viewport height (for applying transformation-persistence)
+  //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
+  //! @return computed bounding box
+  Graphic3d_BndBox4f BoundingBox (const Standard_Integer          theViewId,
+                                  const Handle(Graphic3d_Camera)& theCamera,
+                                  const Standard_Integer          theWindowWidth,
+                                  const Standard_Integer          theWindowHeight,
+                                  const Standard_Boolean          theToIncludeAuxiliary) const;
 
   //! Returns zoom-scale factor.
   Standard_Real considerZoomPersistenceObjects (const Standard_Integer          theViewId,
                                                 const Handle(Graphic3d_Camera)& theCamera,
                                                 const Standard_Integer          theWindowWidth,
-                                                const Standard_Integer          theWindowHeight,
-                                                const Standard_Boolean          theToIgnoreInfiniteFlag) const;
+                                                const Standard_Integer          theWindowHeight) const;
 
   // Render all structures.
   void Render (const Handle(OpenGl_Workspace)&   theWorkspace,
@@ -124,6 +129,9 @@ public:
 
 protected:
 
+  //! Updates BVH trees if their state has been invalidated.
+  void updateBVH() const;
+
   //! Traverses through BVH tree to determine which structures are in view volume.
   void traverse (OpenGl_BVHTreeSelector& theSelector) const;
 
@@ -150,6 +158,9 @@ private:
   //! Set of transform persistent OpenGl_Structures for building BVH tree.
   mutable OpenGl_BVHClipPrimitiveTrsfPersSet myBVHPrimitivesTrsfPers;
 
+  //! Indexed map of always rendered structures.
+  NCollection_IndexedMap<const OpenGl_Structure*> myAlwaysRenderedMap;
+
   //! Is needed for implementation of stochastic order of BVH traverse.
   mutable Standard_Boolean myBVHIsLeftChildQueuedFirst;
 
index cc40241..3735e32 100644 (file)
@@ -242,7 +242,7 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure*  theStructure,
 
   // take priority and remove structure from list found by <theOldLayerId>
   // if the structure is not found there, scan through all other layers
-  if (aLayer.Remove (theStructure, aPriority, Standard_True))
+  if (aLayer.Remove (theStructure, aPriority, Standard_False))
   {
     --myNbStructures;
     if (aLayer.LayerSettings().IsImmediate)
index f710c4e..1355473 100644 (file)
@@ -475,7 +475,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   {
     OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
     OpenGl_Mat4 aWorldView  = aCtx->WorldViewState.Current();
-    TransformPersistence.Apply (aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
+    TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
 
     aCtx->ProjectionState.Push();
     aCtx->WorldViewState.Push();
index 42dec5a..4c23086 100644 (file)
@@ -548,7 +548,7 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
                                                    const Handle(Graphic3d_Camera)& theCamera,
                                                    const Standard_Integer          theWindowWidth,
                                                    const Standard_Integer          theWindowHeight,
-                                                   const Standard_Boolean          theToIgnoreInfiniteFlag) const
+                                                   const Standard_Boolean          theToIncludeAuxiliary) const
 {
   if (myZLayers.LayerIDs().IsBound (theLayerId))
   {
@@ -556,7 +556,7 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
                                                      theCamera,
                                                      theWindowWidth,
                                                      theWindowHeight,
-                                                     theToIgnoreInfiniteFlag);
+                                                     theToIncludeAuxiliary);
   }
 
   return Graphic3d_BndBox4f();
@@ -569,16 +569,14 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
 Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
                                                            const Handle(Graphic3d_Camera)& theCamera,
                                                            const Standard_Integer          theWindowWidth,
-                                                           const Standard_Integer          theWindowHeight,
-                                                           const Standard_Boolean          theToIgnoreInfiniteFlag) const
+                                                           const Standard_Integer          theWindowHeight) const
 {
   if (myZLayers.LayerIDs().IsBound (theLayerId))
   {
     return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
                                                                         theCamera,
                                                                         theWindowWidth,
-                                                                        theWindowHeight,
-                                                                        theToIgnoreInfiniteFlag);
+                                                                        theWindowHeight);
   }
 
   return 1.0;
index 7be0103..7cdfdd4 100644 (file)
@@ -197,12 +197,18 @@ public:
   Standard_EXPORT virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const Standard_OVERRIDE;
 
   //! Returns the bounding box of all structures displayed in the Z layer.
-  //! Never fails. If Z layer does not exist the empty box is returned.
+  //! If Z layer does not exist the empty box is returned.
+  //! @param theLayerId            layer identifier
+  //! @param theCamera             camera definition
+  //! @param theWindowWidth        viewport width  (for applying transformation-persistence)
+  //! @param theWindowHeight       viewport height (for applying transformation-persistence)
+  //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
+  //! @return computed bounding box
   Standard_EXPORT virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
                                                                 const Handle(Graphic3d_Camera)& theCamera,
                                                                 const Standard_Integer          theWindowWidth,
                                                                 const Standard_Integer          theWindowHeight,
-                                                                const Standard_Boolean          theToIgnoreInfiniteFlag) const Standard_OVERRIDE;
+                                                                const Standard_Boolean          theToIncludeAuxiliary) const Standard_OVERRIDE;
 
   //! Returns pointer to an assigned framebuffer object.
   Standard_EXPORT virtual Handle(Standard_Transient) FBO() const Standard_OVERRIDE;
@@ -439,8 +445,7 @@ private:
   Standard_EXPORT virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
                                                                         const Handle(Graphic3d_Camera)& theCamera,
                                                                         const Standard_Integer          theWindowWidth,
-                                                                        const Standard_Integer          theWindowHeight,
-                                                                        const Standard_Boolean          theToIgnoreInfiniteFlag) const Standard_OVERRIDE;
+                                                                        const Standard_Integer          theWindowHeight) const Standard_OVERRIDE;
 
 private:
 
index cf10663..2d8d8ba 100644 (file)
@@ -35,6 +35,7 @@ SelectMgr_BaseFrustum::SelectMgr_BaseFrustum()
 //=======================================================================
 void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
 {
+  myCamera = theCamera;
   myBuilder->SetWorldViewMatrix (theCamera->OrientationMatrix());
   myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix());
   myBuilder->SetWorldViewProjState (theCamera->WorldViewProjState());
@@ -51,6 +52,7 @@ void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection,
                                        const Standard_Integer theIsOrthographic,
                                        const Graphic3d_WorldViewProjState& theWVPState)
 {
+  myCamera.Nullify();
   myBuilder->SetWorldViewMatrix (theWorldView);
   myBuilder->SetProjectionMatrix (theProjection);
   myBuilder->SetWorldViewProjState (theWVPState);
index 5855c6d..740a9b5 100644 (file)
@@ -48,6 +48,9 @@ public:
 
   virtual ~SelectMgr_BaseFrustum() {}
 
+  //! Return camera definition.
+  const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
+
   //! Passes camera projection and orientation matrices to builder
   Standard_EXPORT void SetCamera (const Handle(Graphic3d_Camera)& theCamera);
 
@@ -173,6 +176,7 @@ protected:
   Standard_Boolean    myIsOrthographic;      //!< Defines if current camera is orthographic
 
   Handle(SelectMgr_FrustumBuilder) myBuilder; //!< A tool implementing methods for volume build
+  Handle(Graphic3d_Camera)         myCamera;  //!< camera definition
 };
 
 #endif // _SelectMgr_BaseFrustum_HeaderFile
index 47faa72..ef38255 100644 (file)
@@ -117,7 +117,8 @@ Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Remove (const Handle(Sel
 // purpose  :
 //=======================================================================
 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
-  SelectMgr_SelectableObjectTrsfPersSet::BVH (const Graphic3d_Mat4d& theProjectionMatrix,
+  SelectMgr_SelectableObjectTrsfPersSet::BVH (const Handle(Graphic3d_Camera)& theCamera,
+                                              const Graphic3d_Mat4d& theProjectionMatrix,
                                               const Graphic3d_Mat4d& theWorldViewMatrix,
                                               const Standard_Integer theViewportWidth,
                                               const Standard_Integer theViewportHeight,
@@ -141,7 +142,7 @@ const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
       anObject->BoundingBox (aBoundingBox);
       if (!aBoundingBox.IsVoid())
       {
-        anObject->TransformPersistence().Apply (theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, aBoundingBox);
+        anObject->TransformPersistence().Apply (theCamera, theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, aBoundingBox);
       }
     }
 
index 94ccfc9..86580c2 100644 (file)
@@ -85,7 +85,8 @@ public:
   }
 
   //! Returns BVH tree for the given world view projection (builds it if necessary).
-  Standard_EXPORT const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& BVH (const Graphic3d_Mat4d& theProjectionMatrix,
+  Standard_EXPORT const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& BVH (const Handle(Graphic3d_Camera)& theCamera,
+                                                                              const Graphic3d_Mat4d& theProjectionMatrix,
                                                                               const Graphic3d_Mat4d& theWorldViewMatrix,
                                                                               const Standard_Integer theViewportWidth,
                                                                               const Standard_Integer theViewportHeight,
index 9321864..4d1b8fe 100644 (file)
@@ -53,6 +53,9 @@ public:
 
   Standard_EXPORT void SetActiveSelectionType (const SelectionType& theType);
 
+  //! Returns current camera definition.
+  const Handle(Graphic3d_Camera)& Camera() const { return mySelectingVolumes[Frustum]->Camera(); }
+
   //! Updates camera projection and orientation matrices in all selecting volumes
   Standard_EXPORT void SetCamera (const Handle(Graphic3d_Camera) theCamera);
 
index 16e34cc..3243627 100644 (file)
@@ -333,7 +333,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
       mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
 
       gp_GTrsf aTPers;
-      Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, aViewportWidth, aViewportHeight);
+      Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (mySelectingVolumeMgr.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight);
       aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
       aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
       aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
@@ -449,7 +449,7 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       Standard_Integer aViewportWidth;
       Standard_Integer aViewportHeight;
       mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
-      aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
+      aBVHTree = mySelectableObjectsTrsfPers.BVH (mySelectingVolumeMgr.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
     }
     else
     {
@@ -888,7 +888,7 @@ void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsF
     mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
 
     mySelectableObjects.BVH();
-    mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
+    mySelectableObjectsTrsfPers.BVH (mySelectingVolumeMgr.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
   }
 }
 
index d0c815c..dd5263d 100644 (file)
@@ -2224,7 +2224,7 @@ void V3d_View::Gravity (Standard_Real& theX,
   if (aNbPoints == 0)
   {
     // fallback - just use bounding box of entire scene
-    Bnd_Box aBox = myView->MinMaxValues (Standard_True);
+    Bnd_Box aBox = myView->MinMaxValues();
     if (!aBox.IsVoid())
     {
       aBox.Get (Xmin, Ymin, Zmin,
index fc05e27..69d747e 100644 (file)
@@ -4460,7 +4460,7 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
         Standard_Integer aViewportHeight = 0;
         aMgr.WindowSize (aViewportWidth, aViewportHeight);
 
-        Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aProjection, aWorldView, aViewportWidth, aViewportHeight);
+        Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aMgr.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight);
 
         anInvTrsf.SetValue (1, 1, aMat.GetValue (0, 0));
         anInvTrsf.SetValue (1, 2, aMat.GetValue (0, 1));
index f7cc40e..7ea8a20 100644 (file)
@@ -7,6 +7,8 @@ puts ""
 puts "Visualization - provide a support of zoom persistent selection"
 ##########################################################################################
 
+vclear
+vclose ALL
 vinit View1 w=409 h=409
 vtrihedron tri
 vpan 50 50
@@ -20,60 +22,49 @@ box b5 100 100 100
 # 1) Zoom persistence
 vpoint p1 200 200 200
 
-vdisplay b1 -trsfPers zoom -trsfPersPos 200 200 200
-vdisplay b2 -trsfPers zoom -trsfPersPos 200 200 200
+vdisplay b1 -dispMode 1 -highMode 1 -trsfPers zoom -trsfPersPos 200 200 200
+vdisplay b2 -dispMode 1 -highMode 1 -trsfPers zoom -trsfPersPos 200 200 200
 vsetlocation b2 -25 -25 -25
 
-vmoveto 387 77
-if { ![checkcolor 387 77 0 1 1] } {
-  puts "Error picking zoom persistence object"
-}
-
-vmoveto 352 96
-if { ![checkcolor 352 96 0 1 1] } {
-  puts "Error picking zoom persistent object with location"
-}
+vselect 0 0
+vselect 387 77
+if { [vreadpixel 387 77 rgb name] != "GRAY66" } { puts "Error picking zoom persistence object(s)" }
 
+vselect 0 0
 vselect 330 120 400 50
+if { [vreadpixel 387 77 rgb name] != "GRAY66" || [vreadpixel 352 96 rgb name] != "GRAY66" } { puts "Error selecting zoom persistence object(s)" }
 
-if { ![checkcolor 387 77 0.8 0.8 0.8] || ![checkcolor 352 96 0.8 0.8 0.8] } {
-  puts "Error selecting zoom persistence object(s)"
-}
 # 2) Rotate persistence
 
-vdisplay b3 -trsfPers rotate -trsfPersPos -200 -200 -200
-vmoveto 160 200
-if { ![checkcolor 160 180 0 1 1] } {
-  puts "Error picking rotate persistence object"
-}
+vdisplay b3 -dispMode 1 -highMode 1 -trsfPers rotate -trsfPersPos -200 -200 -200
+vsetmaterial b3 PLASTIC
+vselect 0 0
+vselect 160 200
+if { [vreadpixel 160 180 rgb name] != "WHITE" } { puts "Error picking rotate persistence object" }
+
+vselect 0 0
 vselect 130 230 190 170
-if { ![checkcolor 160 180 0.8 0.8 0.8] } {
-  puts "Error selecting rotate persistence object"
-}
+if { [vreadpixel 160 180 rgb name] != "WHITE" } { puts "Error selecting rotate persistence object" }
 
 # 3) Pan persistence
 
-vdisplay b4 -trsfPers pan
-vmoveto 233 188
-if { ![checkcolor 233 188 0 1 1] } {
-  puts "Error picking pan persistence object"
-}
+vdisplay b4 -dispMode 1 -highMode 1 -trsfPers pan
+vselect 0 0
+vselect 233 188
+if { [vreadpixel 233 188 rgb name] != "GRAY66" } { puts "Error picking pan persistence object" }
+vselect 0 0
 vselect 200 230 270 140
-if { ![checkcolor 233 188 0.8 0.8 0.8] } {
-  puts "Error selecting pan persistence object"
-}
+if { [vreadpixel 233 188 rgb name] != "GRAY66" } { puts "Error selecting pan persistence object" }
 
 # 4) Trihedron persistence
 
-vdisplay b5 -trsfPers trihedron -trsfPersPos -1 -1 300
-vmoveto 132 300
-if { ![checkcolor 132 300 0 1 1] } {
-  puts "Error picking trihedron persistence object"
-}
+vdisplay b5 -dispMode 1 -highMode 1 -trsfPers trihedron -trsfPersPos -1 -1 62
+vselect 0 0
+vselect 132 300
+if { [vreadpixel 132 300 rgb name] != "GRAY66" } { puts "Error picking trihedron persistence object" }
+vselect 0 0
 vselect 50 223 235 395
-if { ![checkcolor 132 300 0.8 0.8 0.8] } {
-  puts "Error selecting trihedron persistence object"
-}
+if { [vreadpixel 132 300 rgb name] != "GRAY66" } { puts "Error selecting trihedron persistence object" }
 
 vselect 50 380 400 50
 
diff --git a/tests/bugs/vis/bug27793 b/tests/bugs/vis/bug27793
new file mode 100644 (file)
index 0000000..f39ba45
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "Object drifts at zoom within Graphic3d_TMF_TriedronPers applied"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+box b 100 200 300
+vclear
+vinit View1
+vtrihedron t1
+vtrihedron t2
+vdisplay -dispMode 1 b
+vaxo
+vdisplay -trsfPers trihedron -trsfPersPos -1 -1 100 t1
+vdisplay -trsfPers trihedron -trsfPersPos  1  1 100 t2
+vsetlocation t2 0 0 -50
+vcamera -persp
+vstereo anaglyph
+vfit
+vzoom 0.05
+vdump $imagedir/${casename}.png -stereo blend