0027957: Visualization, AIS_InteractiveContext - protect from displaying the same...
[occt.git] / src / AIS / AIS_InteractiveContext_1.cxx
index 2cb6e92..aebe4eb 100644 (file)
@@ -44,7 +44,6 @@
 #include <TCollection_ExtendedString.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TopLoc_Location.hxx>
-#include <TopoDS_Shape.hxx>
 #include <V3d_AmbientLight.hxx>
 #include <V3d_DirectionalLight.hxx>
 #include <V3d_Light.hxx>
 
 typedef NCollection_DataMap<Handle(AIS_InteractiveObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > AIS_MapOfObjSelectedOwners;
 
+namespace
+{
+  TopoDS_Shape AIS_myDummyShape;
+}
+
 //=======================================================================
 //function : highlightWithColor
 //purpose  :
 //=======================================================================
 void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOwner)& theOwner,
-                                                 const Quantity_NameOfColor theColor,
                                                  const Handle(V3d_Viewer)& theViewer)
 {
   const Handle(AIS_InteractiveObject) anObj =
@@ -70,7 +73,7 @@ void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOw
   const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
 
   myMainPM->BeginImmediateDraw();
-  theOwner->HilightWithColor (myMainPM, theColor, aHiMode);
+  theOwner->HilightWithColor (myMainPM, getHiStyle (anObj), aHiMode);
   myMainPM->EndImmediateDraw (theViewer.IsNull() ? myMainVwr : theViewer);
 }
 
@@ -78,8 +81,7 @@ void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOw
 //function : highlightSelected
 //purpose  :
 //=======================================================================
