0030672: Visualization - AIS_InteractiveContext::SetLocation() sets invalid selection...
[occt.git] / src / SelectMgr / SelectMgr_SelectionManager.cxx
index 73506ee..195ed54 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <SelectMgr_SelectionManager.ixx>
-#include <SelectMgr_ViewerSelector.hxx>
+#include <SelectMgr_SelectionManager.hxx>
+
+#include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
-#include <SelectMgr_SequenceOfSelector.hxx>
-#include <TColStd_MapIteratorOfMapOfTransient.hxx>
-#include <TColStd_MapIteratorOfMapOfTransient.hxx>
 #include <TCollection_AsciiString.hxx>
-#include <TColStd_ListOfInteger.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfObjectSelectors.hxx>
-#include <OSD_Environment.hxx>
-
-
-static Standard_Boolean SelectDebugModeOnSM()
-{
-  static Standard_Integer isDebugMode( -1 );
-  if ( isDebugMode < 0 ) {
-    isDebugMode = 1;
-    OSD_Environment selectdb("SELECTIONDEBUG");
-    if ( selectdb.Value().IsEmpty() )
-      isDebugMode = 0;
-  }                       
-  return ( isDebugMode != 0 );
-}
-
-static Standard_Integer SMSearch(const SelectMgr_SequenceOfSelector& seq,
-                                 const Handle(SelectMgr_ViewerSelector)& theSel)
-{
-  Standard_Integer ifound=0;
-  for (Standard_Integer i=1;i<=seq.Length()&& ifound==0;i++)
-  {if(theSel==seq.Value(i)) ifound=i;}
-  return ifound;
 
-} 
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectionManager,Standard_Transient)
 
 //==================================================
 // Function: Create
 // Purpose :
 //==================================================
-
-SelectMgr_SelectionManager::SelectMgr_SelectionManager()
-{}
-
-
-//==================================================
-// Function: Add
-// Purpose :
-//==================================================
-void SelectMgr_SelectionManager::
-Add (const Handle(SelectMgr_ViewerSelector)& aViewSel)
+SelectMgr_SelectionManager::SelectMgr_SelectionManager (const Handle(SelectMgr_ViewerSelector)& theSelector)
+: mySelector (theSelector)
 {
-  myselectors.Add(aViewSel);
+  //
 }
 
-
-
-//==================================================
-// Function: Remove
-// Purpose :
-//==================================================
-void SelectMgr_SelectionManager::
-Remove (const Handle(SelectMgr_ViewerSelector)& aViewSel)
-{
-  SelectMgr_DataMapIteratorOfDataMapOfObjectSelectors It(mylocal);
-  for(;It.More();It.Next())
-  {
-    SelectMgr_SequenceOfSelector& theviews =mylocal.ChangeFind(It.Key());
-    Standard_Integer rank = SMSearch(theviews,aViewSel);
-    if(rank!=0 && rank<=theviews.Length()) theviews.Remove(rank);
-  }
-  if(myselectors.Contains(aViewSel)) myselectors.Remove(aViewSel);
-}
-
-//==================================================
-// Function: Contains
-// Purpose :
-//==================================================
-Standard_Boolean SelectMgr_SelectionManager::
-Contains (const Handle(SelectMgr_ViewerSelector)& aViewSel) const
-{return myselectors.Contains(aViewSel);}
-
 //==================================================
 // Function: Contains
 // Purpose :
 //==================================================
-Standard_Boolean SelectMgr_SelectionManager::
-Contains (const Handle(SelectMgr_SelectableObject)& aSelObj) const
-{if (myglobal.Contains(aSelObj)) return Standard_True;
-if (mylocal.IsBound(aSelObj)) return Standard_True;
-return Standard_False;
-}
-
-
-
-//==================================================
-// Function: Load
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Load (const Handle(SelectMgr_SelectableObject)& anObject,
-      const Standard_Integer amode)
+Standard_Boolean SelectMgr_SelectionManager::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
 {
-  if(!myglobal.Contains(anObject))
-    myglobal.Add(anObject);
-  if(amode!=-1) 
-    LoadMode (anObject,amode);
+  return myGlobal.Contains (theObject);
 }
 
-
 //==================================================
 // Function: Load
 // Purpose :
 //==================================================
