Skip to content

Commit

Permalink
0027848: Visualization - sensitivity of lines is too high
Browse files Browse the repository at this point in the history
Improved objects sorting by depth.

The sensitivity calculation for the manipulator has been changed.
Now the sensitivity of the elements of the manipulator depends on its size.

Also fixed the problem of erroneous selection of unfilled circles (SelectMgr_Frustum<N>::hasCircleOverlap() function).

Test case vselect/bugs/bug27848 added.
  • Loading branch information
mzernova authored and vglukhik committed Feb 4, 2023
1 parent c772c6c commit b0afa94
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 85 deletions.
102 changes: 53 additions & 49 deletions src/AIS/AIS_Manipulator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1116,18 +1116,23 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
const Standard_Integer theMode)
{
//Check mode
AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
const AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
if (aMode == AIS_MM_None)
{
return;
}
Handle(SelectMgr_EntityOwner) anOwner;
if (aMode == AIS_MM_None)
{
anOwner = new SelectMgr_EntityOwner (this, 5);
}

if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
// Sensitivity calculation for manipulator parts allows to avoid
// overlapping of sensitive areas when size of manipulator is small.
// Sensitivity is calculated relative to the default size of the manipulator (100.0f).
const Standard_ShortReal aSensitivityCoef = myAxes[0].Size() / 100.0f;
const Standard_Integer aHighSensitivity = Max (Min (RealToInt (aSensitivityCoef * 15), 15), 3); // clamp sensitivity within range [3, 15]
const Standard_Integer aLowSensitivity = Max (Min (RealToInt (aSensitivityCoef * 10), 10), 2); // clamp sensitivity within range [2, 10]

switch (aMode)
{
case AIS_MM_Translation:
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
Expand All @@ -1136,23 +1141,21 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
continue;
}
const Axis& anAxis = myAxes[anIt];
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Translation, 9);
}
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);

// define sensitivity by line
Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
aLine->SetSensitivityFactor (15);
Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment(anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
aLine->SetSensitivityFactor (aHighSensitivity);
theSelection->Add (aLine);

// enlarge sensitivity by triangulation
Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray (anOwner);
Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray(anOwner);
aTri->InitTriangulation (anAxis.TriangleArray()->Attributes(), anAxis.TriangleArray()->Indices(), TopLoc_Location());
theSelection->Add (aTri);
}
break;
}

if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
case AIS_MM_Rotation:
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
Expand All @@ -1161,73 +1164,74 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
continue;
}
const Axis& anAxis = myAxes[anIt];
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
}
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Rotation, 9);

// define sensitivity by circle
const gp_Circ aGeomCircle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle (anOwner, aGeomCircle);
aCircle->SetSensitivityFactor (15);
theSelection->Add (aCircle);
const gp_Circ aGeomCircle (gp_Ax2(gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle(anOwner, aGeomCircle);
aCircle->SetSensitivityFactor (aLowSensitivity);
theSelection->Add(aCircle);
// enlarge sensitivity by triangulation
Handle(Select3D_SensitiveTriangulation) aTri = new ManipSensTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), anAxis.ReferenceAxis().Direction());
Handle(Select3D_SensitiveTriangulation) aTri = new ManipSensTriangulation(anOwner, myAxes[anIt].RotatorDisk().Triangulation(), anAxis.ReferenceAxis().Direction());
theSelection->Add (aTri);
}
break;
}

if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
case AIS_MM_Scaling:
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
if (!myAxes[anIt].HasScaling())
{
continue;
}
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
}
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Scaling, 9);

// define sensitivity by point
Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
aPnt->SetSensitivityFactor (15);
Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint(anOwner, myAxes[anIt].ScalerCubePosition());
aPnt->SetSensitivityFactor (aHighSensitivity);
theSelection->Add (aPnt);
// enlarge sensitivity by triangulation
Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
theSelection->Add (aTri);
}
break;
}

if (aMode == AIS_MM_TranslationPlane || aMode == AIS_MM_None)
case AIS_MM_TranslationPlane:
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
if (!myAxes[anIt].HasDragging())
{
continue;
}
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_TranslationPlane, 9);
}
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_TranslationPlane, 9);