-void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
-                                                const Quantity_NameOfColor theSelColor)
+void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwner)& theOwner)
 {
   const Handle(AIS_InteractiveObject) anObj =
     Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
@@ -89,25 +91,207 @@ void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwn
 
   if (!theOwner->IsAutoHilight())
   {
-    AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-    const Handle(AIS_Selection)& aCurSel = AIS_Selection::CurrentSelection();
     SelectMgr_SequenceOfOwner aSeq;
-    for (aCurSel->Init(); aCurSel->More(); aCurSel->Next())
+    for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
     {
-      const Handle(SelectMgr_EntityOwner) aSelOwnr =
-        Handle(SelectMgr_EntityOwner)::DownCast (aCurSel->Value());
-      if (aSelOwnr->Selectable() != anObj)
-        continue;
-      aSeq.Append (aSelOwnr);
+      if (aSelIter.Value()->IsSameSelectable (anObj))
+      {
+        aSeq.Append (aSelIter.Value());
+      }
     }
     anObj->HilightSelected (myMainPM, aSeq);
   }
   else
   {
-    theOwner->HilightWithColor (myMainPM, theSelColor, aHiMode);
+    theOwner->HilightWithColor (myMainPM, getSelStyle (anObj), aHiMode);
+  }
+}
+
+//=======================================================================
+//function : highlightGlobal
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::highlightGlobal (const Handle(AIS_InteractiveObject)& theObj,
+                                              const Handle(Graphic3d_HighlightStyle)& theStyle,
+                                              const Standard_Integer theMode) const
+{
+  if (theObj.IsNull())
+    return;
+  const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
+
+  if (aGlobOwner.IsNull())
+  {
+    myMainPM->Color (theObj, theStyle, theMode);
+    return;
+  }
+
+  if (!aGlobOwner->IsAutoHilight())
+  {
+    SelectMgr_SequenceOfOwner aSeq;
+    for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
+    {
+      if (aSelIter.Value()->IsSameSelectable (theObj))
+      {
+        aSeq.Append (aSelIter.Value());
+      }
+    }
+    theObj->HilightSelected (myMainPM, aSeq);
+  }
+  else
+  {
+    aGlobOwner->HilightWithColor (myMainPM, theStyle, theMode);
+  }
+}
+
+//=======================================================================
+//function : unhighlightSelected
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
+{
+  NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
+  {
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
+    const Handle(AIS_InteractiveObject) anInteractive = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+    if (anOwner->IsAutoHilight())
+    {
+      const Standard_Integer aHiMode = anInteractive->HasHilightMode() ? anInteractive->HilightMode() : 0;
+      anOwner->Unhilight (myMainPM, aHiMode);
+      if (theIsToHilightSubIntensity)
+      {
+        if (myObjects.IsBound (anInteractive) && myObjects (anInteractive)->IsSubIntensityOn())
+        {
+          highlightWithSubintensity (anOwner, aHiMode);
+        }
+      }
+    }
+    else
+    {
+      if (!anObjToClear.Contains (anInteractive))
+        anObjToClear.Add (anInteractive);
+    }
+    anOwner->State (0);
+    if (anOwner == anInteractive->GlobalSelOwner())
+    {
+      myObjects.ChangeFind (anInteractive)->SetHilightStatus (Standard_False);
+    }
+  }
+  for (NCollection_IndexedMap<Handle(AIS_InteractiveObject)>::Iterator anIter (anObjToClear); anIter.More(); anIter.Next())
+  {
+    const Handle(AIS_InteractiveObject)& anObj = anIter.Value();
+    const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
+    myMainPM->Unhighlight (anObj, aHiMode);
+    anObj->ClearSelected();
+  }
+}
+
+//=======================================================================
+//function : unhighlightGlobal
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::unhighlightGlobal (const Handle(AIS_InteractiveObject)& theObj,
+                                                const Standard_Integer theMode) const
+{
+  if (theObj.IsNull())
+    return;
+  const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
+
+  if (aGlobOwner.IsNull())
+  {
+    myMainPM->Unhighlight (theObj, theMode);
+    return;
+  }
+
+  if (aGlobOwner->IsAutoHilight())
+  {
+    aGlobOwner->Unhilight (myMainPM, theMode);
+  }
+  else
+  {
+    myMainPM->Unhighlight (theObj, theMode);
+    theObj->ClearSelected();
+  }
+}
+
+//=======================================================================
+//function : turnOnSubintensity
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObject)& theObject,
+                                                 const Standard_Integer theDispMode,
+                                                 const Standard_Boolean theIsDisplayedOnly) const
+{
+  // the only differ with selection highlight is color, so
+  // sync transparency values
+  mySubintStyle->SetTransparency (mySelStyle->Transparency());
+
+  if (theObject.IsNull())
+  {
+    for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjsIter (myObjects); anObjsIter.More(); anObjsIter.Next())
+    {
+      const Handle(AIS_GlobalStatus)& aStatus = anObjsIter.Value();
+      if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
+        continue;
+
+      aStatus->SubIntensityOn();
+
+      if (theDispMode == -1)
+      {
+        myMainPM->Color (anObjsIter.Key(), mySubintStyle, aStatus->DisplayMode());
+      }
+      else
+        myMainPM->Color (anObjsIter.Key(), mySubintStyle, theDispMode);
+    }
+  }
+  else
+  {
+    Handle(AIS_GlobalStatus) aStatus;
+    if (!myObjects.Find (theObject, aStatus))
+      return;
+
+    if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
+        return;
+
+    aStatus->SubIntensityOn();
+
+    if (theDispMode == -1)
+    {
+      myMainPM->Color (theObject, mySubintStyle, aStatus->DisplayMode());
+    }
+    else
+      myMainPM->Color (theObject, mySubintStyle, theDispMode);
   }
 }
 
+//=======================================================================
+//function : highlightWithSubintensity
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::highlightWithSubintensity (const Handle(AIS_InteractiveObject)& theObject,
+                                                        const Standard_Integer theMode) const
+{
+  // the only differ with selection highlight is color, so
+  // sync transparency values
+  mySubintStyle->SetTransparency (mySelStyle->Transparency());
+
+  myMainPM->Color (theObject, mySubintStyle, theMode);
+}
+
+//=======================================================================
+//function : highlightWithSubintensity
+//purpose  :
+//=======================================================================
+void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                        const Standard_Integer theMode) const
+{
+  // the only differ with selection highlight is color, so
+  // sync transparency values
+  mySubintStyle->SetTransparency (mySelStyle->Transparency());
+
+  theOwner->HilightWithColor (myMainPM, mySubintStyle, theMode);
+}
+
 //=======================================================================
 //function : MoveTo
 //purpose  :
