0027530: Visualization - AIS_InteractiveContext::HilightNextDetected() doesn't work...
[occt.git] / src / AIS / AIS_InteractiveContext_1.cxx
index 9b07d86..0af8ae0 100644 (file)
@@ -64,7 +64,6 @@ namespace
 //purpose  :
 //=======================================================================
 void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOwner)& theOwner,
-                                                 const Quantity_NameOfColor theColor,
                                                  const Handle(V3d_Viewer)& theViewer)
 {
   const Handle(AIS_InteractiveObject) anObj =
@@ -74,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);
 }
 
@@ -82,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());
@@ -94,19 +92,54 @@ void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwn
   if (!theOwner->IsAutoHilight())
   {
     SelectMgr_SequenceOfOwner aSeq;
-    for (mySelection->Init(); mySelection->More(); mySelection->Next())
+    for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
     {
-      const Handle(SelectMgr_EntityOwner) aSelOwnr =
-        Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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);
   }
 }
 
@@ -117,15 +150,10 @@ void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwn
 void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
 {
   NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
-  for (mySelection->Init(); mySelection->More(); mySelection->Next())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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  :
@@ -173,8 +307,9 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     return myLocalContexts (myCurLocalIndex)->MoveTo (theXPix, theYPix, theView, theToRedrawOnUpdate);
   }
 
-  myAISCurDetected = 0;
-  myAISDetectedSeq.Clear();
+  myCurDetected = 0;
+  myCurHighlighted = 0;
+  myDetectedSeq.Clear();
 
   if (theView->Viewer() != myMainVwr)
   {
@@ -207,15 +342,14 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
     {
       aNewDetected = aDetIter;
     }
-    Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-    if (!anObj.IsNull())
-    {
-      myAISDetectedSeq.Append (anObj);
-    }
+
+    myDetectedSeq.Append (aDetIter);
   }
 
   if (aNewDetected >= 1)
   {
+    myCurHighlighted = myDetectedSeq.Lower();
+
     // 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
@@ -247,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;
       }
     }
@@ -261,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;
       }
 
@@ -290,7 +424,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
       }
       else if (myToHilightSelected)
       {
-        highlightSelected (myLastPicked, mySelectionColor);
+        highlightSelected (myLastPicked);
         toUpdateViewer = Standard_True;
       }
     }
@@ -313,7 +447,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  th
 //function : AddSelect
 //purpose  : 
 //=======================================================================
-AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(Standard_Transient)& theObject)
+AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
 {
   if (HasOpenedContext())
   {
@@ -359,10 +493,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMi
   }
 
   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-
-  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;
 
@@ -407,10 +540,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the
   }
 
   aSelector->Pick (thePolyline, theView);
-
-  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;
 
@@ -463,7 +595,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
   {
     unhighlightSelected (Standard_True);
 
-    mySelection->Select();
+    mySelection->Clear();
     if (toUpdateViewer && myWasLastMain)
     {
         UpdateCurrentViewer();
@@ -544,9 +676,9 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
   }
 
   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
-  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;
 
@@ -593,10 +725,9 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d
   }
 
   aSelector->Pick (thePolyline, theView);
-
-  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;
 
@@ -771,41 +902,37 @@ void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdate
   // In case of selection without using local context
   myMainPM->ClearImmediateDraw();
   AIS_MapOfObjSelectedOwners anObjOwnerMap;
-  for (mySelection->Init(); mySelection->More(); mySelection->Next())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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())
+    {
+      Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObj);
+      aState->SetHilightStatus (Standard_True);
+      aState->SetHilightStyle (anObjSelStyle);
+    }
+    anOwner->State (1);
+    if (!anOwner->IsAutoHilight())
     {
-      const Handle(AIS_InteractiveObject) anObj =
-        Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
-      if (anOwner == anObj->GlobalSelOwner())
+      NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
+      if (anObjOwnerMap.Find (anObj, aSeq))
       {
-        Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObj);
-        aState->SetHilightStatus (Standard_True);
-        aState->SetHilightColor (mySelectionColor);
-      }
-      anOwner->State (1);
-      if (!anOwner->IsAutoHilight())
-      {
-        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())
@@ -832,22 +959,18 @@ void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpda
     return myLocalContexts (myCurLocalIndex)->UnhilightPicked (theToUpdateViewer);
   }
 
