0030452: Visualization - SelectMgr_ViewerSelector::Deactivate() raises exception...
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
index 0f162e9..0fb6c86 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <algorithm>
 
-IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector,MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
 
 namespace {
   // Comparison operator for sorting selection results
@@ -59,24 +59,56 @@ namespace {
     const SelectMgr_IndexedDataMapOfOwnerCriterion&  myMapOfCriterion;
   };
 
-  //! Compute 3d position for detected entity.
-  inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
-                             const gp_GTrsf& theInversedTrsf,
-                             SelectMgr_SelectingVolumeManager& theMgr)
+  static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+}
+
+//=======================================================================
+// function : updatePoint3d
+// purpose  :
+//=======================================================================
+void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+                                              const SelectBasics_PickResult& thePickResult,
+                                              const Handle(SelectBasics_SensitiveEntity)& theEntity,
+                                              const gp_GTrsf& theInversedTrsf,
+                                              const SelectMgr_SelectingVolumeManager& theMgr) const
+{
+  if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
+  {
+    return;
+  }
+
+  if (thePickResult.HasPickedPoint())
+  {
+    theCriterion.Point = thePickResult.PickedPoint();
+  }
+  else
   {
     theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
-    gp_GTrsf anInvTrsf = theInversedTrsf;
-    if (theCriterion.Entity->HasInitLocation())
-    {
-      anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
-    }
-    if (anInvTrsf.Form() != gp_Identity)
-    {
-      anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
-    }
   }
 
-  static const Graphic3d_Mat4d THE_IDENTITY_MAT;
+  gp_GTrsf anInvTrsf = theInversedTrsf;
+  if (theCriterion.Entity->HasInitLocation())
+  {
+    anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
+  }
+  if (anInvTrsf.Form() != gp_Identity)
+  {
+    anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
+  }
+
+  if (mySelectingVolumeMgr.Camera().IsNull())
+  {
+    theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
+  }
+  else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
+  {
+    theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
+  }
+  else
+  {
+    const Standard_Real aDistFromEye = (theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ());
+    theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
+  }
 }
 
 //==================================================
