Salome HOME
Python3 porting: analytical curves in the Plot2D Viewer.
[modules/gui.git] / src / SVTK / SALOME_Actor.cxx
index bb100848c0419ce776ee924bc3a165533b25739c..eafd19747ba007a0da949ec9c543fabc5cb8381f 100644 (file)
@@ -1,30 +1,28 @@
-//  SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers
+// 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
 //
-//  Copyright (C) 2003  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 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 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// 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, 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
+// 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
 //
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers
 //  File   : SALOME_Actor.cxx
 //  Author : Nicolas REJNERI
-//  Module : SALOME
-//  $Header$
 
 /*!
   \class SALOME_Actor SALOME_Actor.h
 
 
 #include "SALOME_Actor.h"
+#include "SALOME_InteractiveObject.hxx"
 
+#include "VTKViewer_Algorithm.h"
 #include "VTKViewer_Transform.h"
 #include "VTKViewer_TransformFilter.h"
-#include "VTKViewer_PassThroughFilter.h"
 #include "VTKViewer_GeometryFilter.h"
-#include "SVTK_RectPicker.h"
+#include "VTKViewer_FramedTextActor.h"
+#include "SVTK_AreaPicker.h"
 
 #include "SVTK_Actor.h"
 
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+
 // VTK Includes
 #include <vtkCell.h>
 #include <vtkLine.h>
+#include <vtkQuadraticEdge.h>
 #include <vtkPicker.h>
 #include <vtkPointPicker.h>
 #include <vtkCellPicker.h>
 #include <vtkPolyDataMapper.h>
 #include <vtkProperty.h>
 #include <vtkOutlineSource.h>
+#include <vtkPolygon.h>
 
 #include <vtkInteractorStyle.h>
 #include <vtkRenderWindowInteractor.h>
+#include <vtkPassThroughFilter.h>
 
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
 
-using namespace std;
+#include <math.h>
+#include <QPoint>
+#include <QVector>
 
 #if defined __GNUC__
   #if __GNUC__ == 2
@@ -77,24 +85,27 @@ namespace
 {
   int
   GetEdgeId(SALOME_Actor* theActor,
-           vtkPicker* thePicker, 
-           int theObjId)
+            vtkPicker* thePicker, 
+            int theObjId)
   {
     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))){
-         int subId;  
-         vtkFloatingPointType pcoords[3], closestPoint[3], weights[3];
-         aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
-         if (aDist < aMinDist) {
-           aMinDist = aDist;
-           anEdgeId = -1 - i;
-         }
-       }
+       aSelEdge = aPickedCell->GetEdge(i);
+        if(vtkLine::SafeDownCast(aPickedCell->GetEdge(i)) || 
+          vtkQuadraticEdge::SafeDownCast(aPickedCell->GetEdge(i))){
+          int subId;  
+          double pcoords[3], closestPoint[3], weights[3];
+          aSelEdge->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
+          if (aDist < aMinDist) {
+            aMinDist = aDist;
+            anEdgeId = -1 - i;
+          }
+        }
       }
     }
     return anEdgeId;
@@ -103,10 +114,10 @@ namespace
   inline
   bool
   CheckDimensionId(Selection_Mode theMode, 
-                  SALOME_Actor *theActor, 
-                  vtkIdType theObjId)
+                   SALOME_Actor *theActor, 
+                   vtkIdType theObjId)
   {
-    switch(theMode){
+    switch(theMode) {
     case CellSelection:
       return true;
     case EdgeSelection:
@@ -115,10 +126,39 @@ 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;
   }
+}
 
+namespace SVTK
+{
+  /*!
+    Make picker work with this actor only
+  */
+  TPickLimiter::TPickLimiter(vtkAbstractPicker* picker, SALOME_Actor* actor):myPicker(picker)
+  {
+    myPicker->InitializePickList();
+    myPicker->AddPickList( actor );
+    myPicker->SetPickFromList( true );
+  }
+  /*!
+    Unlimit picking
+  */
+  TPickLimiter::~TPickLimiter()
+  {
+    myPicker->SetPickFromList( false );
+    myPicker->InitializePickList();
+  }
 }
 
 
@@ -135,22 +175,26 @@ SALOME_Actor
   myPreHighlightActor(SVTK_Actor::New()),
   myHighlightActor(SVTK_Actor::New()),
   myOutline(vtkOutlineSource::New()),