-  for (mySelection->Init(); mySelection->More(); mySelection->Next())
+  for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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)
@@ -869,7 +992,7 @@ void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateVi
 
   unhighlightSelected();
 
-  mySelection->Select();
+  mySelection->Clear();
   myMainPM->ClearImmediateDraw();
 
   if (theToUpdateViewer)
@@ -906,18 +1029,20 @@ 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;
@@ -925,10 +1050,11 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
 
   for (mySelection->Init(); mySelection->More(); mySelection->Next())
   {
-    const Handle(SelectMgr_EntityOwner) anOwner =
-      Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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());
@@ -941,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());
   mySelection->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))
+
+  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();
@@ -985,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;
@@ -1007,19 +1125,19 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
   unhighlightSelected();
 
   mySelection->ClearAndSelect (theOwner);
-  theOwner->State (1);
-  Quantity_NameOfColor aCustomColor;
-  Standard_Boolean isCustomColorSet;
-  if (!IsHilighted (theOwner, isCustomColorSet, aCustomColor) || (isCustomColorSet && aCustomColor!= mySelectionColor))
+  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)
@@ -1045,9 +1163,7 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveOb
   if (!myObjects.IsBound (theObject) || !theObject->HasSelection (aGlobalSelMode))
     return;
 
-  if (!theObject->HasInteractiveContext())
-    theObject->SetContext (this);
-
+  setContextToObject (theObject);
   const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
 
   if (anOwner.IsNull() || !anOwner->HasSelectable())
@@ -1100,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
@@ -1114,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)
@@ -1202,7 +1318,6 @@ void AIS_InteractiveContext::NextSelected()
   if(HasOpenedContext())
   {
     return myLocalContexts (myCurLocalIndex)->NextSelected();
-    return;
   }
 
   mySelection->Next();
@@ -1218,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();
 }
 
 //=======================================================================
@@ -1234,7 +1353,7 @@ TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
     return myLocalContexts (myCurLocalIndex)->SelectedShape();
   }
 
-  if (mySelection->Extent() == 0)
+  if (!mySelection->More())
     return TopoDS_Shape();
 
   const Handle(StdSelect_BRepOwner) anOwner =
@@ -1256,12 +1375,9 @@ Handle(AIS_InteractiveObject) AIS_InteractiveContext::SelectedInteractive() cons
     return myLocalContexts(myCurLocalIndex)->SelectedInteractive();
   }
 
-  const Handle(SelectMgr_EntityOwner) anOwner =
-    Handle(SelectMgr_EntityOwner)::DownCast (mySelection->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
@@ -1274,8 +1390,9 @@ Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::SelectedOwner() const
     return myLocalContexts(myCurLocalIndex)->SelectedOwner();
   }
 
-  return mySelection->Extent() > 0 ?
-    Handle(SelectMgr_EntityOwner)::DownCast (mySelection->Value()) : NULL;
+  return !mySelection->More()
+       ? Handle(SelectMgr_EntityOwner)()
+       : mySelection->Value();
 }
 
 //=======================================================================
@@ -1401,14 +1518,18 @@ Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedInteractive() cons
   return Handle(AIS_InteractiveObject)::DownCast (myLastPicked->Selectable());
 }
 
-
+//=======================================================================
+//function : HasNextDetected
+//purpose  :
+//=======================================================================
 Standard_Boolean AIS_InteractiveContext::HasNextDetected() const 
 {
-  if(!HasOpenedContext())
-    return Standard_False; // temporaire
-  else
+  if (HasOpenedContext())
+  {
     return myLocalContexts(myCurLocalIndex)->HasNextDetected();
-  
+  }
+
+  return !myDetectedSeq.IsEmpty() && myCurHighlighted <= myDetectedSeq.Upper();
 }
 
 