// define sensitivity by two crossed lines
gp_Pnt aP1, aP2;
aP1 = myAxes[((anIt + 1) % 3)].TranslatorTipPosition();
aP2 = myAxes[((anIt + 2) % 3)].TranslatorTipPosition();
Standard_Real aSensitivityOffset = ZoomPersistence() ? aHighSensitivity * (0.5 + M_SQRT2) : 0.0;
gp_Pnt aP1 = myAxes[((anIt + 1) % 3)].TranslatorTipPosition().Translated (myAxes[((anIt + 2) % 3)].ReferenceAxis().Direction().XYZ() * aSensitivityOffset);
gp_Pnt aP2 = myAxes[((anIt + 2) % 3)].TranslatorTipPosition().Translated (myAxes[((anIt + 1) % 3)].ReferenceAxis().Direction().XYZ() * aSensitivityOffset);
gp_XYZ aMidP = (aP1.XYZ() + aP2.XYZ()) / 2.0;
gp_XYZ anOrig = aMidP.Normalized().Multiplied (aSensitivityOffset);

Handle(Select3D_SensitiveSegment) aLine1 = new Select3D_SensitiveSegment(anOwner, aP1, aP2);
aLine1->SetSensitivityFactor(10);
theSelection->Add(aLine1);
Handle(Select3D_SensitiveSegment) aLine2 = new Select3D_SensitiveSegment(anOwner, gp::Origin(), aMidP);
aLine2->SetSensitivityFactor(10);
theSelection->Add(aLine2);
aLine1->SetSensitivityFactor(aLowSensitivity);
theSelection->Add (aLine1);
Handle(Select3D_SensitiveSegment) aLine2 = new Select3D_SensitiveSegment(anOwner, anOrig, aMidP);
aLine2->SetSensitivityFactor (aLowSensitivity);
theSelection->Add (aLine2);

// enlarge sensitivity by triangulation
Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].DraggerSector().Triangulation(), TopLoc_Location(), Standard_True);
theSelection->Add(aTri);
Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].DraggerSector().Triangulation(), TopLoc_Location(), Standard_True);
theSelection->Add (aTri);
}
break;
}
default:
{
anOwner = new SelectMgr_EntityOwner(this, 5);
break;
}
}
}

Expand Down
21 changes: 8 additions & 13 deletions src/SelectMgr/SelectMgr_Frustum.lxx
Original file line number Diff line number Diff line change
Expand Up @@ -869,32 +869,27 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCircleOverlap (const Standard_Real the
const gp_Pnt aCenterProject (aCoefA * aTCenter,
aCoefB * aTCenter,
aCoefC * aTCenter);
if (isDotInside (aCenterProject, aVertices))
{
return true;
}

Standard_Boolean isInside = true;
const Standard_Boolean isCenterInside = isDotInside (aCenterProject, aVertices);

Standard_Boolean isInside = false;
for (Standard_Integer anIdx = aVertices.Lower(); anIdx <= aVertices.Upper(); anIdx++)
{
if (aVertices.Value (anIdx).Distance (aCenterProject) > theRadius)
{
isInside = false;
isInside = true;
break;
}
}

if (theInside != NULL)
{
*theInside = false;
}

if (!theIsFilled && isInside)
{
return false;
*theInside = isInside && isCenterInside;
}

return isInside;
return theIsFilled
? !isInside || (isCenterInside && isInside)
: isInside && isCenterInside;
}

//=======================================================================
Expand Down
25 changes: 23 additions & 2 deletions src/SelectMgr/SelectMgr_SortCriterion.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,33 @@ public:
return ZLayerPosition > theOther.ZLayerPosition;
}

