Salome HOME
PR: mergefrom_PAL_OCC_21Oct04
[modules/kernel.git] / src / VTKViewer / VTKViewer_InteractorStyleSALOME.cxx
index b0cfe0abb33102f28d92d11dc6214ce37e6c9295..c2ac9c3cc00f51623b2e2a338e27bfec587c727b 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
 #include "VTKViewer_InteractorStyleSALOME.h"
+
+#include "VTKViewer_RenderWindowInteractor.h"
 #include "VTKViewer_RenderWindow.h"
+#include "VTKViewer_ViewFrame.h"
+
+#include "VTKViewer_Utilities.h"
+#include "VTKViewer_Trihedron.h"
+#include "VTKViewer_RectPicker.h"
+#include "VTKViewer_CellRectPicker.h"
 
-#include <qapplication.h>
 #include "QAD_Config.h"
 #include "QAD_Application.h"
 #include "QAD_Desktop.h"
 
-#include "SALOME_Selection.h"
 #include "SALOME_Actor.h"
+#include "VTKViewer_Actor.h"
+#include "SALOME_Selection.h"
 #include "SALOME_ListIteratorOfListIO.hxx"
 
 #include <vtkObjectFactory.h>
 #include <vtkMath.h>
 #include <vtkCommand.h>
-#include <vtkAssemblyNode.h>
+#include <vtkCamera.h>
+#include <vtkRenderer.h>
 #include <vtkPicker.h>
 #include <vtkPointPicker.h>
 #include <vtkCellPicker.h>
 #include <vtkLine.h> 
-#include <vtkUnstructuredGrid.h> 
-#include <vtkExtractEdges.h>
-#include <vtkPolyDataMapper.h>
-#include <vtkDataSetCollection.h>
-#include <vtkImageData.h>
-#include <vtkFollower.h>
-
+#include <vtkMapper.h>
+#include <vtkDataSet.h>
+#include <vtkSmartPointer.h>
 
+#include <qapplication.h>
 //VRV: porting on Qt 3.0.5
 #if QT_VERSION >= 0x030005
 #include <qpainter.h>
 #endif
 //VRV: porting on Qt 3.0.5
+#include <algorithm>
 
