Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/gui.git] / src / SVTK / SVTK_InteractorStyle.cxx
index 6c8a04fd09d11ede478ee8226c6d2de0d4f794fa..e7026d8c63f7ac04f1ef9fa44c21609498ad653c 100644 (file)
@@ -1,32 +1,32 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SALOME VTKViewer : build VTK viewer into Salome desktop
 //  File   : 
 //  Author : 
-//  Module : SALOME
-//  $Header$
-//
+
 #include "SVTK_InteractorStyle.h"
 
+#include "VTKViewer_Algorithm.h"
 #include "VTKViewer_Utilities.h"
 #include "SVTK_GenericRenderWindowInteractor.h"
 
 #include <algorithm>
 #include <iostream>
 
-using namespace std;
-
 namespace
 {
   inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
-                              int& theX, 
-                              int& theY)
+                               int& theX, 
+                               int& theY)
   {
     theInteractor->GetEventPosition(theX,theY);
     theY = theInteractor->GetSize()[1] - theY - 1;
@@ -91,7 +89,8 @@ SVTK_InteractorStyle::SVTK_InteractorStyle():
   myControllerIncrement(SVTK_ControllerIncrement::New()),
   myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
   myHighlightSelectionPointActor(SVTK_Actor::New()),
-  myRectBand(0)
+  myRectBand(0),
+  myIsAdvancedZoomingEnabled(false)
 {
   myPointPicker->Delete();
 
@@ -252,8 +251,8 @@ void SVTK_InteractorStyle::RotateXY(int dx, int dy)
   double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
   vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
   const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
-                           -aMatrix->GetElement(0,1), 
-                           -aMatrix->GetElement(0,2)};
+                            -aMatrix->GetElement(0,1), 
+                            -aMatrix->GetElement(0,2)};
   
   aTransform->RotateWXYZ(ryf, anAxis);
             
@@ -268,12 +267,14 @@ void SVTK_InteractorStyle::RotateXY(int dx, int dy)
   GetCurrentRenderer()->ResetCameraClippingRange(); 
 
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
 {
   TranslateView(x, y, oldX, oldY);   
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
@@ -287,14 +288,29 @@ void SVTK_InteractorStyle::DollyXY(int dx, int dy)
   double zoomFactor = pow((double)1.1, dxf + dyf);
   
   vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
-  if (aCam->GetParallelProjection())
+  if (aCam->GetParallelProjection()) {
+    int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
+    if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
+      int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
+      int w = aSize[0];
+      int h = aSize[1];
+      x0 = w / 2;
+      y0 = h / 2;
+      x1 = myOtherPoint.x();
+      y1 = h - myOtherPoint.y();
+      TranslateView( x0, y0, x1, y1 );
+    }
     aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
+    if( IsAdvancedZoomingEnabled() )
+      TranslateView( x1, y1, x0, y0 );
+  }
   else{
     aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
     GetCurrentRenderer()->ResetCameraClippingRange(); 
   }
 
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
@@ -305,9 +321,9 @@ void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
     return;
 
   double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
-                         (double)(x - GetCurrentRenderer()->GetCenter()[0]));
+                          (double)(x - GetCurrentRenderer()->GetCenter()[0]));
   double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