-void SelectMgr_SelectionManager::
-Load (const Handle(SelectMgr_SelectableObject)& anObject,
-      const Handle(SelectMgr_ViewerSelector)& aview,      
-      const Standard_Integer amode)
-{
-  if(!myselectors.Contains(aview)) myselectors.Add(aview);
-  if(amode!=-1)
-    LoadMode (anObject,amode);
-
-
-  if (mylocal.IsBound(anObject)){
-    SelectMgr_SequenceOfSelector& theviews = mylocal.ChangeFind(anObject);
-    if (SMSearch(theviews,aview)==0) theviews.Append(aview);
-  }
-  else {
-    if(!myglobal.Contains(anObject)){
-      SelectMgr_SequenceOfSelector newviews;
-      newviews.Append(aview);
-      mylocal.Bind(anObject,newviews);
-    }
-  }
-}
-
-
-//==================================================
-// Function: Remove
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Remove(const Handle(SelectMgr_SelectableObject)& anObject)
+void SelectMgr_SelectionManager::Load (const Handle(SelectMgr_SelectableObject)& theObject,
+                                       const Standard_Integer theMode)
 {
+  if (myGlobal.Contains(theObject))
+    return;
 
-  if(myglobal.Contains(anObject)) {
-    TColStd_MapIteratorOfMapOfTransient It(myselectors);
-    for(;It.More();It.Next())
-    {
-      Handle(SelectMgr_ViewerSelector) curview = 
-        Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());
-      if(curview->Contains(anObject)){
-        for(anObject->Init();anObject->More();anObject->Next())
-        {
-          curview->Remove(anObject->CurrentSelection());
-        }
-
-      }
-    }
-    myglobal.Remove(anObject);
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    Load (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
   }
 
-  else if(mylocal.IsBound(anObject)) {
-    SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject);
-    for (Standard_Integer i=1;i<=seq.Length();i++) {
-      Handle(SelectMgr_ViewerSelector) curview =
-        Handle(SelectMgr_ViewerSelector)::DownCast(seq(i));
-      if(curview->Contains(anObject)){
-        for(anObject->Init();anObject->More();anObject->Next())
-        {
-          curview->Remove(anObject->CurrentSelection());
-        }
-      }
+  if (!theObject->HasOwnPresentations())
+    return;
 
-    }
-    mylocal.UnBind(anObject);
+  myGlobal.Add(theObject);
+  if (!mySelector->Contains (theObject) && theObject->HasOwnPresentations())
+  {
+    mySelector->AddSelectableObject (theObject);
   }
+  if (theMode != -1)
+    loadMode (theObject, theMode);
 }
 
 //==================================================
 // Function: Remove
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Remove(const Handle(SelectMgr_SelectableObject)& anObject,
-       const Handle(SelectMgr_ViewerSelector)& aVS)
+void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
 {
-  if(aVS->Contains(anObject)) {
-    for(anObject->Init();anObject->More();anObject->Next()){
-      aVS->Remove(anObject->CurrentSelection());
-    }
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    Remove (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()));
+  }
 
+  if (!theObject->HasOwnPresentations())
+    return;
 
-    if(mylocal.IsBound(anObject)) {
-      SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject);
-      Standard_Boolean NotFound (Standard_True);
-      for (Standard_Integer i=1;i<=seq.Length()&&NotFound;i++) {
-        if(seq(i)== aVS){
-          seq.Remove(i);
-          NotFound =Standard_False;
-        }
+  if (myGlobal.Contains (theObject))
+  {
+    if (mySelector->Contains (theObject))
+    {
+      for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+      {
+        mySelector->RemoveSelectionOfObject (theObject, aSelIter.Value());
+        aSelIter.Value()->UpdateBVHStatus (SelectMgr_TBU_Remove);
+        mySelector->Deactivate (aSelIter.Value());
       }
-      if(seq.IsEmpty())
-        mylocal.UnBind(anObject);
+      mySelector->RemoveSelectableObject (theObject);
     }
+    myGlobal.Remove (theObject);
   }
+
+  theObject->ClearSelections();
 }
 
 //==================================================
 // Function: Activate
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Activate(const Handle(SelectMgr_SelectableObject)& anObject,
-         const Standard_Integer aMode,
-         const Standard_Boolean AutomaticProj)
+void SelectMgr_SelectionManager::Activate (const Handle(SelectMgr_SelectableObject)& theObject,
+                                           const Standard_Integer theMode)
 {
-  if(aMode==-1) return;
-  //  Standard_Boolean global = Standard_False;
-  if(!anObject->HasSelection(aMode)) LoadMode(anObject,aMode);
-
-
-  if(myglobal.Contains(anObject)) {
-    TColStd_MapIteratorOfMapOfTransient It(myselectors);
+  if (theMode == -1)
+    return;
 
-    for(;It.More();It.Next()){
-      Handle(SelectMgr_ViewerSelector) curview = 
-        Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());
-      Activate(anObject,aMode,curview,AutomaticProj);
-    }
+  for (PrsMgr_ListOfPresentableObjectsIter anChildIter (theObject->Children()); anChildIter.More(); anChildIter.Next())
+  {
+    Activate (Handle(SelectMgr_SelectableObject)::DownCast (anChildIter.Value()), theMode);
   }
+  if (!theObject->HasOwnPresentations())
+    return;
 
-  else if(mylocal.IsBound(anObject)) {
-    SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject);
-    for (Standard_Integer i=1;i<=seq.Length();i++) {
-      Handle(SelectMgr_ViewerSelector) curview =
-        Handle(SelectMgr_ViewerSelector)::DownCast(seq(i));
-      // ATTENTION : si la selection est a remettre a jour, on le fait la ....      
-      const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode);
+  Standard_Boolean isComputed = Standard_False;
+  if (const Handle(SelectMgr_Selection)& aSelOld = theObject->Selection (theMode))
+  {
+    isComputed = !aSelOld->IsEmpty();
+  }
+  if (!isComputed)
+  {
+    loadMode (theObject, theMode);
+  }
 
-      switch(Sel->UpdateStatus()){
-      case SelectMgr_TOU_Full:
-        anObject->UpdateSelection(aMode); // pas de break expres...
-      case SelectMgr_TOU_Partial:
-        {
-          if(anObject->HasTransformation())
-            anObject->UpdateTransformations(Sel);
-          Sel->UpdateStatus(SelectMgr_TOU_None);
-          break;
-        }
-      default:
-        break;
+  const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode);
+  switch (aSelection->UpdateStatus())
+  {
+    case SelectMgr_TOU_Full:
+    {
+      if (theObject->HasSelection (theMode))
+      {
+        mySelector->RemoveSelectionOfObject (theObject, aSelection);
       }
-
-      curview->Activate(Sel,AutomaticProj);
+      theObject->RecomputePrimitives (theMode);
+      // pass through SelectMgr_TOU_Partial
     }
-  }
-}
-
-
-//==================================================
-// Function: Activate
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Activate(const Handle(SelectMgr_SelectableObject)& anObject,
-         const Standard_Integer aMode,
-         const Handle(SelectMgr_ViewerSelector)& aViewSel,
-         const Standard_Boolean AutomaticProj)
-{
-  if(aMode==-1) return;
-
-  if(!myselectors.Contains(aViewSel)) return;
-
-  if (!anObject->HasSelection(aMode)) LoadMode(anObject,aMode);
-
-  const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode);
-
-  switch(Sel->UpdateStatus()){
-  case SelectMgr_TOU_Full:
-    anObject->UpdateSelection(aMode); 
-  case SelectMgr_TOU_Partial:
+    Standard_FALLTHROUGH
+    case SelectMgr_TOU_Partial:
     {
-      if(anObject->HasTransformation())
-        anObject->UpdateTransformations(Sel);
+      theObject->UpdateTransformations (aSelection);
+      mySelector->RebuildObjectsTree();
       break;
     }
-  default:
-    break;
+    default:
+      break;
   }