-  myOutlineActor(VTKViewer_Actor::New())
+  myOutlineActor(VTKViewer_Actor::New()),
+  myIsDisplayNameActor(false),
+  myNameActor(VTKViewer_FramedTextActor::New())
 {
   myPreHighlightActor->Delete();
   myPreHighlightActor->Initialize();
   myPreHighlightActor->PickableOff();
   myPreHighlightActor->SetVisibility( false );
+  myPreHighlightActor->SetCoincident3DAllowed(true);
 
   myHighlightActor->Delete();
   myHighlightActor->Initialize();
   myHighlightActor->PickableOff();
   myHighlightActor->SetVisibility( false );
+  myHighlightActor->SetCoincident3DAllowed(true);
 
   myOutline->Delete();
 
   vtkPolyDataMapper* anOutlineMapper = vtkPolyDataMapper::New();
-  anOutlineMapper->SetInput(myOutline->GetOutput());
+  anOutlineMapper->SetInputConnection(myOutline->GetOutputPort());
 
   myOutlineActor->Delete();
   myOutlineActor->SetMapper( anOutlineMapper );
@@ -162,6 +206,24 @@ SALOME_Actor
   myOutlineActor->GetProperty()->SetAmbient(1.0);
   myOutlineActor->GetProperty()->SetDiffuse(0.0);
   myOutlineActor->SetVisibility( false );
+
+  // Name actor
+  myNameActor->Delete();
+  myNameActor->SetVisibility(false);
+  myNameActor->SetPickable(false);
+  myNameActor->SetModePosition(VTKViewer_FramedTextActor::TopRight);
+  myNameActor->SetLayoutType(VTKViewer_FramedTextActor::Vertical);
+
+  SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
+
+  QColor aForegroundColor = aResourceMgr->colorValue( "VTKViewer", "group_names_text_color", Qt::white );
+  myNameActor->SetForegroundColor(aForegroundColor.redF(),
+                                  aForegroundColor.greenF(),
+                                  aForegroundColor.blueF());
+
+  double aGroupNamesTransparency = 0.5;
+  aGroupNamesTransparency = aResourceMgr->doubleValue( "VTKViewer", "group_names_transparency", aGroupNamesTransparency );
+  myNameActor->SetTransparency(aGroupNamesTransparency);
 }
 
 /*!
@@ -211,8 +273,9 @@ void
 SALOME_Actor
 ::setName(const char* theName)
 {
-  if(hasIO())  
+  if(hasIO())   
     myIO->setName(theName);
+  myNameActor->SetText(theName);
   Superclass::setName(theName);
 }
 
@@ -228,9 +291,10 @@ 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() );
 }
 
 /*!
@@ -242,9 +306,13 @@ SALOME_Actor
 {
   Superclass::RemoveFromRender(theRenderer);
 
+  myHighlightActor->RemoveFromRender(theRenderer);
+  myPreHighlightActor->RemoveFromRender(theRenderer);
+
   theRenderer->RemoveActor( myPreHighlightActor.GetPointer() );
   theRenderer->RemoveActor( myHighlightActor.GetPointer() );
   theRenderer->RemoveActor( myOutlineActor.GetPointer() );
+  theRenderer->RemoveActor( myNameActor.GetPointer() );
 }
 
 /*!
@@ -298,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);
 
@@ -314,7 +382,7 @@ SALOME_Actor
 */
 void
 SALOME_Actor
-::SetPosition(vtkFloatingPointType _arg[3])
+::SetPosition(double _arg[3])
 {
   SetPosition(_arg[0],_arg[1],_arg[2]);
 }
@@ -339,6 +407,18 @@ SALOME_Actor
       myHighlightActor->SetVisibility( theVisibility && isHighlighted() && aHasIndex);
     }
   }
+
+  UpdateNameActors();
+}
+
+/*!
+  Gets know whether the actor should be displayed or not
+*/
+bool 
+SALOME_Actor
+::ShouldBeDisplayed()
+{
+  return true;
 }
 
 /*!
@@ -351,7 +431,7 @@ SALOME_Actor
 {
   mySelector = theSelector;
 }
-
+  
 /*!
   To map current selection to VTK representation
 */