-//----------------------------------------------------------------------------
-VTKViewer_InteractorStyleSALOME *VTKViewer_InteractorStyleSALOME::New() 
+#include "utilities.h"
+
+using namespace std;
+
+
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
+
+
+static bool IsStored(Handle(SALOME_InteractiveObject)& theIO,
+                    const SALOME_ListIO& theListIO)
 {
-  // First try to create the object from the vtkObjectFactory
-  vtkObject* ret = vtkObjectFactory::CreateInstance("VTKViewer_InteractorStyleSALOME");
-  if(ret)
-    {
-      return (VTKViewer_InteractorStyleSALOME*)ret;
+  if (!theListIO.IsEmpty()){
+    SALOME_ListIteratorOfListIO anIter(theListIO);
+    for(; anIter.More(); anIter.Next()) {
+      Handle(SALOME_InteractiveObject) anIO = anIter.Value();
+      if(theIO->isSame(anIO)) {
+       theIO = anIO; //Added by SRN, fix SAL1307
+       return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+static bool IsSelected(Handle(SALOME_InteractiveObject)& theIO, 
+                      SALOME_Selection* theSel)
+{
+  return IsStored(theIO,theSel->StoredIObjects());
+}
+
+
+static int GetEdgeId(vtkPicker *thePicker, SALOME_Actor *theActor, int theObjId){
+  int anEdgeId = -1;
+  if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
+    float aPickPosition[3];
+    thePicker->GetPickPosition(aPickPosition);
+    float aMinDist = 1000000.0, aDist = 0;
+    for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
+      if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
+       int subId;  float pcoords[3], closestPoint[3], weights[3];
+       aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
+       if (aDist < aMinDist) {
+         aMinDist = aDist;
+         anEdgeId = i;
+       }
+      }
     }
-  // If the factory was unable to create the object, then create it here.
-  return new VTKViewer_InteractorStyleSALOME;
+  }
+  return anEdgeId;
+}
+
+
+static bool CheckDimensionId(Selection_Mode theMode, SALOME_Actor *theActor, vtkIdType theObjId){
+  switch(theMode){
+  case CellSelection:
+    return true;
+  case EdgeSelection:
+    return ( theActor->GetObjDimension( theObjId ) == 1 );
+  case FaceSelection:
+    return ( theActor->GetObjDimension( theObjId ) == 2 );
+  case VolumeSelection:
+    return ( theActor->GetObjDimension( theObjId ) == 3 );
+  };
+  return false;
 }
 
 
 //----------------------------------------------------------------------------
+vtkStandardNewMacro(VTKViewer_InteractorStyleSALOME);
+//----------------------------------------------------------------------------
+
 VTKViewer_InteractorStyleSALOME::VTKViewer_InteractorStyleSALOME() 
 {
-  m_Triedron = 0;
+  m_Trihedron = 0;
   this->MotionFactor = 10.0;
   this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
   this->RadianToDegree = 180.0 / vtkMath::Pi();
   this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
   loadCursors();
+
+  myPreSelectionActor = VTKViewer_Actor::New();
+  myPreSelectionActor->GetProperty()->SetColor(0,1,1);
+  myPreSelectionActor->GetProperty()->SetLineWidth(5);
+  myPreSelectionActor->GetProperty()->SetPointSize(5);
+
+  OnSelectionModeChanged();
 }
 
 //----------------------------------------------------------------------------
 VTKViewer_InteractorStyleSALOME::~VTKViewer_InteractorStyleSALOME() 
 {
+  if(MYDEBUG) INFOS("VTKViewer_InteractorStyleSALOME::~VTKViewer_InteractorStyleSALOME()");
+  m_ViewFrame->RemoveActor(myPreSelectionActor);
 }
 
 //----------------------------------------------------------------------------
-void VTKViewer_InteractorStyleSALOME::setTriedron( vtkActorCollection* triedron )
+void VTKViewer_InteractorStyleSALOME::setPreselectionProp(const double& theRed, const double& theGreen, 
+                                                         const double& theBlue, const int& theWidth) 
 {
-  m_Triedron = triedron;
+  myPreSelectionActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
+  myPreSelectionActor->GetProperty()->SetLineWidth(theWidth);
+  myPreSelectionActor->GetProperty()->SetPointSize(theWidth);
+}
+
+//----------------------------------------------------------------------------
+void VTKViewer_InteractorStyleSALOME::SetInteractor(vtkRenderWindowInteractor *theInteractor){
+  m_Interactor = dynamic_cast<VTKViewer_RenderWindowInteractor*>(theInteractor);
+  Superclass::SetInteractor(theInteractor);
+}
+
+//----------------------------------------------------------------------------
+void VTKViewer_InteractorStyleSALOME::setViewFrame(VTKViewer_ViewFrame* theViewFrame){
+  m_ViewFrame = theViewFrame;
+  m_ViewFrame->AddActor(myPreSelectionActor);
+  myPreSelectionActor->Delete();
+}
+
+//----------------------------------------------------------------------------
+void VTKViewer_InteractorStyleSALOME::setGUIWindow(QWidget* theWindow){
+  myGUIWindow = theWindow;
+}
+
+//----------------------------------------------------------------------------
+void VTKViewer_InteractorStyleSALOME::setTriedron(VTKViewer_Trihedron* theTrihedron){
+  m_Trihedron = theTrihedron;
 }
 
 //----------------------------------------------------------------------------
@@ -120,140 +222,45 @@ void VTKViewer_InteractorStyleSALOME::RotateXY(int dx, int dy)
   cam->Azimuth(rxf);
   cam->Elevation(ryf);
   cam->OrthogonalizeViewUp();
-  this->CurrentRenderer->ResetCameraClippingRange();
-  vtkRenderWindowInteractor *rwi = this->Interactor;
-  /* VSV Light follows camera: if (this->CurrentLight)
-    {
-      // get the first light
-      this->CurrentLight->SetPosition(cam->GetPosition());
-      this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
-      }        */
-  rwi->Render();
+  ::ResetCameraClippingRange(this->CurrentRenderer); 
+  //this->Interactor->Render();
+  myGUIWindow->update();
 }
 
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::PanXY(int x, int y, int oldX, int oldY)
 {
   TranslateView(x, y, oldX, oldY);   
-  //vtkRenderWindowInteractor *rwi = this->Interactor;
-  /* VSV Light follows camera: if (this->CurrentLight)
-    {
-      vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
-      this->CurrentLight->SetPosition(cam->GetPosition());
-      this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
-      }*/
-    
-  this->Interactor->Render();
+  //this->Interactor->Render();
+  myGUIWindow->update();
 }
 
-//----------------------------------------------------------------------------
-void VTKViewer_InteractorStyleSALOME::ControlLblSize(double aOldScale, double aNewScale) {
-  m_Triedron->InitTraversal();
-  vtkActor *ac = m_Triedron->GetNextActor();
-  bool IsConeActor = true;
-  while(!(ac==NULL)) {
-    float aMaxXRange;
-    float aMaxYRange;
-    float aMaxZRange;
-    if(ac->IsA("vtkFollower")) {
-      float aScale[3];
-      ac->GetScale(aScale);
-      
-      float aPosition[3];
-      ac->GetPosition(aPosition);
-      
-      float aPercent = (aOldScale-aNewScale)/aOldScale;
-      ac->SetScale(aScale[0]*(1-aPercent),aScale[1]*(1-aPercent),aScale[2]*(1-aPercent));
-           
-      //Set new position
-      float aLength = ac->GetLength();
-      if (aPosition[0]!=0) {
-       //x
-       aPosition[0] = aMaxXRange;
-      } else if (aPosition[1]!=0) {
-       //y
-       aPosition[1] = aMaxYRange;
-      } else if (aPosition[2]!=0) {
-       //z
-       aPosition[2] = aMaxZRange;
-      }
-      ac->SetPosition(aPosition);
-      
-      IsConeActor = true;
-    }
-    else {
-      if (IsConeActor) {
-       //coneActor is the first in the list (see m_Triedron->AddItem(...) in VTKViewer_ViewFrame::AddVector(...))
-       IsConeActor = false;
-       
-       float aPosition[3];
-       ac->GetPosition(aPosition);
-       
-       if (aPosition[0]!=0) {
-         //x
-         float* aXRange = ac->GetXRange();
-         if (aXRange[0] < aXRange[1]) aMaxXRange = aXRange[1];
-         else aMaxXRange = aXRange[0];
-       } else if (aPosition[1]!=0) {
-         //y
-         float* aYRange = ac->GetYRange();
-         if (aYRange[0] < aYRange[1]) aMaxYRange = aYRange[1];
-         else aMaxYRange = aYRange[0];
-       } else if (aPosition[2]!=0) {
-         //z
-         float* aZRange = ac->GetZRange();
-         if (aZRange[0] < aZRange[1]) aMaxZRange = aZRange[1];
-         else aMaxZRange = aZRange[0];
-       }
-      } 
-    }
-    ac = m_Triedron->GetNextActor();
-  }
-}
 
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::DollyXY(int dx, int dy)
 {
-  vtkCamera *cam;
+  if (this->CurrentRenderer == NULL) return;
+
   double dxf = this->MotionFactor * (double)(dx) / (double)(this->CurrentRenderer->GetCenter()[1]);
   double dyf = this->MotionFactor * (double)(dy) / (double)(this->CurrentRenderer->GetCenter()[1]);
 
   double zoomFactor = pow((double)1.1, dxf + dyf);
   
-  if (this->CurrentRenderer == NULL)
-    {
-      return;
-    }
-  
-  cam = this->CurrentRenderer->GetActiveCamera();
-    if (cam->GetParallelProjection())
-    {
-      double aOldScale = cam->GetParallelScale();
-      cam->SetParallelScale(cam->GetParallelScale()/zoomFactor);
-      double aNewScale = cam->GetParallelScale();
+  vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
+  if (aCam->GetParallelProjection())
+    aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
+  else{
+    aCam->Dolly(zoomFactor);
+    ::ResetCameraClippingRange(this->CurrentRenderer);
+  }
 
-      // for controlling label size
-      ControlLblSize(aOldScale,aNewScale);
-    }
-    else
-    {
-      cam->Dolly(zoomFactor);
-      this->CurrentRenderer->ResetCameraClippingRange();
-    }
-  
-  /* VSV Light follows camera: if (this->CurrentLight)
-    {      
-      this->CurrentLight->SetPosition(cam->GetPosition());
-      this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
-      }*/
-  
-  this->Interactor->Render();
+  //this->Interactor->Render();
+  myGUIWindow->update();
 }
 
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::SpinXY(int x, int y, int oldX, int oldY)
 {
-  vtkRenderWindowInteractor *rwi = this->Interactor;
   vtkCamera *cam;
 
   if (this->CurrentRenderer == NULL)
@@ -273,7 +280,8 @@ void VTKViewer_InteractorStyleSALOME::SpinXY(int x, int y, int oldX, int oldY)
   cam->Roll(newAngle - oldAngle);
   cam->OrthogonalizeViewUp();
       
-  rwi->Render();
+  //this->Interactor->Render();
+  myGUIWindow->update();
 }
 
 
@@ -319,6 +327,8 @@ void VTKViewer_InteractorStyleSALOME::OnLeftButtonDown(int ctrl, int shift,
   }
   return;
 }
+
+
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::OnLeftButtonUp(int vtkNotUsed(ctrl),
                                                     int shift, 
@@ -333,6 +343,7 @@ void VTKViewer_InteractorStyleSALOME::OnLeftButtonUp(int vtkNotUsed(ctrl),
   }
 }
 
+
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::OnMiddleButtonDown(int ctrl,
                                                         int shift, 
@@ -363,6 +374,8 @@ void VTKViewer_InteractorStyleSALOME::OnMiddleButtonDown(int ctrl,
       startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
   }
 }
+
+
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::OnMiddleButtonUp(int vtkNotUsed(ctrl),
                                                       int shift, 
@@ -377,6 +390,7 @@ void VTKViewer_InteractorStyleSALOME::OnMiddleButtonUp(int vtkNotUsed(ctrl),
   }
 }
 