-  Sel->UpdateStatus(SelectMgr_TOU_None);
+  aSelection->UpdateStatus(SelectMgr_TOU_None);
 
-  if  (myglobal.Contains(anObject)) 
-    aViewSel->Activate (anObject->Selection(aMode));
-
-  else {
-    if (mylocal.IsBound(anObject)) {
-      if (SMSearch(mylocal.Find(anObject),aViewSel)==0)
-        (mylocal.ChangeFind (anObject)).Append(aViewSel);
-      aViewSel->Activate (anObject->Selection(aMode),AutomaticProj);
+  switch (aSelection->BVHUpdateStatus())
+  {
+    case SelectMgr_TBU_Add:
+    case SelectMgr_TBU_Renew:
+    {
+      mySelector->AddSelectionToObject (theObject, aSelection);
+      break;
     }
-  }
-}
-
-//==================================================
-// Function: Deactivate
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject)
-{
-  Standard_Boolean global = Standard_False;
-  if(myglobal.Contains(anObject)) global = Standard_True;
-  TColStd_MapIteratorOfMapOfTransient It(myselectors);
-  Handle(SelectMgr_ViewerSelector) curview; 
-  for(;It.More();It.Next()){
-    curview = Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());
-    if (global || mylocal.IsBound (anObject)) {
-      for (anObject->Init();anObject->More();anObject->Next())
-      {curview->Deactivate(anObject->CurrentSelection());}  
-
+    case SelectMgr_TBU_Remove:
+    {
+      if (aSelection->GetSelectionState() == SelectMgr_SOS_Deactivated)
+      {
+        mySelector->AddSelectionToObject (theObject, aSelection);
+      }
+      break;
     }
-
+    default:
+      break;
   }
-}
-
-//==================================================
-// Function: Deactivate
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject,
-           const Standard_Integer amode)
+  aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
 
-{
-  Standard_Boolean global = Standard_False;
-  if(myglobal.Contains(anObject)) global = Standard_True;
-  TColStd_MapIteratorOfMapOfTransient It(myselectors);
-  Handle(SelectMgr_ViewerSelector) curview;
-  for(;It.More();It.Next()){
-    curview = Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());
-    if (global || mylocal.IsBound(anObject)) {
-      if(anObject->HasSelection(amode))
-        curview->Deactivate(anObject->Selection(amode));
-
-    }
+  if (myGlobal.Contains (theObject))
+  {
+    mySelector->Activate (theObject->Selection (theMode));
   }
 }
 