-                         (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
+                          (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
   
   newAngle *= this->RadianToDegree;
   oldAngle *= this->RadianToDegree;
@@ -317,6 +333,7 @@ void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
   cam->OrthogonalizeViewUp();
       
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 
@@ -337,8 +354,8 @@ void SVTK_InteractorStyle::OnMouseMove()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnMouseMove( this->Interactor->GetControlKey(),
-                    this->Interactor->GetShiftKey(),
-                    x, y );
+                     this->Interactor->GetShiftKey(),
+                     x, y );
 }
 
 /*!
@@ -349,8 +366,8 @@ void SVTK_InteractorStyle::OnLeftButtonDown()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnLeftButtonDown( this->Interactor->GetControlKey(),
-                         this->Interactor->GetShiftKey(),
-                         x, y );
+                          this->Interactor->GetShiftKey(),
+                          x, y );
 }
 
 /*!
@@ -361,8 +378,8 @@ void SVTK_InteractorStyle::OnLeftButtonUp()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnLeftButtonUp( this->Interactor->GetControlKey(),
-                       this->Interactor->GetShiftKey(),
-                       x, y );
+                        this->Interactor->GetShiftKey(),
+                        x, y );
 }
 
 /*!
@@ -373,8 +390,8 @@ void SVTK_InteractorStyle::OnMiddleButtonDown()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
-                           this->Interactor->GetShiftKey(),
-                           x, y );
+                            this->Interactor->GetShiftKey(),
+                            x, y );
 }
 
 /*!
@@ -385,8 +402,8 @@ void SVTK_InteractorStyle::OnMiddleButtonUp()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
-                         this->Interactor->GetShiftKey(),
-                         x, y );
+                          this->Interactor->GetShiftKey(),
+                          x, y );
 }
 
 /*!
@@ -397,8 +414,8 @@ void SVTK_InteractorStyle::OnRightButtonDown()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnRightButtonDown( this->Interactor->GetControlKey(),
-                          this->Interactor->GetShiftKey(),
-                          x, y );
+                           this->Interactor->GetShiftKey(),
+                           x, y );
 }
 
 /*!
@@ -409,16 +426,36 @@ void SVTK_InteractorStyle::OnRightButtonUp()
   int x, y;
   GetEventPosition( this->Interactor, x, y );
   this->OnRightButtonUp( this->Interactor->GetControlKey(),
-                        this->Interactor->GetShiftKey(),
-                        x, y );
+                         this->Interactor->GetShiftKey(),
+                         x, y );
+}
+
+/*!
+  To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
+*/
+void SVTK_InteractorStyle::OnMouseWheelForward()
+{
+  int x, y;
+  GetEventPosition( this->Interactor, x, y );
+  myOtherPoint = QPoint(x, y);
+}
+
+/*!
+  To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
+*/
+void SVTK_InteractorStyle::OnMouseWheelBackward()
+{
+  int x, y;
+  GetEventPosition( this->Interactor, x, y );
+  myOtherPoint = QPoint(x, y);
 }
 
 /*!
   To handle mouse move event
 */
 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl), 
