0027618: Visualization - selection returns entity overlapped by another entity on...
authorkgv <kgv@opencascade.com>
Sun, 25 Mar 2018 17:41:41 +0000 (20:41 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 26 Mar 2018 12:55:57 +0000 (15:55 +0300)
SelectMgr_ViewerSelector::updatePoint3d() - scale tolerance according to Camera defintion.
SelectMgr_RectangularFrustum::segmentSegmentDistance() now uses gp::Resolution() instead of Precision::Confusion().

src/SelectMgr/SelectMgr_RectangularFrustum.cxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.hxx
tests/bugs/vis/bug24420
tests/bugs/vis/bug26413
tests/bugs/vis/bug27618 [new file with mode: 0644]

index 6322cf2..6b74179 100644 (file)
@@ -39,7 +39,7 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
   Standard_Real aSn = aCoef;
   Standard_Real aTc, aTn, aTd = aCoef;
 
-  if (aCoef < Precision::Confusion())
+  if (aCoef < gp::Resolution())
   {
     aTn = anE;
     aTd = aC;
@@ -68,7 +68,7 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
   {
     aTn = aTd;
   }
-  aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
+  aTc = (Abs (aTd) < gp::Resolution() ? 0.0 : aTn / aTd);
 
   gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTc;
   theDepth = myNearPickedPnt.Distance (aClosestPnt) * myScale;
index eed1b3f..8709197 100644 (file)
@@ -59,29 +59,47 @@ namespace {
     const SelectMgr_IndexedDataMapOfOwnerCriterion&  myMapOfCriterion;
   };
 
-  //! Compute 3d position for detected entity.
-  inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
-                             const gp_GTrsf& theInversedTrsf,
-                             SelectMgr_SelectingVolumeManager& theMgr)
+  static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+}
+
+//=======================================================================
+// function : updatePoint3d
+// purpose  :
+//=======================================================================
+void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+                                              const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                                              const gp_GTrsf& theInversedTrsf,
+                                              const SelectMgr_SelectingVolumeManager& theMgr) const
+{
+  if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
   {
-    if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
-    {
-      return;
-    }
+    return;
+  }
 
-    theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
-    gp_GTrsf anInvTrsf = theInversedTrsf;
-    if (theCriterion.Entity->HasInitLocation())
-    {
-      anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
-    }
-    if (anInvTrsf.Form() != gp_Identity)
-    {
-      anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
-    }
+  theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
+  gp_GTrsf anInvTrsf = theInversedTrsf;
+  if (theCriterion.Entity->HasInitLocation())
+  {
+    anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
+  }
+  if (anInvTrsf.Form() != gp_Identity)
+  {
+    anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
   }
 
-  static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+  if (mySelectingVolumeMgr.Camera().IsNull())
+  {
+    theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
+  }
+  else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
+  {
+    theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
+  }
+  else
+  {
+    const Standard_Real aDistFromEye = (theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ());
+    theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
+  }
 }
 
 //==================================================
@@ -91,6 +109,7 @@ namespace {
 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
 preferclosest(Standard_True),
 myToUpdateTolerance (Standard_True),
+myCameraScale (1.0),
 myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
 myEntityIdx (0)
@@ -249,7 +268,6 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   aCriterion.Priority  = anOwner->Priority();
   aCriterion.Depth     = aPickResult.Depth();
   aCriterion.MinDist   = aPickResult.DistToGeomCenter();
-  aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
   aCriterion.ToPreferClosest = preferclosest;
 
   if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
@@ -260,7 +278,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
     {
       if (aCriterion > *aPrevCriterion)
       {
-        updatePoint3d (aCriterion, theInversedTrsf, theMgr);
+        updatePoint3d (aCriterion, theEntity, theInversedTrsf, theMgr);
         *aPrevCriterion = aCriterion;
       }
     }
@@ -268,7 +286,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   else
   {
     aCriterion.NbOwnerMatches = 1;
-    updatePoint3d (aCriterion, theInversedTrsf, theMgr);
+    updatePoint3d (aCriterion, theEntity, theInversedTrsf, theMgr);
     mystored.Add (anOwner, aCriterion);
   }
 }
@@ -477,6 +495,17 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
                                  mySelectingVolumeMgr.WorldViewMatrix(),
                                  mySelectingVolumeMgr.WorldViewProjState(),
                                  aWidth, aHeight);
+  const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
+  if (!aCamera.IsNull())
+  {
+    myCameraEye = aCamera->Eye().XYZ();
+    myCameraDir = aCamera->Direction().XYZ();
+    myCameraScale = aCamera->IsOrthographic()
+                  ? aCamera->Scale()
+                  : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
+    const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
+    myCameraScale *= aPixelSize;
+  }
 
   for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
   {
@@ -521,7 +550,6 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       aMgr = mySelectingVolumeMgr;
     }
 