@@ -166,9 +350,14 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
 
   if (aNewDetected >= 1)
   {
-    // does nothing if previously detected object is equal to the current one
+    // Does nothing if previously detected object is equal to the current one.
+    // However in advanced selection modes the owners comparison
+    // is not effective because in that case only one owner manage the
+    // selection in current selection mode. It is necessary to check the current detected
+    // entity and hilight it only if the detected entity is not the same as
+    // previous detected (IsForcedHilight call)
     Handle(SelectMgr_EntityOwner) aNewPickedOwner = myMainSel->Picked (aNewDetected);
-    if (aNewPickedOwner == myLastPicked)
+    if (aNewPickedOwner == myLastPicked && !aNewPickedOwner->IsForcedHilight())
     {
       return myLastPicked->IsSelected()
            ? AIS_SOD_Selected
@@ -192,7 +381,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
       }
       else if (myToHilightSelected)
       {
-        highlightWithColor (aNewPickedOwner, mySelectionColor, theView->Viewer());
+        highlightSelected (aNewPickedOwner);
         toUpdateViewer = Standard_True;
       }
     }
@@ -206,7 +395,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     {
       if (!myLastPicked->IsSelected() || myToHilightSelected)
       {
-        highlightWithColor (myLastPicked, myHilightColor, theView->Viewer());
+        highlightWithColor (myLastPicked, theView->Viewer());
         toUpdateViewer = Standard_True;
       }
 
@@ -235,7 +424,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
       }
       else if (myToHilightSelected)
       {
-        highlightSelected (myLastPicked, mySelectionColor);
+        highlightSelected (myLastPicked);
         toUpdateViewer = Standard_True;
       }
     }
@@ -254,6 +443,24 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
   return aStatus;
 }
 
+//=======================================================================
+//function : AddSelect
+//purpose  : 
+//=======================================================================
+AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
+{
+  if (HasOpenedContext())
+  {
+    return myLocalContexts(myCurLocalIndex)->AddSelect (theObject);
+  }
+  mySelection->AddSelect (theObject);
+
+  Standard_Integer aSelNum = NbSelected();
+  return (aSelNum == 0) ? AIS_SOP_NothingSelected
+                        : (aSelNum == 1) ? AIS_SOP_OneSelected
+                                         : AIS_SOP_SeveralSelected;
+}
+
 //=======================================================================
 //function : Select
 //purpose  : 
@@ -286,15 +493,13 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMi
   }
 
   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-
-  for (aSelector->Init(); aSelector->More(); aSelector->Next())
+  for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
   {
-    const Handle(SelectMgr_EntityOwner)& aCurOwner = aSelector->Picked();
+    const Handle(SelectMgr_EntityOwner)& aCurOwner = aSelector->Picked (aPickIter);
     if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner))
       continue;
 
-    AIS_Selection::Select (aCurOwner);
+    mySelection->Select (aCurOwner);
     aCurOwner->State (1);
   }
 
@@ -335,16 +540,13 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the
   }
 
   aSelector->Pick (thePolyline, theView);
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-
-  for (aSelector->Init(); aSelector->More(); aSelector->Next())
+  for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aSelector->Picked());
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
       continue;
 
-    AIS_Selection::Select (anOwner);
+    mySelection->Select (anOwner);
     anOwner->State (1);
   }
 