-                                      int shift,
-                                      int x, int y) 
+                                       int shift,
+                                       int x, int y) 
 {
   myShiftState = shift;
   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
@@ -431,7 +468,7 @@ void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
   To handle left mouse button down event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, 
-                                           int x, int y) 
+                                            int x, int y) 
 {
   this->FindPokedRenderer(x, y);
   if(GetCurrentRenderer() == NULL)
@@ -450,68 +487,68 @@ void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
     if (ctrl)
       startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
     else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
-             myCurrFocalPointType == SVTK::StartFocalPointSelection )
+              myCurrFocalPointType == SVTK::StartFocalPointSelection )
     {
       SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
 
-      SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
+      bool isPicked = false;
+      vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
       
-      if ( anActor )
+      if( anActorCollection )
       {
-       myPointPicker->Pick( aSelectionEvent->myX,
-                            aSelectionEvent->myY, 
-                            0.0, 
-                            GetCurrentRenderer() );
-       int aVtkId = myPointPicker->GetPointId();
-       if ( aVtkId >= 0 )
-       {
-         int anObjId = anActor->GetNodeObjId( aVtkId );
-         vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId);
-         
-         if (myCurrRotationPointType == SVTK::StartPointSelection) {
-           myCurrRotationPointType = SVTK::SetRotateSelected;
-         
-           // invoke event for update coordinates in SVTK_SetRotationPointDlg
-           InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
-         }
-         else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
-           myCurrFocalPointType = SVTK::SetFocalPointSelected;
-         
-           // invoke event for update coordinates in SVTK_ViewParameterDlg
-           InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
-         }
-       }
-       else
-       {
-         if (myCurrRotationPointType == SVTK::StartPointSelection) {
-           // invoke event with no data (for SVTK_SetRotationPointDlg)
-           InvokeEvent(SVTK::RotationPointChanged,0);
-           myCurrRotationPointType = myPrevRotationPointType;
-         }
-         else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
-           // invoke event with no data (for SVTK_ViewParameterDlg)
-           InvokeEvent(SVTK::FocalPointChanged,0);
-           myCurrFocalPointType = myPrevFocalPointType;
-         }
-       }
+        anActorCollection->InitTraversal();
+        while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
+        {
+          if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
+          {
+            SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
+            myPointPicker->Pick( aSelectionEvent->myX,
+                                 aSelectionEvent->myY, 
+                                 0.0, 
+                                 GetCurrentRenderer() );
+            int aVtkId = myPointPicker->GetPointId();
+            if ( aVtkId >= 0 )
+            {
+              int anObjId = anActor->GetNodeObjId( aVtkId );
+              vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId);
+              
+              if (myCurrRotationPointType == SVTK::StartPointSelection) {
+                myCurrRotationPointType = SVTK::SetRotateSelected;
+                
+                // invoke event for update coordinates in SVTK_SetRotationPointDlg
+                InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
+              }
+              else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
+                myCurrFocalPointType = SVTK::SetFocalPointSelected;
+                
+                // invoke event for update coordinates in SVTK_ViewParameterDlg
+                InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
+              }
+
+              isPicked = true;
+              break;
+            }
+          }
+        }
       }
-      else
+
+      if( !isPicked )
       {
-       if (myCurrRotationPointType == SVTK::StartPointSelection) {
-         // invoke event with no data (for SVTK_SetRotationPointDlg)
-         InvokeEvent(SVTK::RotationPointChanged,0);
-         myCurrRotationPointType = myPrevRotationPointType;
-       }
-       else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
-         // invoke event with no data (for SVTK_ViewParameterDlg)
-         InvokeEvent(SVTK::FocalPointChanged,0);
-         myCurrFocalPointType = myPrevFocalPointType;
-       }
+        if (myCurrRotationPointType == SVTK::StartPointSelection) {
+          // invoke event with no data (for SVTK_SetRotationPointDlg)
+          InvokeEvent(SVTK::RotationPointChanged,0);
+          myCurrRotationPointType = myPrevRotationPointType;
+        }
+        else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
+          // invoke event with no data (for SVTK_ViewParameterDlg)
+          InvokeEvent(SVTK::FocalPointChanged,0);
+          myCurrFocalPointType = myPrevFocalPointType;
+        }
       }
     
       myHighlightSelectionPointActor->SetVisibility( false );
       if(GetCurrentRenderer() != NULL)
-       GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
+        GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
 
       GetRenderWidget()->setCursor(myDefCursor); 
     }
@@ -526,9 +563,9 @@ void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
   To handle left mouse button up event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
