Salome HOME
Upgrade to paraview 5.4
[modules/gui.git] / src / SVTK / SALOME_Actor.cxx
index ad20490b22ba51da80df7cf4dd6ac145f25d7a07..eafd19747ba007a0da949ec9c543fabc5cb8381f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
@@ -6,7 +6,7 @@
 // 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.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -38,7 +38,7 @@
 #include "VTKViewer_TransformFilter.h"
 #include "VTKViewer_GeometryFilter.h"
 #include "VTKViewer_FramedTextActor.h"
-#include "SVTK_RectPicker.h"
+#include "SVTK_AreaPicker.h"
 
 #include "SVTK_Actor.h"
 
@@ -48,6 +48,7 @@
 // VTK Includes
 #include <vtkCell.h>
 #include <vtkLine.h>
+#include <vtkQuadraticEdge.h>
 #include <vtkPicker.h>
 #include <vtkPointPicker.h>
 #include <vtkCellPicker.h>
@@ -58,6 +59,7 @@
 #include <vtkPolyDataMapper.h>
 #include <vtkProperty.h>
 #include <vtkOutlineSource.h>
+#include <vtkPolygon.h>
 
 #include <vtkInteractorStyle.h>
 #include <vtkRenderWindowInteractor.h>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
 
+#include <math.h>
+#include <QPoint>
+#include <QVector>
+
 #if defined __GNUC__
   #if __GNUC__ == 2
     #define __GNUC_2__
@@ -84,14 +90,17 @@ namespace
   {
     int anEdgeId = 0;
     if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
-      vtkFloatingPointType aPickPosition[3];
+      double aPickPosition[3];
       thePicker->GetPickPosition(aPickPosition);
-      vtkFloatingPointType aMinDist = 1000000.0, aDist = 0;
+      double aMinDist = 1000000.0, aDist = 0;
+      vtkCell* aSelEdge;
       for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
-        if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
+       aSelEdge = aPickedCell->GetEdge(i);
+        if(vtkLine::SafeDownCast(aPickedCell->GetEdge(i)) || 
+          vtkQuadraticEdge::SafeDownCast(aPickedCell->GetEdge(i))){
           int subId;  
-          vtkFloatingPointType pcoords[3], closestPoint[3], weights[3];
-          aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
+          double pcoords[3], closestPoint[3], weights[3];
+          aSelEdge->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
           if (aDist < aMinDist) {
             aMinDist = aDist;
             anEdgeId = -1 - i;
@@ -108,7 +117,7 @@ namespace
                    SALOME_Actor *theActor, 
                    vtkIdType theObjId)
   {
-    switch(theMode){
+    switch(theMode) {
     case CellSelection:
       return true;
     case EdgeSelection:
@@ -117,6 +126,15 @@ namespace
       return ( theActor->GetObjDimension( theObjId ) == 2 );
     case VolumeSelection:
       return ( theActor->GetObjDimension( theObjId ) == 3 );
+    case Elem0DSelection:        
+      return ((theActor->GetObjDimension( theObjId ) == 0) &&
+               theActor->GetElemCell(theObjId) && 
+              (theActor->GetElemCell(theObjId)->GetCellType() == VTK_VERTEX));
+    case BallSelection:
+      return ((theActor->GetObjDimension( theObjId ) == 0) &&
+               theActor->GetElemCell(theObjId) && 
+              (theActor->GetElemCell(theObjId)->GetCellType() == VTK_POLY_VERTEX));
+
     };
     return false;
   }
@@ -176,7 +194,7 @@ SALOME_Actor
   myOutline->Delete();
 
   vtkPolyDataMapper* anOutlineMapper = vtkPolyDataMapper::New();
-  anOutlineMapper->SetInput(myOutline->GetOutput());
+  anOutlineMapper->SetInputConnection(myOutline->GetOutputPort());
 
   myOutlineActor->Delete();
   myOutlineActor->SetMapper( anOutlineMapper );
@@ -203,7 +221,7 @@ SALOME_Actor
                                   aForegroundColor.greenF(),
                                   aForegroundColor.blueF());
 
-  vtkFloatingPointType aGroupNamesTransparency = 0.5;
+  double aGroupNamesTransparency = 0.5;
   aGroupNamesTransparency = aResourceMgr->doubleValue( "VTKViewer", "group_names_transparency", aGroupNamesTransparency );
   myNameActor->SetTransparency(aGroupNamesTransparency);
 }
@@ -273,8 +291,8 @@ SALOME_Actor
 
   myRenderer = theRenderer;
 
-  theRenderer->AddActor( myPreHighlightActor.GetPointer() );
-  theRenderer->AddActor( myHighlightActor.GetPointer() );
+  myHighlightActor->AddToRender(theRenderer);
+  myPreHighlightActor->AddToRender(theRenderer);
   theRenderer->AddActor( myOutlineActor.GetPointer() );
   theRenderer->AddActor( myNameActor.GetPointer() );
 }