@@ -391,49 +593,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
   }
   else
   {
-    AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-    Handle(AIS_Selection) aSelection = AIS_Selection::CurrentSelection();
-    NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
-    for (aSelection->Init(); aSelection->More(); aSelection->Next())
-    {
-      const Handle(SelectMgr_EntityOwner) anOwner
-        = Handle(SelectMgr_EntityOwner)::DownCast (aSelection->Value());
-
-      if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
-        continue;
-
-      const Handle(AIS_InteractiveObject) anObject =
-        Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-      anOwner->State (0);
-      if (anOwner == anObject->GlobalSelOwner())
-      {
-        myObjects.ChangeFind (anObject)->SetHilightStatus (Standard_False);
-      }
-      if (!anOwner->IsAutoHilight())
-      {
-        if (!anObjToClear.Contains (anObject))
-          anObjToClear.Add (anObject);
-      }
-      else
-      {
-        const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
-        anOwner->Unhilight (myMainPM, aHiMode);
-        if (myObjects.IsBound (anObject) && myObjects(anObject)->IsSubIntensityOn())
-        {
-          anOwner->HilightWithColor (myMainPM, mySubIntensity, aHiMode);
-        }
-      }
-    }
-    while (!anObjToClear.IsEmpty())
-    {
-      const Handle(AIS_InteractiveObject)& anObj = anObjToClear.FindKey (anObjToClear.Size());
-      const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
-      myMainPM->Unhighlight (anObj, aHiMode);
-      anObj->ClearSelected();
-      anObjToClear.RemoveLast();
-    }
+    unhighlightSelected (Standard_True);
 
-    AIS_Selection::Select();
+    mySelection->Clear();
     if (toUpdateViewer && myWasLastMain)
     {
         UpdateCurrentViewer();
@@ -514,14 +676,13 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
   }
 
   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  for (aSelector->Init(); aSelector->More(); aSelector->Next())
+  for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =  Handle(SelectMgr_EntityOwner)::DownCast (aSelector->Picked());
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
       continue;
 
-    AIS_SelectStatus aSelStatus = AIS_Selection::Select (anOwner);
+    AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
     Standard_Integer aState = (aSelStatus == AIS_SS_Added) ? 1 : 0;
     anOwner->State (aState);
   }
@@ -564,15 +725,13 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d
   }
 
   aSelector->Pick (thePolyline, theView);
-
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  for (aSelector->Init(); aSelector->More(); aSelector->Next())
+  for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =  Handle(SelectMgr_EntityOwner)::DownCast (aSelector->Picked());
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
       continue;
 
-    AIS_SelectStatus aSelStatus = AIS_Selection::Select (anOwner);
+    AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
     Standard_Integer aState = (aSelStatus == AIS_SS_Added) ? 1 : 0;
     anOwner->State (aState);
   }
@@ -742,44 +901,38 @@ void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdate
 
   // In case of selection without using local context
   myMainPM->ClearImmediateDraw();
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aSel = AIS_Selection::Selection (myCurrentName.ToCString());
   AIS_MapOfObjSelectedOwners anObjOwnerMap;
-  for (aSel->Init(); aSel->More(); aSel->Next())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aSel->Value());
-    if (!anOwner.IsNull() && anOwner->HasSelectable())
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
+    const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+    const Handle(Graphic3d_HighlightStyle)& anObjSelStyle = getSelStyle (anObj);
+    if (anOwner == anObj->GlobalSelOwner())
     {
-      const Handle(AIS_InteractiveObject) anObj =
-        Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-      if (anOwner == anObj->GlobalSelOwner())
-      {
-        Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObj);
-        aState->SetHilightStatus (Standard_True);
-        aState->SetHilightColor (mySelectionColor);
-      }
-      anOwner->State (1);
-      if (!anOwner->IsAutoHilight())
+      Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObj);
+      aState->SetHilightStatus (Standard_True);
+      aState->SetHilightStyle (anObjSelStyle);
+    }
+    anOwner->State (1);
+    if (!anOwner->IsAutoHilight())
+    {
+      NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
+      if (anObjOwnerMap.Find (anObj, aSeq))
       {
-        NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
-        if (anObjOwnerMap.Find (anObj, aSeq))
-        {
-          aSeq->Append (anOwner);
-        }
-        else
-        {
-          aSeq = new SelectMgr_SequenceOfOwner();
-          aSeq->Append (anOwner);
-          anObjOwnerMap.Bind (anObj, aSeq);
-        }
+        aSeq->Append (anOwner);
       }
       else
       {
-        const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
-        anOwner->HilightWithColor (myMainPM, mySelectionColor, aHiMode);
+        aSeq = new SelectMgr_SequenceOfOwner();
+        aSeq->Append (anOwner);
+        anObjOwnerMap.Bind (anObj, aSeq);
       }
     }