-                                         int shift, 
-                                         int vtkNotUsed(x),
-                                         int vtkNotUsed(y))
+                                          int shift, 
+                                          int vtkNotUsed(x),
+                                          int vtkNotUsed(y))
 {
   myShiftState = shift;
   // finishing current viewer operation
@@ -542,8 +579,8 @@ void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
   To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
-                                             int shift, 
-                                             int x, int y) 
+                                              int shift, 
+                                              int x, int y) 
 {
   this->FindPokedRenderer(x, y);
   if(GetCurrentRenderer() == NULL)
@@ -570,9 +607,9 @@ void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
   To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
-                                           int shift, 
-                                           int vtkNotUsed(x),
-                                           int vtkNotUsed(y))
+                                            int shift, 
+                                            int vtkNotUsed(x),
+                                            int vtkNotUsed(y))
 {
   myShiftState = shift;
   // finishing current viewer operation
@@ -587,8 +624,8 @@ void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
   To handle right mouse button down event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
-                                            int shift, 
-                                            int x, int y) 
+                                             int shift, 
+                                             int x, int y) 
 {
   this->FindPokedRenderer(x, y);
   if(GetCurrentRenderer() == NULL)
@@ -614,9 +651,9 @@ void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
   To handle right mouse button up event (reimplemented from vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
-                                          int shift, 
-                                          int vtkNotUsed(x),
-                                          int vtkNotUsed(y))
+                                           int shift, 
+                                           int vtkNotUsed(x),
+                                           int vtkNotUsed(y))
 {
   myShiftState = shift;
   // finishing current viewer operation
@@ -775,8 +812,8 @@ void SVTK_InteractorStyle::startPointSelection()
     vtkFloatingPointType aColor[3];
     GetCurrentRenderer()->GetBackground( aColor );
     myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
-                                                           1. - aColor[1],
-                                                           1. - aColor[2]);
+                                                            1. - aColor[1],
+                                                            1. - aColor[2]);
   }
 
   setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
@@ -794,8 +831,8 @@ void SVTK_InteractorStyle::startFocalPointSelection()
     vtkFloatingPointType aColor[3];
     GetCurrentRenderer()->GetBackground( aColor );
     myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
-                                                           1. - aColor[1],
-                                                           1. - aColor[2]);
+                                                            1. - aColor[1],
+                                                            1. - aColor[2]);
   }
 
   setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
@@ -858,9 +895,9 @@ void SVTK_InteractorStyle::startGlobalPan()
   Fits viewer contents to rect
 */
 void SVTK_InteractorStyle::fitRect(const int left, 
-                                  const int top, 
-                                  const int right, 
-                                  const int bottom)
+                                   const int top, 
+                                   const int right, 
+                                   const int bottom)
 {
   if (GetCurrentRenderer() == NULL) 
     return;
@@ -956,10 +993,10 @@ void SVTK_InteractorStyle::setCursor(const int operation)
     case VTK_INTERACTOR_STYLE_CAMERA_NONE:
     default:
       if ( myCurrRotationPointType == SVTK::StartPointSelection ||
-          myCurrFocalPointType == SVTK::StartFocalPointSelection )
-       GetRenderWidget()->setCursor(myHandCursor);
+           myCurrFocalPointType == SVTK::StartFocalPointSelection )
+        GetRenderWidget()->setCursor(myHandCursor);
       else
-       GetRenderWidget()->setCursor(myDefCursor); 
+        GetRenderWidget()->setCursor(myDefCursor); 
       myCursorState = false;
       break;
   }