@@ -369,23 +449,26 @@ SALOME_Actor
       mySelector->GetIndex( getIO(), aMapIndex );
       switch( mySelectionMode ){
       case NodeSelection:
-       myHighlightActor->GetProperty()->SetRepresentationToPoints();
-       myHighlightActor->MapPoints( this, aMapIndex );
-       break;
+        myHighlightActor->GetProperty()->SetRepresentationToPoints();
+        myHighlightActor->MapPoints( this, aMapIndex );
+        break;
       case EdgeOfCellSelection:
-       myHighlightActor->GetProperty()->SetRepresentationToWireframe();
-       myHighlightActor->MapEdge( this, aMapIndex );
-       break;
+        myHighlightActor->GetProperty()->SetRepresentationToWireframe();
+        myHighlightActor->MapEdge( this, aMapIndex );
+        break;
       case CellSelection:
       case EdgeSelection:
       case FaceSelection:
       case VolumeSelection:
-       myHighlightActor->GetProperty()->SetRepresentationToSurface();
-       myHighlightActor->MapCells( this, aMapIndex );
-       break;
+      case Elem0DSelection: 
+      case BallSelection: 
+        myHighlightActor->GetProperty()->SetRepresentationToSurface();
+        myHighlightActor->MapCells( this, aMapIndex );
+        break;
       }
       myHighlightActor->SetVisibility( GetVisibility() && theIsHighlight );
     }
+    myHighlightActor->SetMarkerEnabled( mySelectionMode == NodeSelection );
   }
 
   highlight(theIsHighlight);
@@ -398,9 +481,11 @@ void
 SALOME_Actor
 ::highlight(bool theIsHighlight)
 {
-  vtkFloatingPointType aBounds[6];
-  GetInput()->GetBounds(aBounds);
+  double aBounds[6];
+  vtkDataSet * aDataSet = GetHighlightedDataSet();
+  aDataSet->GetBounds(aBounds);
   myOutline->SetBounds(aBounds);
+  myOutline->Update();
   myOutlineActor->SetVisibility( GetVisibility() && theIsHighlight );
 
   Superclass::highlight(theIsHighlight);
@@ -413,56 +498,61 @@ SALOME_Actor
 bool
 SALOME_Actor
 ::PreHighlight(vtkInteractorStyle *theInteractorStyle, 
-              SVTK_SelectionEvent* theSelectionEvent,
-              bool theIsHighlight)
+               SVTK_SelectionEvent* theSelectionEvent,
+               bool theIsHighlight)
 {
-  if ( !GetPickable() )
+  if ( !GetPickable() || !mySelector || !mySelector->IsPreSelectionEnabled() )
     return false;
-
+      
   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
   //
   myPreHighlightActor->SetVisibility( false );
   bool anIsPreselected = myIsPreselected;
-  
+  SetPreSelected( false );
+
   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
   bool anIsChanged = (mySelectionMode != aSelectionMode);
 
-  vtkFloatingPointType x = theSelectionEvent->myX;
-  vtkFloatingPointType y = theSelectionEvent->myY;
-  vtkFloatingPointType z = 0.0;
+  myPreHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
 
-  if( !theIsHighlight ) {
-    SetPreSelected( false );
-    vtkActorCollection* theActors = aRenderer->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 );
+  double x = theSelectionEvent->myX;
+  double y = theSelectionEvent->myY;
+  double z = 0.0;
 
+  if( !theIsHighlight ) {
+    if ( hasIO() ) {
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      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 );
+    }
   }else{
-    switch(aSelectionMode){
+    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 );
-       myIsPreselected = (anObjId >= 0);
-       if(myIsPreselected){
-         const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
-         int anExtent = aMapIndex.Extent();
-         anIsChanged |= (anExtent == 0 || anExtent > 0 && anObjId != aMapIndex(1));
-         if(anIsChanged){
-           TColStd_IndexedMapOfInteger aMapIndex;
-           aMapIndex.Add( anObjId );
-           
-           myPreHighlightActor->GetProperty()->SetRepresentationToPoints();
-           myPreHighlightActor->MapPoints( this, aMapIndex );
-         }
-         myPreHighlightActor->SetVisibility( true );
-       }
+        int anObjId = GetNodeObjId( aVtkId );
+        myIsPreselected = (anObjId >= 0);
+        if(myIsPreselected){
+          const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
+          int anExtent = aMapIndex.Extent();
+          anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
+          if(anIsChanged){
+            TColStd_IndexedMapOfInteger aMapIndex;
+            aMapIndex.Add( anObjId );
+            
+            myPreHighlightActor->GetProperty()->SetRepresentationToPoints();
+            myPreHighlightActor->MapPoints( this, aMapIndex );
+          }
+          myPreHighlightActor->SetVisibility( true );
+        }
       }
       break;
     }