@@ -288,6 +306,9 @@ SALOME_Actor
 {
   Superclass::RemoveFromRender(theRenderer);
 
+  myHighlightActor->RemoveFromRender(theRenderer);
+  myPreHighlightActor->RemoveFromRender(theRenderer);
+
   theRenderer->RemoveActor( myPreHighlightActor.GetPointer() );
   theRenderer->RemoveActor( myHighlightActor.GetPointer() );
   theRenderer->RemoveActor( myOutlineActor.GetPointer() );
@@ -345,9 +366,9 @@ SALOME_Actor
 */
 void
 SALOME_Actor
-::SetPosition(vtkFloatingPointType _arg1, 
-              vtkFloatingPointType _arg2, 
-              vtkFloatingPointType _arg3)
+::SetPosition(double _arg1, 
+              double _arg2, 
+              double _arg3)
 {
   Superclass::SetPosition(_arg1,_arg2,_arg3);
 
@@ -361,7 +382,7 @@ SALOME_Actor
 */
 void
 SALOME_Actor
-::SetPosition(vtkFloatingPointType _arg[3])
+::SetPosition(double _arg[3])
 {
   SetPosition(_arg[0],_arg[1],_arg[2]);
 }
@@ -410,7 +431,7 @@ SALOME_Actor
 {
   mySelector = theSelector;
 }
-
+  
 /*!
   To map current selection to VTK representation
 */
@@ -439,12 +460,15 @@ SALOME_Actor
       case EdgeSelection:
       case FaceSelection:
       case VolumeSelection:
+      case Elem0DSelection: 
+      case BallSelection: 
         myHighlightActor->GetProperty()->SetRepresentationToSurface();
         myHighlightActor->MapCells( this, aMapIndex );
         break;
       }
       myHighlightActor->SetVisibility( GetVisibility() && theIsHighlight );
     }
+    myHighlightActor->SetMarkerEnabled( mySelectionMode == NodeSelection );
   }
 
   highlight(theIsHighlight);
