diff --git a/src/AIS/AIS_LocalContext.cdl b/src/AIS/AIS_LocalContext.cdl index 5dc1160934..977ffee1da 100644 --- a/src/AIS/AIS_LocalContext.cdl +++ b/src/AIS/AIS_LocalContext.cdl @@ -327,15 +327,21 @@ is theOwner : EntityOwner from SelectMgr; toUpdateViewer : Boolean from Standard = Standard_True); + ClearSelected (me : mutable; + toUpdateViewer : Boolean from Standard = Standard_True); + ---Purpose: Clears local context selection. + -- @param toUpdateViewer [in] if TRUE the viewer will be updated. + ClearSelected (me : mutable; + theIO : InteractiveObject from AIS; + toUpdateViewer : Boolean from Standard = Standard_True); + ---Purpose: Removes an interactive object from the local context selection. + -- Method deselects all associated entity owners. + -- @param theIO [in] the interactive object. + -- @param toUpdateViewer [in] if TRUE the viewer will be updated. - ClearSelected(me:mutable;updateviewer : Boolean from Standard=Standard_True); - ---Purpose: - - ---Category: GET THE DETECTED - HasDetected (me) returns Boolean from Standard; ---C++: inline diff --git a/src/AIS/AIS_LocalContext.cxx b/src/AIS/AIS_LocalContext.cxx index 1e815ee64d..230606cd11 100644 --- a/src/AIS/AIS_LocalContext.cxx +++ b/src/AIS/AIS_LocalContext.cxx @@ -320,12 +320,22 @@ Erase(const Handle(AIS_InteractiveObject)& anInteractive) if(myMainPM->IsDisplayed(anInteractive,STAT->HilightMode())) myMainPM->SetVisibility (anInteractive, STAT->HilightMode(), Standard_False); } - //selection step - - TColStd_ListIteratorOfListOfInteger It(STAT->SelectionModes()); - for(;It.More();It.Next()) - mySM->Deactivate(anInteractive,It.Value(),myMainVS); - // STAT->ClearSelectionModes(); + + // Deactivate selectable entities of interactive object + if (mySM->Contains (anInteractive)) + { + TColStd_ListIteratorOfListOfInteger aModeIter (STAT->SelectionModes()); + for (; aModeIter.More(); aModeIter.Next()) + { + mySM->Deactivate (anInteractive, aModeIter.Value(), myMainVS); + } + } + + UpdateSort(); + + // Remove object from current selection of local context + ClearSelected (anInteractive, Standard_False); + return status; } @@ -485,68 +495,16 @@ Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& a AddOrRemoveSelected(aSelectable); myActiveObjects.UnBind(aSelectable); - //Last detected object keeps for lastindex initialization. - Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked(); + // Remove the interactive object from selection manager + if (mySM->Contains (aSelectable)) + { + mySM->Remove (aSelectable); + } UpdateSort(); - //Object removes from SelectMgr - if( mySM->Contains(aSelectable) ) - mySM->Remove(aSelectable); - - //Object removes from Detected sequence - AIS_SequenceOfInteractive detectAIS; - - Standard_Integer i = 1; - for(i = 1 ; i < myAISDetectedSeq.Length(); i++) - { - Handle(AIS_InteractiveObject) anObj = DetectedCurrentObject(); - if( !anObj.IsNull() && anObj != aSelectable ) - myAISDetectedSeq.Remove( i ); - } - - Standard_Integer aHM = aSelectable->HasHilightMode() ? aSelectable->HilightMode() : 0; - - //EntityOwners remove from AIS_Selection - Handle(AIS_Selection) aSel = AIS_Selection::Selection(mySelName.ToCString()); - AIS_NListTransient::Iterator anIter(aSel->Objects()); - AIS_NListTransient removeEntites; - for(; anIter.More(); anIter.Next()){ - const Handle(Standard_Transient)& Tr = anIter.Value(); - if (!Tr.IsNull()){ - const Handle(SelectMgr_EntityOwner)& anOwnr = *((const Handle(SelectMgr_EntityOwner)*) &Tr); - if(anOwnr->Selectable() == aSelectable){ - removeEntites.Append(Tr); - if(IsSelected(anOwnr)) - anOwnr->Unhilight(myMainPM, aHM);//Unhilight selected - } - } - } - AIS_NListTransient::Iterator anIterRemove(removeEntites); - for(; anIterRemove.More(); anIterRemove.Next()) - aSel->Select(anIterRemove.Value());//EntityOwner removes from the selection data - - //EntityOwners remove from myMapOfOwner - SelectMgr_IndexedMapOfOwner ownersToKeep; - const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer(); - for(i = 1; i <= myMapOfOwner.Extent(); i++){ - const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner(i) ; - if(!anOwner.IsNull()) { - if(anOwner->Selectable() != aSelectable) - ownersToKeep.Add(anOwner); - else - { - if(anOwner->IsHilighted(myMainPM, aHM)) - { - for(aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) - Unhilight(anOwner, aViewer->ActiveView()); - } - } - } - } - myMapOfOwner.Clear(); - myMapOfOwner.Assign(ownersToKeep); - mylastindex = myMapOfOwner.FindIndex(aLastPicked); + // Remove object from current selection of local context + ClearSelected (aSelectable, Standard_False); return Standard_True; } diff --git a/src/AIS/AIS_LocalContext_1.cxx b/src/AIS/AIS_LocalContext_1.cxx index 7ce7815cf0..280c1c0210 100644 --- a/src/AIS/AIS_LocalContext_1.cxx +++ b/src/AIS/AIS_LocalContext_1.cxx @@ -915,6 +915,85 @@ void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer) mylastindex = 0; } +//================================================== +// Function: ClearSelected +// Purpose : +//================================================== +void AIS_LocalContext::ClearSelected (const Handle(AIS_InteractiveObject)& theIO, + const Standard_Boolean toUpdateViewer) +{ + // Keep last detected object for lastindex initialization. + Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked(); + + // Remove the interactive object from detected sequence + for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx) + { + Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx); + if (!aDetectedIO.IsNull() && aDetectedIO == theIO) + { + myAISDetectedSeq.Remove (anIdx--); + } + } + + Standard_Integer aHilightMode = theIO->HasHilightMode() ? theIO->HilightMode() : 0; + + // Remove entity owners from AIS_Selection + Handle(AIS_Selection) aSelection = AIS_Selection::Selection (mySelName.ToCString()); + AIS_NListTransient::Iterator anIter (aSelection->Objects()); + AIS_NListTransient aRemoveEntites; + for (; anIter.More(); anIter.Next()) + { + Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anIter.Value()); + if (anOwner.IsNull() || anOwner->Selectable() != theIO) + { + continue; + } + + aRemoveEntites.Append (anOwner); + + if (IsSelected (anOwner)) + { + anOwner->Unhilight (myMainPM, aHilightMode); + } + } + AIS_NListTransient::Iterator anIterRemove (aRemoveEntites); + for (; anIterRemove.More(); anIterRemove.Next()) + { + aSelection->Select (anIterRemove.Value()); + } + + // Remove entity owners from myMapOfOwner + SelectMgr_IndexedMapOfOwner anOwnersToKeep; + const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer(); + for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner.Extent(); anIdx++) + { + Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner (anIdx); + if (anOwner.IsNull()) + { + continue; + } + + if (anOwner->Selectable() != theIO) + { + anOwnersToKeep.Add (anOwner); + } + else + { + for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) + { + Unhilight (anOwner, aViewer->ActiveView()); + } + } + } + myMapOfOwner.Clear(); + myMapOfOwner.Assign (anOwnersToKeep); + mylastindex = myMapOfOwner.FindIndex (aLastPicked); + + if (toUpdateViewer) + { + aViewer->Update(); + } +} //======================================================================= //function : SetSelected diff --git a/tests/bugs/vis/bug24966 b/tests/bugs/vis/bug24966 new file mode 100644 index 0000000000..e6841ddc94 --- /dev/null +++ b/tests/bugs/vis/bug24966 @@ -0,0 +1,33 @@ +puts "============" +puts "OCC24966" +puts "============" +puts "" +#################################################################################### +# Visualization - Problem in local selection mode with selected objects staying +# in the viewer after erase +# Selected entity owners coming from decomposition are not erased in local selection +# context +#################################################################################### + +vinit View1 +pload ALL +vinit + +vertex p1 100 100 0 +vertex p2 150 300 0 +edge e1 p1 p2 + +vdisplay e1 +vselmode e1 2 1 +vselmode e1 1 1 +vselect 0 0 2500 2500 +verase -local + +set x_coord 261 +set y_coord 204 +checkcolor $x_coord $y_coord 0 0 0 +if { $stat != 1 } { + puts "Error : Selection is not erased." +} + +vdump ${imagedir}/${casename}.png