diff --git a/src/AIS/AIS_LocalContext_1.cxx b/src/AIS/AIS_LocalContext_1.cxx index d04e392cb2..42ed128404 100644 --- a/src/AIS/AIS_LocalContext_1.cxx +++ b/src/AIS/AIS_LocalContext_1.cxx @@ -888,9 +888,13 @@ void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObjec } } - // 2. Refresh context's detection and selection and keep only active owners + // 2. Refresh context's detection and selection and keep only active owners. // Keep last detected object for lastindex initialization. - Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked(); + Handle(SelectMgr_EntityOwner) aLastPicked; + if (IsValidIndex (mylastindex)) + { + aLastPicked = myMapOfOwner->FindKey (mylastindex); + } // Remove entity owners from detected sequences for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx) @@ -969,12 +973,43 @@ void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObjec } myMapOfOwner->Clear(); myMapOfOwner->Assign (anOwnersToKeep); - mylastindex = myMapOfOwner->FindIndex (aLastPicked); - if (!IsValidIndex (mylastindex)) + + if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull()) { myMainPM->ClearImmediateDraw(); + mylastindex = 0; + } + else if (!aLastPicked.IsNull()) + { + // For a case when the last detected owner was unhilighted and removed as outdated we + // need to check if there were other detected owners with less priority. If yes then + // one from the remaining should be treated. + Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length(); + for (; anIndex <= aDetectedSeqLength; anIndex++) + { + if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex))) + { + break; // detected owner was not removed + } + } + if (anIndex <= aDetectedSeqLength) + { + // Last detected owner was not removed, update mylastindex variable + mylastindex = myMapOfOwner->FindIndex (aLastPicked); + } + else + { + // Last detected owner was removed. First object from sequence become detected. + // Pass any active view because in current implementation the highlighting is + // synchronized in all view. + aViewer->InitActiveViews(); + manageDetected (myMainVS->Picked (myDetectedSeq.First()), + aViewer->ActiveView(), + Standard_False); + } } + // Renew iterator of ::DetectedCurrentObject() if (!isAISRemainsDetected) { // Remove the interactive object from detected sequences diff --git a/src/QABugs/QABugs_19.cxx b/src/QABugs/QABugs_19.cxx index 70a5fb2a78..09101acaa3 100644 --- a/src/QABugs/QABugs_19.cxx +++ b/src/QABugs/QABugs_19.cxx @@ -52,6 +52,8 @@ #include #include +#include + #include #define QCOMPARE(val1, val2) \ @@ -4640,6 +4642,100 @@ static Standard_Integer OCC26746( return 0; } +DEFINE_STANDARD_HANDLE(QABugs_VertexFilter, SelectMgr_Filter); +class QABugs_VertexFilter: public SelectMgr_Filter +{ +public: + Standard_EXPORT QABugs_VertexFilter() : SelectMgr_Filter() {} + + Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)&) const + { + return Standard_False; + } +}; + +//======================================================================= +//function : BUC26658 +//purpose : Checks selection in the context after using a selection filter +//======================================================================= +static Standard_Integer BUC26658 (Draw_Interpretor& theDI, + Standard_Integer /*theNArg*/, + const char ** theArgVal) +{ + Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); + if(aContext.IsNull()) { + theDI << "use 'vinit' command before " << theArgVal[0] << "\n"; + return 1; + } + + TopoDS_Shape aBoxShape = BRepPrimAPI_MakeBox(20,20,20).Shape(); + Handle(AIS_Shape) anAISIO = new AIS_Shape(aBoxShape); + + // visualization of the box in the local mode with possibility to + // select box vertices + aContext->OpenLocalContext(); + + int aDispMode = 0;// wireframe + anAISIO->SetDisplayMode(aDispMode); + aContext->Display(anAISIO, aDispMode, 0, false, true, AIS_DS_Displayed); + theDI.Eval(" vfit"); + + aContext->Load(anAISIO, -1, true); /// load allowing decomposition + aContext->Deactivate(anAISIO); + aContext->Activate(anAISIO, AIS_Shape::SelectionMode(TopAbs_VERTEX), false); + aContext->UpdateCurrentViewer(); + + // select a point on the box + Handle(V3d_View) myV3dView = ViewerTest::CurrentView(); + double Xv,Yv; + myV3dView->Project(20,20,0,Xv,Yv); + Standard_Integer Xp,Yp; + myV3dView->Convert(Xv,Yv,Xp,Yp); + + aContext->MoveTo(Xp,Yp, myV3dView); + aContext->Select(); + bool aHasSelected = false; + for (aContext->InitSelected(); aContext->MoreSelected() && !aHasSelected; aContext->NextSelected()) { + Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); + if (!anIO.IsNull()) { + const TopoDS_Shape aShape = aContext->SelectedShape(); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) + aHasSelected = true; + } + } + if (aHasSelected) + cout << "has selected vertex : OK" << endl; + else { + theDI << "has selected vertex : bugged - Faulty\n"; + return 1; + } + // filter to deny any selection in the viewer + Handle(QABugs_VertexFilter) aFilter = new QABugs_VertexFilter(); + aContext->AddFilter(aFilter); + + // update previous selection by hand + aContext->LocalContext()->ClearOutdatedSelection(anAISIO, true); + + // check that there are no selected vertices + aContext->Select(); + aHasSelected = false; + for (aContext->InitSelected(); aContext->MoreSelected() && !aHasSelected; aContext->NextSelected()) { + Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); + if (!anIO.IsNull()) { + const TopoDS_Shape aShape = aContext->SelectedShape(); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) + aHasSelected = true; + } + } + if (!aHasSelected) cout << "has no selected vertex after filter : OK" << endl; + else { + theDI << "has no selected vertex after filter : bugged - Faulty\n"; + return 1; + } + + return 0; +} + void QABugs::Commands_19(Draw_Interpretor& theCommands) { const char *group = "QABugs"; @@ -4735,5 +4831,7 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) { theCommands.Add ("OCC26746", "OCC26746 torus [toler NbCheckedPoints] ", __FILE__, OCC26746, group); + theCommands.Add ("BUC26658", "BUC26658 unexpected selection in the context using a selection filter", __FILE__, BUC26658, group); + return; } diff --git a/tests/bugs/vis/buc26658 b/tests/bugs/vis/buc26658 new file mode 100755 index 0000000000..fc41bfc987 --- /dev/null +++ b/tests/bugs/vis/buc26658 @@ -0,0 +1,9 @@ +puts "===========" +puts "BUC26658" +puts "===========" +puts "==================================" +puts "It takes visual check for this BUG" +puts "==================================" + +vinit +BUC26658