@@ -374,271 +182,233 @@ Deactivate(const Handle(SelectMgr_SelectableObject)& anObject,
 // Function: Deactivate
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject,
-           const Standard_Integer aMode,
-           const Handle(SelectMgr_ViewerSelector)& aViewSel)
+void SelectMgr_SelectionManager::Deactivate (const Handle(SelectMgr_SelectableObject)& theObject,
+                                             const Standard_Integer theMode)
 {
-  if(myselectors.Contains(aViewSel))
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
   {
-    if(myglobal.Contains(anObject)|| mylocal.IsBound(anObject)) 
-      if(anObject->HasSelection(aMode))
-        aViewSel->Deactivate (anObject->Selection(aMode));
-  }  
-
-}
-//==================================================
-// Function: Deactivate
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject,
-           const Handle(SelectMgr_ViewerSelector)& aViewSel)
-
-{
-  if(myselectors.Contains(aViewSel))
+    Deactivate (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
+  }
+  if (!theObject->HasOwnPresentations())
   {
-    if(myglobal.Contains(anObject)|| mylocal.IsBound(anObject)) {
-      for (anObject->Init();anObject->More();anObject->Next())
-      {aViewSel->Deactivate(anObject->CurrentSelection());}}  
-
-  }  
-
-}
-
-
-//==================================================
-// Function: Sleep
-// Purpose :
-//==================================================
-void SelectMgr_SelectionManager::
-Sleep (const Handle(SelectMgr_ViewerSelector)& aViewSel)
-{
-  if (myselectors.Contains(aViewSel))
-    aViewSel->Sleep();
-}
-
-void SelectMgr_SelectionManager::
-Sleep (const Handle(SelectMgr_SelectableObject)& anObject)
-{
-
-  if(myglobal.Contains(anObject)){
-    for( TColStd_MapIteratorOfMapOfTransient It(myselectors);
-      It.More();It.Next())
-      Handle(SelectMgr_ViewerSelector)::DownCast(It.Key())->Sleep(anObject);
+    return;
   }
-  else if(mylocal.IsBound(anObject)){
-    const SelectMgr_SequenceOfSelector & VSeq = mylocal(anObject);
-    for (Standard_Integer I=1;I<=VSeq.Length();I++)
-      VSeq(I)->Sleep(anObject);
+  if (!myGlobal.Contains(theObject))
+  {
+    return;
   }
 
-
+  const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode);
+  if (theMode == -1)
+  {
+    for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+    {
+      mySelector->Deactivate (aSelIter.Value());
+    }
+  }
+  else if (!aSel.IsNull())
+  {
+    mySelector->Deactivate (aSel);
+  }
 }
 
 //=======================================================================
-//function : Sleep
-//purpose  : 
+//function : IsActivated
+//purpose  :
 //=======================================================================
-void SelectMgr_SelectionManager::
-Sleep(const Handle(SelectMgr_SelectableObject)& anObject,
-      const Handle(SelectMgr_ViewerSelector)& aViewSel)
+Standard_Boolean SelectMgr_SelectionManager::IsActivated (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                          const Standard_Integer theMode) const
 {
-  if(!myselectors.Contains(aViewSel)) return;
-
-  if(!myglobal.Contains(anObject)){
-    if(!mylocal.IsBound(anObject))
-      return;
-    if(SMSearch(mylocal(anObject),aViewSel)==0)
-      return;
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    if (IsActivated (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode))
+      return Standard_True;
+  }
+  if (!theObject->HasOwnPresentations())
+  {
+    return Standard_False;
+  }
+  if (!myGlobal.Contains(theObject))
+  {
+    return Standard_False;
   }
-  aViewSel->Sleep(anObject);
-}
-
-
-
-//==================================================
-// Function: Awake
-// Purpose :
-//==================================================
-void SelectMgr_SelectionManager::
-Awake (const Handle(SelectMgr_ViewerSelector)& aViewSel,
-       const Standard_Boolean AutomaticProj)
-{
-  if (myselectors.Contains(aViewSel))
-    aViewSel->Awake(AutomaticProj);
-}
-
 
-//=======================================================================
-//function : Awake
-//purpose  : 
-//=======================================================================
-void SelectMgr_SelectionManager::Awake (const Handle(SelectMgr_SelectableObject)& anObject,
-                                        const Standard_Boolean AutomaticProj)
-{
-  if(myglobal.Contains(anObject)){
-    for( TColStd_MapIteratorOfMapOfTransient It(myselectors);
-      It.More();It.Next())
-      Handle(SelectMgr_ViewerSelector)::DownCast( It.Key())->Awake(anObject,AutomaticProj);
+  if (theMode == -1)
+  {
+    for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+    {
+      if (mySelector->Status (aSelIter.Value()) == SelectMgr_SOS_Activated)
+      {
+        return Standard_True;
+      }
+    }
+    return Standard_False;
   }
-  else if(mylocal.IsBound(anObject)){
-    const SelectMgr_SequenceOfSelector & VSeq = mylocal(anObject);
-    for (Standard_Integer I=1;I<=VSeq.Length();I++)
-      VSeq(I)->Awake(anObject,AutomaticProj);
+
+  const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode);
+  if (aSelection.IsNull())
+  {
+    return Standard_False;
   }
+  return !aSelection.IsNull()
+       && mySelector->Status (aSelection) == SelectMgr_SOS_Activated;
 }
 
 //=======================================================================
-//function : Awake
-//purpose  : 
+//function : ClearSelectionStructures
+//purpose  : Removes sensitive entities from all viewer selectors
+//           after method Clear() was called to the selection they belonged to
+//           or it was recomputed somehow
 //=======================================================================
-void SelectMgr_SelectionManager::Awake (const Handle(SelectMgr_SelectableObject)& anObject,
-                                        const Handle(SelectMgr_ViewerSelector)& aViewSel,
-                                        const Standard_Boolean AutomaticProj)
+void SelectMgr_SelectionManager::ClearSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
+                                                           const Standard_Integer theMode)
 {
-  if(!myselectors.Contains(aViewSel)) return;
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    ClearSelectionStructures (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
+  }
 
-  if(!myglobal.Contains(anObject)){
-    if(!mylocal.IsBound(anObject))
-      return;
-    if(SMSearch(mylocal(anObject),aViewSel)==0)
-      return;
+  if (!theObj->HasOwnPresentations())
+  {
+    return;
+  }
+  if (!myGlobal.Contains(theObj))
+  {
+    return;
   }
-  aViewSel->Awake(anObject,AutomaticProj);
 
+  if (theMode != -1)
+  {
+    if (const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode))
+    {
+      mySelector->RemoveSelectionOfObject (theObj, aSelection);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_Add);
+    }
+  }
+  else
+  {
+    for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObj->Selections()); aSelIter.More(); aSelIter.Next())
+    {
+      const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
+      mySelector->RemoveSelectionOfObject (theObj, aSelection);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_Add);
+    }
+  }
+  mySelector->RebuildObjectsTree();
 }
 
