0027945: Visualization - handle correctly view clipping planes within zoom-persistent...
authorkgv <kgv@opencascade.com>
Thu, 13 Oct 2016 11:01:19 +0000 (14:01 +0300)
committerapn <apn@opencascade.com>
Thu, 13 Oct 2016 11:01:37 +0000 (14:01 +0300)
OpenGl_Structure::Render() and SelectMgr_ViewerSelector::checkOverlap()
now clip entire zoom/rotate persistence object
by checking anchor point with global clipping planes.

Image dump has been added to the new test case.

src/OpenGl/OpenGl_Structure.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
tests/bugs/vis/bug27945 [new file with mode: 0644]

index 26b654e..608050e 100644 (file)
@@ -516,12 +516,43 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   if (aCtx->Clipping().IsClippingOrCappingOn())
   {
     const Graphic3d_BndBox4f& aBBox = BoundingBox();
-    if ((!myTrsfPers.IsNull() && myTrsfPers->IsTrihedronOr2d())
-     || (!myClipPlanes.IsNull() && myClipPlanes->ToOverrideGlobal()))
+    if (!myClipPlanes.IsNull()
+      && myClipPlanes->ToOverrideGlobal())
     {
       aCtx->ChangeClipping().DisableGlobal (aCtx);
       hasDisabled = aCtx->Clipping().HasDisabled();
     }
+    else if (!myTrsfPers.IsNull())
+    {
+      if (myTrsfPers->IsZoomOrRotate())
+      {
+        // Zoom/rotate persistence object lives in two worlds at the same time.
+        // Global clipping planes can not be trivially applied without being converted
+        // into local space of transformation persistence object.
+        // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+        const gp_Pnt anAnchor = myTrsfPers->AnchorPoint();
+        for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next())
+        {
+          const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+          if (!aPlane->IsOn())
+          {
+            continue;
+          }
+
+          // check for clipping
+          const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
+          const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+          if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+          {
+            isClipped = true;
+            break;
+          }
+        }
+      }
+
+      aCtx->ChangeClipping().DisableGlobal (aCtx);
+      hasDisabled = aCtx->Clipping().HasDisabled();
+    }
 
     // Set of clipping planes that do not intersect the structure,
     // and thus can be disabled to improve rendering performance
index 9c140e0..e87ccb9 100644 (file)
@@ -60,6 +60,7 @@ SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTrans
     = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
   aMgr.myToAllowOverlap = myToAllowOverlap;
   aMgr.mySelectingVolumes[myActiveSelectionType / 2]->SetBuilder (theBuilder);
+  aMgr.myViewClipPlanes = myViewClipPlanes;
 
   return aMgr;
 }
@@ -469,6 +470,7 @@ gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const
 //=======================================================================
 void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
 {
+  myViewClipPlanes = thePlanes;
   if (myActiveSelectionType != Point)
     return;
 
index a249f8f..42ae476 100644 (file)
@@ -170,6 +170,9 @@ public:
 
   Standard_EXPORT virtual Standard_Boolean IsOverlapAllowed() const Standard_OVERRIDE;
 
+  //! Return view clipping planes.
+  const Handle(Graphic3d_SequenceOfHClipPlane)& ViewClipping() const { return myViewClipPlanes; }
+
   //! Valid for point selection only!
   //! Computes depth range for global (defined for the whole view) clipping planes.
   Standard_EXPORT void SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes);
@@ -196,8 +199,9 @@ public:
 private:
   enum { Frustum, FrustumSet, VolumeTypesNb };       //!< Defines the amount of available selecting volumes
 
-  Handle(SelectMgr_BaseFrustum) mySelectingVolumes[VolumeTypesNb];      //!< Array of selecting volumes
-  Standard_Boolean              myToAllowOverlap;      //!< Defines if partially overlapped entities will me detected or not
+  Handle(SelectMgr_BaseFrustum)          mySelectingVolumes[VolumeTypesNb]; //!< Array of selecting volumes
+  Handle(Graphic3d_SequenceOfHClipPlane) myViewClipPlanes;                  //!< view clipping planes
+  Standard_Boolean                       myToAllowOverlap;                  //!< Defines if partially overlapped entities will me detected or not
 };
 