@@ -86,10 +118,12 @@ namespace {
 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
 preferclosest(Standard_True),
 myToUpdateTolerance (Standard_True),
+myCameraScale (1.0),
 myCurRank (0),
 myIsLeftChildQueuedFirst (Standard_False),
 myEntityIdx (0)
 {
+  myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
 }
 
 //==================================================
@@ -98,15 +132,18 @@ myEntityIdx (0)
 //==================================================
 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
 {
-  for (theSelection->Init(); theSelection->More(); theSelection->Next())
+  for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
   {
-    theSelection->Sensitive()->SetActiveForSelection();
+    aSelEntIter.Value()->SetActiveForSelection();
   }
 
-  theSelection->SetSelectionState (SelectMgr_SOS_Activated);
+  if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
+  {
+    theSelection->SetSelectionState (SelectMgr_SOS_Activated);
 
-  myTolerances.Add (theSelection->Sensitivity());
-  myToUpdateTolerance = Standard_True;
+    myTolerances.Add (theSelection->Sensitivity());
+    myToUpdateTolerance = Standard_True;
+  }
 }
 
 //==================================================
@@ -115,15 +152,18 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
 //==================================================
 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
 {
-  for (theSelection->Init(); theSelection->More(); theSelection->Next())
+  for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
   {
-    theSelection->Sensitive()->ResetSelectionActiveStatus();
+    aSelEntIter.Value()->ResetSelectionActiveStatus();
   }
 
-  theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
+  if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
+  {
+    theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
 
-  myTolerances.Decrement (theSelection->Sensitivity());
-  myToUpdateTolerance = Standard_True;
+    myTolerances.Decrement (theSelection->Sensitivity());
+    myToUpdateTolerance = Standard_True;
+  }
 }
 
 //==================================================
@@ -171,13 +211,46 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   if (!anOwner.IsNull())
   {
     aSelectable = anOwner->Selectable();
-    if (aSelectable->TransformPersistence().Flags == Graphic3d_TMF_TriedronPers
-     || aSelectable->TransformPersistence().Flags == Graphic3d_TMF_2d
-     || (!aSelectable->ClipPlanes().IsNull() && aSelectable->ClipPlanes()->ToOverrideGlobal()))
+  }
+  if (!aSelectable.IsNull())
+  {
+    if (!aSelectable->ClipPlanes().IsNull()
+      && aSelectable->ClipPlanes()->ToOverrideGlobal())
     {
       theMgr.SetViewClippingEnabled (Standard_False);
       toRestoresViewClipEnabled = Standard_True;
     }
+    else if (!aSelectable->TransformPersistence().IsNull())
+    {
+      if (aSelectable->TransformPersistence()->IsZoomOrRotate()
+      && !theMgr.ViewClipping().IsNull())
+      {
+        // Zoom/rotate persistence object lives in two worlds at the same time.
+        // Global clipping planes can not be trivially applied without being converted
+        // into local space of transformation persistence object.
+        // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+        const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+        const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint();
+        for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
+        {
+          const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+          if (!aPlane->IsOn())
+          {
+            continue;
+          }
+
+          const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+          if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
+          {
+            return;
+          }
+        }
+      }
+
+      theMgr.SetViewClippingEnabled (Standard_False);
+      toRestoresViewClipEnabled = Standard_True;
+    }
   }
 
   SelectBasics_PickResult aPickResult;
@@ -194,6 +267,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   }
 
   if (HasDepthClipping (anOwner)
+  && !aSelectable.IsNull()
   &&  theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
   {
     Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
@@ -203,30 +277,30 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
   }
 
   SelectMgr_SortCriterion aCriterion;
-  myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
+  myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
   aCriterion.Entity    = theEntity;
   aCriterion.Priority  = anOwner->Priority();
   aCriterion.Depth     = aPickResult.Depth();
   aCriterion.MinDist   = aPickResult.DistToGeomCenter();
-  aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
   aCriterion.ToPreferClosest = preferclosest;
 
-  const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner);
-  if (aPrevStoredIndex != 0)
+  if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
   {
+    ++aPrevCriterion->NbOwnerMatches;
+    aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
     if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
     {
-      SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex);
-      if (aCriterion > aPrevCriterion)
+      if (aCriterion > *aPrevCriterion)
       {
-        updatePoint3d (aCriterion, theInversedTrsf, theMgr);
-        aPrevCriterion = aCriterion;
+        updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
+        *aPrevCriterion = aCriterion;
       }
     }
   }
   else
   {
-    updatePoint3d (aCriterion, theInversedTrsf, theMgr);
+    aCriterion.NbOwnerMatches = 1;
+    updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
     mystored.Add (anOwner, aCriterion);
   }
 }