@@ -457,10 +481,11 @@ void
 SALOME_Actor
 ::highlight(bool theIsHighlight)
 {
-  vtkFloatingPointType aBounds[6];
+  double aBounds[6];
   vtkDataSet * aDataSet = GetHighlightedDataSet();
   aDataSet->GetBounds(aBounds);
   myOutline->SetBounds(aBounds);
+  myOutline->Update();
   myOutlineActor->SetVisibility( GetVisibility() && theIsHighlight );
 
   Superclass::highlight(theIsHighlight);
@@ -476,7 +501,7 @@ SALOME_Actor
                SVTK_SelectionEvent* theSelectionEvent,
                bool theIsHighlight)
 {
-  if ( !GetPickable() )
+  if ( !GetPickable() || !mySelector || !mySelector->IsPreSelectionEnabled() )
     return false;
       
   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
@@ -490,9 +515,9 @@ SALOME_Actor
 
   myPreHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
 
-  vtkFloatingPointType x = theSelectionEvent->myX;
-  vtkFloatingPointType y = theSelectionEvent->myY;
-  vtkFloatingPointType z = 0.0;
+  double x = theSelectionEvent->myX;
+  double y = theSelectionEvent->myY;
+  double z = 0.0;
 
   if( !theIsHighlight ) {
     if ( hasIO() ) {
@@ -500,9 +525,9 @@ SALOME_Actor
       vtkActorCollection* theActors = aCopy.GetActors();
       theActors->InitTraversal();
       while( vtkActor *ac = theActors->GetNextActor() )
-       if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) )
-         if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
-           anActor->SetPreSelected( false );
+        if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) )
+          if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
+            anActor->SetPreSelected( false );
     }
   }else{
     switch(aSelectionMode) {
@@ -535,6 +560,8 @@ SALOME_Actor
     case EdgeSelection:
     case FaceSelection:
     case VolumeSelection: 
+    case Elem0DSelection:        
+    case BallSelection: 
     {
       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
       myCellPicker->Pick( x, y, z, aRenderer );
@@ -596,17 +623,17 @@ SALOME_Actor
       if( !mySelector->IsSelected( myIO ) ) {
         SetPreSelected( true );
 
-       if ( hasIO() ) {
-         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
-         vtkActorCollection* theActors = aCopy.GetActors();
-         theActors->InitTraversal();
-         while( vtkActor *anAct = theActors->GetNextActor() ) {
-           if( anAct != this )
-             if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( anAct ) )
-               if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
-                 anActor->SetPreSelected( true );
-         }
-       }
+        if ( hasIO() ) {
+          VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+          vtkActorCollection* theActors = aCopy.GetActors();
+          theActors->InitTraversal();
+          while( vtkActor *anAct = theActors->GetNextActor() ) {
+            if( anAct != this )
+              if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( anAct ) )
+                if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
+                  anActor->SetPreSelected( true );
+          }
+        }
       }
     }
     default:
