0028310: Visualization - crash on iteration through detected interactive objects
authorapl <apl@opencascade.com>
Wed, 18 Jan 2017 11:20:51 +0000 (14:20 +0300)
committerapn <apn@opencascade.com>
Thu, 19 Jan 2017 14:24:49 +0000 (17:24 +0300)
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
src/QABugs/QABugs_19.cxx
tests/bugs/vis/bug28310 [new file with mode: 0644]

index 9823026..70d7400 100644 (file)
@@ -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();
     }
   }
 
index 8f3db98..ac2e420 100644 (file)
@@ -5359,6 +5359,41 @@ static Standard_Integer OCC27893 (Draw_Interpretor& /*theDI*/, Standard_Integer
 }
 
 //========================================================================
+//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 (file)
index 0000000..68098c0
--- /dev/null
@@ -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