+    else
+    {
+      const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
+      anOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
+    }
   }
 
   if (!anObjOwnerMap.IsEmpty())
@@ -806,24 +959,18 @@ void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpda
     return myLocalContexts (myCurLocalIndex)->UnhilightPicked (theToUpdateViewer);
   }
 
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aSel = AIS_Selection::Selection (myCurrentName.ToCString());
-  for (aSel->Init(); aSel->More(); aSel->Next())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aSel->Value());
-    if (!anOwner.IsNull() && anOwner->HasSelectable())
+    const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
+    const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+    if (anOwner == anObj->GlobalSelOwner())
     {
-      const Handle(AIS_InteractiveObject) anObj =
-        Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-      if (anOwner == anObj->GlobalSelOwner())
-      {
-        myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
-      }
-      anOwner->State (0);
-      const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HasHilightMode() : 0;
-      anOwner->Unhilight (myMainPM, aHiMode);
+      myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
     }
+
+    anOwner->State (0);
+    const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HasHilightMode() : 0;
+    anOwner->Unhilight (myMainPM, aHiMode);
   }
 
   if (theToUpdateViewer)
@@ -843,42 +990,9 @@ void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateVi
   if (NbSelected() == 0)
     return;
 
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aSel = AIS_Selection::CurrentSelection();
-  NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
-  for (aSel->Init(); aSel->More(); aSel->Next())
-  {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aSel->Value());
-    if (!anOwner.IsNull() && anOwner->HasSelectable())
-    {
-      const Handle(AIS_InteractiveObject) anObj =
-        Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-      if (anOwner == anObj->GlobalSelOwner())
-      {
-        myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
-      }
-      anOwner->State (0);
-      if (!anOwner->IsAutoHilight())
-      {
-        if (!anObjToClear.Contains (anObj))
-          anObjToClear.Add (anObj);
-      }
-      else
-      {
-        const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
-        anOwner->Unhilight (myMainPM, aHiMode);
-      }
-    }
-  }
+  unhighlightSelected();
 
-  while (!anObjToClear.IsEmpty())
-  {
-    anObjToClear.FindKey (anObjToClear.Size())->ClearSelected();
-    anObjToClear.RemoveLast();
-  }
-
-  AIS_Selection::Select();
+  mySelection->Clear();
   myMainPM->ClearImmediateDraw();
 
   if (theToUpdateViewer)
@@ -915,31 +1029,32 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
     return;
   if(!myObjects.IsBound (theObject))
     Display (theObject, Standard_False);
-  if (theObject->HasSelection (0))
+  if (!theObject->HasSelection (theObject->GlobalSelectionMode()))
     return;
 
+  const Handle(Graphic3d_HighlightStyle)& anObjSelStyle =
+    getSelStyle (theObject);
+
   if (NbSelected() == 1 && myObjects (theObject)->IsHilighted())
   {
-    Quantity_NameOfColor aHiCol;
-    Standard_Boolean hasHiCol = Standard_False;
-    if (IsHilighted (theObject, hasHiCol, aHiCol))
+    Handle(Graphic3d_HighlightStyle) aCustomStyle;
+    if (HighlightStyle (theObject, aCustomStyle))
     {
-      if (hasHiCol && aHiCol!= mySelectionColor)
+      if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
       {
-        HilightWithColor (theObject, mySelectionColor, theToUpdateViewer);
+        HilightWithColor (theObject, anObjSelStyle, theToUpdateViewer);
       }
     }
     return;
   }
 
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aCurSel = AIS_Selection::Selection (myCurrentName.ToCString());
-  for (aCurSel->Init(); aCurSel->More(); aCurSel->Next())
+  for (mySelection->Init(); mySelection->More(); mySelection->Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aCurSel->Value());
-    if (anOwner.IsNull() || !anOwner->HasSelectable())
+    const Handle(SelectMgr_EntityOwner) anOwner = mySelection->Value();
+    if (!myFilters->IsOk (anOwner))
+    {
       continue;
+    }
 
     Handle(AIS_InteractiveObject) aSelectable =
       Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