@@ -1431,23 +1552,79 @@ Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::DetectedOwner() const
 Standard_Integer AIS_InteractiveContext::HilightNextDetected (const Handle(V3d_View)& theView,
                                                               const Standard_Boolean  theToRedrawImmediate)
 {
-  return HasOpenedContext()
-       ? myLocalContexts (myCurLocalIndex)->HilightNextDetected (theView, theToRedrawImmediate)
-       : 0;
-    
+  if (HasOpenedContext())
+  {
+    return myLocalContexts (myCurLocalIndex)->HilightNextDetected (theView, theToRedrawImmediate);
+  }
+
+  myMainPM->ClearImmediateDraw();
+  if (myDetectedSeq.IsEmpty())
+  {
+    return 0;
+  }
+
+  if (++myCurHighlighted > myDetectedSeq.Upper())
+  {
+    myCurHighlighted = myDetectedSeq.Lower();
+  }
+  const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
+  if (anOwner.IsNull())
+  {
+    return 0;
+  }
+
+  highlightWithColor (anOwner, theView->Viewer());
+  myLastPicked = anOwner;
+  myLastinMain = myLastPicked;
+
+  if (theToRedrawImmediate)
+  {
+    myMainPM->RedrawImmediate (theView->Viewer());
+    myMainVwr->RedrawImmediate();
+  }
+
+  return myCurHighlighted;
 }
 
 //=======================================================================
-//function : HilightNextDetected
+//function : HilightPreviousDetected
 //purpose  :
 //=======================================================================
 Standard_Integer AIS_InteractiveContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
                                                                   const Standard_Boolean  theToRedrawImmediate)
 {
-  return HasOpenedContext()
-       ? myLocalContexts (myCurLocalIndex)->HilightPreviousDetected (theView, theToRedrawImmediate)
-       : 0;
-    
+  if (HasOpenedContext())
+  {
+    return myLocalContexts (myCurLocalIndex)->HilightPreviousDetected (theView, theToRedrawImmediate);
+  }
+
+  myMainPM->ClearImmediateDraw();
+  if (myDetectedSeq.IsEmpty())
+  {
+    return 0;
+  }
+
+  if (--myCurHighlighted < myDetectedSeq.Lower())
+  {
+    myCurHighlighted = myDetectedSeq.Upper();
+  }
+  const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
+  if (anOwner.IsNull())
+  {
+    return 0;
+  }
+
+  highlightWithColor (anOwner, theView->Viewer());
+  myLastPicked = anOwner;
+  myLastinMain = myLastPicked;
+
+  if (theToRedrawImmediate)
+  {
+    myMainPM->RedrawImmediate (theView->Viewer());
+    myMainVwr->RedrawImmediate();
+  }
+
+  return myCurHighlighted;
 }
 
 //=======================================================================
@@ -1458,13 +1635,13 @@ void AIS_InteractiveContext::InitDetected()
 {
   if (HasOpenedContext())
   {
-    myLocalContexts(myCurLocalIndex)->InitDetected();
+    myLocalContexts (myCurLocalIndex)->InitDetected();
     return;
   }
 
-  if(myAISDetectedSeq.Length() != 0)
+  if (!myDetectedSeq.IsEmpty())
   {
-    myAISCurDetected = 1;
+    myCurDetected = myDetectedSeq.Lower();
   }
 }
 
@@ -1476,11 +1653,10 @@ Standard_Boolean AIS_InteractiveContext::MoreDetected() const
 {
   if (HasOpenedContext())
   {
-    return myLocalContexts(myCurLocalIndex)->MoreDetected();
+    return myLocalContexts (myCurLocalIndex)->MoreDetected();
   }
 
-  return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length()) ?
-          Standard_True : Standard_False;
+  return myCurDetected >= myDetectedSeq.Lower() && myCurDetected <= myDetectedSeq.Upper();
 }
 
 //=======================================================================
@@ -1489,13 +1665,13 @@ Standard_Boolean AIS_InteractiveContext::MoreDetected() const
 //=======================================================================
 void AIS_InteractiveContext::NextDetected()
 {
-  if(HasOpenedContext())
+  if (HasOpenedContext())
   {
-    myLocalContexts(myCurLocalIndex)->NextDetected();
+    myLocalContexts (myCurLocalIndex)->NextDetected();
     return;
   }
 
-  myAISCurDetected++;
+  myCurDetected++;
 }
 
 //=======================================================================
@@ -1530,7 +1706,9 @@ Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedCurrentObject() co
     return myLocalContexts(myCurLocalIndex)->DetectedCurrentObject();
   }
 
-  return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;
+  return MoreDetected()
+    ? Handle(AIS_InteractiveObject)::DownCast (myMainSel->Picked (myDetectedSeq (myCurDetected))->Selectable())
+    : NULL;
 }
 
 //=======================================================================