-
 //=======================================================================
-//function : IsActivated
-//purpose  : 
+//function : RestoreSelectionStructuress
+//purpose  : Re-adds newely calculated sensitive  entities of recomputed selection
+//           defined by mode theMode to all viewer selectors contained that selection.
 //=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject) const
+void SelectMgr_SelectionManager::RestoreSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
+                                                             const Standard_Integer theMode)
 {
-  for(anObject->Init();anObject->More();anObject->Next()){
-    if(IsActivated(anObject,anObject->CurrentSelection()->Mode()))
-      return Standard_True;
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    RestoreSelectionStructures (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
   }
-  return Standard_False;
-}
-//=======================================================================
-//function : IsActivated
-//purpose  : 
-//=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject,
-                                                         const Standard_Integer aMode) const
-{
-  if(!anObject->HasSelection(aMode)) return Standard_False;
-  if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))) 
-    return Standard_False;
-
-  Handle(Standard_Transient) Tr;
-  const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode);
-  for(TColStd_MapIteratorOfMapOfTransient It(myselectors);It.More();It.Next()){
-    Tr = It.Key();
-    Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr);
-    if(VS->Status(Sel)==SelectMgr_SOS_Activated)
-      return Standard_True;
+  if (!theObj->HasOwnPresentations())
+  {
+    return;
+  }
+  if (!myGlobal.Contains(theObj))
+  {
+    return;
   }
-  return Standard_False;
 
+  if (theMode != -1)
+  {
+    if (const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode))
+    {
+      mySelector->AddSelectionToObject (theObj, aSelection);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
+    }
+  }
+  else
+  {
+    for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObj->Selections()); aSelIter.More(); aSelIter.Next())
+    {
+      const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
+      mySelector->AddSelectionToObject (theObj, aSelection);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
+    }
+  }
+  mySelector->RebuildObjectsTree();
 }
 
-//=======================================================================
-//function : IsActivated
-//purpose  : 
-//=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject,
-                                                         const Handle(SelectMgr_ViewerSelector)& VS,
-                                                         const Standard_Integer aMode) const
+//==================================================
+// Function: recomputeSelectionMode
+// Purpose :
+//==================================================
+void SelectMgr_SelectionManager::recomputeSelectionMode (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                         const Handle(SelectMgr_Selection)& theSelection,
+                                                         const Standard_Integer theMode)
 {
-  if(!anObject->HasSelection(aMode))                               
-    return Standard_False;
-  if(!myselectors.Contains(VS))                                   
-    return Standard_False;
-  if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))) 
-    return Standard_False;
-  const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode);
-  return (VS->Status(Sel)==SelectMgr_SOS_Activated);
+  theSelection->UpdateStatus (SelectMgr_TOU_Full);
+
+  ClearSelectionStructures (theObject, theMode);
+  theObject->RecomputePrimitives (theMode);
+  RestoreSelectionStructures (theObject, theMode);
+  theSelection->UpdateStatus (SelectMgr_TOU_None);
+  theSelection->UpdateBVHStatus (SelectMgr_TBU_None);
 }
 
 //==================================================
 // Function: Update
 // Purpose :
 //==================================================
