diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx index 6322cf2d10..6b741791ae 100644 --- a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx @@ -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; diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index eed1b3fc9b..8709197b0b 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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) - { - if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point) - { - return; - } + static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT; +} - 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()); - } +//======================================================================= +// 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) + { + return; } - static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT; + 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()); + } + + 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() diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.hxx b/src/SelectMgr/SelectMgr_ViewerSelector.hxx index ae444bbded..4cbe359253 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.hxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.hxx @@ -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 myZLayerOrderMap; Handle(Select3D_BVHBuilder3d) myEntitySetBuilder; + gp_Pnt myCameraEye; + gp_Dir myCameraDir; + Standard_Real myCameraScale; private: diff --git a/tests/bugs/vis/bug24420 b/tests/bugs/vis/bug24420 index 361dc1b042..3331c52482 100644 --- a/tests/bugs/vis/bug24420 +++ b/tests/bugs/vis/bug24420 @@ -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 } { diff --git a/tests/bugs/vis/bug26413 b/tests/bugs/vis/bug26413 index d321f66fa7..afbc550269 100644 --- a/tests/bugs/vis/bug26413 +++ b/tests/bugs/vis/bug26413 @@ -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 index 0000000000..c8fc1670b2 --- /dev/null +++ b/tests/bugs/vis/bug27618 @@ -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