]> OCCT Git - occt-copy.git/commitdiff
0030695: Visualization - selection by box should use clipping planes set for viewer...
authornds <nds@opencascade.com>
Fri, 24 May 2019 13:06:20 +0000 (16:06 +0300)
committernds <nds@opencascade.com>
Fri, 24 May 2019 13:06:20 +0000 (16:06 +0300)
src/Graphic3d/Graphic3d_ClipPlane.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/StdSelect/StdSelect_ViewerSelector3d.cxx
tests/bugs/vis/bug30695 [new file with mode: 0644]

index 8e4c34835e514f8ef724ece1c987e51a43734e2f..ddbbd321aaa61a788a67466c9638894022e18835 100755 (executable)
@@ -233,6 +233,31 @@ public:
     return aState;
   }
 
+  //! Check if the given bounding box is In and touch the clipping planes
+  Standard_Boolean ProbeBoxTouch (const Graphic3d_BndBox3d& theBox) const
+  {
+    Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
+    for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
+    {
+      if (aPlaneIter->IsBoxFullInHalfspace (theBox))
+      {
+        // within union operation, if box is entirely inside at least one half-space, others can be ignored
+        return Standard_False;
+      }
+      else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
+      {
+        // the box is not fully out, and not fully in, check is it on (but not intersect)
+        if (ProbeBoxMaxPointHalfspace (theBox) != Graphic3d_ClipState_Out)
+        {
+          return Standard_True;
+        }
+        // if at least one full out test fail, clipping state is inconclusive (partially clipped)
+        aState = Graphic3d_ClipState_On;
+      }
+    }
+    return Standard_False;
+  }
+
 public:
 
   //! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
@@ -271,6 +296,16 @@ public:
     return IsPointOutHalfspace (aMaxPnt);
   }
 
+  //! Check if the given bounding box is fully outside of the half-space (e.g. should be discarded by clipping plane).
+  Graphic3d_ClipState ProbeBoxMaxPointHalfspace (const Graphic3d_BndBox3d& theBox) const
+  {
+    const Graphic3d_Vec4d aMaxPnt (myEquation.x() > 0.0 ? theBox.CornerMax().x() : theBox.CornerMin().x(),
+                                   myEquation.y() > 0.0 ? theBox.CornerMax().y() : theBox.CornerMin().y(),
+                                   myEquation.z() > 0.0 ? theBox.CornerMax().z() : theBox.CornerMin().z(),
+                                   1.0);
+    return ProbePointHalfspace (aMaxPnt);
+  }
+
   //! Check if the given bounding box is fully inside (or touches from inside) the half-space (e.g. NOT discarded by clipping plane).
   bool IsBoxFullInHalfspace (const Graphic3d_BndBox3d& theBox) const
   {
index 3b3d9dad9fb1bc39bf3a44a9b33b8d985f2351cf..a0f8cddbb27cee0450ef9900420dc7c817b592d7 100644 (file)
@@ -435,7 +435,36 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
   {
     return;
   }
+  // in case of Box/Polyline selection - keep only Owners having all Entities detected
+  if (!theMgr.ViewClipping().IsNull() &&
+      theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
+ //&& theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
+  {
+    Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
+    // If box selection is active, and the whole sensitive tree is out of the clip planes
+    // selection is empty for this object
+    const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+    for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
+    {
+      const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+      if (!aPlane->IsOn())
+      {
+        continue;
+      }
 
+      Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
+      if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
+      {
+        return;
+      }
+      //if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
+      //{
+      //  return;
+      //}
+    }
+  }
   const Standard_Integer aFirstStored = mystored.Extent() + 1;
 
   Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
@@ -479,17 +508,52 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
     }
     else
     {
-      Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
-      Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
-      for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
+      bool aClipped = false;
+      if (!theMgr.ViewClipping().IsNull() &&
+          theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
+     //&& theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
       {
-        const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
-        if (aSensitive->IsActiveForSelection())
+        Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
+        // If box selection is active, and the whole sensitive tree is out of the clip planes
+        // selection is empty for this object
+        const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+        for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
         {
-          const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
-          SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
-          computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
-          checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
+          const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+          if (!aPlane->IsOn())
+          {
+            continue;
+          }
+          Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
+          if (aState == Graphic3d_ClipState_Out)
+          {
+            aClipped = true;
+            break;
+          }
+          if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
+          {
+            if (aPlane->ProbeBoxTouch (aBBox))
+              continue;
+            aClipped = true;
+            break;
+          }
+        }
+      }
+      if (!aClipped)
+      {
+        Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
+        Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
+        for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
+        {
+          const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
+          if (aSensitive->IsActiveForSelection())
+          {
+            const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
+            SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
+            computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
+            checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
+          }
         }
       }
       if (aHead < 0)
index 19fc15a01dcdb27d5dca760bd289fa87d052bf54..8ed26b7c6d51827d1e9d43b2fc59e6a1f670714c 100644 (file)
@@ -175,6 +175,8 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
   mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
                                              aMaxMousePos);
 
+  mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes());
+
   TraverseSensitives();
 }
 
@@ -193,6 +195,8 @@ void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
   mySelectingVolumeMgr.BuildSelectingVolume (thePolyline);
 
+  mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes());
+
   TraverseSensitives();
 }
 
diff --git a/tests/bugs/vis/bug30695 b/tests/bugs/vis/bug30695
new file mode 100644 (file)
index 0000000..85e240d
--- /dev/null
@@ -0,0 +1,36 @@
+puts "============="
+puts "0030695: Visualization - selection by box should use clipping planes set for viewer"
+puts "============="
+
+pload ALL
+vinit View1
+
+box b 10 10 10
+vdisplay b
+
+box b1 -5 0 0 2 2 2
+vdisplay b1
+
+box b2 13 0 0 2 2 2
+vdisplay b2
+
+box b3 16 0 0 2 2 2
+vdisplay b3
+
+vsetdispmode 1
+
+vtop
+vfit
+vzoom 0.5
+vselect 40 100 370 300
+vnbselected
+
+vclipplane create pln
+vclipplane set pln view Driver1/Viewer1/View1
+vclipplane change pln equation -1 0 0 5
+
+vselect 40 100 370 300
+vnbselected
+
+vselect 40 100 370 300 -allowoverlap 1
+vnbselected