-#endif
\ No newline at end of file
+#endif
index 70c1c77..bb95574 100644 (file)
@@ -176,12 +176,44 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   if (!anOwner.IsNull())
   {
     aSelectable = anOwner->Selectable();
-    if ((!aSelectable->TransformPersistence().IsNull() && aSelectable->TransformPersistence()->IsTrihedronOr2d())
-     || (!aSelectable->ClipPlanes().IsNull() && aSelectable->ClipPlanes()->ToOverrideGlobal()))
+    if (!aSelectable->ClipPlanes().IsNull()
+      && aSelectable->ClipPlanes()->ToOverrideGlobal())
     {
       theMgr.SetViewClippingEnabled (Standard_False);
       toRestoresViewClipEnabled = Standard_True;
     }
+    else if (!aSelectable->TransformPersistence().IsNull())
+    {
+      if (aSelectable->TransformPersistence()->IsZoomOrRotate()
+      && !theMgr.ViewClipping().IsNull())
+      {
+        // Zoom/rotate persistence object lives in two worlds at the same time.
+        // Global clipping planes can not be trivially applied without being converted
+        // into local space of transformation persistence object.
+        // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+        const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+        const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint();
+        for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
+        {
+          const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+          if (!aPlane->IsOn())
+          {
+            continue;
+          }
+
+          const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
+          const Graphic3d_Vec4d  aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+          if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+          {
+            return;
+          }
+        }
+      }
+
+      theMgr.SetViewClippingEnabled (Standard_False);
+      toRestoresViewClipEnabled = Standard_True;
+    }
   }
 
   SelectBasics_PickResult aPickResult;
diff --git a/tests/bugs/vis/bug27945 b/tests/bugs/vis/bug27945
new file mode 100644 (file)
index 0000000..f3539be
--- /dev/null
@@ -0,0 +1,72 @@
+puts "==========="
+puts "OCC27945"
+puts "Visualization - handle correctly view clipping planes within zoom-persistent objects"
+puts "==========="
+puts ""
+
+pload MODELING VISUALIZATION
+
+box b 3 1 2
+box z000 50 40 30
+box z010 50 40 30
+box z002 50 40 30
+box z012 50 40 30
+box z300 50 40 30
+box z302 50 40 30
+box z310 50 40 30
+box z312 50 40 30
+box r1 0.2 0.1 0.1
+box r2 0.2 0.1 0.1
+
+vclear
+vinit View1
+vaxo
+vzbufftrihedron
+vdisplay -dispMode 1 b
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 0 0 0 z000
+vsetlocation z000 -25 -20 -15
+vdrawtext    t000 "000\n" -pos 0 0 0 -color RED -halign right
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 0 1 0 z010
+vsetlocation z010 -25 -20 -15
+vdrawtext    t010 "010\n" -pos 0 1 0 -color RED -halign right
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 0 0 2 z002
+vsetlocation z002 -25 -20 -15
+vdrawtext    t002 "002\n" -pos 0 0 2 -color RED -halign right
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 0 1 2 z012
+vsetlocation z012 -25 -20 -15
+vdrawtext    t012 "012\n" -pos 0 1 2 -color RED -halign right
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 3 0 0 z300
+vsetlocation z300 -25 -20 -15
+vdrawtext    t300 "300\n" -pos 3 0 0 -color RED -halign left
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 3 0 2 z302
+vsetlocation z302 -25 -20 -15
+vdrawtext    t302 "302\n" -pos 3 0 2 -color RED -halign left
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 3 1 0 z310
+vsetlocation z310 -25 -20 -15
+vdrawtext    t310 "310\n" -pos 3 1 0 -color RED -halign left
+
+vdisplay -noupdate -dispMode 1 -trsfPers zoom -trsfPersPos 3 1 2 z312
+vsetlocation z312 -25 -20 -15
+vdrawtext    t312 "312\n" -pos 3 1 2 -color RED -halign left
+
+vdisplay -noupdate -dispMode 1 -trsfPers rotate -trsfPersPos -1 1 2 r1
+vdisplay -noupdate -dispMode 1 -trsfPers rotate -trsfPersPos  4 1 2 r2
+
+vfit
+vrotate 0.1 0 0
+
+vclipplane pln -equation -1 0 0 2 -set
+
+set aColor1 [vreadpixel 320 160 rgb name]
+set aColor2 [vreadpixel 80  250 rgb name]
+if { "$aColor1" != "BLACK"      } { puts "Error: zoom-persistent object is not clipped" }
+if { "$aColor2" != "GOLDENROD3" } { puts "Error: zoom-persistent object is clipped" }
+
+vdump $imagedir/${casename}.png