@@ -952,33 +1067,24 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
   }
 
   // added to avoid untimely viewer update...
-  const Handle(SelectMgr_Selection)& aSel = theObject->Selection (0);
-  if (aSel->IsEmpty())
+  Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
+  if (anOwner.IsNull())
     return;
-  aSel->Init();
-  Handle(SelectMgr_EntityOwner) anOwner =
-    Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
-  AIS_Selection::ClearAndSelect (anOwner);
-  anOwner->State (1);
-  if (anOwner == theObject->GlobalSelOwner())
-  {
-    Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (theObject);
-    aState->SetHilightStatus (Standard_True);
-    aState->SetHilightColor (mySelectionColor);
-  }
-  Quantity_NameOfColor aHiCol;
-  Standard_Boolean hasHiCol = Standard_False;
-  if (IsHilighted (theObject, hasHiCol, aHiCol))
+  mySelection->ClearAndSelect (anOwner);
+
+  Handle(Graphic3d_HighlightStyle) aCustomStyle;
+  if (HighlightStyle (theObject, aCustomStyle))
   {
-    if (hasHiCol && aHiCol!= mySelectionColor)
+    if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
     {
-      HilightWithColor (theObject, mySelectionColor, Standard_False);
+      HilightWithColor (theObject, anObjSelStyle, Standard_False);
     }
   }
   else
   {
-    HilightWithColor (theObject, mySelectionColor, Standard_False);
+    HilightWithColor (theObject, anObjSelStyle, Standard_False);
   }
+  anOwner->State (1);
 
   if (theToUpdateViewer)
     UpdateCurrentViewer();
@@ -991,22 +1097,23 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
 void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
                                           const Standard_Boolean theToUpdateViewer)
 {
-  if (theOwner.IsNull() || !theOwner->HasSelectable())
+  if (theOwner.IsNull() || !theOwner->HasSelectable() || !myFilters->IsOk (theOwner))
     return;
 
   const Handle(AIS_InteractiveObject) anObject =
     Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
+  const Handle(Graphic3d_HighlightStyle)& anObjSelStyle =
+    getSelStyle (anObject);
 
   if (NbSelected() == 1 && theOwner->IsSelected())
   {
-    Quantity_NameOfColor aCustomColor;
-    Standard_Boolean isCustomColorSet;
-    if (IsHilighted (theOwner, isCustomColorSet, aCustomColor))
+    Handle(Graphic3d_HighlightStyle) aCustomStyle;
+    if (HighlightStyle (theOwner, aCustomStyle))
     {
-      if (isCustomColorSet && aCustomColor != mySelectionColor)
+      if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
       {
         const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
-        theOwner->HilightWithColor (myMainPM, mySelectionColor, aHiMode);
+        theOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
       }
     }
     return;
@@ -1015,53 +1122,22 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
   if (!myObjects.IsBound (anObject))
     Display (anObject, Standard_False);
 
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aCurSel = AIS_Selection::Selection (myCurrentName.ToCString());
-  NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
-  for (aCurSel->Init(); aCurSel->More(); aCurSel->Next())
-  {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aCurSel->Value());
-    if (!anOwner->HasSelectable())
-      continue;
-    const Handle(AIS_InteractiveObject) anInteractive =
-      Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-    if (anOwner->IsAutoHilight())
-    {
-      const Standard_Integer aHiMode = anInteractive->HasHilightMode() ? anInteractive->HilightMode() : 0;
-      anOwner->Unhilight (myMainPM, aHiMode);
-    }
-    else
-    {
-      if (!anObjToClear.Contains (anInteractive))
-        anObjToClear.Add (anInteractive);
-    }
-    anOwner->State (0);
-    if (theOwner == anObject->GlobalSelOwner())
-    {
-      myObjects.ChangeFind (anObject)->SetHilightStatus (Standard_False);
-    }
-  }
-  while (!anObjToClear.IsEmpty())
-  {
-    anObjToClear.FindKey (anObjToClear.Size())->ClearSelected();
-    anObjToClear.RemoveLast();
-  }
+  unhighlightSelected();
 
-  AIS_Selection::ClearAndSelect (theOwner);
-  theOwner->State (1);
-  Quantity_NameOfColor aCustomColor;
-  Standard_Boolean isCustomColorSet;
-  if (!IsHilighted (theOwner, isCustomColorSet, aCustomColor) || (isCustomColorSet && aCustomColor!= mySelectionColor))
+  mySelection->ClearAndSelect (theOwner);
+  Handle(Graphic3d_HighlightStyle) aCustomStyle;
+  if (!HighlightStyle (theOwner, aCustomStyle) ||
+    (!aCustomStyle.IsNull() && aCustomStyle != anObjSelStyle))
   {
-    highlightSelected (theOwner, mySelectionColor);
+    highlightSelected (theOwner);
   }
 
+  theOwner->State (1);
   if (theOwner == anObject->GlobalSelOwner())
   {
     Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObject);
     aState->SetHilightStatus (Standard_True);
-    aState->SetHilightColor (mySelectionColor);
+    aState->SetHilightStyle (anObjSelStyle);
   }
 
   if (theToUpdateViewer)