@@ -629,7 +656,7 @@ SALOME_Actor
             SVTK_SelectionEvent* theSelectionEvent,
             bool theIsHighlight)
 {
-  if ( !GetPickable() || !mySelector )
+  if ( !GetPickable() || !mySelector || !mySelector->IsSelectionEnabled() )
     return false;
 
   myOutlineActor->SetVisibility( false );
@@ -646,104 +673,32 @@ SALOME_Actor
   if ( !theIsHighlight )
     return true;
 
-  myHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
-
-  vtkFloatingPointType x = theSelectionEvent->myX;
-  vtkFloatingPointType y = theSelectionEvent->myY;
-  vtkFloatingPointType z = 0.0;
+  double x = theSelectionEvent->myX;
+  double y = theSelectionEvent->myY;
 
-  if( !theSelectionEvent->myIsRectangle ) {
-    switch(aSelectionMode){
-    case NodeSelection: {
-      SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
-      myPointPicker->Pick( x, y, z, aRenderer );
-
-      int aVtkId = myPointPicker->GetPointId();
-      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
-        int anObjId = GetNodeObjId( aVtkId );
-        if( hasIO() && anObjId >= 0 ) {
-          mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
-          mySelector->AddIObject( this );
-        }
-      }
-      break;
-    }
-    case CellSelection: 
-    case EdgeSelection:
-    case FaceSelection:
-    case VolumeSelection: 
-    {
-      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
-      myCellPicker->Pick( x, y, z, aRenderer );
-    
-      int aVtkId = myCellPicker->GetCellId();
-      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
-        int anObjId = GetElemObjId( aVtkId );
-        if( anObjId >= 0 ) {
-          if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) {
-            mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
-            mySelector->AddIObject( this );
-          }
-        }
-      }
-      break;
-    }
-    case EdgeOfCellSelection: 
-    {
-      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
-      myCellPicker->Pick( x, y, z, aRenderer );
-    
-      int aVtkId = myCellPicker->GetCellId();
-      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
-        int anObjId = GetElemObjId( aVtkId );
-        if( anObjId >= 0 ) {
-          int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
-          if( hasIO() && anEdgeId < 0 ) {
-            mySelector->AddOrRemoveIndex( myIO, anObjId, false );
-            mySelector->AddOrRemoveIndex( myIO, anEdgeId, true );
-            mySelector->AddIObject( this );
-          } 
-        }
-      }
-      break;
-    }
-    case ActorSelection : 
-    {
-      if ( hasIO() ) {
-       if( mySelector->IsSelected( myIO ) && anIsShift )
-         mySelector->RemoveIObject( this );
-       else {
-         mySelector->AddIObject( this );
-       }
-      }
-      break;
-    }
-    default:
-      break;
-    }
-  }else{
-    vtkFloatingPointType xLast = theSelectionEvent->myLastX;
-    vtkFloatingPointType yLast = theSelectionEvent->myLastY;
-    vtkFloatingPointType zLast = 0.0;
+  if( theSelectionEvent->myIsRectangle || theSelectionEvent->myIsPolygon ) {
+    double xLast = theSelectionEvent->myLastX;
+    double yLast = theSelectionEvent->myLastY;
 
-    vtkFloatingPointType x1 = x < xLast ? x : xLast;
-    vtkFloatingPointType y1 = y < yLast ? y : yLast;
-    vtkFloatingPointType z1 = z < zLast ? z : zLast;
-    vtkFloatingPointType x2 = x > xLast ? x : xLast;
-    vtkFloatingPointType y2 = y > yLast ? y : yLast;
-    vtkFloatingPointType z2 = z > zLast ? z : zLast;
+    double x1 = x < xLast ? x : xLast;
+    double y1 = y < yLast ? y : yLast;
+    double x2 = x > xLast ? x : xLast;
+    double y2 = y > yLast ? y : yLast;
 
     switch(aSelectionMode){
     case NodeSelection: {
 
-      SVTK::TPickLimiter aPickLimiter( myPointRectPicker, this );
-      myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
+      SVTK::TPickLimiter aPickLimiter( myPointAreaPicker, this );
+      if ( theSelectionEvent->myIsRectangle )
+        myPointAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode );
+      else if( theSelectionEvent->myIsPolygon )
+        myPointAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode );
 
-      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap();
-      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
+      const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myPointAreaPicker->GetPointIdsMap();
+      SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
       TColStd_MapOfInteger anIndexes;
       if(aMapIter != aVectorIdsMap.end()){
-        const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
+        const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
         vtkIdType anEnd = aVectorIds.size();
         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
           int aPointId = aVectorIds[anId];
@@ -755,20 +710,20 @@ SALOME_Actor
       }
       
       if ( hasIO() ) {
-       if( !anIndexes.IsEmpty() ) {
-         mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
-         mySelector->AddIObject( this );
-         anIndexes.Clear();
-       }
-       else if ( !anIsShift )
-         mySelector->RemoveIObject( this );
+        if( !anIndexes.IsEmpty() ) {
+          mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
+          mySelector->AddIObject( this );
+          anIndexes.Clear();
+        }
+        else if ( !anIsShift )
+          mySelector->RemoveIObject( this );
       }
       break;
     }
     case ActorSelection :
     {
-      vtkFloatingPointType aPnt[3];
-      vtkFloatingPointType* aBounds = GetBounds();
+      double aPnt[3];
+      double* aBounds = GetBounds();
 
       bool anIsPicked = true;
       for( int i = 0; i <= 1; i++ ) {
@@ -777,17 +732,28 @@ SALOME_Actor
             aRenderer->SetWorldPoint( aBounds[ i ], aBounds[ j ], aBounds[ k ], 1.0 );
             aRenderer->WorldToDisplay();
             aRenderer->GetDisplayPoint( aPnt );
-
-            if( aPnt[0] < x1 || aPnt[0] > x2 || aPnt[1] < y1 || aPnt[1] > y2 ) {
-              anIsPicked = false;
-              break;
+            bool anIsPointInSelection;
+            if( theSelectionEvent->myIsRectangle )
+              anIsPointInSelection =  aPnt[0] > x1 && aPnt[0] < x2 && aPnt[1] > y1 && aPnt[1] < y2;
+            else if( theSelectionEvent->myIsPolygon )
+              anIsPointInSelection = myPointAreaPicker->isPointInPolygon( QPoint( aPnt[0], aPnt[1] ),
+                                                                          theSelectionEvent->myPolygonPoints );
+
+            if( !anIsPointInSelection ) {
+                anIsPicked = false;
+                break;
             }
           }
         }
       }
 
-      if( anIsPicked )
-        mySelector->AddIObject(this);
+      if ( hasIO() ) {
+        if( anIsPicked && mySelector->IsSelected( myIO ) && anIsShift )
+          mySelector->RemoveIObject( this );
+        else if ( anIsPicked ){
+          mySelector->AddIObject( this );
+        }
+      }
 
       break;
     }