-void SelectMgr_SelectionManager::
-RecomputeSelection (const Handle(SelectMgr_SelectableObject)& anObject,
-                    const Standard_Boolean ForceUpdate,
-                    const Standard_Integer aMode)
+void SelectMgr_SelectionManager::RecomputeSelection (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                     const Standard_Boolean theIsForce,
+                                                     const Standard_Integer theMode)
 {
-  if( SelectDebugModeOnSM() ) cout<<"===>SelectMgr_SelectionManager::Update"<<endl;
-
-  if(ForceUpdate){
-    if( SelectDebugModeOnSM() ) cout<<"\t Global Recalculation of selections"<<endl;
-    if(aMode==-1){
-      anObject->UpdateSelection();
-      anObject->UpdateTransformation();
+  if (theIsForce)
+  {
+    if (theMode == -1)
+    {
+      ClearSelectionStructures (theObject);
+      theObject->RecomputePrimitives();
+      theObject->UpdateTransformation();
+      RestoreSelectionStructures (theObject);
     }
-    else if(anObject->HasSelection(aMode)){
-      anObject->UpdateSelection(aMode);
-      anObject->UpdateTransformation();
+    else if (theObject->HasSelection (theMode))
+    {
+      ClearSelectionStructures (theObject, theMode);
+      theObject->RecomputePrimitives (theMode);
+      theObject->UpdateTransformation();
+      RestoreSelectionStructures (theObject, theMode);
     }
     return;
   }
-  // objet is not known to SMgr.
-  if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))){
-    if( SelectDebugModeOnSM() ) {cout<<"\t Object not loaded in the SelectionManager"<<endl;
-    cout<<"\t eventual selections are flagged"<<endl;}
-    if( aMode == -1 ){
-      for(anObject->Init();anObject->More();anObject->Next()){
-        if( SelectDebugModeOnSM() ) cout<<"\t\t Mode "<<anObject->CurrentSelection()->Mode()<<"  ";
-        anObject->CurrentSelection()->UpdateStatus(SelectMgr_TOU_Full);
-      }
-      if( SelectDebugModeOnSM() )  
-        cout << endl;
+
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    RecomputeSelection (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theIsForce, theMode);
+  }
+  if (!theObject->HasOwnPresentations())
+  {
+    return;
+  }
+  if (!myGlobal.Contains (theObject))
+  {
+    return;
+  }
+
+  if (theMode == -1)
+  {
+    for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+    {
+      const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
+      const Standard_Integer aSelMode = aSelection->Mode();
+      recomputeSelectionMode (theObject, aSelection, aSelMode);
     }
-    else if (anObject->HasSelection(aMode))
-      anObject->Selection(aMode)->UpdateStatus(SelectMgr_TOU_Full);
-  }
-
-  // recalculate whatever is required
-  // and set flag on top...
-  else{
-    TColStd_MapIteratorOfMapOfTransient It;
-    Handle(Standard_Transient) Tr;
-    Standard_Boolean Found;
-    // object selections are parsed
-
-    for(anObject->Init();anObject->More();anObject->Next()){
-      const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection();
-      Sel->UpdateStatus(SelectMgr_TOU_Full);
-      Standard_Integer curmode = Sel->Mode();
-      Found = Standard_False;
-
-      // parsing of selections ...
-      for(It.Initialize(myselectors);It.More();It.Next()){
-        Tr = It.Key();
-        Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr);
-        if(VS->Status(Sel)==SelectMgr_SOS_Activated){
-          Found  = Standard_True;
-          switch(Sel->UpdateStatus()){
-    case SelectMgr_TOU_Full:
-      anObject->UpdateSelection(curmode); // no break on purpose...
-    case SelectMgr_TOU_Partial:
-      anObject->UpdateTransformations(Sel);
-      break;
-    default:
-      break;
-          }
-          if(Found){
-            VS->Convert(Sel);
-            Sel->UpdateStatus(SelectMgr_TOU_None);
-          }
-        }
-      }
+  }
+  else
+  {
+    if (const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode))
+    {
+      recomputeSelectionMode (theObject, aSelection, theMode);
     }
   }
 }