@@ -1029,55 +1066,69 @@ void SVTK_InteractorStyle::onFinishOperation()
       }
       else {
         if (myPoint == myOtherPoint)
-         {
-           // process point selection
-           this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
-           Interactor->StartPickCallback();
-           
-           SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
-
-           aSelectionEvent->myIsRectangle = false;
-
-           if(!myShiftState)
-             GetSelector()->ClearIObjects();
-
-           if(anActor)
-             {
-               anActor->Highlight( this, aSelectionEvent, true );
-             }
-           else
-             {
-               if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor)
-                 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
-             }
-           myLastHighlitedActor = anActor;
-         } 
-       else 
-         {
-           //processing rectangle selection
-           Interactor->StartPickCallback();
-           GetSelector()->StartPickCallback();
-           aSelectionEvent->myIsRectangle = true;
-
-           if(!myShiftState)
-             GetSelector()->ClearIObjects();
-
-           vtkActorCollection* aListActors = GetCurrentRenderer()->GetActors();
-           aListActors->InitTraversal();
-           while(vtkActor* aActor = aListActors->GetNextActor())
-             {
-               if(aActor->GetVisibility())
-                 {
-                   if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
-                     {
-                       if(aSActor->hasIO())
-                         aSActor->Highlight( this, aSelectionEvent, true );
-                     }
-                 }
-             }
-         }
-       Interactor->EndPickCallback();
-       GetSelector()->EndPickCallback();
+          {
+            // process point selection
+            this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
+            Interactor->StartPickCallback();
+            
+            SALOME_Actor* aHighlightedActor = NULL;
+            vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
+
+            aSelectionEvent->myIsRectangle = false;
+
+            if(!myShiftState)
+              GetSelector()->ClearIObjects();
+
+            if( anActorCollection )
+            {
+              anActorCollection->InitTraversal();
+              while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
+              {
+                if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
+                {
+                  if( anActor->Highlight( this, aSelectionEvent, true ) )
+                  {
+                    aHighlightedActor = anActor;
+                    break;
+                  }
+                }
+              }
+            }
+
+            if( !aHighlightedActor )
+            {
+              if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
+                myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
+            }
+            myLastHighlitedActor = aHighlightedActor;
+          } 
+        else 
+          {
+            //processing rectangle selection
+            Interactor->StartPickCallback();
+            GetSelector()->StartPickCallback();
+            aSelectionEvent->myIsRectangle = true;
+
+            if(!myShiftState)
+              GetSelector()->ClearIObjects();
+
+            VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
+            vtkActorCollection* aListActors = aCopy.GetActors();
+            aListActors->InitTraversal();
+            while(vtkActor* aActor = aListActors->GetNextActor())
+              {
+                if(aActor->GetVisibility())
+                  {
+                    if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
+                      {
+                        if(aSActor->hasIO())
+                          aSActor->Highlight( this, aSelectionEvent, true );
+                      }
+                  }
+              }
+          }
+        Interactor->EndPickCallback();
+        GetSelector()->EndPickCallback();
       } 
     } 
     break;
@@ -1164,40 +1215,63 @@ void SVTK_InteractorStyle::onCursorMove(QPoint mousePos)
 
   bool anIsChanged = false;
 
-  SALOME_Actor *anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
+  SALOME_Actor* aPreHighlightedActor = NULL;
+  vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
 
   if ( myCurrRotationPointType == SVTK::StartPointSelection ||
        myCurrFocalPointType == SVTK::StartFocalPointSelection )
   {
     myHighlightSelectionPointActor->SetVisibility( false );
 
-    if ( anActor )
+    if( anActorCollection )
     {
-      myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
-      int aVtkId = myPointPicker->GetPointId();
-      if ( aVtkId >= 0 ) {
-       int anObjId = anActor->GetNodeObjId( aVtkId );
-
-       TColStd_IndexedMapOfInteger aMapIndex;
-       aMapIndex.Add( anObjId );
-       myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
-
-       myHighlightSelectionPointActor->SetVisibility( true );
-       anIsChanged = true;
+      anActorCollection->InitTraversal();
+      while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
+      {
+        if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
+        {
+          SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
+          myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
+          int aVtkId = myPointPicker->GetPointId();
+          if ( aVtkId >= 0 ) {
+            int anObjId = anActor->GetNodeObjId( aVtkId );
+
+            TColStd_IndexedMapOfInteger aMapIndex;
+            aMapIndex.Add( anObjId );
+            myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
+
+            myHighlightSelectionPointActor->SetVisibility( true );
+            anIsChanged = true;
+            break;
+          }
+        }
       }
     }
   }
   else {
-    if (anActor){
-      anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true );
+    if( anActorCollection )
+    {
+      anActorCollection->InitTraversal();
+      while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
+      {
+        if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
+        {
+          anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
+          if( anActor->isPreselected() )
+          {
+            aPreHighlightedActor = anActor;
+            break;
+          }
+        }
+      }
     }
 
-    if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor)
+    if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
       anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );   
 
   }
   
-  myLastPreHighlitedActor = anActor;
+  myLastPreHighlitedActor = aPreHighlightedActor;
 
   if(anIsChanged)
     this->Render();