-    const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
     const Graphic3d_Mat4d& aProjectionMat   = mySelectingVolumeMgr.ProjectionMatrix();
     const Graphic3d_Mat4d& aWorldViewMat    = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
                                             ? mySelectingVolumeMgr.WorldViewMatrix()
index ae444bb..4cbe359 100644 (file)
@@ -321,6 +321,12 @@ private: // implementation of deprecated methods
     return myCurRank <= myIndexes->Length();
   }
 
+  //! Compute 3d position for detected entity.
+  void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+                      const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                      const gp_GTrsf& theInversedTrsf,
+                      const SelectMgr_SelectingVolumeManager& theMgr) const;
+
 protected:
 
   Standard_Boolean                              preferclosest;
@@ -331,6 +337,9 @@ protected:
   SelectMgr_ToleranceMap                        myTolerances;
   NCollection_DataMap<Graphic3d_ZLayerId, Standard_Integer> myZLayerOrderMap;
   Handle(Select3D_BVHBuilder3d)                 myEntitySetBuilder;
+  gp_Pnt                                        myCameraEye;
+  gp_Dir                                        myCameraDir;
+  Standard_Real                                 myCameraScale;
 
 private:
 
index 361dc1b..3331c52 100644 (file)
@@ -1,12 +1,9 @@
 puts "============"
-puts "CR24420"
+puts "CR24420: Test for type of sensitivity of AIS_Plane"
 puts "============"
 puts ""
 
-#######################################################################
-#  Test for type of sensitivity of AIS_Plane
-#######################################################################
-
+pload VISUALIZATION
 set aV "Driver1/Viewer1/View1"
 vinit name=$aV l=32 t=32 w=400 h=400
 vactivate $aV
@@ -20,7 +17,7 @@ puts "Testing Select3D_TOS_INTERIOR type of sensitivity:"
 vplane pl1 p1 p2 p3 0
 vfit
 
-vmoveto 200 200
+vmoveto 210 210
 checkcolor 395 200 0 1 1
 
 if { $stat != 1 } {
@@ -34,7 +31,7 @@ puts "Testing Select3D_TOS_BOUNDARY type of sensitivity:"
 vplane pl2 p1 p2 p3 1
 vfit
 
-vmoveto 200 200
+vmoveto 210 210
 checkcolor 395 200 0.5 0.8 0.9
 
 if { $stat != 1 } {
index d321f66..afbc550 100644 (file)
@@ -25,8 +25,8 @@ set y_sel_tol 400
 
 set x_notol 374
 set y_notol 309
-set x_tol 370
-set y_tol 312
+set x_tol 372
+set y_tol 310
 
 vselmode b 2 1
 
@@ -78,3 +78,4 @@ checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
 checkcolor $x_on_vert $y_on_vert 0 1 1
 
 vdump ${imagedir}/${casename}.png
+vseldump ${imagedir}/${casename}_sel_ent.png -type entity
diff --git a/tests/bugs/vis/bug27618 b/tests/bugs/vis/bug27618
new file mode 100644 (file)
index 0000000..c8fc167
--- /dev/null
@@ -0,0 +1,37 @@
+puts "# ==================================================================="
+puts "# 0027618: Visualization - selection returns entity overlapped by another entity on border cases"
+puts "# ==================================================================="
+puts ""
+
+pload MODELING VISUALIZATION
+set s 0.001
+box bb  0*$s  0*$s  0*$s 100*$s 100*$s 50*$s
+box bt 50*$s 50*$s 25*$s  20*$s  20*$s 40*$s
+vclear
+vinit View1
+vpoint p0 0*$s   0*$s  0*$s
+vpoint p1 0*$s 100*$s 50*$s
+vdisplay -dispMode 1 -highMode 1 bb bt
+vsetcolor bt RED
+vaxo
+vfit
+
+vpoint pp 245 -190 0
+vdisplay -2d topLeft -topmost pp
+vselmode pp 0 0
+vmoveto 245 190
+
+if { [vreadpixel 235 140 rgb name] == "DARKTURQUOISE" } { puts "Error: top should NOT be highlighted" }
+if { [vreadpixel 235 190 rgb name] != "DARKTURQUOISE" } { puts "Error: bottom should be highlighted" }
+vseldump $imagedir/${casename}_sel_depth.png  -type depth
+vseldump $imagedir/${casename}_sel_entity.png -type entity
+
+vcamera -persp
+
+vmoveto 0 0
+vmoveto 245 190
+if { [vreadpixel 235 140 rgb name] == "DARKTURQUOISE" } { puts "Error: top should NOT be highlighted" }
+if { [vreadpixel 235 190 rgb name] != "DARKTURQUOISE" } { puts "Error: bottom should be highlighted" }
+
+vseldump $imagedir/${casename}_perps_sel_depth.png  -type depth
+vseldump $imagedir/${casename}_persp_sel_entity.png -type entity