@@ -795,15 +761,20 @@ SALOME_Actor
     case EdgeSelection:
     case FaceSelection:
     case VolumeSelection: 
+    case Elem0DSelection:        
+    case BallSelection: 
     {
-      SVTK::TPickLimiter aPickLimiter( myCellRectPicker, this );
-      myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
-
-      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap();
-      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
+      SVTK::TPickLimiter aPickLimiter( myCellAreaPicker, this );
+      if( theSelectionEvent->myIsRectangle )
+        myCellAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode );
+      else if( theSelectionEvent->myIsPolygon )
+        myCellAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode );
+
+      const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myCellAreaPicker->GetCellIdsMap();
+      SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
       TColStd_MapOfInteger anIndexes;
       if(aMapIter != aVectorIdsMap.end()){
-        const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
+        const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
         vtkIdType anEnd = aVectorIds.size();
         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
           int aCellId = aVectorIds[anId];
@@ -819,14 +790,86 @@ SALOME_Actor
       }
       
       if ( hasIO() ) {
-       if( !anIndexes.IsEmpty() ) {
-         mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
-         mySelector->AddIObject( this );
-         anIndexes.Clear();
-       }
-       else if ( !anIsShift )
-         mySelector->RemoveIObject( this );
+        if( !anIndexes.IsEmpty() ) {
+          mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
+          mySelector->AddIObject( this );
+          anIndexes.Clear();
+        }
+        else if ( !anIsShift )
+          mySelector->RemoveIObject( this );
+      }
+    }
+    default:
+      break;
+    }
+  }
+  else {
+    switch(aSelectionMode){
+    case NodeSelection: {
+      SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
+      myPointPicker->Pick( x, y, 0.0, aRenderer );
+
+      int aVtkId = myPointPicker->GetPointId();
+      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
+        int anObjId = GetNodeObjId( aVtkId );
+        if( hasIO() && anObjId >= 0 ) {
+          mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
+          mySelector->AddIObject( this );
+        }
+      }
+      break;
+    }
+    case CellSelection:
+    case EdgeSelection:
+    case FaceSelection:
+    case VolumeSelection:
+    case Elem0DSelection:
+    case BallSelection:
+    {
+      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
+      myCellPicker->Pick( x, y, 0.0, aRenderer );
+
+      int aVtkId = myCellPicker->GetCellId();
+      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
+        int anObjId = GetElemObjId( aVtkId );
+        if( anObjId >= 0 ) {
+          if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) {
+            mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
+            mySelector->AddIObject( this );
+          }
+        }
+      }
+      break;
+    }
+    case EdgeOfCellSelection:
+    {
+      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
+      myCellPicker->Pick( x, y, 0.0, aRenderer );
+
+      int aVtkId = myCellPicker->GetCellId();
+      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
+        int anObjId = GetElemObjId( aVtkId );
+        if( anObjId >= 0 ) {
+          int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
+          if( hasIO() && anEdgeId < 0 ) {
+            mySelector->AddOrRemoveIndex( myIO, anObjId, false );
+            mySelector->AddOrRemoveIndex( myIO, anEdgeId, true );
+            mySelector->AddIObject( this );
+          }
+        }
+      }
+      break;
+    }
+    case ActorSelection :
+    {
+      if ( hasIO() ) {
+        if( mySelector->IsSelected( myIO ) && anIsShift )
+          mySelector->RemoveIObject( this );
+        else {
+          mySelector->AddIObject( this );
+        }
       }
+      break;
     }
     default:
       break;