@@ -1233,19 +1307,22 @@ void SVTK_InteractorStyle::Place(const int theX, const int theY)
 */
 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
 {
+  if (GetCurrentRenderer() == NULL)
+    return;
+
   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
   double viewFocus[4], focalDepth, viewPoint[3];
   vtkFloatingPointType newPickPoint[4], oldPickPoint[4], motionVector[3];
   cam->GetFocalPoint(viewFocus);
 
   this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
-                             viewFocus[2], viewFocus);
+                              viewFocus[2], viewFocus);
   focalDepth = viewFocus[2];
 
   this->ComputeDisplayToWorld(double(toX), double(toY),
-                             focalDepth, newPickPoint);
+                              focalDepth, newPickPoint);
   this->ComputeDisplayToWorld(double(fromX),double(fromY),
-                             focalDepth, oldPickPoint);
+                              focalDepth, oldPickPoint);
   
   // camera motion is reversed
   motionVector[0] = oldPickPoint[0] - newPickPoint[0];
@@ -1255,11 +1332,11 @@ void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
   cam->GetFocalPoint(viewFocus);
   cam->GetPosition(viewPoint);
   cam->SetFocalPoint(motionVector[0] + viewFocus[0],
-                    motionVector[1] + viewFocus[1],
-                    motionVector[2] + viewFocus[2]);
+                     motionVector[1] + viewFocus[1],
+                     motionVector[2] + viewFocus[2]);
   cam->SetPosition(motionVector[0] + viewPoint[0],
-                  motionVector[1] + viewPoint[1],
-                  motionVector[2] + viewPoint[2]);
+                   motionVector[1] + viewPoint[1],
+                   motionVector[2] + viewPoint[2]);
 }
 
 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
@@ -1341,19 +1418,19 @@ void SVTK_InteractorStyle::OnTimer()
     {
       if ( !myBBFirstCheck )
       {
-       if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
-            fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
-            fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
-         // bounding box was changed => send SVTK::RotationPointChanged event
-         // invoke event for update coordinates in SVTK_SetRotationPointDlg
-         InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
-         for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
-       }
+        if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
+             fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
+             fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
+          // bounding box was changed => send SVTK::RotationPointChanged event
+          // invoke event for update coordinates in SVTK_SetRotationPointDlg
+          InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
+          for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
+        }
       }
       else 
       {
-       for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
-       myBBFirstCheck = false;
+        for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
+        myBBFirstCheck = false;
       }
     }
   }