// closest object is selected unless difference is within tolerance
if (Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
// closest object is selected if their depths are not equal within tolerance
if (Abs (Depth - theOther.Depth) > Tolerance + theOther.Tolerance)
{
return Depth < theOther.Depth;
}

Standard_Real aCos = 1.0;
if (Normal.Modulus() > 0 && theOther.Normal.Modulus() > 0)
{
gp_Dir aNormal (Normal.x(), Normal.y(), Normal.z());
gp_Dir anOtherNormal (theOther.Normal.x(), theOther.Normal.y(), theOther.Normal.z());
aCos = Abs (Cos (aNormal.Angle (anOtherNormal)));
}

Standard_Real aDepth = Depth - Tolerance;
Standard_Real anOtherDepth = theOther.Depth - theOther.Tolerance;
// Comparison depths taking into account tolerances occurs when the surfaces are parallel
// or have the same sensitivity and the angle between them is less than 60 degrees.
if (Abs (aDepth - anOtherDepth) > Precision::Confusion())
{
if ((aCos > 0.5 && Abs (Tolerance - theOther.Tolerance) < Precision::Confusion())
|| Abs (aCos - 1.0) < Precision::Confusion())
{
return aDepth < anOtherDepth;
}
}

// if two objects have similar depth, select the one with higher priority
if (Priority > theOther.Priority)
{
Expand Down
2 changes: 1 addition & 1 deletion src/SelectMgr/SelectMgr_ViewerSelector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEnti
aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Box)
{
updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
if (aCriterion.IsCloserDepth (*aPrevCriterion))
{
updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
*aPrevCriterion = aCriterion;
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/v3d/dimensions/bug24389
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ check_picking $pick_coord $check_coord "diameter dimension (diam1)"
check_cross_picking $pick_coord diam1 "diameter dimension (diam1)"

# check sensitives "diam2"
set pick_coord { { 221 99 } { 285 99 } }
set pick_coord { { 222 99 } { 285 99 } }
set check_coord { 239 99 }
check_picking $pick_coord $check_coord "diameter dimension (diam2)"
check_cross_picking $pick_coord diam2 "diameter dimension (diam2)"
Expand Down
4 changes: 2 additions & 2 deletions tests/v3d/manipulator/drag_in_2d_view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ vmanipulator m -attach b

vdump $imagedir/${casename}_1.png

set mouse_pick {226 214}
set mouse_drag {306 265}
set mouse_pick {231 207}
set mouse_drag {311 258}

# note: mouse events cannot be emulated here, so the original bug cannot be reproduced by this test case
vmoveto {*}$mouse_pick
Expand Down
2 changes: 1 addition & 1 deletion tests/v3d/manipulator/dragg
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ vdump $anImage2
# -------------------------------------------

set mouse_pick {316 261}
set mouse_drag {279 286}
set mouse_drag {281 286}

vmoveto {*}$mouse_pick
vselect {*}$mouse_pick
Expand Down
10 changes: 5 additions & 5 deletions tests/v3d/manipulator/rotate
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ vmanipulator m -attach c1 -adjustPosition 1 -adjustSize 0 -enableModes 1 -size 4

vmanipulator m -followRotation 1

set mouse_pick {200 092}
set mouse_pick {199 092}
set mouse_drag {176 142}

vmoveto {*}$mouse_pick
Expand All @@ -65,8 +65,8 @@ vdump $anImage1

vmanipulator m -followRotation 1

set mouse_pick {173 137}
set mouse_drag {233 144}
set mouse_pick {175 135}
set mouse_drag {232 144}

vmoveto {*}$mouse_pick
vselect {*}$mouse_pick
Expand Down Expand Up @@ -113,7 +113,7 @@ vmanipulator m -followRotation 0
# test rotation around y axis (world reference frame)
# ---------------------------------------------------

set mouse_pick {205 087}
set mouse_pick {205 088}
set mouse_drag {232 127}

vmoveto {*}$mouse_pick
Expand All @@ -129,7 +129,7 @@ vdump $anImage4
# test rotation around z axis (world reference frame)
# ---------------------------------------------------

set mouse_pick {228 141}
set mouse_pick {228 142}
set mouse_drag {184 143}

vmoveto {*}$mouse_pick
Expand Down
2 changes: 1 addition & 1 deletion tests/v3d/manipulator/translate
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ vdump $anImage4
# ----------------------------------------------------

set mouse_pick {199 164}
set mouse_drag {246 177}
set mouse_drag {246 176}

vmoveto {*}$mouse_pick
vselect {*}$mouse_pick
Expand Down
2 changes: 1 addition & 1 deletion tests/vselect/bugs/bug23012
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set x1 210
set y1 184

set x2 207
set y2 180
set y2 182

stepread [locate_data_file OCC23012-Sample_3.stp] a *
stepread [locate_data_file OCC23012-Sample_9.stp] b *
Expand Down
2 changes: 1 addition & 1 deletion tests/vselect/bugs/bug23539_2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ vselect 300 200 300 60 400 60 407 150 -xor
set NbSelected1 [vnbselected]
if { ${NbSelected1} != 13 } { puts "Error : Polygonal shift selection doesn't work properly" }

vselect 350 120 -xor
vselect 350 121 -xor

set NbSelected1 [vnbselected]
if { ${NbSelected1} != 12 } { puts "Error : (case 2)" }
Expand Down
23 changes: 23 additions & 0 deletions tests/vselect/bugs/bug27848
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
puts "============="
puts "0027848: Visualization - sensitivity of lines is too high"
puts "============="

pload VISUALIZATION

vinit View1
vclear

box b 10 10 0.1
vdisplay b -dispmode 1

vline l 0 0 0 10 10 0
vdisplay l

vpoint p 20 20 0

vtop
vfit

vselect 100 305

if { [string match "*AIS_Line*" [vstate]] } { puts "Error: AIS_Shape should be detected" }
Loading

0 comments on commit b0afa94

Please sign in to comment.