0026792: Visualization, Graphic3d - Z-fit support for transform persistence is missin...
authorapl <apl@opencascade.com>
Thu, 19 Nov 2015 08:16:14 +0000 (11:16 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 27 Nov 2015 07:18:12 +0000 (10:18 +0300)
Add missing code for z-fit support for zoom, rotate persistent object.
Fixed wrong statement that should enable frustum culling optimization for zoom, rotate persistent object.
Fixed BVH_LinearBuilder.lxx to correctly control number of items in leaf node for a case of items with equal bounding boxes.
Added non-regression test case for z-clipping of transform persistent objects.

src/BVH/BVH_LinearBuilder.lxx
src/Graphic3d/Graphic3d_CView.cxx
src/OpenGl/OpenGl_BVHClipPrimitiveTrsfPersSet.cxx
src/OpenGl/OpenGl_BVHTreeSelector.cxx
src/OpenGl/OpenGl_Layer.cxx
src/OpenGl/OpenGl_Structure.hxx
tests/bugs/vis/bug26792 [new file with mode: 0644]

index 478c788..d822a0f 100644 (file)
@@ -181,10 +181,11 @@ Standard_Integer BVH_LinearBuilder<T, N>::EmitHierachy (BVH_Tree<T, N>*
                                                         std::vector<BVH_EncodedLink>::iterator theStart,
                                                         std::vector<BVH_EncodedLink>::iterator theFinal)
 {
-  if (theFinal - theStart > BVH_Builder<T, N>::myLeafNodeSize && theBit >= 0)
+  if (theFinal - theStart > BVH_Builder<T, N>::myLeafNodeSize)
   {
-    std::vector<BVH_EncodedLink>::iterator aPosition = std::lower_bound (
-      theStart, theFinal, BVH_EncodedLink(), BVH::BitComparator (theBit));
+    std::vector<BVH_EncodedLink>::iterator aPosition =
+      (theBit >= 0) ? std::lower_bound (theStart, theFinal, BVH_EncodedLink(), BVH::BitComparator (theBit))
+                    :                   theStart + ((theFinal - theStart) / 2);
 
     if (aPosition == theStart || aPosition == theFinal)
     {
index 5568201..ed4f057 100644 (file)
@@ -401,53 +401,6 @@ void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructur
   }
 }
 
-//! Auxiliary method for MinMaxValues() method
-inline void addStructureBndBox (const Handle(Graphic3d_Structure)& theStruct,
-                                const Standard_Boolean             theToIgnoreInfiniteFlag,
-                                Bnd_Box&                           theBndBox)
-{
-  if (!theStruct->IsVisible())
-  {
-    return;
-  }
-  else if (theStruct->IsInfinite()
-       && !theToIgnoreInfiniteFlag)
-  {
-    // XMin, YMin .... ZMax are initialized by means of infinite line data
-    const Bnd_Box aBox = theStruct->MinMaxValues (Standard_False);
-    if (!aBox.IsWhole()
-     && !aBox.IsVoid())
-    {
-      theBndBox.Add (aBox);
-    }
-    return;
-  }
-
-  // Only non-empty and non-infinite structures
-  // are taken into account for calculation of MinMax
-  if (theStruct->IsEmpty()
-   || theStruct->TransformPersistenceMode() != Graphic3d_TMF_None)
-  {
-    return;
-  }
-
-  // "FitAll" operation ignores object with transform persistence parameter
-  const Bnd_Box aBox = theStruct->MinMaxValues (theToIgnoreInfiniteFlag);
-
-  // 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())
-    return;
-
-  theBndBox.Add (aBox);
-}
-
 // =======================================================================
 // function : MinMaxValues
 // purpose  :
@@ -472,20 +425,70 @@ Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
 {
   Bnd_Box aResult;
   const Standard_Integer aViewId = Identification();
+
+  Handle(Graphic3d_Camera) aCamera = Camera();
+  Standard_Integer aWinWidth  = 0;
+  Standard_Integer aWinHeight = 0;
+  if (IsDefined())
+  {
+    Window()->Size (aWinWidth, aWinHeight);
+  }
+
   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
   {
     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
-    if (!aStructIter.Value()->IsVisible())
+    if (!aStructure->IsVisible() || aStructure->IsEmpty())
+    {
+      continue;
+    }
+    else if (!aStructure->CStructure()->ViewAffinity.IsNull()
+          && !aStructure->CStructure()->ViewAffinity->IsVisible (aViewId))
+    {
+      continue;
+    }
+
+    // "FitAll" operation ignores object with transform persistence parameter
+    if (aStructure->TransformPersistence().Flags != Graphic3d_TMF_None)
+    {
+      // Panning and 2d persistence apply changes to projection or/and its translation components.
+      // It makes them incompatible with z-fitting algorithm. Ignored by now.
+      if (!theToIgnoreInfiniteFlag ||
+          (aStructure->TransformPersistence().Flags & Graphic3d_TMF_2d) ||
+          (aStructure->TransformPersistence().Flags & Graphic3d_TMF_PanPers) ||
+          (aStructure->TransformPersistence().Flags & Graphic3d_TMF_TriedronPers))
+      {
+        continue;
+      }
+    }
+
+    Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
+
+    if (aBox.IsWhole() || aBox.IsVoid())
     {
       continue;
     }
-    else if (!aStructIter.Value()->CStructure()->ViewAffinity.IsNull()
-          && !aStructIter.Value()->CStructure()->ViewAffinity->IsVisible (aViewId))
+
+    if (aStructure->TransformPersistence().Flags != Graphic3d_TMF_None)
+    {
+      const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
+      const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
+      aStructure->TransformPersistence().Apply (aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, 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())
     {
       continue;
     }
 
-    addStructureBndBox (aStructure, theToIgnoreInfiniteFlag, aResult);
+    aResult.Add (aBox);
   }
   return aResult;
 }
index 3555254..761b0cc 100644 (file)
@@ -1,4 +1,4 @@
-// Created on: 2015-06-30
+\feff// Created on: 2015-06-30
 // Created by: Anton POLETAEV
 // Copyright (c) 2015 OPEN CASCADE SAS
 //
@@ -67,7 +67,7 @@ void OpenGl_BVHClipPrimitiveTrsfPersSet::Swap (const Standard_Integer theIdx1,
   const Standard_Integer aStructIdx1 = theIdx1 + 1;
   const Standard_Integer aStructIdx2 = theIdx2 + 1;
 
-  myStructs.Swap (aStructIdx1, aStructIdx2);
+  myStructs    .Swap (aStructIdx1, aStructIdx2);
   myStructBoxes.Swap (aStructIdx1, aStructIdx2);
 }
 
@@ -137,7 +137,9 @@ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
                                            const OpenGl_Mat4& theWorldViewMatrix,
                                            const Graphic3d_WorldViewProjState& theWVPState)
 {
-  if (!myIsDirty && (myStructBoxesState.IsValid() && !myStructBoxesState.IsChanged(theWVPState)))
+  if (!myIsDirty
+    && (myStructBoxesState.IsValid()
+    && !myStructBoxesState.IsChanged (theWVPState)))
   {
     return myBVH;
   }
@@ -149,13 +151,8 @@ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >&
     const OpenGl_Structure* aStructure = myStructs (aStructIdx);
 
     HBndBox4f aBoundingBox = new Graphic3d_BndBox4f;
-
-    if (aStructure->TransformPersistence.Flags && !(aStructure->TransformPersistence.Flags & Graphic3d_TMF_2d))
-    {
-      *aBoundingBox = aStructure->BoundingBox();
-
-      aStructure->TransformPersistence.Apply (theProjectionMatrix, theWorldViewMatrix, 0, 0, *aBoundingBox);
-    }
+    *aBoundingBox = aStructure->BoundingBox();
+     aStructure->TransformPersistence.Apply (theProjectionMatrix, theWorldViewMatrix, 0, 0, *aBoundingBox);
 
     myStructBoxes.Add (aBoundingBox);
   }
index f71f9bf..09298ea 100644 (file)
@@ -35,10 +35,8 @@ OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
 // =======================================================================
 void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theCamera)
 {
-  if (myWorldViewProjState == theCamera->WorldViewProjState())
-  {
+  if (!myWorldViewProjState.IsChanged (theCamera->WorldViewProjState()))
     return;
-  }
 
   myIsProjectionParallel = theCamera->IsOrthographic();
 
index d902414..f873314 100644 (file)
@@ -64,7 +64,7 @@ void OpenGl_Layer::Add (const OpenGl_Structure* theStruct,
   }
   else if (!isForChangePriority)
   {
-    if (!theStruct->TransformPersistence.Flags)
+    if (theStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
     {
       myBVHPrimitives.Add (theStruct);
     }
@@ -177,7 +177,7 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
         if (aStruct->IsAlwaysRendered())
           continue;
 
-        if (!aStruct->TransformPersistence.Flags)
+        if (aStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
         {
           myBVHPrimitives.Add (aStruct);
         }
@@ -224,7 +224,8 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
 void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
 {
   // handle a case when all objects are infinite
-  if (myBVHPrimitives.Size() == 0 && myBVHPrimitivesTrsfPers.Size() == 0)
+  if (myBVHPrimitives        .Size() == 0
+   && myBVHPrimitivesTrsfPers.Size() == 0)
     return;
 
   theSelector.CacheClipPtsProjections();
@@ -237,20 +238,18 @@ void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
     if (isTrsfPers)
     {
       if (myBVHPrimitivesTrsfPers.Size() == 0)
-      {
         continue;
-      }
-      const OpenGl_Mat4& aProjection = theSelector.ProjectionMatrix();
-      const OpenGl_Mat4& aWorldView  = theSelector.WorldViewMatrix();
+
+      const OpenGl_Mat4& aProjection                = theSelector.ProjectionMatrix();
+      const OpenGl_Mat4& aWorldView                 = theSelector.WorldViewMatrix();
       const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState();
       aBVHTree = myBVHPrimitivesTrsfPers.BVH (aProjection, aWorldView, aWVPState);
     }
     else
     {
       if (myBVHPrimitives.Size() == 0)
-      {
         continue;
-      }
+
       aBVHTree = myBVHPrimitives.BVH();
     }
 
index b4a1372..479a683 100644 (file)
@@ -163,7 +163,9 @@ public:
         || IsForHighlight
         || IsMutable
         || Is2dText
-        || TransformPersistence.Flags != 0;
+        || (TransformPersistence.Flags & Graphic3d_TMF_2d)           != 0
+        || (TransformPersistence.Flags & Graphic3d_TMF_PanPers)      != 0
+        || (TransformPersistence.Flags & Graphic3d_TMF_TriedronPers) != 0;
   }
 
   //! This method releases GL resources without actual elements destruction.
diff --git a/tests/bugs/vis/bug26792 b/tests/bugs/vis/bug26792
new file mode 100644 (file)
index 0000000..6502545
--- /dev/null
@@ -0,0 +1,21 @@
+puts "================================================================"
+puts "CR26792"
+puts "Visualization, Graphic3d - Z-fit support for transform persistence is missing after removing Visual3d_View"
+puts "================================================================"
+puts ""
+
+vinit
+vclear
+vaxo
+
+box b 100 100 100
+vdisplay b -trsfPers zoom
+vzoom 0.01
+vzfit
+
+checkcolor 204 184 1.0 1.0 0.0
+checkcolor 232 205 1.0 1.0 0.0
+checkcolor 262 182 1.0 1.0 0.0
+checkcolor 233 184 1.0 1.0 0.0
+
+set only_screen 1
\ No newline at end of file