@@ -470,73 +560,80 @@ SALOME_Actor
     case EdgeSelection:
     case FaceSelection:
     case VolumeSelection: 
+    case Elem0DSelection:        
+    case BallSelection: 
     {
+      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
       myCellPicker->Pick( x, y, z, aRenderer );
       
       int aVtkId = myCellPicker->GetCellId();
       if ( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) && hasIO() ) {
-       int anObjId = GetElemObjId (aVtkId );
-       if ( anObjId >= 0 ) {
-         myIsPreselected = CheckDimensionId(aSelectionMode,this,anObjId);
-         if(myIsPreselected){
-           const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
-           int anExtent = aMapIndex.Extent();
-           anIsChanged |= (anExtent == 0 || anExtent > 0 && anObjId != aMapIndex(1));
-           if(anIsChanged){
-             TColStd_IndexedMapOfInteger aMapIndex;
-             aMapIndex.Add( anObjId );
-             
-             myPreHighlightActor->GetProperty()->SetRepresentationToSurface();
-             myPreHighlightActor->MapCells( this, aMapIndex );
-           }
-           myPreHighlightActor->SetVisibility( true );
-         }
-       }
+        int anObjId = GetElemObjId (aVtkId );
+        if ( anObjId >= 0 ) {
+          myIsPreselected = CheckDimensionId(aSelectionMode,this,anObjId);
+          if(myIsPreselected){
+            const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
+            int anExtent = aMapIndex.Extent();
+            anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
+            if(anIsChanged){
+              TColStd_IndexedMapOfInteger aMapIndex;
+              aMapIndex.Add( anObjId );
+              
+              myPreHighlightActor->GetProperty()->SetRepresentationToSurface();
+              myPreHighlightActor->MapCells( this, aMapIndex );
+            }
+            myPreHighlightActor->SetVisibility( true );
+          }
+        }
       }
       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);