@@ -880,7 +923,7 @@ SALOME_Actor
 */
 void
 SALOME_Actor
-::SetNameActorOffset(int theOffset[2])
+::SetNameActorOffset(double theOffset[2])
 {
   myNameActor->SetOffset(theOffset);
 }
@@ -892,7 +935,7 @@ SALOME_Actor
 */
 void
 SALOME_Actor
-::GetNameActorSize(vtkRenderer* theRenderer, int theSize[2]) const
+::GetNameActorSize(vtkRenderer* theRenderer, double theSize[2]) const
 {
   myNameActor->GetSize(theRenderer, theSize);
 }
@@ -906,7 +949,7 @@ SALOME_Actor
 {
   if( vtkRenderer* aRenderer = GetRenderer() )
   {
-    int anOffset[2] = { 0, 0 };
+    double anOffset[2] = { 0, 0 };
     VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
     vtkActorCollection* aCollection = aCopy.GetActors();
     for( int anIndex = 0, aNbItems = aCollection->GetNumberOfItems(); anIndex < aNbItems; anIndex++ )
@@ -918,7 +961,7 @@ SALOME_Actor
           anActor->SetNameActorOffset( anOffset );
           if( anActor->GetVisibility() )
           {
-            int aSize[2];
+            double aSize[2];
             anActor->GetNameActorSize( aRenderer, aSize );
             anOffset[0] = anOffset[0] + aSize[0];
             anOffset[1] = anOffset[1] + aSize[1];
@@ -953,25 +996,57 @@ SALOME_Actor
 }
 
 /*!
-  To set up a picker for point rectangle selection (initialized by SVTK_Renderer::AddActor)
-  \param theRectPicker - new picker
+  To set up a picker for point rectangle or polygonal selection (initialized by SVTK_Renderer::AddActor)
+  \param theAreaPicker - new picker
 */
 void
 SALOME_Actor
-::SetPointRectPicker(SVTK_RectPicker* theRectPicker) 
+::SetPointAreaPicker(SVTK_AreaPicker* theAreaPicker)
 {
-  myPointRectPicker = theRectPicker;
+  myPointAreaPicker = theAreaPicker;
 }
 
 /*!
-  To set up a picker for cell rectangle selection (initialized by SVTK_Renderer::AddActor)
-  \param theRectPicker - new picker
+  To set up a picker for cell rectangle of polygonal selection (initialized by SVTK_Renderer::AddActor)
+  \param theAreaPicker - new picker
 */
 void
 SALOME_Actor
-::SetCellRectPicker(SVTK_RectPicker* theRectPicker) 
+::SetCellAreaPicker(SVTK_AreaPicker* theAreaPicker)
 {
-  myCellRectPicker = theRectPicker;
+  myCellAreaPicker = theAreaPicker;
+}
+
+/*!
+  To find a gravity center of object
+  \param theObjId - identification of object
+*/
+double*
+SALOME_Actor
+::GetGravityCenter( int theObjId )
+{
+  double* result = new double[3];
+  for( int i = 0; i < 3; i++ )
+    result[i]= 0.0;
+
+  vtkPoints* points = GetElemCell( theObjId )->GetPoints();
+  int nbPoints = points->GetNumberOfPoints();
+
+  if( nbPoints <= 0 )
+    return NULL;
+
+  for( int i = 0; i < nbPoints; i++ )
+  {
+    double* aPoint = points->GetPoint(i);
+    result[0] += aPoint[0];
+    result[1] += aPoint[1];
+    result[2] += aPoint[2];
+  }
+  result[0] = result[0] / nbPoints;
+  result[1] = result[1] / nbPoints;
+  result[2] = result[2] / nbPoints;
+
+  return result;
 }
 
 /*!