@@ -1430,9 +1507,9 @@ void SVTK_InteractorStyle::endDrawRect()
   Main process event method (reimplemented from #vtkInteractorStyle)
 */
 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
-                                         unsigned long event,
-                                         void* clientData, 
-                                         void* callData )
+                                          unsigned long event,
+                                          void* clientData, 
+                                          void* callData )
 {
   if ( clientData ) {
     vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
@@ -1443,140 +1520,140 @@ void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
     if ( self ) {
       switch ( event ) {
       case SVTK::SpaceMouseMoveEvent : 
-       self->onSpaceMouseMove( (double*)callData ); 
-       return;
+        self->onSpaceMouseMove( (double*)callData ); 
+        return;
       case SVTK::SpaceMouseButtonEvent : 
-       self->onSpaceMouseButton( *((int*)callData) ); 
-       return;
+        self->onSpaceMouseButton( *((int*)callData) ); 
+        return;
       case SVTK::PanLeftEvent: 
-       self->IncrementalPan(-aSpeedIncrement, 0);
-       return;
+        self->IncrementalPan(-aSpeedIncrement, 0);
+        return;
       case SVTK::PanRightEvent:
-       self->IncrementalPan(aSpeedIncrement, 0);
-       return;
+        self->IncrementalPan(aSpeedIncrement, 0);
+        return;
       case SVTK::PanUpEvent:
-       self->IncrementalPan(0, aSpeedIncrement);
-       return;
+        self->IncrementalPan(0, aSpeedIncrement);
+        return;
       case SVTK::PanDownEvent:
-       self->IncrementalPan(0, -aSpeedIncrement);
-       return;
+        self->IncrementalPan(0, -aSpeedIncrement);
+        return;
       case SVTK::ZoomInEvent:
-       self->IncrementalZoom(aSpeedIncrement);
-       return;
+        self->IncrementalZoom(aSpeedIncrement);
+        return;
       case SVTK::ZoomOutEvent:
-       self->IncrementalZoom(-aSpeedIncrement);
-       return;
+        self->IncrementalZoom(-aSpeedIncrement);
+        return;
       case SVTK::RotateLeftEvent: 
-       self->IncrementalRotate(-aSpeedIncrement, 0);
-       return;
+        self->IncrementalRotate(-aSpeedIncrement, 0);
+        return;
       case SVTK::RotateRightEvent:
-       self->IncrementalRotate(aSpeedIncrement, 0);
-       return;
+        self->IncrementalRotate(aSpeedIncrement, 0);
+        return;
       case SVTK::RotateUpEvent:
-       self->IncrementalRotate(0, -aSpeedIncrement);
-       return;
+        self->IncrementalRotate(0, -aSpeedIncrement);
+        return;
       case SVTK::RotateDownEvent:
-       self->IncrementalRotate(0, aSpeedIncrement);
-       return;
+        self->IncrementalRotate(0, aSpeedIncrement);
+        return;
       case SVTK::PlusSpeedIncrementEvent:
-       self->ControllerIncrement()->Increase();
-       return;
+        self->ControllerIncrement()->Increase();
+        return;
       case SVTK::MinusSpeedIncrementEvent:
-       self->ControllerIncrement()->Decrease();
-       return;
+        self->ControllerIncrement()->Decrease();
+        return;
       case SVTK::SetSpeedIncrementEvent:
-       self->ControllerIncrement()->SetStartValue(*((int*)callData));
-       return;
+        self->ControllerIncrement()->SetStartValue(*((int*)callData));
+        return;
 
       case SVTK::SetSMDecreaseSpeedEvent:
-       self->mySMDecreaseSpeedBtn = *((int*)callData);
-       return;
+        self->mySMDecreaseSpeedBtn = *((int*)callData);
+        return;
       case SVTK::SetSMIncreaseSpeedEvent:
-       self->mySMIncreaseSpeedBtn = *((int*)callData);
-       return;
+        self->mySMIncreaseSpeedBtn = *((int*)callData);
+        return;
       case SVTK::SetSMDominantCombinedSwitchEvent:
-       self->mySMDominantCombinedSwitchBtn = *((int*)callData);
-       return;
+        self->mySMDominantCombinedSwitchBtn = *((int*)callData);
+        return;
 
       case SVTK::StartZoom:
-       self->startZoom();
-       return;
+        self->startZoom();
+        return;
       case SVTK::StartPan:
-       self->startPan();
-       return;
+        self->startPan();
+        return;
       case SVTK::StartRotate:
-       self->startRotate();
-       return;
+        self->startRotate();
+        return;
       case SVTK::StartGlobalPan:
-       self->startGlobalPan();
-       return;
+        self->startGlobalPan();
+        return;
       case SVTK::StartFitArea:
-       self->startFitArea();
-       return;
+        self->startFitArea();
+        return;
 
       case SVTK::SetRotateGravity:
-       if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
-       {
-         self->myHighlightSelectionPointActor->SetVisibility( false );
-         if( self->GetCurrentRenderer() != NULL )
-           self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
-         self->GetRenderWidget()->setCursor(self->myDefCursor); 
-       }
-       self->myPrevRotationPointType = self->myCurrRotationPointType;
-       self->myCurrRotationPointType = SVTK::SetRotateGravity;
-       if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) 
-         // invoke event for update coordinates in SVTK_SetRotationPointDlg
-         self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
-       return;
+        if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
+        {
+          self->myHighlightSelectionPointActor->SetVisibility( false );
+          if( self->GetCurrentRenderer() != NULL )
+            self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
+          self->GetRenderWidget()->setCursor(self->myDefCursor); 
+        }
+        self->myPrevRotationPointType = self->myCurrRotationPointType;
+        self->myCurrRotationPointType = SVTK::SetRotateGravity;
+        if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) 
+          // invoke event for update coordinates in SVTK_SetRotationPointDlg
+          self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
+        return;
       case SVTK::StartPointSelection:
-       self->startPointSelection();
-       return;
+        self->startPointSelection();
+        return;
 
       case SVTK::ChangeRotationPoint:
-       if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
-       {
-         self->myHighlightSelectionPointActor->SetVisibility( false );
-         if( self->GetCurrentRenderer() != NULL )
-           self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
-         self->GetRenderWidget()->setCursor(self->myDefCursor); 
-       }
-       self->myPrevRotationPointType = self->myCurrRotationPointType;
-       self->myCurrRotationPointType = SVTK::SetRotateSelected;
-       aSelectedPoint = (vtkFloatingPointType*)callData;
-       self->myRotationPointX = aSelectedPoint[0];
-       self->myRotationPointY = aSelectedPoint[1];
-       self->myRotationPointZ = aSelectedPoint[2];
-       return;
+        if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
+        {
+          self->myHighlightSelectionPointActor->SetVisibility( false );
+          if( self->GetCurrentRenderer() != NULL )
+            self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
+          self->GetRenderWidget()->setCursor(self->myDefCursor); 
+        }
+        self->myPrevRotationPointType = self->myCurrRotationPointType;
+        self->myCurrRotationPointType = SVTK::SetRotateSelected;
+        aSelectedPoint = (vtkFloatingPointType*)callData;
+        self->myRotationPointX = aSelectedPoint[0];
+        self->myRotationPointY = aSelectedPoint[1];
+        self->myRotationPointZ = aSelectedPoint[2];
+        return;
 
       case SVTK::SetFocalPointGravity:
-       if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
-       {
-         self->myHighlightSelectionPointActor->SetVisibility( false );
-         if( self->GetCurrentRenderer() != NULL )
-           self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
-         self->GetRenderWidget()->setCursor(self->myDefCursor); 
-       }
-       self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
-       if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
-         // invoke event for update coordinates in SVTK_ViewParameterDlg
-         self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
-       }
-       return;
+        if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
+        {
+          self->myHighlightSelectionPointActor->SetVisibility( false );
+          if( self->GetCurrentRenderer() != NULL )
+            self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
+          self->GetRenderWidget()->setCursor(self->myDefCursor); 
+        }
+        self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
+        if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
+          // invoke event for update coordinates in SVTK_ViewParameterDlg
+          self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
+        }
+        return;
       case SVTK::StartFocalPointSelection:
-       self->startFocalPointSelection();
-       return;
+        self->startFocalPointSelection();
+        return;
 
       case SVTK::SetFocalPointSelected:
-       if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
-       {
-         self->myHighlightSelectionPointActor->SetVisibility( false );
-         if( self->GetCurrentRenderer() != NULL )
-           self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
-         self->GetRenderWidget()->setCursor(self->myDefCursor); 
-       }
-       self->myPrevFocalPointType = self->myCurrFocalPointType;
-       self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
-       return;
+        if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
+        {
+          self->myHighlightSelectionPointActor->SetVisibility( false );
+          if( self->GetCurrentRenderer() != NULL )
+            self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
+          self->GetRenderWidget()->setCursor(self->myDefCursor); 
+        }
+        self->myPrevFocalPointType = self->myCurrFocalPointType;
+        self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
+        return;
       }
     }
   }