-         myIsPreselected = anEdgeId < 0;
-         if(myIsPreselected){
-           const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
-           int anExtent = aMapIndex.Extent();
-           anIsChanged |= (anExtent == 0);
-           anIsChanged |= (anExtent == 2 && (anObjId != aMapIndex(1) || anEdgeId != aMapIndex(2)));
-           if(anIsChanged){
-             TColStd_IndexedMapOfInteger aMapIndex;
-             aMapIndex.Add( anObjId );
-             aMapIndex.Add( anEdgeId );
-
-             myPreHighlightActor->GetProperty()->SetRepresentationToWireframe();
-             myPreHighlightActor->MapEdge( this, aMapIndex );
-           }
-           myPreHighlightActor->SetVisibility( true );
-         }
-       }
+        int anObjId = GetElemObjId( aVtkId );
+        if ( anObjId >= 0 ) {
+          int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
+          myIsPreselected = anEdgeId < 0;
+          if(myIsPreselected){
+            const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
+            int anExtent = aMapIndex.Extent();
+            anIsChanged |= (anExtent == 0 || anExtent == 1);
+            anIsChanged |= (anExtent == 2 && (anObjId != aMapIndex(1) || anEdgeId != aMapIndex(2)));
+            if(anIsChanged){
+              TColStd_IndexedMapOfInteger aMapIndex;
+              aMapIndex.Add( anObjId );
+              aMapIndex.Add( anEdgeId );
+
+              myPreHighlightActor->GetProperty()->SetRepresentationToWireframe();
+              myPreHighlightActor->MapEdge( this, aMapIndex );
+            }
+            myPreHighlightActor->SetVisibility( true );
+          }
+        }
       }
       break;
     }
     case ActorSelection : 
     {
       if( !mySelector->IsSelected( myIO ) ) {
-       SetPreSelected( true );
-
-       vtkActorCollection* theActors = aRenderer->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 );
-       }
+        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:
@@ -556,10 +653,10 @@ SALOME_Actor
 bool
 SALOME_Actor
 ::Highlight(vtkInteractorStyle *theInteractorStyle, 
-           SVTK_SelectionEvent* theSelectionEvent,
-           bool theIsHighlight)
+            SVTK_SelectionEvent* theSelectionEvent,
+            bool theIsHighlight)
 {
-  if ( !GetPickable() )
+  if ( !GetPickable() || !mySelector || !mySelector->IsSelectionEnabled() )
     return false;
 
   myOutlineActor->SetVisibility( false );
@@ -576,172 +673,203 @@ SALOME_Actor
   if ( !theIsHighlight )
     return true;
 
-  vtkFloatingPointType x = theSelectionEvent->myX;
-  vtkFloatingPointType y = theSelectionEvent->myY;
-  vtkFloatingPointType z = 0.0;
+  double x = theSelectionEvent->myX;
+  double y = theSelectionEvent->myY;
+
+  if( theSelectionEvent->myIsRectangle || theSelectionEvent->myIsPolygon ) {
+    double xLast = theSelectionEvent->myLastX;
+    double yLast = theSelectionEvent->myLastY;
+
+    double x1 = x < xLast ? x : xLast;
+    double y1 = y < yLast ? y : yLast;
+    double x2 = x > xLast ? x : xLast;
+    double y2 = y > yLast ? y : yLast;
 
-  if( !theSelectionEvent->myIsRectangle ) {
     switch(aSelectionMode){
     case NodeSelection: {
-      myPointPicker->Pick( x, y, z, aRenderer );
 
-      int aVtkId = myPointPicker->GetPointId();
-      if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
-       int anObjId = GetNodeObjId( aVtkId );
-       if( anObjId >= 0 ) {
-         mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
-         mySelector->AddIObject( this );
-       }
+      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_AreaPicker::TVectorIdsMap& aVectorIdsMap = myPointAreaPicker->GetPointIdsMap();
+      SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
+      TColStd_MapOfInteger anIndexes;
+      if(aMapIter != aVectorIdsMap.end()){
+        const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
+        vtkIdType anEnd = aVectorIds.size();
+        for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
+          int aPointId = aVectorIds[anId];
+          if( aPointId >= 0 && mySelector->IsValid( this, aPointId, true ) ) {
+            int anObjId = GetNodeObjId( aPointId );
+            anIndexes.Add( anObjId );
+          }
+        }
       }
-      break;
-    }
-    case CellSelection: 
-    case EdgeSelection:
-    case FaceSelection:
-    case VolumeSelection: 
-    {
-      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 ( CheckDimensionId(aSelectionMode,this,anObjId) ) {
-           mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
-           mySelector->AddIObject( this );
-         }
-       }
+      
+      if ( hasIO() ) {
+        if( !anIndexes.IsEmpty() ) {
+          mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
+          mySelector->AddIObject( this );
+          anIndexes.Clear();
+        }
+        else if ( !anIsShift )
+          mySelector->RemoveIObject( this );
       }
       break;
     }
-    case EdgeOfCellSelection: 
+    case ActorSelection :
     {
-      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( anEdgeId < 0 ) {
-           mySelector->AddOrRemoveIndex( myIO, anObjId, false );
-           mySelector->AddOrRemoveIndex( myIO, anEdgeId, true );
-           mySelector->AddIObject( this );
-         } 
-       }
+      double aPnt[3];
+      double* aBounds = GetBounds();
+
+      bool anIsPicked = true;
+      for( int i = 0; i <= 1; i++ ) {
+        for( int j = 2; j <= 3; j++ ) {
+          for( int k = 4; k <= 5; k++ ) {
+            aRenderer->SetWorldPoint( aBounds[ i ], aBounds[ j ], aBounds[ k ], 1.0 );
+            aRenderer->WorldToDisplay();
+            aRenderer->GetDisplayPoint( aPnt );
+            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 ( hasIO() ) {
+        if( anIsPicked && mySelector->IsSelected( myIO ) && anIsShift )
+          mySelector->RemoveIObject( this );
+        else if ( anIsPicked ){
+          mySelector->AddIObject( this );
+        }
       }
+
       break;
     }
-    case ActorSelection : 
+    case CellSelection: 
+    case EdgeSelection:
+    case FaceSelection:
+    case VolumeSelection: 
+    case Elem0DSelection:        
+    case BallSelection: 
     {
-      if( mySelector->IsSelected( myIO ) && anIsShift )
-       mySelector->RemoveIObject( this );
-      else {
-       mySelector->AddIObject( 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_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
+        vtkIdType anEnd = aVectorIds.size();
+        for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
+          int aCellId = aVectorIds[anId];
+          if ( !mySelector->IsValid( this, aCellId ) )
+            continue;
+
+          int anObjId = GetElemObjId( aCellId );
+          if( anObjId != -1 )
+            if ( CheckDimensionId(aSelectionMode,this,anObjId) ) {
+              anIndexes.Add(anObjId);
+            }
+        }
+      }
+      
+      if ( hasIO() ) {
+        if( !anIndexes.IsEmpty() ) {
+          mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
+          mySelector->AddIObject( this );
+          anIndexes.Clear();
+        }
+        else if ( !anIsShift )
+          mySelector->RemoveIObject( this );
       }
-      break;
     }
     default:
       break;
     }
-  }else{
-    vtkFloatingPointType xLast = theSelectionEvent->myLastX;
-    vtkFloatingPointType yLast = theSelectionEvent->myLastY;
-    vtkFloatingPointType zLast = 0.0;
-
-    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;
-
+  }
+  else {
     switch(aSelectionMode){
     case NodeSelection: {
-      myPointRectPicker->InitializePickList();
-      myPointRectPicker->AddPickList(this);
-      myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
+      SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
+      myPointPicker->Pick( x, y, 0.0, aRenderer );
 
-      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap();
-      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
-      TColStd_MapOfInteger anIndexes;
-      if(aMapIter != aVectorIdsMap.end()){
-       const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
-       vtkIdType anEnd = aVectorIds.size();
-       for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
-         int aPointId = aVectorIds[anId];
-         if( aPointId >= 0 && mySelector->IsValid( this, aPointId, true ) ) {
-           int anObjId = GetNodeObjId( aPointId );
-           anIndexes.Add( anObjId );
-         }
-       }
-      }
-      
-      if( !anIndexes.IsEmpty() ) {
-       mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
-       mySelector->AddIObject( this );
-       anIndexes.Clear();
+      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 );
+        }
       }
-      else
-       mySelector->RemoveIObject( this );
-
       break;
     }
-    case ActorSelection :
+    case CellSelection:
+    case EdgeSelection:
+    case FaceSelection:
+    case VolumeSelection:
+    case Elem0DSelection:
+    case BallSelection:
     {
-      vtkFloatingPointType aPnt[3];
-      vtkFloatingPointType* aBounds = GetBounds();
+      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
+      myCellPicker->Pick( x, y, 0.0, aRenderer );
 
-      bool anIsPicked = true;
-      for( int i = 0; i <= 1; i++ ) {
-       for( int j = 2; j <= 3; j++ ) {
-         for( int k = 4; k <= 5; k++ ) {
-           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;
-           }
-         }
-       }
+      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 );
+          }
+        }
       }