@@ -279,27 +353,24 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
                                                const Standard_Integer theViewportWidth,
                                                const Standard_Integer theViewportHeight)
 {
-  NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
-    myMapOfObjectSensitives.ChangeFind (theObject);
-
+  Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
   if (anEntitySet->Size() == 0)
+  {
     return;
+  }
 
-  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
-
+  const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
   gp_GTrsf aInversedTrsf;
-
-  if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
+  if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
   {
-    if (!theObject->TransformPersistence().Flags)
+    if (theObject->TransformPersistence().IsNull())
     {
       aInversedTrsf = theObject->InversedTransformation();
     }
     else
     {
       gp_GTrsf aTPers;
-      Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (
-        theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
+      Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
 
       aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
       aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
@@ -328,7 +399,10 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
   {
     return;
   }
-  Standard_Integer aStack[32];
+
+  const Standard_Integer aFirstStored = mystored.Extent() + 1;
+
+  Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
   Standard_Integer aHead = -1;
   for (;;)
   {
@@ -369,8 +443,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
       Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
       for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
       {
-        const Handle(SelectMgr_SensitiveEntity)& aSensitive =
-          anEntitySet->GetSensitiveById (anIdx);
+        const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
         if (aSensitive->IsActiveForSelection())
         {
           const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
@@ -388,6 +461,35 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
       --aHead;
     }
   }
+
+  // in case of Box/Polyline selection - keep only Owners having all Entities detected
+  if (mySelectingVolumeMgr.IsOverlapAllowed()
+  || (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box
+   && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
+  {
+    return;
+  }
+
+  for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
+  {
+    const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
+    const Handle(SelectBasics_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
+    Standard_Integer aNbOwnerEntities = 0;
+    for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next())
+    {
+      if (aSensIter.Value()->BaseSensitive()->OwnerId() == anOwner)
+      {
+        if (++aNbOwnerEntities > aCriterion.NbOwnerMatches)
+        {
+          // Remove from index map.
+          // Considering NCollection_IndexedDataMap implementation, the values for lower indexes will not be modified.
+          // Hence, just keep iterating in backward direction.
+          mystored.RemoveFromIndex (aStoredIter);
+          break;
+        }
+      }
+    }
+  }
 }
 
 //=======================================================================
@@ -407,6 +509,17 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
                                  mySelectingVolumeMgr.WorldViewMatrix(),
                                  mySelectingVolumeMgr.WorldViewProjState(),
                                  aWidth, aHeight);
+  const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
+  if (!aCamera.IsNull())
+  {
+    myCameraEye = aCamera->Eye().XYZ();
+    myCameraDir = aCamera->Direction().XYZ();
+    myCameraScale = aCamera->IsOrthographic()
+                  ? aCamera->Scale()
+                  : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
+    const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
+    myCameraScale *= aPixelSize;
+  }
 
   for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
   {
@@ -442,7 +555,7 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       // define corresponding frustum builder parameters
       Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
       aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
-      aBuilder->SetWorldViewMatrix (THE_IDENTITY_MAT);
+      aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
       aBuilder->SetWindowSize (aWidth, aHeight);
       aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
     }
@@ -451,13 +564,12 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       aMgr = mySelectingVolumeMgr;
     }
 
-    const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
     const Graphic3d_Mat4d& aProjectionMat   = mySelectingVolumeMgr.ProjectionMatrix();
     const Graphic3d_Mat4d& aWorldViewMat    = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
                                             ? mySelectingVolumeMgr.WorldViewMatrix()
-                                            : THE_IDENTITY_MAT;
+                                            : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
 
-    const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
+    const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
 
     Standard_Integer aNode = 0;
     if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
@@ -465,7 +577,7 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
       continue;
     }
 
-    Standard_Integer aStack[32];
+    Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
     Standard_Integer aHead = -1;
     for (;;)
     {
@@ -525,6 +637,15 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
   SortResult();
 }
 
+//==================================================
+// Function: ClearPicked
+// Purpose :
+//==================================================
+void SelectMgr_ViewerSelector::ClearPicked()
+{
+  mystored.Clear();
+}
+
 //==================================================
 // Function: Picked
 // Purpose :
@@ -573,6 +694,19 @@ const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standa
 //
 //==================================================
 
+//==================================================
+// Function: SetEntitySetBuilder
+// Purpose :
+//==================================================
+void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
+{
+  myEntitySetBuilder = theBuilder;
+  for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
+  {
+    aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
+  }
+}
+
 //==================================================
 // Function: Contains
 // Purpose :
@@ -591,16 +725,16 @@ Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_Selecta
                                                   const SelectMgr_StateOfSelection theWantedState) const
 {
   Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
-  for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
+  for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
   {
-      if (theWantedState == SelectMgr_SOS_Any)
-      {
-        theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
-      }
-      else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
-      {
-        theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
-      }
+    if (theWantedState == SelectMgr_SOS_Any)
+    {
+      theModeList.Append (aSelIter.Value()->Mode());
+    }
+    else if (theWantedState == aSelIter.Value()->GetSelectionState())
+    {
+      theModeList.Append (aSelIter.Value()->Mode());
+    }
   }
 
   return hasActivatedStates;
@@ -616,15 +750,9 @@ Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_Sele
   if (!Contains (theSelectableObject))
     return Standard_False;
 
-  for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
-  {
-    if (theMode == theSelectableObject->CurrentSelection()->Mode())
-    {
-      return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
-    }
-  }
-
-  return Standard_False;
+  const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+  return !aSel.IsNull()
+       && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
 }
 
 //==================================================
@@ -637,15 +765,9 @@ Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_Sele
   if (!Contains (theSelectableObject))
     return Standard_False;
 
-  for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
-  {
-    if (theMode == theSelectableObject->CurrentSelection()->Mode())
-    {
-      return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
-    }
-  }
-
-  return Standard_False;
+  const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+  return !aSel.IsNull()
+       && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
 }
 
 
@@ -667,22 +789,12 @@ SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(Select
 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
 {
   TCollection_AsciiString aStatus ("Status Object :\n\t");
-
-  for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
+  for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
   {
-    if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
+    if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
     {
-      aStatus = aStatus + "Mode " +
-        TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
-        " present - ";
-      if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
-      {
-        aStatus = aStatus + " Active \n\t";
-      }
-      else
-      {
-        aStatus = aStatus + " Inactive \n\t";
-      }
+      aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - "
+              + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t");
     }
   }
 
@@ -712,16 +824,12 @@ void SelectMgr_ViewerSelector::SortResult()
   if(myIndexes.IsNull() || anExtent != myIndexes->Length())
     myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
 
-  // to work faster...
-  TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
-
-  // indices from 1 to N are loaded
-  Standard_Integer I ;
-  for (I=1; I <= anExtent; I++)
-    thearr(I)=I;
-
-  std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
-
+  TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
+  for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
+  {
+    anIndexArray.SetValue (anIndexIter, anIndexIter);
+  }
+  std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
 }
 
 //=======================================================================
@@ -742,7 +850,7 @@ void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_Selec
   if (!myMapOfObjectSensitives.IsBound (theObject))
   {
     mySelectableObjects.Append (theObject);
-    NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
+    Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
     myMapOfObjectSensitives.Bind (theObject, anEntitySet);
   }
 }
@@ -754,12 +862,10 @@ void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_Selec
 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
                                                      const Handle(SelectMgr_Selection)& theSelection)
 {
-  if (myMapOfObjectSensitives.IsBound (theObject))
+  if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
   {
-    NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
-      myMapOfObjectSensitives.ChangeFind (theObject);
-    anEntitySet->Append (theSelection);
-    anEntitySet->BVH();
+    (*anEntitySet)->Append (theSelection);
+    (*anEntitySet)->BVH();
   }
   else
   {
@@ -783,10 +889,10 @@ void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_Sele
 //=======================================================================
 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
 {
-  if (myMapOfObjectSensitives.IsBound (theObject))
+  Handle(SelectMgr_SelectableObject) anObj = theObject;
+  if (myMapOfObjectSensitives.UnBind (theObject))
   {
     mySelectableObjects.Remove (theObject);
-    myMapOfObjectSensitives.UnBind (theObject);
   }
 }
 
@@ -798,11 +904,9 @@ void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_Se
 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
                                                         const Handle(SelectMgr_Selection)& theSelection)
 {
-  if (myMapOfObjectSensitives.IsBound (theObject))
+  if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
   {
-    NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
-      myMapOfObjectSensitives.ChangeFind (theObject);
-    anEntitySet->Remove (theSelection);
+    (*anEntitySet)->Remove (theSelection);
   }
 }
 
@@ -841,7 +945,7 @@ void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_Sel
   if (!Contains (theObject))
     return;
 
-  NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
+  Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
   anEntitySet->MarkDirty();
 
   if (theIsForce)
@@ -857,12 +961,10 @@ void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_Sel
 //=======================================================================
 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
 {
-  SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
-  for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
+  for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
   {
-    NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
-      aSensitivesIter.ChangeValue();
-    Standard_Integer anEntitiesNb = anEntitySet->Size();
+    Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
+    const Standard_Integer anEntitiesNb = anEntitySet->Size();
     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
     {
       anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
@@ -889,13 +991,14 @@ void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasic
 {
   for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
   {
-    const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
-    Standard_Integer anEntitiesNb = anEntitySet->Size();
+    const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
+    const Standard_Integer anEntitiesNb = anEntitySet->Size();
     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
     {
-      if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
+      const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
+      if (aSensitive->IsActiveForSelection())
       {
-        theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
+        theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
       }
     }
   }