+
 //----------------------------------------------------------------------------
 void VTKViewer_InteractorStyleSALOME::OnRightButtonDown(int ctrl,
                                                        int shift, 
@@ -423,12 +437,6 @@ void VTKViewer_InteractorStyleSALOME::OnRightButtonUp(int vtkNotUsed(ctrl),
 }
 
 //----------------------------------------------------------------------------
-void VTKViewer_InteractorStyleSALOME::PrintSelf(ostream& os, vtkIndent indent)
-{
-  vtkInteractorStyle::PrintSelf(os,indent);
-
-}
-
 /* XPM */
 const char* imageZoomCursor[] = { 
 "32 32 3 1",
@@ -506,6 +514,8 @@ const char* imageRotateCursor[] = {
 "................................",
 "................................"};
 
+
+//----------------------------------------------------------------------------
 // loads cursors for viewer operations - zoom, pan, etc...
 void VTKViewer_InteractorStyleSALOME::loadCursors()
 {
@@ -519,6 +529,8 @@ void VTKViewer_InteractorStyleSALOME::loadCursors()
   myCursorState     = false;
 }
 
+
+//----------------------------------------------------------------------------
 // event filter - controls mouse and keyboard events during viewer operations
 bool VTKViewer_InteractorStyleSALOME::eventFilter(QObject* object, QEvent* event)
 {
@@ -531,6 +543,8 @@ bool VTKViewer_InteractorStyleSALOME::eventFilter(QObject* object, QEvent* event
   return QObject::eventFilter(object, event);
 }
 
+
+//----------------------------------------------------------------------------
 // starts Zoom operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startZoom()
 {
@@ -544,6 +558,8 @@ void VTKViewer_InteractorStyleSALOME::startZoom()
   qApp->installEventFilter(this);
 }
 
+
+//----------------------------------------------------------------------------
 // starts Pan operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startPan()
 {
@@ -557,6 +573,7 @@ void VTKViewer_InteractorStyleSALOME::startPan()
   qApp->installEventFilter(this);
 }
 
+//----------------------------------------------------------------------------
 // starts Rotate operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startRotate()
 {
@@ -570,6 +587,8 @@ void VTKViewer_InteractorStyleSALOME::startRotate()
   qApp->installEventFilter(this);
 }
 
+
+//----------------------------------------------------------------------------
 // starts Spin operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startSpin()
 {
@@ -584,6 +603,8 @@ void VTKViewer_InteractorStyleSALOME::startSpin()
 }
 
 
+
+//----------------------------------------------------------------------------
 // starts Fit Area operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startFitArea()
 {
@@ -597,6 +618,29 @@ void VTKViewer_InteractorStyleSALOME::startFitArea()
   qApp->installEventFilter(this);
 }
 
+
+//----------------------------------------------------------------------------
+void  VTKViewer_InteractorStyleSALOME::ViewFitAll() {
+  int aTriedronWasVisible = false;
+  if(m_Trihedron){
+    aTriedronWasVisible = m_Trihedron->GetVisibility() == VTKViewer_Trihedron::eOn;
+    if(aTriedronWasVisible) m_Trihedron->VisibilityOff();
+  }
+
+  if(m_Trihedron->GetVisibleActorCount(CurrentRenderer)){
+    m_Trihedron->VisibilityOff();
+    ::ResetCamera(CurrentRenderer);
+  }else{
+    m_Trihedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
+    ::ResetCamera(CurrentRenderer,true);
+  }
+  if(aTriedronWasVisible) m_Trihedron->VisibilityOn();
+  else m_Trihedron->VisibilityOff();
+  ::ResetCameraClippingRange(CurrentRenderer);
+}
+
+
+//----------------------------------------------------------------------------
 // starts Global Panning operation (e.g. through menu command)
 void VTKViewer_InteractorStyleSALOME::startGlobalPan()
 {
@@ -612,35 +656,15 @@ void VTKViewer_InteractorStyleSALOME::startGlobalPan()
   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
   myScale = cam->GetParallelScale();
 
-  // make fit all
-  Standard_Boolean TriedronWasVisible = false;
-  if ( m_Triedron ) {
-    m_Triedron->InitTraversal();
-    vtkActor *ac = m_Triedron->GetNextActor();
-    while(!(ac==NULL)) {
-      if(ac->GetVisibility()) {
-       TriedronWasVisible = true;
-       ac->VisibilityOff();
-      }
-      ac = m_Triedron->GetNextActor();
-    }
-  }
-  this->CurrentRenderer->ResetCamera();
-  this->CurrentRenderer->ResetCameraClippingRange();
-  if( m_Triedron && TriedronWasVisible ) {
-    m_Triedron->InitTraversal();
-    vtkActor *ac = m_Triedron->GetNextActor();
-    while(!(ac==NULL)) {
-      ac->VisibilityOn();
-      ac = m_Triedron->GetNextActor();
-    }
-  }
-  //VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(this->Interactor->GetRenderWindow());
+  ViewFitAll();
+
   if (myGUIWindow) myGUIWindow->update();
   
   qApp->installEventFilter(this);
 }
 
+
+//----------------------------------------------------------------------------
 // returns TRUE if needs redrawing
 bool VTKViewer_InteractorStyleSALOME::needsRedrawing()
 {
@@ -651,16 +675,15 @@ bool VTKViewer_InteractorStyleSALOME::needsRedrawing()
          State == VTK_INTERACTOR_STYLE_CAMERA_NONE;
 }
 
+
+//----------------------------------------------------------------------------
 // fits viewer contents to rect
 void VTKViewer_InteractorStyleSALOME::fitRect(const int left, 
                                        const int top, 
                                        const int right, 
                                        const int bottom)
 {
-  if (this->CurrentRenderer == NULL) {
-    return;
-  }
-  vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
+  if (this->CurrentRenderer == NULL) return;
  
   // move camera
   int x = (left + right)/2;
@@ -670,31 +693,24 @@ void VTKViewer_InteractorStyleSALOME::fitRect(const int left,
   int oldY = aSize[1]/2;
   TranslateView(oldX, oldY, x, y);
 
-      
   // zoom camera
   double dxf = (double)(aSize[0]) / (double)(abs(right - left));
   double dyf = (double)(aSize[1]) / (double)(abs(bottom - top));
   double zoomFactor = (dxf + dyf)/2 ;
 
-  if (cam->GetParallelProjection()) {
-    cam->SetParallelScale(cam->GetParallelScale()/zoomFactor);
-  } else {
-    cam->Dolly(zoomFactor);
-    this->CurrentRenderer->ResetCameraClippingRange();
+  vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
+  if(aCam->GetParallelProjection())
+    aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
+  else{
+    aCam->Dolly(zoomFactor);
+    ::ResetCameraClippingRange(this->CurrentRenderer);
   }
   
-  //vtkRenderWindowInteractor *rwi = this->Interactor;
-  /* VSV Light follows camera: if (this->CurrentLight) {
-    this->CurrentLight->SetPosition(cam->GetPosition());
-    this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
-    }*/
-  //  rwi->Render();
-  //VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(rwi->GetRenderWindow());
   myGUIWindow->update();
 }
 
 
-
+//----------------------------------------------------------------------------
 // starts viewer operation (!internal usage!)
 void VTKViewer_InteractorStyleSALOME::startOperation(int operation)
 {
@@ -722,6 +738,8 @@ void VTKViewer_InteractorStyleSALOME::startOperation(int operation)
   }
 }
 
+
+//----------------------------------------------------------------------------
 // sets proper cursor for window when viewer operation is activated
 void VTKViewer_InteractorStyleSALOME::setCursor(const int operation)
 {
@@ -761,10 +779,14 @@ void VTKViewer_InteractorStyleSALOME::setCursor(const int operation)
   }
 }
 
+
+//----------------------------------------------------------------------------
 // called when viewer operation started (!put necessary initialization here!)
 void VTKViewer_InteractorStyleSALOME::onStartOperation()
 {
   if (!myGUIWindow) return;
+  // VSV: LOD actor activisation
+  //  this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
   switch (State) {
     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
@@ -784,19 +806,22 @@ void VTKViewer_InteractorStyleSALOME::onStartOperation()
   }
 }
 
+
+//----------------------------------------------------------------------------
 // called when viewer operation finished (!put necessary post-processing here!)
 void VTKViewer_InteractorStyleSALOME::onFinishOperation() 
 {
   if (!myGUIWindow) return;
 
+
   QAD_Study* aActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
   SALOME_Selection* aSel    = SALOME_Selection::Selection( aActiveStudy->getSelection() );
-  vtkRenderWindowInteractor *rwi = this->Interactor;
 
-  int aSelectionMode = aSel->SelectionMode();
+  // VSV: LOD actor activisation
+  //  rwi->GetRenderWindow()->SetDesiredUpdateRate(rwi->GetStillUpdateRate());
+
+  Selection_Mode aSelectionMode = aSel->SelectionMode();
   bool aSelActiveCompOnly = aSel->IsSelectActiveCompOnly();
-  SALOMEDS::SComponent_var aActiveComponent = SALOMEDS::SComponent::_narrow(
-     aActiveStudy->getStudyDocument()->FindObject(QAD_Application::getDesktop()->getActiveComponent()));
 
   switch (State) {
     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
@@ -811,7 +836,7 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
       if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
         // making fit rect opeation 
         int w, h, x, y;
-        rwi->GetSize(w, h);
+        m_Interactor->GetSize(w, h);
         int x1, y1, x2, y2;
         x1 = rect.left(); 
         y1 = h - rect.top() - 1;
@@ -821,206 +846,114 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
       }
       else {
         if (myPoint == myOtherPoint) {
-        // process point selection
+         // process point selection
           int w, h, x, y;
-          rwi->GetSize(w, h);
+          m_Interactor->GetSize(w, h);
           x = myPoint.x(); 
           y = h - myPoint.y() - 1;
-          vtkActorCollection* listactors = NULL;
+
           this->FindPokedRenderer(x, y);
-         rwi->StartPickCallback();
-          rwi->GetPicker()->Pick(x, y, 0.0, this->CurrentRenderer);
+         m_Interactor->StartPickCallback();
+
+         vtkPicker* aPicker = vtkPicker::SafeDownCast(m_Interactor->GetPicker());
+          aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
     
-          if ( rwi->GetPicker()->IsA("vtkCellPicker") ) {
-            vtkCellPicker* picker;
-            if ( (picker = vtkCellPicker::SafeDownCast(rwi->GetPicker())) ) {
-             MESSAGE ( " CellId : " << picker->GetCellId() );
-              if ( picker->GetCellId() >= 0 ) {
-                vtkActor* ac = picker->GetActor();
-                if ( ac->IsA("SALOME_Actor") ) {
-                  SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
-                  MESSAGE ( " NAME Actor : " << SActor->getName() );
-
-                  //Cell selection //////////////////////////////////// NB
-                  if ( aSelectionMode == 3 ) {
-                    if ( SActor->hasIO() ) {
-                      Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-                      // Look in the current selection
-                      SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
-                      Standard_Boolean IsSelected = false;
-                      for(;It.More();It.Next()) {
-                        Handle(SALOME_InteractiveObject) IOS = It.Value();
-                        if(IO->isSame(IOS)) {
-                          IsSelected = true;
-                         IO = IOS; //Added by SRN, fix SAL1307
-                          break;
-                       }
-                      }
-                     if(IsSelected) {
-                        // This IO is already in the selection
-                       //if(shift) {
-                         bool add = aSel->AddOrRemoveIndex( IO, picker->GetCellId(), myShiftState, false );
-                         //Sel->RemoveIObject(IO);
-                       //}
-                     } else {
-                       if(!myShiftState) {
-                         this->HighlightProp( NULL );
-                         aSel->ClearIObjects();
-                        }
-                        bool add = aSel->AddOrRemoveIndex( IO, picker->GetCellId(), myShiftState, false );
-                        aSel->AddIObject( IO, false );
-                     }
-                    }
-                 }
-                  //Edge selection ////////////////////////// NB
-                  else if ( aSelectionMode == 2 ) {
-                    if(SActor->hasIO()){
-                      Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-                      float pickPosition[3],pcoords[3],closestPoint[3],weights[3],dist1=1000000.0,dist2=0;
-                      int subId,edgeId=-10,pickedID,result;
-                      pickedID = picker->GetCellId();
-                      picker->GetPickPosition(pickPosition);
-                     if (vtkDataSet* UGrid = SActor->GetMapper()->GetInput()){
-                       if (vtkCell* pickedCell = UGrid->GetCell(pickedID)){
-                         edgeId = -1;
-                         for (int i = 0, iEnd = pickedCell->GetNumberOfEdges(); i < iEnd; i++){
-                           vtkCell* edge = pickedCell->GetEdge(i);
-                           if(vtkLine* line = vtkLine::SafeDownCast(edge)){
-                             result = line->EvaluatePosition(pickPosition,closestPoint,subId,pcoords,dist2,weights);
-                             if (dist2 < dist1) {
-                               dist1  = dist2;
-                               edgeId = i;
-                             }
-                           }
-                         }
-                         MESSAGE("edgeID transformed = "<<edgeId);
-                         // Look in the current selection
-                         SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
-                         Standard_Boolean IsSelected = false;
-                         for(;It.More();It.Next()) {
-                           Handle(SALOME_InteractiveObject) IOS = It.Value();
-                           if(IO->isSame(IOS)) {
-                             IO = IOS; //Added by SRN, fix SAL1307
-                             IsSelected = true;
-                             break;
-                           }
-                         }
-                         if(!myShiftState) {
-                           this->HighlightProp( NULL );
-                           aSel->ClearIObjects();
-                         }
-                         aSel->SetSelectionMode(2, true);
-                         bool add = aSel->AddOrRemoveIndex( IO, pickedID, true, false);
-                         if(edgeId >= 0)
-                           add = aSel->AddOrRemoveIndex( IO, -edgeId-1, true, true );
-                         aSel->AddIObject( IO, false );
-                       }
+         SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
+
+          if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
+           int aVtkId = picker->GetCellId();
+           if ( aVtkId >= 0 && SActor && SActor->hasIO() && IsValid( SActor, aVtkId ) ) {
+             int anObjId = SActor->GetElemObjId(aVtkId);
+             if(anObjId >= 0){
+               Handle(SALOME_InteractiveObject) IO = SActor->getIO();
+               if(aSelectionMode != EdgeOfCellSelection) {
+                 if(CheckDimensionId(aSelectionMode,SActor,anObjId)){
+                   if(MYDEBUG) INFOS(" CellId : "<<anObjId);
+                   if (IsSelected(IO,aSel)) {
+                     // This IO is already in the selection
+                     aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false );
+                   } else {
+                     if (!myShiftState) {
+                       this->HighlightProp( NULL );
+                       aSel->ClearIObjects();
                      }
+                     aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false );
+                     aSel->AddIObject( IO, false );
+                   }
+                 }
+               }else{
+                 if (!myShiftState) {
+                   this->HighlightProp( NULL );
+                   aSel->ClearIObjects();
+                 }
+                 int anEdgeId = GetEdgeId(picker,SActor,anObjId);
+                 if (anEdgeId >= 0) {
+                   if(MYDEBUG) INFOS(" CellId : "<<anObjId<<"; EdgeId : "<<anEdgeId);
+                   aSel->AddOrRemoveIndex( IO, anObjId, true, false);
+                   aSel->AddOrRemoveIndex( IO, -anEdgeId-1, true, true );
+                   aSel->AddIObject( IO, false );
+                 } 
+               }
+             }
+           } else {
+             this->HighlightProp( NULL );
+             aSel->ClearIObjects();
+           }
+          } else if ( vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker) ) {
+           int aVtkId = picker->GetPointId();
+           if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ) {
+             if ( SActor && SActor->hasIO() ) {
+               int anObjId = SActor->GetNodeObjId(aVtkId);
+               if(anObjId >= 0){
+                 Handle(SALOME_InteractiveObject) IO = SActor->getIO();
+                 if(IsSelected(IO,aSel)) {
+                   // This IO is already in the selection
+                   aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false );
+                 } else {
+                   if(!myShiftState) {
+                     this->HighlightProp( NULL );
+                     aSel->ClearIObjects();
                    }
+                   if(MYDEBUG) INFOS(" PointId : "<<anObjId);
+                   aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false );
+                   aSel->AddIObject( IO, false );
                  }
-                } else {
-                  this->HighlightProp( NULL );
-                  aSel->ClearIObjects();
-                }
-              }
-            }
-          } else if ( rwi->GetPicker()->IsA("vtkPointPicker") ) {
-            vtkPointPicker* picker;
-            if ( (picker = vtkPointPicker::SafeDownCast(rwi->GetPicker())) ) {
-              MESSAGE ( " PointId : " << picker->GetPointId() );
-              if ( picker->GetPointId() >= 0 ) {
-                vtkActor* ac = picker->GetActor();
-                if ( ac->IsA("SALOME_Actor") ) {
-                  SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
-                  MESSAGE ( " NAME Actor : " << SActor->getName() );
-                  if ( SActor->hasIO() ) {
-                    Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-/*                 if (IO.IsNull()) 
-                     break;
-                   if (aSelActiveCompOnly && 
-                       strcmp(aActiveComponent->ComponentDataType(), IO->getComponentDataType()) != 0) {
-                     break;
-                   }*/
-                    // Look in the current selection
-                    SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
-                    Standard_Boolean IsSelected = false;
-                    for(;It.More();It.Next()) {
-                      Handle(SALOME_InteractiveObject) IOS = It.Value();
-                      if(IO->isSame(IOS)) {
-                       IO = IOS; //Added by SRN, fix SAL1307
-                        IsSelected = true;
-                        break;
-                      }
-                    }
-                    if(IsSelected) {
-                      // This IO is already in the selection
-                      bool add = aSel->AddOrRemoveIndex( IO, picker->GetPointId(), myShiftState, false );
-                    } else {
-                      if(!myShiftState) {
-                        this->HighlightProp( NULL );
-                        aSel->ClearIObjects();
-                      }
-                      bool add = aSel->AddOrRemoveIndex( IO, picker->GetPointId(), myShiftState, false );
-                      aSel->AddIObject( IO, false );
-                    }
-                  }
-                } 
-              } else {
-                this->HighlightProp( NULL );
-                aSel->ClearIObjects();
-              } 
-            }
-          } else {
-            vtkPicker* picker;
-            if ( (picker = vtkPicker::SafeDownCast(rwi->GetPicker())) )        {
-              listactors = picker->GetActors();
-            }
-            if ( listactors->GetNumberOfItems() == 0 ) {
-              // No selection clear all
-              this->PropPicked = 0;
-              this->HighlightProp( NULL );
-              aSel->ClearIObjects();
-            } else {
-              vtkActor* ac;
-              listactors->InitTraversal();
-              ac = listactors->GetNextActor();
-              if ( ac->IsA("SALOME_Actor") ) {
-                SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
-                if ( SActor->hasIO() ) {      
-                  this->PropPicked++;
-                  Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-                  // Look in the current selection
-                  SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
-                  Standard_Boolean IsSelected = false;
-                  for(;It.More();It.Next()) {
-                    Handle(SALOME_InteractiveObject) IOS = It.Value();
-                    if( IO->isSame(IOS) ) {
-                     IO = IOS; //Added by SRN, fix SAL1307
-                      IsSelected = true;
-                      break;
-                    }
-                  }
-                  if(IsSelected) {
-                    // This IO is already in the selection
-                    if(myShiftState) {
-                      aSel->RemoveIObject(IO);
-                    }
-                  }
-                  else {
-                    if(!myShiftState) {
-                      this->HighlightProp( NULL );
-                      aSel->ClearIObjects();
-                    }
-                    aSel->AddIObject( IO, false );
-                  }
-                }
-              }
-            }
-           rwi->EndPickCallback();
-          }
+               }
+             }
+           } else {
+             this->HighlightProp( NULL );
+             aSel->ClearIObjects();
+           } 
+         } else {
+           if ( SActor && SActor->hasIO() ) {
+             this->PropPicked++;
+             Handle(SALOME_InteractiveObject) IO = SActor->getIO();
+             if(IsSelected(IO,aSel)) {
+               // This IO is already in the selection
+               if(myShiftState) {
+                 aSel->RemoveIObject(IO);
+               }
+             }
+             else {
+               if(!myShiftState) {
+                 this->HighlightProp( NULL );
+                 aSel->ClearIObjects();
+               }
+               aSel->AddIObject( IO, false );
+             }
+           }else{
+             // No selection clear all
+             this->PropPicked = 0;
+             this->HighlightProp( NULL );
+             aSel->ClearIObjects();
+           }
+         }
+         m_Interactor->EndPickCallback();
         } else {
           //processing rectangle selection
-         rwi->StartPickCallback();
+         QString aComponentDataType = QAD_Application::getDesktop()->getComponentDataType();
+         if(aSelActiveCompOnly && aComponentDataType.isEmpty()) return;
+         m_Interactor->StartPickCallback();
 
          if (!myShiftState) {
            this->PropPicked = 0;
@@ -1029,11 +962,11 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
          }
 
          // Compute bounds
-         vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
+         //      vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
          QRect rect(myPoint, myOtherPoint);
          rect = rect.normalize();
          int w, h, x, y;
-         rwi->GetSize(w, h);
+         m_Interactor->GetSize(w, h);
          int x1, y1, x2, y2;
          x1 = rect.left(); 
          y1 = h - rect.top() - 1;
@@ -1041,149 +974,116 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
          y2 = h - rect.bottom() - 1;
 
          switch (aSelectionMode) {
-         case 1: // Nodes selection
-           {
-             if (! rwi->GetPicker()->IsA("vtkPointPicker") ) break;
-             vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(rwi->GetPicker());
+         case NodeSelection: {
+           if ( vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(m_Interactor->GetPicker()) ) {
              vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
              aListActors->InitTraversal();
-             vtkActor* aActor;
-             for (int k = 0; k < aListActors->GetNumberOfItems(); k++) {
-               aActor = aListActors->GetNextActor();
-               if (aActor != NULL) {
-                 if (aActor->GetVisibility() == 0) 
-                   continue;
-                 vtkAbstractMapper3D* aMapper3D = aActor->GetMapper();
-                 if ((aMapper3D != NULL) && (aActor->IsA("SALOME_Actor"))) {
-                   SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor);
-
-                   if ((SActor != NULL) && (SActor->hasIO())) {
-                     Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-                     if (IO.IsNull()) 
-                       continue;
-                     if (aSelActiveCompOnly && 
-                              strcmp(aActiveComponent->ComponentDataType(), IO->getComponentDataType()) != 0) {
-                       continue;
-                     }
-
-                     vtkMapper*       aMapper;
-                     vtkVolumeMapper* aVolumeMapper;
-                     vtkDataSet*      aDataSet;
-                     
-                     if ( (aMapper = vtkMapper::SafeDownCast(aMapper3D)) != NULL ) {
-                       aDataSet = aMapper->GetInput();
-                     } else if ((aVolumeMapper = vtkVolumeMapper::SafeDownCast(aMapper3D)) != NULL ){
-                       aDataSet = aVolumeMapper->GetInput();
-                     } else {
-                       continue;
-                     }
-                     if (aDataSet) {
-                       for (int i=0; i < aDataSet->GetNumberOfPoints(); i++) {
-                         float* aPoint;
-                         aPoint = aDataSet->GetPoint(i);
-                         if (IsInRect(aPoint,  x1, y1, x2, y2)) {
-                           float aDisp[3];
-                           ComputeWorldToDisplay(aPoint[0],
-                                                 aPoint[1],
-                                                 aPoint[2], aDisp);
-                           aPointPicker->Pick(aDisp[0], aDisp[1], 0.0, CurrentRenderer);
-                           if ( aPointPicker->GetPointId() >= 0) { // && (!aSel->IsIndexSelected(IO, aPointPicker->GetPointId()))) {
-                             aSel->AddOrRemoveIndex(IO, aPointPicker->GetPointId(), true, false);
-                             aSel->AddIObject(IO, false);
+             while (vtkActor* aActor = aListActors->GetNextActor()) {
+               if (!aActor->GetVisibility()) 
+                 continue;
+               if(SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor)) {
+                 if (SActor->hasIO()) {
+                   Handle(SALOME_InteractiveObject) IO = SActor->getIO();
+                   if (IO.IsNull()) 
+                     continue;
+                   if (aSelActiveCompOnly && aComponentDataType != IO->getComponentDataType())
+                     continue;
+                   if (vtkDataSet* aDataSet = SActor->GetInput()) {
+                     SALOME_Selection::TContainerOfId anIndices;
+                     for(int i = 0; i < aDataSet->GetNumberOfPoints(); i++) {
+                       float aPoint[3];
+                       aDataSet->GetPoint(i,aPoint);
+                       if (IsInRect(aPoint,x1,y1,x2,y2)){
+                         float aDisp[3];
+                         ComputeWorldToDisplay(aPoint[0],aPoint[1],aPoint[2],aDisp);
+                         if(aPointPicker->Pick(aDisp[0],aDisp[1],0.0,CurrentRenderer)){
+                           if(vtkActorCollection *anActorCollection = aPointPicker->GetActors()){
+                             if(anActorCollection->IsItemPresent(SActor)){
+                               float aPickedPoint[3];
+                               aPointPicker->GetMapperPosition(aPickedPoint);
+                               vtkIdType aVtkId = aDataSet->FindPoint(aPickedPoint);
+                               if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ){
+                                 int anObjId = SActor->GetNodeObjId(aVtkId);
+                                 anIndices.insert(anObjId);
+                               }
+                             }
                            }
                          }
                        }
                      }
+                     if (!anIndices.empty()) {
+                       aSel->AddOrRemoveIndex(IO, anIndices, true, false);
+                       aSel->AddIObject(IO, false);
+                       anIndices.clear();
+                     }else{
+                       aSel->RemoveIObject(IO, false);
+                     }
                    }
                  }
                }
              }
            }
            break;
-         case 2: // edges selection
-         case 3: // triangles selection
+         }
+         case CellSelection:
+         case EdgeOfCellSelection:
+         case EdgeSelection:
+         case FaceSelection:
+         case VolumeSelection: 
            {
-             aSel->SetSelectionMode(aSelectionMode,true);
-             if (!rwi->GetPicker()->IsA("vtkCellPicker") ) break;
-             vtkCellPicker* aCellPicker = vtkCellPicker::SafeDownCast(rwi->GetPicker());
-             vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
+             vtkSmartPointer<VTKViewer_CellRectPicker> picker = VTKViewer_CellRectPicker::New();
+             picker->SetTolerance(0.001);
+             picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
+             
+             vtkActorCollection* aListActors = picker->GetActors();
              aListActors->InitTraversal();
-             vtkActor* aActor;
-             for (int k = 0, kEnd = aListActors->GetNumberOfItems(); k < kEnd; k++){
-               vtkActor* aActor = aListActors->GetNextActor();
-               if (vtkActor* aActor = aListActors->GetNextActor()){
-                 if (aActor->GetVisibility() == 0) continue;
-                 if(SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor)) {
-                   if(SActor->hasIO()) {
-                     Handle(SALOME_InteractiveObject) IO = SActor->getIO();
-                     if(IO.IsNull()) continue;
-                     if(aSelActiveCompOnly)
-                       if(strcmp(aActiveComponent->ComponentDataType(),IO->getComponentDataType()) != 0)
+             while(vtkActor* aActor = aListActors->GetNextActor()) {
+               if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
+                 if (aSActor->hasIO()) {
+                   Handle(SALOME_InteractiveObject) aIO = aSActor->getIO();
+                   if (aSelActiveCompOnly && aComponentDataType != aIO->getComponentDataType())
+                     continue;
+                   VTKViewer_CellDataSet cellList = picker->GetCellData(aActor);
+                   if ( !cellList.empty() ) {
+                     if(MYDEBUG) INFOS ( " NAME Actor : " << aSActor->getName() );
+                     SALOME_Selection::TContainerOfId anIndexes;
+                     VTKViewer_CellDataSet::iterator it;
+                     for ( it = cellList.begin(); it != cellList.end(); ++it ) {
+                       int aCellId = (*it).cellId;
+                       
+                       if ( !IsValid( aSActor, aCellId ) )
                          continue;
-                     if(vtkDataSet* aDataSet = SActor->GetMapper()->GetInput()){
-                       for(int i = 0, iEnd = aDataSet->GetNumberOfCells(); i < iEnd; i++){
-                         if(vtkCell* aCell = aDataSet->GetCell(i)){
-                           if(IsInRect(aCell,  x1, y1, x2, y2)){
-                             float* aBounds = aCell->GetBounds();
-                             float aCenter[3];
-                             aCenter[0] =(aBounds[0] + aBounds[1])/2; // Center X
-                             aCenter[1] =(aBounds[2] + aBounds[3])/2; // Center Y
-                             aCenter[2] =(aBounds[4] + aBounds[5])/2; // Center Z
-                             float aDisp[3];
-                             ComputeWorldToDisplay(aCenter[0],aCenter[1],aCenter[2],aDisp);
-                             aCellPicker->Pick(aDisp[0], aDisp[1], 0.0, CurrentRenderer);
-                             if(aCellPicker->GetCellId() >= 0 && !aSel->IsIndexSelected(IO,aCellPicker->GetCellId())){
-                               aSel->AddOrRemoveIndex( IO, aCellPicker->GetCellId(), true, false);
-                               aSel->AddIObject( IO, false );
-                             }
-                           }
+                       
+                       int anObjId = aSActor->GetElemObjId(aCellId);
+                       if (anObjId != -1){
+                         if ( CheckDimensionId(aSelectionMode,aSActor,anObjId) ) {
+                           anIndexes.insert(anObjId);
                          }
                        }
                      }
+                     aSel->AddOrRemoveIndex(aIO, anIndexes, true, false);
+                     aSel->AddIObject(aIO, false);
                    }
                  }
                }
              }
            }
-           break;
-         case 4: // objects selection
+           break;          
+         case ActorSelection: // objects selection
            {
-             vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
-             aListActors->InitTraversal();
-             vtkActor* aActor;
+             vtkSmartPointer<VTKViewer_RectPicker> picker = VTKViewer_RectPicker::New();
+             picker->SetTolerance(0.001);
+             picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
+
+             vtkActorCollection* aListActors = picker->GetActors();
              SALOME_ListIO aListIO;
-             for (int k = 0; k < aListActors->GetNumberOfItems(); k++) {
-               aActor = aListActors->GetNextActor();
-               if (aActor) {
-                 if (aActor->GetVisibility() == 0) 
-                   continue;
-                 if ( aActor->IsA("SALOME_Actor") ) {
-                   SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor);
-                   if ( aSActor->hasIO() && IsInRect(aSActor, x1, y1, x2, y2)) {   
-                     Handle(SALOME_InteractiveObject) aIO = aSActor->getIO();
-                     if (aIO.IsNull())
-                       continue;
-                     if (aSelActiveCompOnly && 
-                              strcmp(aActiveComponent->ComponentDataType(), aIO->getComponentDataType()) != 0) {
-                       continue;
-                     }
-                     if (aListIO.IsEmpty()) {
-                       aListIO.Append( aIO );
-                     } else {
-                       SALOME_ListIteratorOfListIO It(aListIO);
-                       bool isStored = false;
-                       for(;It.More();It.Next()) {
-                         Handle(SALOME_InteractiveObject) IOS = It.Value();
-                         if( aIO->isSame(IOS) ) {
-                           aIO = IOS; //Added by SRN, fix SAL1307
-                           isStored = true;
-                           break;
-                         }
-                       }
-                       if (!isStored)
-                         aListIO.Append( aIO );
-                     }
-                   }
+             aListActors->InitTraversal();
+             while(vtkActor* aActor = aListActors->GetNextActor()) {
+               if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
+                 if (aSActor->hasIO()) {
+                   Handle(SALOME_InteractiveObject) aIO = aSActor->getIO();
+                   if (!IsStored(aIO,aListIO))
+                     aListIO.Append(aIO);
                  }
                }
              }
@@ -1197,7 +1097,7 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
              }
            } // end case 4
          } //end switch
-         rwi->EndPickCallback();
+         m_Interactor->EndPickCallback();
        }
        aActiveStudy->update3dViewers();
       } 
@@ -1211,13 +1111,15 @@ void VTKViewer_InteractorStyleSALOME::onFinishOperation()
   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: 
     {
       int w, h, x, y;
-      rwi->GetSize(w, h);
+      m_Interactor->GetSize(w, h);
       x = myPoint.x(); 
       y = h - myPoint.y() - 1;
       Place(x, y);
     }
     break;
   }
+  if (myGUIWindow) myGUIWindow->update();
+
 }
 
 // called during viewer operation when user moves mouse (!put necessary processing here!)
@@ -1283,84 +1185,136 @@ void VTKViewer_InteractorStyleSALOME::onOperation(QPoint mousePos)
   this->LastPos[1] = h - mousePos.y() - 1;
 }
 
+// called when selection mode changed (!put necessary initialization here!)
+void VTKViewer_InteractorStyleSALOME::OnSelectionModeChanged()
+{
+  
+  myPreSelectionActor->SetVisibility(false);
+  myElemId = myEdgeId = myNodeId = -1;
+  mySelectedActor = NULL;
+}
+
 // called when user moves mouse inside viewer window and there is no active viewer operation 
 // (!put necessary processing here!)
 void VTKViewer_InteractorStyleSALOME::onCursorMove(QPoint mousePos) {
   // processing highlighting
-  QAD_Study* myActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
-  SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
-      
-  vtkRenderWindowInteractor *rwi = this->Interactor;
+  QAD_Study* anActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
+  SALOME_Selection* Sel = SALOME_Selection::Selection( anActiveStudy->getSelection() );
+  Selection_Mode aSelectionMode = Sel->SelectionMode();
+
   int w, h, x, y;
-  rwi->GetSize(w, h);
+  m_Interactor->GetSize(w, h);
   x = mousePos.x(); y = h - mousePos.y() - 1;
 
   this->FindPokedRenderer(x,y);
-  rwi->StartPickCallback();
-  rwi->GetPicker()->Pick(x, y, 0.0, this->CurrentRenderer);
-
-  if ( rwi->GetPicker()->IsA("vtkPicker") ) {
-    vtkPicker* picker = vtkPicker::SafeDownCast(rwi->GetPicker());
-    vtkActor* ac = picker->GetActor();
-    
-    if ( ac != NULL ) {
-      if ( ac->IsA("SALOME_Actor") ) {
-        SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
-        if ( preview != SActor ) {
-          if ( preview != NULL ) {
-            preview->SetPreSelected( false );
-          }
-         preview = SActor;
+  m_Interactor->StartPickCallback();
+  myPreSelectionActor->SetVisibility(false);
+
+  vtkPicker* aPicker = vtkPicker::SafeDownCast(m_Interactor->GetPicker());
+  aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
+
+  SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
+
+  if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
+    int aVtkId = picker->GetCellId();
+    if ( aVtkId >= 0 ) {
+      int anObjId = SActor->GetElemObjId(aVtkId);
+      if ( SActor && SActor->hasIO() && IsValid( SActor, aVtkId ) ) {
+       bool anIsSameObjId = (mySelectedActor == SActor && myElemId == anObjId);
+       bool aResult = anIsSameObjId;
+       if(!anIsSameObjId) {
+         if(aSelectionMode != EdgeOfCellSelection) {
+           aResult = CheckDimensionId(aSelectionMode,SActor,anObjId);
+           if(aResult){
+             mySelectedActor = SActor;
+             myElemId = anObjId;
+             if(MYDEBUG) INFOS(" CellId : "<<anObjId);
+             m_Interactor->setCellData(anObjId,SActor,myPreSelectionActor);
+           }
+         }
+       }
+       if(aSelectionMode == EdgeOfCellSelection){
+         int anEdgeId = GetEdgeId(picker,SActor,anObjId);
+         bool anIsSameEdgeId = (myEdgeId != anEdgeId) && anIsSameObjId;
+         aResult = anIsSameEdgeId;
+         if(!anIsSameEdgeId) {
+           aResult = (anEdgeId >= 0);
+           if (aResult) {
+             mySelectedActor = SActor;
+             myEdgeId = anEdgeId;
+             myElemId = anObjId;
+             if(MYDEBUG) INFOS(" CellId : "<<anObjId<<"; EdgeId : "<<anEdgeId);
+             m_Interactor->setEdgeData(anObjId,SActor,-anEdgeId-1,myPreSelectionActor);
+           } 
+         }
+       }
+       if(aResult) {
+         myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
+         myPreSelectionActor->SetVisibility(true);
+       }
+      }
+    }
+  }
+  else if (vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker)) {
+    int aVtkId = picker->GetPointId();
+    if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ) {
+      if ( SActor && SActor->hasIO() ) {
+       int anObjId = SActor->GetNodeObjId(aVtkId);
+       bool anIsSameObjId = (mySelectedActor == SActor && myNodeId == anObjId);
+       if(!anIsSameObjId) {
+         mySelectedActor = SActor;
+         myNodeId = anObjId;
+         if(MYDEBUG) INFOS(" PointId : "<<anObjId);
+         m_Interactor->setPointData(anObjId,SActor,myPreSelectionActor);
+       }
+       myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
+       myPreSelectionActor->SetVisibility(true);
+      }
+    }
+  }
+  else if ( vtkPicker* picker = vtkPicker::SafeDownCast(aPicker) ) {
+    if ( SActor ) {
+      if ( myPreViewActor != SActor ) {
+       if ( myPreViewActor != NULL ) {
+         myPreViewActor->SetPreSelected( false );
+       }
+       myPreViewActor = SActor;
              
-         if ( SActor->hasIO() ) {
-            Handle( SALOME_InteractiveObject) IO = SActor->getIO();
-
-            SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
-            Standard_Boolean IsSelected = false;
-            for(;It.More();It.Next()) {
-              Handle(SALOME_InteractiveObject) IOS = It.Value();
-              if(IO->isSame(IOS)) {
-                IsSelected = true;
-                break;
-              }
-            }
-
-            if ( !IsSelected ) {
+       if ( SActor->hasIO() ) {
+         Handle( SALOME_InteractiveObject) IO = SActor->getIO();
+         if ( !IsSelected(IO,Sel) ) {
             // Find All actors with same IO
-              vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
-              theActors->InitTraversal();
-              vtkActor *ac = theActors->GetNextActor();
-              while( ac ) {
-                if ( ac->IsA("SALOME_Actor") ) {
-                  SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
-                  if ( anActor->hasIO() ) {
-                    Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
-                    if(IO->isSame(IOS)) {
-                      anActor->SetPreSelected( true );
-                    }
-                  }
-                }
-                ac = theActors->GetNextActor();
-              }
-              // MESSAGE ( " NAME PREVIEW " << SActor->getName() );
-            }
-          }
-        }
+           vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
+           theActors->InitTraversal();
+           while( vtkActor *ac = theActors->GetNextActor() ) {
+             if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
+               if ( anActor->hasIO() ) {
+                 Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
+                 if(IO->isSame(IOS)) {
+                   anActor->SetPreSelected( true );
+                 }
+               }
+             }
+           }
+           //if(MYDEBUG) INFOS ( " NAME PREVIEW " << SActor->getName() );
+         }
+       }
       }
     } else {
-      preview = NULL;
+      myPreViewActor = NULL;
       vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
       theActors->InitTraversal();
-      vtkActor *ac = theActors->GetNextActor();
-      while( ac ) {
-        if ( ac->IsA("SALOME_Actor") ) {
-          SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
+      while( vtkActor *ac = theActors->GetNextActor() ) {
+        if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
           anActor->SetPreSelected( false );
         }
-        ac = theActors->GetNextActor();
       }
     }
   }
+  m_Interactor->EndPickCallback();
+  //m_Interactor->Render();
+  myGUIWindow->update();
+  
   this->LastPos[0] = x;
   this->LastPos[1] = y;
 }
@@ -1382,13 +1336,8 @@ void VTKViewer_InteractorStyleSALOME::Place(const int theX, const int theY)
   // restore zoom scale
   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
   cam->SetParallelScale(myScale);
-  this->CurrentRenderer->ResetCameraClippingRange();
+  ::ResetCameraClippingRange(this->CurrentRenderer);
 
-  /* VSV Light follows camera: if (this->CurrentLight) {
-    this->CurrentLight->SetPosition(cam->GetPosition());
-    this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
-    }*/
-  //VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(this->Interactor->GetRenderWindow());
   if (myGUIWindow) myGUIWindow->update();
 
 }
@@ -1485,3 +1434,65 @@ bool VTKViewer_InteractorStyleSALOME::IsInRect(float* thePoint,
 
   return ((aPnt[0]>left) && (aPnt[0]<right) && (aPnt[1]>bottom) && (aPnt[1]<top));
 }
+
+void  VTKViewer_InteractorStyleSALOME::SetFilter( const Handle(VTKViewer_Filter)& theFilter )
+{
+  myFilters[ theFilter->GetId() ] = theFilter;
+}
+
+bool  VTKViewer_InteractorStyleSALOME::IsFilterPresent( const int theId )
+{
+  return myFilters.find( theId ) != myFilters.end();
+}
+
+void  VTKViewer_InteractorStyleSALOME::RemoveFilter( const int theId )
+{
+  if ( IsFilterPresent( theId ) )
+    myFilters.erase( theId );
+}
+
+
+bool VTKViewer_InteractorStyleSALOME::IsValid( SALOME_Actor* theActor,
+                                               const int     theId,
+                                               const bool    theIsNode )
+{
+  std::map<int, Handle(VTKViewer_Filter)>::const_iterator anIter;
+  for ( anIter = myFilters.begin(); anIter != myFilters.end(); ++anIter )
+  {
+    const Handle(VTKViewer_Filter)& aFilter = anIter->second;
+    if ( theIsNode == aFilter->IsNodeFilter() &&
+         !aFilter->IsValid( theActor, theId ) )
+      return false;
+  }
+  return true;
+}
+
+Handle(VTKViewer_Filter) VTKViewer_InteractorStyleSALOME::GetFilter( const int theId )
+{
+  return IsFilterPresent( theId ) ? myFilters[ theId ] : Handle(VTKViewer_Filter)();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+