-
-      if( anIsPicked )
-       mySelector->AddIObject(this);
-
       break;
     }
-    case CellSelection: 
-    case EdgeSelection:
-    case FaceSelection:
-    case VolumeSelection: 
+    case EdgeOfCellSelection:
     {
-      myCellRectPicker->InitializePickList();
-      myCellRectPicker->AddPickList(this);
-      myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
+      SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
+      myCellPicker->Pick( x, y, 0.0, aRenderer );
 
-      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap();
-      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
-      TColStd_MapOfInteger anIndexes;
-      if(aMapIter != aVectorIdsMap.end()){
-       const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
-       vtkIdType anEnd = aVectorIds.size();
-       for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
-         int aCellId = aVectorIds[anId];
-         if ( !mySelector->IsValid( this, aCellId ) )
-           continue;
-
-         int anObjId = GetElemObjId( aCellId );
-         if( anObjId != -1 )
-           if ( CheckDimensionId(aSelectionMode,this,anObjId) ) {
-             anIndexes.Add(anObjId);
-           }
-       }
+      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 );
+          }
+        }
       }
-      mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
-      mySelector->AddIObject( this );
+      break;
+    }
+    case ActorSelection :
+    {
+      if ( hasIO() ) {
+        if( mySelector->IsSelected( myIO ) && anIsShift )
+          mySelector->RemoveIObject( this );
+        else {
+          mySelector->AddIObject( this );
+        }
+      }
+      break;
     }
     default:
       break;
