From f2a88e54e88b3a50cd9e9898cac03c1e14b2ed65 Mon Sep 17 00:00:00 2001 From: apl Date: Wed, 18 Jan 2017 14:20:51 +0300 Subject: [PATCH] 0028310: Visualization - crash on iteration through detected interactive objects AIS_InteractiveContext::Remove (anIObj, ...) removes object from sequence of detected owners. Therefore further iteration on detected will not require updating this list with ::MoveTo(). Additional modification includes incrementing properly the iterator of CurrentDetectedObject and resets iterator of Highlighted detected objects, because nothing is really highlighted after that. --- src/AIS/AIS_InteractiveContext.cxx | 25 +++++++++++++++++--- src/QABugs/QABugs_19.cxx | 38 ++++++++++++++++++++++++++++++ tests/bugs/vis/bug28310 | 14 +++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 tests/bugs/vis/bug28310 diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index 982302611d..70d74004c6 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -2418,13 +2418,31 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t // Object removes from Detected sequence Standard_DISABLE_DEPRECATION_WARNINGS - for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper(); ++aDetIter) + for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper();) { - Handle(AIS_InteractiveObject) anObj = DetectedCurrentObject(); + Handle(SelectMgr_EntityOwner) aPicked = myMainSel->Picked (myDetectedSeq (aDetIter)); + Handle(AIS_InteractiveObject) anObj; + if (!aPicked.IsNull()) + { + anObj = Handle(AIS_InteractiveObject)::DownCast (aPicked->Selectable()); + } + if (!anObj.IsNull() - && anObj != theIObj) + && anObj == theIObj) { myDetectedSeq.Remove (aDetIter); + if (myCurDetected == aDetIter) + { + myCurDetected = Min (myDetectedSeq.Upper(), aDetIter); + } + if (myCurHighlighted == aDetIter) + { + myCurHighlighted = 0; + } + } + else + { + aDetIter++; } } Standard_ENABLE_DEPRECATION_WARNINGS @@ -2448,6 +2466,7 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t { clearDynamicHighlight(); myLastinMain.Nullify(); + myLastPicked.Nullify(); } } diff --git a/src/QABugs/QABugs_19.cxx b/src/QABugs/QABugs_19.cxx index 8f3db989b2..ac2e4207d8 100644 --- a/src/QABugs/QABugs_19.cxx +++ b/src/QABugs/QABugs_19.cxx @@ -5358,6 +5358,41 @@ static Standard_Integer OCC27893 (Draw_Interpretor& /*theDI*/, Standard_Integer return 0; } +//======================================================================== +//function : OCC28310 +//purpose : Tests validness of iterator in AIS_InteractiveContext after +// an removing object from it +//======================================================================== +static Standard_Integer OCC28310 (Draw_Interpretor& /*theDI*/, Standard_Integer /*theArgc*/, const char** theArgv) +{ + const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + if (aCtx.IsNull()) + { + std::cout << "No interactive context. Use 'vinit' command before " << theArgv[0] << "\n"; + return 1; + } + + TopoDS_Shape aBox = BRepPrimAPI_MakeBox (10.0, 10.0, 10.0).Shape(); + Handle(AIS_InteractiveObject) aBoxObj = new AIS_Shape (aBox); + aCtx->Display (aBoxObj, AIS_Shaded, 0, Standard_False); + ViewerTest::CurrentView()->FitAll(); + aCtx->MoveTo (200, 200, ViewerTest::CurrentView()); + aCtx->Select(); + + aCtx->Remove (aBoxObj, Standard_True); + // nullify the object explicitly to simulate situation in project, + // when ::Remove is called from another method and the object is destroyed + // before ::DetectedInteractive is called + aBoxObj.Nullify(); + + for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected()) + { + Handle(AIS_InteractiveObject) anObj = aCtx->DetectedInteractive(); + } + + return 0; +} + //======================================================================== //function : Commands_19 //purpose : @@ -5494,5 +5529,8 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) { theCommands.Add ("OCC27893", "OCC27893: Creates a box and selects it via AIS_InteractiveContext API", __FILE__, OCC27893, group); + theCommands.Add("OCC28310", + "OCC28310: Tests validness of iterator in AIS_InteractiveContext after an removing object from it", + __FILE__, OCC28310, group); return; } diff --git a/tests/bugs/vis/bug28310 b/tests/bugs/vis/bug28310 new file mode 100644 index 0000000000..68098c0c03 --- /dev/null +++ b/tests/bugs/vis/bug28310 @@ -0,0 +1,14 @@ +puts "===========" +puts "OCC28310" +puts "===========" +puts "" +########################################################################## +# Visualization - crash on iteration through detected interactive objects +########################################################################## + +pload VISUALIZATION QAcommands + +vinit View1 + +# Sequence of C++ commands crashes the application +OCC28310