@@ -650,206 +420,153 @@ RecomputeSelection (const Handle(SelectMgr_SelectableObject)& anObject,
 //           If ForceUpdate = True, and they are "TO RECALCULATE"
 //           This is done without caring for the state of activation.
 //=======================================================================
-void SelectMgr_SelectionManager::Update(const Handle(SelectMgr_SelectableObject)& anObject,
-                                        const Standard_Boolean ForceUpdate)
+void SelectMgr_SelectionManager::Update (const Handle(SelectMgr_SelectableObject)& theObject,
+                                         const Standard_Boolean theIsForce)
 {
-  PrsMgr_ListOfPresentableObjectsIter anIter (anObject->Children());
-  for (; anIter.More(); anIter.Next())
+  for (PrsMgr_ListOfPresentableObjectsIter aChildIter (theObject->Children()); aChildIter.More(); aChildIter.Next())
   {
-    const Handle(SelectMgr_SelectableObject) aSelectable = Handle(SelectMgr_SelectableObject)::DownCast (anIter.Value());
-
-    if (!aSelectable.IsNull())
-    {
-      Update (aSelectable, ForceUpdate);
-    }
+    Update (Handle(SelectMgr_SelectableObject)::DownCast (aChildIter.Value()), theIsForce);
+  }
+  if (!theObject->HasOwnPresentations())
+  {
+    return;
   }
 
-  Standard_Boolean wasrecomputed;
-
-  for(anObject->Init();anObject->More();anObject->Next()){
-    const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection();
-    wasrecomputed = Standard_False;
-    if(ForceUpdate){
-      switch(Sel->UpdateStatus()){
-      case SelectMgr_TOU_Full:
-        anObject->UpdateSelection(Sel->Mode()); // no break on purpose...
-      case SelectMgr_TOU_Partial:
-        anObject->UpdateTransformations(Sel);
-        wasrecomputed = Standard_True;
-        break;
-      default:
-        break;
-      }
-      Sel->UpdateStatus(SelectMgr_TOU_None);
-    }
-
-    // it is checked which selectors are concerned by the selection
-    // to redo projections if necessary.
-    Handle(Standard_Transient) Tr;
-    for(TColStd_MapIteratorOfMapOfTransient It(myselectors);It.More();It.Next()){
-      Tr = It.Key();
-      Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr);
-      if(VS->Status(Sel)==SelectMgr_SOS_Activated)
-        switch(Sel->UpdateStatus()){
-  case SelectMgr_TOU_Full:
-    anObject->UpdateSelection(Sel->Mode()); // no break on purpose...
-  case SelectMgr_TOU_Partial:
-    anObject->UpdateTransformations(Sel);
-    wasrecomputed = Standard_True;
-    break;
-  default:
-    break;
+  for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+  {
+    const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
+    if (theIsForce || mySelector->Status (aSelection) == SelectMgr_SOS_Activated)
+    {
+      switch (aSelection->UpdateStatus())
+      {
+        case SelectMgr_TOU_Full:
+        {
+          ClearSelectionStructures (theObject, aSelection->Mode());
+          theObject->RecomputePrimitives (aSelection->Mode()); // no break on purpose...
+          RestoreSelectionStructures (theObject, aSelection->Mode());
+          // pass through SelectMgr_TOU_Partial
+        }
+        Standard_FALLTHROUGH
+        case SelectMgr_TOU_Partial:
+        {
+          theObject->UpdateTransformations (aSelection);
+          mySelector->RebuildObjectsTree();
+          break;
+        }
+        default:
+          break;
       }
-      if(wasrecomputed)
-        VS->Convert(Sel);
-      Sel->UpdateStatus(SelectMgr_TOU_None);
+      aSelection->UpdateStatus (SelectMgr_TOU_None);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
     }
   }
 }
 
-
 //==================================================
-// Function: Update
-// Purpose : Attention, it is required to know what is done...
+// Function: loadMode
+// Purpose : Private Method
 //==================================================
-void SelectMgr_SelectionManager::
-Update(const Handle(SelectMgr_SelectableObject)& anObject,
-       const Handle(SelectMgr_ViewerSelector)& aViewSel,
-       const Standard_Boolean ForceUpdate)
-{ 
-  if( SelectDebugModeOnSM() ) cout<<"==>SelectMgr_SelectionManager::Update(obj,VS)"<<endl;
-  if(!myselectors.Contains(aViewSel)) return;
-
-  Standard_Boolean okay = myglobal.Contains(anObject);
-  if(!okay)
-    okay = (mylocal.IsBound(anObject) && (SMSearch(mylocal.Find(anObject),aViewSel)!=0)) ;
-  if(!okay) return;
-
-
-  // 
-  Standard_Boolean wasrecomputed;
-  for(anObject->Init();anObject->More();anObject->Next()){
-    const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection();
-    wasrecomputed = Standard_False;
-    if(ForceUpdate){
-      switch(Sel->UpdateStatus()){
-      case SelectMgr_TOU_Full:
-        anObject->UpdateSelection(Sel->Mode()); //  no break on purpose...
-      case SelectMgr_TOU_Partial:
-        anObject->UpdateTransformations(Sel);
-        wasrecomputed = Standard_True;
-        break;
-      default:
-        break;
-      }
-      Sel->UpdateStatus(SelectMgr_TOU_None);
-    }
+void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObject)& theObject,
+                                           const Standard_Integer theMode)
+{
+  if (theMode == -1)
+  {
+    return;
+  }
 
-    if(aViewSel->Status(Sel) == SelectMgr_SOS_Activated){
-      switch(Sel->UpdateStatus()){
-      case SelectMgr_TOU_Full:
-        anObject->UpdateSelection(Sel->Mode());
-      case SelectMgr_TOU_Partial:
-        if(anObject->HasTransformation())
-          anObject->UpdateTransformations(Sel);
-        wasrecomputed = Standard_True;
-        break;
-      default:
-        break;
+  if (const Handle(SelectMgr_Selection)& aSelOld = theObject->Selection (theMode))
+  {
+    if (aSelOld->IsEmpty())
+    {
+      if (aSelOld->BVHUpdateStatus() == SelectMgr_TBU_Remove)
+      {
+        Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
+        theObject->AddSelection (aNewSel, theMode);
+        aNewSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
+        aNewSel->SetSelectionState (SelectMgr_SOS_Deactivated);
       }
-      if(wasrecomputed)
-        aViewSel->Convert(Sel);
-      Sel->UpdateStatus(SelectMgr_TOU_None);
     }
+    return;
   }
-}
 
-//==================================================
-// Function: Status
-// Purpose :
-//==================================================
-TCollection_AsciiString SelectMgr_SelectionManager::
-Status() const{
-  TCollection_AsciiString theMgrStatus("\t\t\tStatus of the SelectManager :;\n\t\t\t============================\n");
-
-  TCollection_AsciiString nbview (myselectors.Extent()),nbglobal(myglobal.Extent());
-
-  theMgrStatus +=             "\t Number of ViewerSelectors: ";
-  theMgrStatus += nbview +  "\n\t Number of global objects : " + nbglobal+"\n";
-  theMgrStatus = theMgrStatus+"\t Number of local objects  : " + TCollection_AsciiString (mylocal.Extent())+"  \n";
-
-  return theMgrStatus;
+  Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
+  theObject->AddSelection (aNewSel, theMode);
+  if (myGlobal.Contains (theObject))
+  {
+    mySelector->AddSelectionToObject (theObject, aNewSel);
+    aNewSel->UpdateBVHStatus (SelectMgr_TBU_None);
+  }
 }
 
-//==================================================
-// Function: Status
-// Purpose :
-//==================================================
-
-
-TCollection_AsciiString SelectMgr_SelectionManager::
-Status(const Handle(SelectMgr_SelectableObject)& anObject) const
+//=======================================================================
+//function : SetUpdateMode
+//purpose  :
+//=======================================================================
+void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                const SelectMgr_TypeOfUpdate theType)
 {
-  TCollection_AsciiString TheStatus("\t\tStatus of object:");
-
-  if(myglobal.Contains(anObject))
-  {TheStatus += "GLOBAL (available for all viewers in the SelectionManager)\n";}
-  else if (mylocal.IsBound(anObject))TheStatus +="LOCAL:\n\t\t"; 
-  TColStd_MapIteratorOfMapOfTransient It(myselectors);
-  Standard_Integer iv = 0;
-  //  Standard_Boolean FirstTime=Standard_True;
-  for(;It.More();It.Next()){
-    const Handle(SelectMgr_ViewerSelector)& curview = 
-      Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());  
-    iv++;
-    TheStatus = TheStatus + "status in the ViewerSelector :"+TCollection_AsciiString(iv)+"\n\t\t";
-    TheStatus+=curview->Status(anObject);
-    TheStatus+="\n\t\t----------------------\n\t\t";
+  for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
+  {
+    aSelIter.Value()->UpdateStatus (theType);
   }
-
-  return TheStatus;
-
 }
 
-//==================================================
-// Function: LoadMode
-// Purpose : Private Method
-//==================================================
-
-
-void SelectMgr_SelectionManager
-::LoadMode (const Handle(SelectMgr_SelectableObject)& anObject,
-            const Standard_Integer amode)
+//=======================================================================
+//function : SetUpdateMode
+//purpose  :
+//=======================================================================
+void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                const Standard_Integer theMode,
+                                                const SelectMgr_TypeOfUpdate theType)
 {
-  if(amode==-1) return;
-  if(!anObject->HasSelection(amode))
+  if (const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode))
   {
-    Handle(SelectMgr_Selection) NewSel = new SelectMgr_Selection(amode); 
-    anObject->AddSelection (NewSel,amode);
+    aSel->UpdateStatus (theType);
   }
 }
 
-
 //=======================================================================
-//function : SetUpdateMode
-//purpose  : 
+//function : SetSelectionSensitivity
+//purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject and
+//           changes previous sensitivity value of all sensitive entities in selection with theMode
+//           to the given theNewSensitivity.
 //=======================================================================
-
-void SelectMgr_SelectionManager::
-SetUpdateMode(const Handle(SelectMgr_SelectableObject)& anObject,
-              const SelectMgr_TypeOfUpdate aType)
+void SelectMgr_SelectionManager::SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                          const Standard_Integer theMode,
+                                                          const Standard_Integer theNewSens)
 {
-  for(anObject->Init();anObject->More();anObject->Next())
-    anObject->CurrentSelection()->UpdateStatus(aType);
+  Standard_ASSERT_RAISE (theNewSens > 0, "Error! Selection sensitivity have positive value.");
+  if (theObject.IsNull())
+  {
+    return;
+  }
 
+  const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode);
+  if (aSel.IsNull())
+  {
+    return;
+  }
+
+  const Standard_Integer aPrevSens = aSel->Sensitivity();
+  aSel->SetSensitivity (theNewSens);
+  if (myGlobal.Contains (theObject)
+   && mySelector->Contains (theObject))
+  {
+    mySelector->myTolerances.Decrement (aPrevSens);
+    mySelector->myTolerances.Add (theNewSens);
+    mySelector->myToUpdateTolerance = Standard_True;
+  }
 }
 
-void SelectMgr_SelectionManager::
-SetUpdateMode(const Handle(SelectMgr_SelectableObject)& anObject,
-              const Standard_Integer aMode,
-              const SelectMgr_TypeOfUpdate aType)
+//=======================================================================
+//function : UpdateSelection
+//purpose  :
+//=======================================================================
+void SelectMgr_SelectionManager::UpdateSelection (const Handle(SelectMgr_SelectableObject)& theObject)
 {
-  if(anObject->HasSelection(aMode))
-    anObject->Selection(aMode)->UpdateStatus(aType);
+  if (myGlobal.Contains (theObject)
+   && mySelector->Contains (theObject))
+  {
+    mySelector->MoveSelectableObject (theObject);
+  }
 }
-