@@ -753,6 +881,98 @@ SALOME_Actor
   return true;
 }
 
+/*!
+  To get flag of displaying of name actor
+  \return flag to display or not to display name actor
+*/
+bool
+SALOME_Actor
+::IsDisplayNameActor() const
+{
+  return myIsDisplayNameActor;
+}
+
+/*!
+  To set flag of displaying of name actor
+  \param theIsDisplayNameActor flag to display or not to display name actor
+*/
+void
+SALOME_Actor
+::SetIsDisplayNameActor(bool theIsDisplayNameActor)
+{
+  SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
+  bool isShowGroupNames = aResourceMgr->booleanValue("VTKViewer", "show_group_names", false);
+  myIsDisplayNameActor = theIsDisplayNameActor && isShowGroupNames;
+  UpdateNameActors();
+}
+
+/*!
+  To set text of name actor
+  \param theText - text of name actor
+*/
+void
+SALOME_Actor
+::SetNameActorText(const char* theText)
+{
+  myNameActor->SetText(theText);
+}
+
+/*!
+  To set offset of name actor
+  \param theOffset - offset of name actor
+*/
+void
+SALOME_Actor
+::SetNameActorOffset(double theOffset[2])
+{
+  myNameActor->SetOffset(theOffset);
+}
+
+/*!
+  To get size of name actor
+  \param theRenderer - renderer
+  \param theSize - size of name actor
+*/
+void
+SALOME_Actor
+::GetNameActorSize(vtkRenderer* theRenderer, double theSize[2]) const
+{
+  myNameActor->GetSize(theRenderer, theSize);
+}
+
+/*!
+  Update visibility of name actors
+*/
+void
+SALOME_Actor
+::UpdateNameActors()
+{
+  if( vtkRenderer* aRenderer = GetRenderer() )
+  {
+    double anOffset[2] = { 0, 0 };
+    VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+    vtkActorCollection* aCollection = aCopy.GetActors();
+    for( int anIndex = 0, aNbItems = aCollection->GetNumberOfItems(); anIndex < aNbItems; anIndex++ )
+    {
+      if( SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>( aCollection->GetItemAsObject( anIndex ) ) )
+      {
+        if( anActor->IsDisplayNameActor() )
+        {
+          anActor->SetNameActorOffset( anOffset );
+          if( anActor->GetVisibility() )
+          {
+            double aSize[2];
+            anActor->GetNameActorSize( aRenderer, aSize );
+            anOffset[0] = anOffset[0] + aSize[0];
+            anOffset[1] = anOffset[1] + aSize[1];
+          }
+        }
+      }
+    }
+  }
+  myNameActor->SetVisibility( GetVisibility() && IsDisplayNameActor() );
+}
+
 /*!
   To set up a picker for nodal selection (initialized by SVTK_Renderer::AddActor)
   \param thePointPicker - new picker
@@ -776,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;
 }
 
 /*!
@@ -816,3 +1068,62 @@ SALOME_Actor
 {
   myHighlightActor->SetProperty(theProperty);
 }
+
+/*!
+  Set standard point marker
+  \param theMarkerType type of the marker
+  \param theMarkerScale scale of the marker
+*/
+void
+SALOME_Actor
+::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
+{
+  myPreHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
+  myHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
+}
+
+/*!
+  Set custom point marker
+  \param theMarkerId id of the marker texture
+  \param theMarkerTexture marker texture
+*/
+void
+SALOME_Actor
+::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
+{
+  myPreHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
+  myHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
+}
+
+/*!
+  Get type of the point marker
+  \return type of the point marker
+*/
+VTK::MarkerType
+SALOME_Actor
+::GetMarkerType()
+{
+  return myPreHighlightActor->GetMarkerType();
+}
+
+/*!
+  Get scale of the point marker
+  \return scale of the point marker
+*/
+VTK::MarkerScale
+SALOME_Actor
+::GetMarkerScale()
+{
+  return myPreHighlightActor->GetMarkerScale();
+}
+
+/*!
+  Get texture identifier of the point marker
+  \return texture identifier of the point marker
+ */
+int
+SALOME_Actor
+::GetMarkerTexture()
+{
+  return myPreHighlightActor->GetMarkerTexture();
+}