@@ -1077,23 +1153,18 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
                                                   const Standard_Boolean theToUpdateViewer)
 {
-  if (!theObject->HasInteractiveContext())
-    theObject->SetContext (this);
+  if (theObject.IsNull())
+    return;
 
   if (HasOpenedContext())
     return myLocalContexts (myCurLocalIndex)->AddOrRemoveSelected (theObject, theToUpdateViewer);
 
-  if (theObject.IsNull() || !myObjects.IsBound (theObject) || !theObject->HasSelection (0))
-    return;
-
-  const Handle(SelectMgr_Selection)& aSel = theObject->Selection (0);
-
-  if (aSel->IsEmpty())
+  const Standard_Integer aGlobalSelMode = theObject->GlobalSelectionMode();
+  if (!myObjects.IsBound (theObject) || !theObject->HasSelection (aGlobalSelMode))
     return;
 
-  aSel->Init();
-  const Handle(SelectMgr_EntityOwner) anOwner =
-    Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
+  setContextToObject (theObject);
+  const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
 
   if (anOwner.IsNull() || !anOwner->HasSelectable())
     return;
@@ -1134,10 +1205,7 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityO
   if (theOwner.IsNull() || !theOwner->HasSelectable())
     return;
 
-  AIS_Selection::SetCurrentSelection (myCurrentName.ToCString());
-  Handle(AIS_Selection) aCurSel = AIS_Selection::Selection (myCurrentName.ToCString());
-
-  AIS_SelectStatus aSelStat = AIS_Selection::Select (theOwner);
+  AIS_SelectStatus aSelStat = mySelection->Select (theOwner);
 
   Standard_Integer aState = aSelStat == AIS_SS_Added ?  1 : 0;
   theOwner->State (aState);
@@ -1148,11 +1216,11 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityO
   const Standard_Integer aHiMode = anObj->HasHilightMode() ? anObj->HilightMode() : 0;
   if (aState == 1)
   {
-    highlightSelected (theOwner, mySelectionColor);
+    highlightSelected (theOwner);
     if (isGlobal)
     {
       aStatus->SetHilightStatus (Standard_True);
-      aStatus->SetHilightColor (mySelectionColor);
+      aStatus->SetHilightStyle (getSelStyle (anObj));
     }
   }
   else
@@ -1162,7 +1230,7 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityO
     else
       anObj->ClearSelected();
     aStatus->SetHilightStatus (Standard_False);
-    aStatus->SetHilightColor (Quantity_NOC_WHITE);
+    aStatus->SetHilightStyle (new Graphic3d_HighlightStyle());
   }
 
   if (theToUpdateViewer)
@@ -1193,10 +1261,10 @@ Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(AIS_Interactiv
       break;
     }
   }
-  if (!theObj->HasSelection (aGlobalSelMode) || !isGlobalModeActivated)
+  if (!theObj->HasSelection (aGlobalSelMode) || !isGlobalModeActivated || theObj->GlobalSelOwner().IsNull())
     return Standard_False;
 
