0027317: Some visualisation tests failed because of exceptions generated by FP signals.
[occt.git] / src / OpenGl / OpenGl_BVHClipPrimitiveSet.cxx
index 4f3b9e8..a21840f 100644 (file)
@@ -16,6 +16,7 @@
 #include <OpenGl_BVHClipPrimitiveSet.hxx>
 
 #include <BVH_BinnedBuilder.hxx>
+#include <Graphic3d_GraphicDriver.hxx>
 
 // =======================================================================
 // function : OpenGl_BVHClipPrimitiveSet
@@ -41,7 +42,7 @@ Standard_Integer OpenGl_BVHClipPrimitiveSet::Size() const
 // =======================================================================
 Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
 {
-  return myStructs (theIdx + 1)->BoundingBox();
+  return myStructs.FindKey (theIdx + 1)->BoundingBox();
 }
 
 // =======================================================================
@@ -51,12 +52,19 @@ Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theId
 Standard_ShortReal OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx,
                                                        const Standard_Integer theAxis) const
 {
-  Graphic3d_BndBox4f aBndBox = myStructs (theIdx + 1)->BoundingBox();
-  Standard_ShortReal aCenter =  theAxis == 0 ? (aBndBox.CornerMin().x() + aBndBox.CornerMax().x()) * 0.5f
-                             : (theAxis == 1 ? (aBndBox.CornerMin().y() + aBndBox.CornerMax().y()) * 0.5f
-                             : (theAxis == 2 ? (aBndBox.CornerMin().z() + aBndBox.CornerMax().z()) * 0.5f
-                             : (aBndBox.CornerMin().w() + aBndBox.CornerMax().w()) * 0.5f));
-  return aCenter;
+  Graphic3d_BndBox4f aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox();
+
+  // to prevent float overflow
+  const Standard_Real aMin = Standard_Real (aBndBox.CornerMin()[theAxis]);
+  const Standard_Real aMax = Standard_Real (aBndBox.CornerMax()[theAxis]);
+  const Standard_Real aCenter = (aMin + aMax) * 0.5;
+
+  if (aCenter <= Standard_Real (-ShortRealLast()))
+    return -ShortRealLast();
+  if (aCenter >= Standard_Real (ShortRealLast()))
+    return ShortRealLast();
+
+  return Standard_ShortReal (aCenter);
 }
 
 // =======================================================================
@@ -66,61 +74,45 @@ Standard_ShortReal OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer th
 void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1,
                                        const Standard_Integer theIdx2)
 {
-  const OpenGl_Structure* aStruct1 = myStructs (theIdx1 + 1);
-  const OpenGl_Structure* aStruct2 = myStructs (theIdx2 + 1);
-  myStructs.ChangeValue (theIdx1 + 1) = aStruct2;
-  myStructs.ChangeValue (theIdx2 + 1) = aStruct1;
+  myStructs.Swap (theIdx1 + 1, theIdx2 + 1);
 }
 
 // =======================================================================
-// function : Assign
+// function : Add
 // purpose  :
 // =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Assign (const OpenGl_ArrayOfStructure& theStructs)
+Standard_Boolean OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
 {
-  myStructs.Clear();
+  const Standard_Integer aSize = myStructs.Size();
 
-  const Standard_Integer aNbPriorities = theStructs.Length();
-  OpenGl_SequenceOfStructure::Iterator aStructIter;
-  for (Standard_Integer aPriorityIdx = 0; aPriorityIdx < aNbPriorities; ++aPriorityIdx)
+  if (myStructs.Add (theStruct) > aSize) // new structure?
   {
-    const OpenGl_SequenceOfStructure& aSeq = theStructs (aPriorityIdx);
-    for (aStructIter.Init (aSeq); aStructIter.More(); aStructIter.Next())
-    {
-      const OpenGl_Structure* aStruct = aStructIter.Value();
-      if (!aStruct->IsAlwaysRendered())
-        myStructs.Append (aStruct);
-    }
-  }
+    MarkDirty();
 
-  MarkDirty();
-}
+    return Standard_True;
+  }
 
-// =======================================================================
-// function : Add
-// purpose  :
-// =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
-{
-  myStructs.Append (theStruct);
-  MarkDirty();
+  return Standard_False;
 }
 
 // =======================================================================
 // function : Remove
 // purpose  :
 // =======================================================================
-void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
+Standard_Boolean OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
 {
-  for (Standard_Integer anIdx = 1; anIdx <= myStructs.Size(); ++anIdx)
+  const Standard_Integer anIndex = myStructs.FindIndex (theStruct);
+
+  if (anIndex != 0)
   {
-    if (myStructs (anIdx) == theStruct)
-    {
-      myStructs.Remove (anIdx);
-      MarkDirty();
-      break;
-    }
+    myStructs.Swap (Size(), anIndex);
+    myStructs.RemoveLast();
+    MarkDirty();
+
+    return Standard_True;
   }
+
+  return Standard_False;
 }
 
 // =======================================================================
@@ -139,5 +131,5 @@ void OpenGl_BVHClipPrimitiveSet::Clear()
 // =======================================================================
 const OpenGl_Structure* OpenGl_BVHClipPrimitiveSet::GetStructureById (Standard_Integer theId)
 {
-  return myStructs (theId + 1);
+  return myStructs.FindKey (theId + 1);
 }