0027893: Visualization - AIS_InteractiveContext::SetSelected does not work
[occt.git] / src / AIS / AIS_InteractiveContext_1.cxx
index 9b80e59..efbfd12 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,22 +91,55 @@ 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);
   }
 }
 
@@ -114,18 +149,11 @@ void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwn
 //=======================================================================
 void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
 {
-  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())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (aCurSel->Value());
-    if (anOwner.IsNull() || !anOwner->HasSelectable())
-      continue;
-
-    const Handle(AIS_InteractiveObject) anInteractive =
-      Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+    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;
@@ -134,7 +162,7 @@ void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsTo
       {
         if (myObjects.IsBound (anInteractive) && myObjects (anInteractive)->IsSubIntensityOn())
         {
-          anOwner->HilightWithColor (myMainPM, mySubIntensity, aHiMode);
+          highlightWithSubintensity (anOwner, aHiMode);
         }
       }
     }
@@ -158,6 +186,112 @@ void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsTo
   }
 }
 
+//=======================================================================
+//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  :
@@ -216,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
@@ -242,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;
       }
     }
@@ -256,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;
       }
 
@@ -285,7 +424,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
       }
       else if (myToHilightSelected)
       {
-        highlightSelected (myLastPicked, mySelectionColor);
+        highlightSelected (myLastPicked);
         toUpdateViewer = Standard_True;
       }
     }
@@ -304,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  : 
@@ -336,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);
   }
 
@@ -385,15 +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 = 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);
   }
 
@@ -442,7 +595,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
   {
     unhighlightSelected (Standard_True);
 
-    AIS_Selection::Select();
+    mySelection->Clear();
     if (toUpdateViewer && myWasLastMain)
     {
         UpdateCurrentViewer();
@@ -523,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 = 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);
   }
@@ -573,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 = 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);
   }
@@ -751,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())
@@ -815,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)
@@ -854,7 +992,7 @@ void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateVi
 
   unhighlightSelected();
 
-  AIS_Selection::Select();
+  mySelection->Clear();
   myMainPM->ClearImmediateDraw();
 
   if (theToUpdateViewer)
@@ -891,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() || !myFilters->IsOk (anOwner))
+    const Handle(SelectMgr_EntityOwner) anOwner = mySelection->Value();
+    if (!myFilters->IsOk (anOwner))
+    {
       continue;
+    }
 
     Handle(AIS_InteractiveObject) aSelectable =
       Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
@@ -928,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();
@@ -972,17 +1102,18 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
 
   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;
@@ -993,20 +1124,20 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
 
   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)
@@ -1035,14 +1166,7 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveOb
   if (!theObject->HasInteractiveContext())
     theObject->SetContext (this);
 
-  const Handle(SelectMgr_Selection)& aSel = theObject->Selection (aGlobalSelMode);
-
-  if (aSel->IsEmpty())
-    return;
-
-  aSel->Init();
-  const Handle(SelectMgr_EntityOwner) anOwner =
-    Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
+  const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
 
   if (anOwner.IsNull() || !anOwner->HasSelectable())
     return;
@@ -1083,10 +1207,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);
@@ -1097,11 +1218,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
@@ -1111,7 +1232,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)
@@ -1175,7 +1296,7 @@ void AIS_InteractiveContext::InitSelected()
     return;
   }
 
-  AIS_Selection::Selection (myCurrentName.ToCString())->Init();
+  mySelection->Init();
 }
 
 //=======================================================================
@@ -1187,7 +1308,7 @@ Standard_Boolean AIS_InteractiveContext::MoreSelected() const
   if (HasOpenedContext())
     return myLocalContexts (myCurLocalIndex)->MoreSelected();
 
-  return AIS_Selection::Selection (myCurrentName.ToCString())->More();
+  return mySelection->More();
 }
 
 //=======================================================================
@@ -1199,10 +1320,9 @@ void AIS_InteractiveContext::NextSelected()
   if(HasOpenedContext())
   {
     return myLocalContexts (myCurLocalIndex)->NextSelected();
-    return;
   }
 
-  AIS_Selection::Selection (myCurrentName.ToCString())->Next();
+  mySelection->Next();
 }
 
 //=======================================================================
@@ -1215,9 +1335,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();
 }
 
 //=======================================================================
@@ -1231,12 +1355,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());
@@ -1253,12 +1377,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
@@ -1271,10 +1392,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();
 }
 
 //=======================================================================
@@ -1508,13 +1628,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();