-  return myObjects (theObj)->IsHilighted();
+  return theObj->GlobalSelOwner()->State() == 1;
 }
 
 //=======================================================================
@@ -1226,7 +1294,7 @@ void AIS_InteractiveContext::InitSelected()
     return;
   }
 
-  AIS_Selection::Selection (myCurrentName.ToCString())->Init();
+  mySelection->Init();
 }
 
 //=======================================================================
@@ -1238,7 +1306,7 @@ Standard_Boolean AIS_InteractiveContext::MoreSelected() const
   if (HasOpenedContext())
     return myLocalContexts (myCurLocalIndex)->MoreSelected();
 
-  return AIS_Selection::Selection (myCurrentName.ToCString())->More();
+  return mySelection->More();
 }
 
 //=======================================================================
@@ -1250,10 +1318,9 @@ void AIS_InteractiveContext::NextSelected()
   if(HasOpenedContext())
   {
     return myLocalContexts (myCurLocalIndex)->NextSelected();
-    return;
   }
 
-  AIS_Selection::Selection (myCurrentName.ToCString())->Next();
+  mySelection->Next();
 }
 
 //=======================================================================
@@ -1266,9 +1333,13 @@ Standard_Boolean AIS_InteractiveContext::HasSelectedShape() const
   {
     return myLocalContexts(myCurLocalIndex)->HasSelectedShape();
   }
+  if (!mySelection->More())
+    return Standard_False;
 
-  Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (SelectedInteractive());
-  return !aShape.IsNull();
+  const Handle(StdSelect_BRepOwner) anOwner =
+    Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
+
+  return !anOwner.IsNull() && anOwner->HasShape();
 }
 
 //=======================================================================
@@ -1282,12 +1353,12 @@ TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
     return myLocalContexts (myCurLocalIndex)->SelectedShape();
   }
 
-  if (AIS_Selection::Selection (myCurrentName.ToCString())->Extent() == 0)
+  if (!mySelection->More())
     return TopoDS_Shape();
 
   const Handle(StdSelect_BRepOwner) anOwner =
-    Handle(StdSelect_BRepOwner)::DownCast (AIS_Selection::Selection (myCurrentName.ToCString())->Value());
-  if (!anOwner->HasSelectable())
+    Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
+  if (anOwner.IsNull() || !anOwner->HasSelectable())
     return TopoDS_Shape();
 
   return anOwner->Shape().Located (anOwner->Location() * anOwner->Shape().Location());
@@ -1304,12 +1375,9 @@ Handle(AIS_InteractiveObject) AIS_InteractiveContext::SelectedInteractive() cons
     return myLocalContexts(myCurLocalIndex)->SelectedInteractive();
   }
 
-  const Handle(SelectMgr_EntityOwner) anOwner =
-    Handle(SelectMgr_EntityOwner)::DownCast (AIS_Selection::Selection (myCurrentName.ToCString())->Value());
-  if (anOwner.IsNull() || !anOwner->HasSelectable())
-    return NULL;
-
-  return Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+  return !mySelection->More()
+       ? Handle(AIS_InteractiveObject)()
+       : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
 }
 //=======================================================================
 //function : SelectedOwner
@@ -1322,10 +1390,9 @@ Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::SelectedOwner() const
     return myLocalContexts(myCurLocalIndex)->SelectedOwner();
   }
 
-  Handle(AIS_Selection) aCurSel = AIS_Selection::Selection (myCurrentName.ToCString());
-
-  return aCurSel->Extent() > 0 ?
-    Handle(SelectMgr_EntityOwner)::DownCast (aCurSel->Value()) : NULL;
+  return !mySelection->More()
+       ? Handle(SelectMgr_EntityOwner)()
+       : mySelection->Value();
 }
 
 //=======================================================================
@@ -1559,13 +1626,11 @@ const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
     return myLocalContexts(myCurLocalIndex)->DetectedCurrentShape();
   }
 
-  static TopoDS_Shape aDummyShape;
-
   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
 
   if (aCurrentShape.IsNull())
   {
-    return aDummyShape;
+    return AIS_myDummyShape;
   }
 
   return aCurrentShape->Shape();