Salome HOME
Second integration of PV3D viewer:
[modules/gui.git] / src / SVTK / SVTK_InteractorStyle.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME VTKViewer : build VTK viewer into Salome desktop
24 //  File   : 
25 //  Author : 
26
27 #include "SVTK_InteractorStyle.h"
28
29 #include "VTKViewer_Algorithm.h"
30 #include "VTKViewer_Utilities.h"
31 #include "SVTK_GenericRenderWindowInteractor.h"
32
33 #include "SVTK_Selection.h"
34 #include "SVTK_Event.h" 
35 #include "SVTK_Selector.h"
36 #include "SVTK_Functor.h"
37 #include "SVTK_Actor.h"
38
39 #include "VTKViewer_Algorithm.h"
40 #include "SVTK_Functor.h"
41
42 #include "SUIT_Tools.h"
43 #include "SALOME_Actor.h"
44 #include "ViewerTools_ScreenScaling.h"
45
46 #include <vtkObjectFactory.h>
47 #include <vtkMath.h>
48 #include <vtkCommand.h>
49 #include <vtkCamera.h>
50 #include <vtkRenderer.h>
51 #include <vtkPointPicker.h>
52 #include <vtkCellPicker.h>
53 #include <vtkRenderWindow.h>
54 #include <vtkRenderWindowInteractor.h>
55 #include <vtkCallbackCommand.h>
56 #include <vtkRendererCollection.h>
57 #include <vtkDataSet.h>
58 #include <vtkPerspectiveTransform.h> 
59 #include <vtkMatrix4x4.h>
60
61 #include <QtxRubberBand.h>
62
63 #include <QPixmap>
64 #include <QWidget>
65 #include <QPolygon>
66
67 #include <algorithm>
68 #include <iostream>
69
70 namespace
71 {
72   inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
73                                int& theX, 
74                                int& theY)
75   {
76     theInteractor->GetEventPosition(theX,theY);
77     theY = theInteractor->GetSize()[1] - theY - 1;
78   }
79 }
80
81
82 vtkStandardNewMacro(SVTK_InteractorStyle)
83
84
85 /*!
86   Constructor
87 */
88 SVTK_InteractorStyle::SVTK_InteractorStyle():
89   myLastHighlitedActor(NULL),
90   myLastPreHighlitedActor(NULL),
91   myControllerIncrement(SVTK_ControllerIncrement::New()),
92   myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
93   mySelectionEvent(new SVTK_SelectionEvent()),
94   myHighlightSelectionPointActor(SVTK_Actor::New()),
95   myPointPicker(vtkPointPicker::New()),
96   myRectBand(0),
97   myPolygonBand(0),
98   myPoligonState(Disable),
99   myIsAdvancedZoomingEnabled(false),
100   myInteractivePoint{0.0, 0.0, 0.0}
101 {
102   myPointPicker->Delete();
103
104   myPointPicker->SetTolerance(0.025);
105
106   this->MotionFactor = 10.0;
107   this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
108   this->RadianToDegree = 180.0 / vtkMath::Pi();
109   this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
110
111   loadCursors();
112
113   // set custom event handling function (to handle 3d space mouse events)
114   EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
115
116   // set default values of properties.  user may edit them in preferences.
117   mySMDecreaseSpeedBtn = 1;
118   mySMIncreaseSpeedBtn = 2;
119   mySMDominantCombinedSwitchBtn = 9;
120   //
121   myControllerIncrement->Delete();
122   myControllerOnKeyDown->Delete();
123
124   myCurrRotationPointType = SVTK::SetRotateGravity;
125   myPrevRotationPointType = myCurrRotationPointType;
126
127   myCurrFocalPointType = SVTK::SetFocalPointSelected;
128   myPrevFocalPointType = myCurrFocalPointType;
129
130   myHighlightSelectionPointActor->Delete();
131   myHighlightSelectionPointActor->Initialize();
132   myHighlightSelectionPointActor->PickableOff();
133   myHighlightSelectionPointActor->SetVisibility( false );
134   
135   myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
136   myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
137   myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
138
139   myBBFirstCheck = true;
140 }
141
142 /*!
143   Destructor
144 */
145 SVTK_InteractorStyle::~SVTK_InteractorStyle() 
146 {
147   endDrawRect();
148   endDrawPolygon();
149 }
150
151 /*!
152   \return widget for rendering
153 */
154 QWidget* SVTK_InteractorStyle::GetRenderWidget()
155 {
156   return myInteractor->GetRenderWidget();
157 }
158
159 /*!
160   \return selector
161 */
162 SVTK_Selector* SVTK_InteractorStyle::GetSelector() 
163 {
164   return myInteractor->GetSelector();
165 }
166
167 /*!
168   Realeaze actors
169 */
170 void SVTK_InteractorStyle::FreeActors()
171 {
172   myLastHighlitedActor = NULL;
173   myLastPreHighlitedActor = NULL;
174 }
175
176 /*!
177   Generate special SVTK_SelectionEvent
178 */
179 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
180 {
181   mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
182
183   mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
184   mySelectionEvent->myIsShift = Interactor->GetShiftKey();
185
186   mySelectionEvent->myLastX = mySelectionEvent->myX;
187   mySelectionEvent->myLastY = mySelectionEvent->myY;
188
189   GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
190
191   return mySelectionEvent.get();
192 }
193
194 /*!
195   Generate special SVTK_SelectionEvent with flipped Y coordinate
196 */
197 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
198 {
199   mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
200
201   mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
202   mySelectionEvent->myIsShift = Interactor->GetShiftKey();
203
204   mySelectionEvent->myLastX = mySelectionEvent->myX;
205   mySelectionEvent->myLastY = mySelectionEvent->myY;
206
207   this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
208
209   return mySelectionEvent.get();
210 }
211
212 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
213 {
214   /*   if(GetCurrentRenderer() == NULL)
215     return;
216   
217   int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
218   double aDeltaElevation = -20.0 / size[1];
219   double aDeltaAzimuth = -20.0 / size[0];
220   
221   double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
222   double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
223   
224   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
225   cam->Azimuth(rxf);
226   cam->Elevation(ryf);
227   cam->OrthogonalizeViewUp();
228
229   GetCurrentRenderer()->ResetCameraClippingRange(); 
230
231   this->Render();*/
232
233   if(GetCurrentRenderer() == NULL)
234     return;
235   
236   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
237
238   double viewFP[3], viewPos[3];
239   cam->GetFocalPoint(viewFP);
240   cam->GetPosition(viewPos);
241
242   if ( myCurrRotationPointType == SVTK::SetRotateGravity )
243   {
244     double aCenter[3];
245     if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) ) 
246     {
247       myRotationPointX = aCenter[0];
248       myRotationPointY = aCenter[1];
249       myRotationPointZ = aCenter[2];
250     }
251   }
252
253   // Calculate corresponding transformation
254   vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
255   aTransform->Identity();
256   aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
257
258   // Azimuth transformation
259   int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
260   double aDeltaAzimuth = -20.0 / size[0];
261   
262   double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
263   aTransform->RotateWXYZ(rxf, cam->GetViewUp());
264
265   // Elevation transformation
266   double aDeltaElevation = -20.0 / size[1];
267
268   double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
269   vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
270   const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
271                             -aMatrix->GetElement(0,1), 
272                             -aMatrix->GetElement(0,2)};
273   
274   aTransform->RotateWXYZ(ryf, anAxis);
275             
276   aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
277
278   // To apply the transformation
279   cam->SetPosition(aTransform->TransformPoint(viewPos));
280   cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
281   aTransform->Delete();
282
283   cam->OrthogonalizeViewUp();
284
285   GetCurrentRenderer()->ResetCameraClippingRange(); 
286
287   this->Render();
288   this->InvokeEvent(SVTK::OperationFinished,NULL);
289 }
290
291 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
292 {
293   TranslateView(x, y, oldX, oldY);   
294   this->Render();
295   this->InvokeEvent(SVTK::OperationFinished,NULL);
296 }
297
298 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
299 {
300   if (GetCurrentRenderer() == NULL) 
301     return;
302
303   double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
304   double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
305
306   double zoomFactor = pow((double)1.1, dxf + dyf);
307   
308   vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
309   if (aCam->GetParallelProjection()) {
310     int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
311     if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
312       int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
313       int w = aSize[0];
314       int h = aSize[1];
315       x0 = w / 2;
316       y0 = h / 2;
317       x1 = myOtherPoint.x();
318       y1 = h - myOtherPoint.y();
319       TranslateView( x0, y0, x1, y1 );
320     }
321     aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
322     if( IsAdvancedZoomingEnabled() )
323       TranslateView( x1, y1, x0, y0 );
324   }
325   else{
326     aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
327     GetCurrentRenderer()->ResetCameraClippingRange(); 
328   }
329
330   this->Render();
331   this->InvokeEvent(SVTK::OperationFinished,NULL);
332 }
333
334 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
335 {
336   vtkCamera *cam;
337
338   if (GetCurrentRenderer() == NULL)
339     return;
340
341   double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
342                           (double)(x - GetCurrentRenderer()->GetCenter()[0]));
343   double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
344                           (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
345   
346   newAngle *= this->RadianToDegree;
347   oldAngle *= this->RadianToDegree;
348
349   cam = GetCurrentRenderer()->GetActiveCamera();
350   cam->Roll(newAngle - oldAngle);
351   cam->OrthogonalizeViewUp();
352       
353   this->Render();
354   this->InvokeEvent(SVTK::OperationFinished,NULL);
355 }
356
357
358 /*!
359   To reset reset view
360 */
361 void SVTK_InteractorStyle::OnConfigure() 
362 {
363   this->FindPokedRenderer(0,0);
364   this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
365 }
366
367 /*!
368   To handle mouse move event
369 */
370 void SVTK_InteractorStyle::OnMouseMove() 
371 {
372   int x, y;
373   GetEventPosition( this->Interactor, x, y );
374   this->OnMouseMove( this->Interactor->GetControlKey(),
375                      this->Interactor->GetShiftKey(),
376                      x, y );
377 }
378
379 /*!
380   To handle left mouse button down event (reimplemented from vtkInteractorStyle)
381 */
382 void SVTK_InteractorStyle::OnLeftButtonDown()
383 {
384   int x, y;
385   GetEventPosition( this->Interactor, x, y );
386   this->OnLeftButtonDown( this->Interactor->GetControlKey(),
387                           this->Interactor->GetShiftKey(),
388                           x, y );
389 }
390
391 /*!
392   To handle left mouse button up event (reimplemented from vtkInteractorStyle)
393 */
394 void SVTK_InteractorStyle::OnLeftButtonUp()
395 {
396   int x, y;
397   GetEventPosition( this->Interactor, x, y );
398   this->OnLeftButtonUp( this->Interactor->GetControlKey(),
399                         this->Interactor->GetShiftKey(),
400                         x, y );
401 }
402
403 /*!
404   To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
405 */
406 void SVTK_InteractorStyle::OnMiddleButtonDown() 
407 {
408   int x, y;
409   GetEventPosition( this->Interactor, x, y );
410   this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
411                             this->Interactor->GetShiftKey(),
412                             x, y );
413 }
414
415 /*!
416   To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
417 */
418 void SVTK_InteractorStyle::OnMiddleButtonUp()
419 {
420   int x, y;
421   GetEventPosition( this->Interactor, x, y );
422   this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
423                           this->Interactor->GetShiftKey(),
424                           x, y );
425 }
426
427 /*!
428   To handle right mouse button down event (reimplemented from vtkInteractorStyle)
429 */
430 void SVTK_InteractorStyle::OnRightButtonDown() 
431 {
432   int x, y;
433   GetEventPosition( this->Interactor, x, y );
434   this->OnRightButtonDown( this->Interactor->GetControlKey(),
435                            this->Interactor->GetShiftKey(),
436                            x, y );
437 }
438
439 /*!
440   To handle right mouse button up event (reimplemented from vtkInteractorStyle)
441 */
442 void SVTK_InteractorStyle::OnRightButtonUp()
443 {
444   int x, y;
445   GetEventPosition( this->Interactor, x, y );
446   this->OnRightButtonUp( this->Interactor->GetControlKey(),
447                          this->Interactor->GetShiftKey(),
448                          x, y );
449 }
450
451 /*!
452   To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
453 */
454 void SVTK_InteractorStyle::OnMouseWheelForward()
455 {
456   int x, y;
457   GetEventPosition( this->Interactor, x, y );
458   myOtherPoint = QPoint(x, y);
459 }
460
461 /*!
462   To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
463 */
464 void SVTK_InteractorStyle::OnMouseWheelBackward()
465 {
466   int x, y;
467   GetEventPosition( this->Interactor, x, y );
468   myOtherPoint = QPoint(x, y);
469 }
470
471 /*!
472   To handle mouse double click event
473 */
474 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
475 {
476   if( myPoligonState == InProcess ) {
477     onFinishOperation();
478     myPoligonState = Finished;
479   }
480 }
481
482 /*!
483   To handle mouse move event
484 */
485 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl), 
486                                        int shift,
487                                        int x, int y) 
488 {
489   if ( myPoligonState == Start ) {
490     // if right button was pressed and mouse is moved
491     // we can to draw a polygon for polygonal selection
492     myPoligonState = InProcess;
493     startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
494   }
495   myShiftState = shift;
496   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
497     onOperation(QPoint(x, y));
498   else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
499     onCursorMove(QPoint(x, y));
500 }
501
502 /*!
503   To handle left mouse button down event (reimplemented from vtkInteractorStyle)
504 */
505 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, 
506                                             int x, int y) 
507 {
508   this->FindPokedRenderer(x, y);
509   if(GetCurrentRenderer() == NULL)
510     return;
511
512   if ( myPoligonState != Disable )
513     return;
514
515   myShiftState = shift;
516   // finishing current viewer operation
517   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
518     onFinishOperation();
519     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
520   }
521   myOtherPoint = myPoint = QPoint(x, y);
522   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
523     startOperation(ForcedState);
524   } else {
525     if (ctrl)
526       startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
527     else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
528               myCurrFocalPointType == SVTK::StartFocalPointSelection )
529     {
530       SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
531
532       bool isPicked = false;
533       vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
534       
535       if( anActorCollection )
536       {
537         anActorCollection->InitTraversal();
538         while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
539         {
540           if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
541           {
542                 Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
543                 double* aCoords = NULL;
544                 vtkIdType aVtkId;
545                 bool isTrueType = false;
546                 
547                 if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
548                         ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
549                 {
550               SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
551               myPointPicker->Pick( aSelectionEvent->myX,
552                                    aSelectionEvent->myY,
553                                    0.0,
554                                    GetCurrentRenderer() );
555               aVtkId = myPointPicker->GetPointId();
556               if ( aVtkId >= 0 )
557               {
558                 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
559                 aCoords = anActor->GetNodeCoord(anObjId);
560                 isTrueType = true;
561               }
562                 }
563
564                 if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection ||  aSelectionMode == VolumeSelection )
565                 {
566               vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
567               aCellPicker->SetTolerance( 0.005 );
568               SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
569               aCellPicker->Pick( aSelectionEvent->myX,
570                                  aSelectionEvent->myY,
571                                  0.0,
572                                  GetCurrentRenderer() );
573               aVtkId = aCellPicker->GetCellId();
574               vtkIdType aCellId = anActor->GetElemObjId( aVtkId );
575
576               if( aSelectionMode == EdgeSelection )
577                 isTrueType = anActor->GetObjDimension( aCellId ) == 1;
578               else if( aSelectionMode == FaceSelection )
579                 isTrueType = anActor->GetObjDimension( aCellId ) == 2;
580               else if( aSelectionMode == VolumeSelection )
581                 isTrueType = anActor->GetObjDimension( aCellId ) == 3;
582
583               if ( aVtkId >= 0 && isTrueType )
584                 aCoords = anActor->GetGravityCenter( aCellId );
585                 }
586
587                 if( aVtkId >= 0 )
588                 {
589               if (myCurrRotationPointType == SVTK::StartPointSelection) {
590                 myCurrRotationPointType = SVTK::SetRotateSelected;
591                 // invoke event for update coordinates in SVTK_SetRotationPointDlg
592                 if( isTrueType )
593                   InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
594                 else
595                   InvokeEvent(SVTK::RotationPointChanged);
596                 GetSelector()->SetSelectionMode(ActorSelection);
597               }
598               else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
599                 myCurrFocalPointType = SVTK::SetFocalPointSelected;
600                 
601                 // invoke event for update coordinates in SVTK_ViewParameterDlg
602                 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
603               }
604
605               isPicked = true;
606               break;
607             }
608           }
609         }
610       }
611
612       if( !isPicked )
613       {
614         if (myCurrRotationPointType == SVTK::StartPointSelection) {
615           // invoke event with no data (for SVTK_SetRotationPointDlg)
616           InvokeEvent(SVTK::RotationPointChanged,0);
617           myCurrRotationPointType = myPrevRotationPointType;
618           GetSelector()->SetSelectionMode(ActorSelection);
619         }
620         else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
621           // invoke event with no data (for SVTK_ViewParameterDlg)
622           InvokeEvent(SVTK::FocalPointChanged,0);
623           myCurrFocalPointType = myPrevFocalPointType;
624         }
625       }
626     
627       myHighlightSelectionPointActor->SetVisibility( false );
628       if(GetCurrentRenderer() != NULL)
629         GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
630
631       GetRenderWidget()->setCursor(myDefCursor); 
632     }
633     else
634       startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
635   }
636   
637   return;
638 }
639
640 /*!
641   To handle left mouse button up event (reimplemented from vtkInteractorStyle)
642 */
643 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
644                                           int shift, 
645                                           int x,
646                                           int y)
647 {
648   myShiftState = shift;
649   if( myPoligonState == InProcess ) { // add a new point of polygon
650     // The mouse events were already scaled up with a pixel ratio for a proper selection,
651     // but rubber band's implemented with QPainter scales them on its own.
652     // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
653     const double pixelRatio = ViewerTools_ScreenScaling::getPR();
654
655     myPolygonPoints.append(QPoint(x / pixelRatio, y / pixelRatio));
656     this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
657     mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
658     return;
659   }
660   else if ( myPoligonState == Closed ) { // close polygon and apply a selection
661     onFinishOperation();
662     myPoligonState = Finished;
663     return;
664   }
665   else if( myPoligonState == Finished || myPoligonState == NotValid )
666     return;
667   // finishing current viewer operation
668   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
669     onFinishOperation();
670     int lastOperation = State;
671     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
672     if (lastOperation == VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
673       InvokeEvent(SVTK::InteractiveSelectionFinished, nullptr);
674     }
675   }
676 }
677
678 /*!
679   To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
680 */
681 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
682                                               int shift, 
683                                               int x, int y) 
684 {
685   this->FindPokedRenderer(x, y);
686   if(GetCurrentRenderer() == NULL)
687     return;
688
689   if ( myPoligonState != Disable )
690     return;
691
692   myShiftState = shift;
693   // finishing current viewer operation
694   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
695     onFinishOperation();
696     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
697   }
698   myOtherPoint = myPoint = QPoint(x, y);
699   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
700       ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
701     startOperation(ForcedState);
702   }
703   else {
704     if (ctrl)
705       startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
706   }
707 }
708
709
710 /*!
711   To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
712 */
713 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
714                                             int shift, 
715                                             int vtkNotUsed(x),
716                                             int vtkNotUsed(y))
717 {
718   if( myPoligonState == InProcess ) { // delete a point of polygon
719     if ( myPolygonPoints.size() > 2 ) {
720       myPolygonPoints.remove( myPolygonPoints.size() - 1 );
721       mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
722     }
723     return;
724   }
725   myShiftState = shift;
726   // finishing current viewer operation
727   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
728     onFinishOperation();
729     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
730   }
731 }
732
733
734 /*!
735   To handle right mouse button down event (reimplemented from vtkInteractorStyle)
736 */
737 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
738                                              int shift, 
739                                              int x, int y) 
740 {
741   this->FindPokedRenderer(x, y);
742   if(GetCurrentRenderer() == NULL)
743     return;
744
745   myShiftState = shift;
746
747   if ( !ctrl ) {
748     myPoligonState = Start;
749     this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
750     mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
751   }
752   // finishing current viewer operation
753   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
754     onFinishOperation();
755     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
756   }
757   myOtherPoint = myPoint = QPoint(x, y);
758   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE && 
759       ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
760     startOperation(ForcedState);
761   }
762   else {
763     if (ctrl)
764       startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);  
765   }
766 }
767
768 /*!
769   To handle right mouse button up event (reimplemented from vtkInteractorStyle)
770 */
771 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
772                                            int shift, 
773                                            int vtkNotUsed(x),
774                                            int vtkNotUsed(y))
775 {
776   if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
777     myPoligonState = Disable;
778     mySelectionEvent->myPolygonPoints.clear();
779   }
780
781   if( myPoligonState != Disable ) {
782     endDrawPolygon();
783     myPoligonState = Finished;
784     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
785     return;
786   }
787
788   myShiftState = shift;
789   // finishing current viewer operation
790   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
791     onFinishOperation();
792     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
793   }
794 }
795
796 /* XPM */
797 const char* imageZoomCursor[] = { 
798 "32 32 3 1",
799 ". c None",
800 "a c #000000",
801 "# c #ffffff",
802 "................................",
803 "................................",
804 ".#######........................",
805 "..aaaaaaa.......................",
806 "................................",
807 ".............#####..............",
808 "...........##.aaaa##............",
809 "..........#.aa.....a#...........",
810 ".........#.a.........#..........",
811 ".........#a..........#a.........",
812 "........#.a...........#.........",
813 "........#a............#a........",
814 "........#a............#a........",
815 "........#a............#a........",
816 "........#a............#a........",
817 ".........#...........#.a........",
818 ".........#a..........#a.........",
819 ".........##.........#.a.........",
820 "........#####.....##.a..........",
821 ".......###aaa#####.aa...........",
822 "......###aa...aaaaa.......#.....",
823 ".....###aa................#a....",
824 "....###aa.................#a....",
825 "...###aa...............#######..",
826 "....#aa.................aa#aaaa.",
827 ".....a....................#a....",
828 "..........................#a....",
829 "...........................a....",
830 "................................",
831 "................................",
832 "................................",
833 "................................"};
834
835 const char* imageRotateCursor[] = { 
836 "32 32 3 1",
837 ". c None",
838 "a c #000000",
839 "# c #ffffff",
840 "................................",
841 "................................",
842 "................................",
843 "................................",
844 "........#.......................",
845 ".......#.a......................",
846 "......#######...................",
847 ".......#aaaaa#####..............",
848 "........#..##.a#aa##........##..",
849 ".........a#.aa..#..a#.....##.aa.",
850 ".........#.a.....#...#..##.aa...",
851 ".........#a.......#..###.aa.....",
852 "........#.a.......#a..#aa.......",
853 "........#a.........#..#a........",
854 "........#a.........#a.#a........",
855 "........#a.........#a.#a........",
856 "........#a.........#a.#a........",
857 ".........#.........#a#.a........",
858 "........##a........#a#a.........",
859 "......##.a#.......#.#.a.........",
860 "....##.aa..##.....##.a..........",
861 "..##.aa.....a#####.aa...........",
862 "...aa.........aaa#a.............",
863 "................#.a.............",
864 "...............#.a..............",
865 "..............#.a...............",
866 "...............a................",
867 "................................",
868 "................................",
869 "................................",
870 "................................",
871 "................................"};
872
873
874 /*!
875   loads cursors for viewer operations - zoom, pan, etc...
876 */
877 void SVTK_InteractorStyle::loadCursors()
878 {
879   myDefCursor       = QCursor(Qt::ArrowCursor);
880   myHandCursor      = QCursor(Qt::PointingHandCursor);
881   myPanCursor       = QCursor(Qt::SizeAllCursor);
882   myZoomCursor      = QCursor(QPixmap(imageZoomCursor));
883   myRotateCursor    = QCursor(QPixmap(imageRotateCursor));
884   mySpinCursor      = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
885   myGlobalPanCursor = QCursor(Qt::CrossCursor);
886   myCursorState     = false;
887 }
888
889
890 /*!
891   Starts Zoom operation (e.g. through menu command)
892 */
893 void SVTK_InteractorStyle::startZoom()
894 {
895   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
896   {
897     onFinishOperation();
898     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
899   }
900   setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
901   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
902 }
903
904
905 /*!
906   Starts Pan operation (e.g. through menu command)
907 */
908 void SVTK_InteractorStyle::startPan()
909 {
910   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
911   {
912     onFinishOperation();
913     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
914   }
915   setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
916   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
917 }
918
919 /*!
920   Starts Rotate operation (e.g. through menu command)
921 */
922 void SVTK_InteractorStyle::startRotate()
923 {
924   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
925   {
926     onFinishOperation();
927     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
928   }
929   setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
930   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
931 }
932
933 /*!
934   Starts Interactive Selection operation
935 */
936 void SVTK_InteractorStyle::startInteractiveSelection()
937 {
938         if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
939         {
940                 onFinishOperation();
941                 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
942         }
943         ForcedState = VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION;
944 }
945
946
947 /*!
948   Set rotation point selected by user
949 */
950 void SVTK_InteractorStyle::startPointSelection()
951 {
952   myCurrRotationPointType = SVTK::StartPointSelection;
953
954   if(GetCurrentRenderer() != NULL) {
955     GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
956     double aColor[3];
957     GetCurrentRenderer()->GetBackground( aColor );
958     myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
959                                                             1. - aColor[1],
960                                                             1. - aColor[2]);
961   }
962
963   setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
964 }
965
966 /*!
967   Set focal point selected by user
968 */
969 void SVTK_InteractorStyle::startFocalPointSelection()
970 {
971   myCurrFocalPointType = SVTK::StartFocalPointSelection;
972
973   if(GetCurrentRenderer() != NULL) {
974     GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
975     double aColor[3];
976     GetCurrentRenderer()->GetBackground( aColor );
977     myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
978                                                             1. - aColor[1],
979                                                             1. - aColor[2]);
980   }
981
982   setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
983 }
984
985 /*! 
986   Starts Spin operation (e.g. through menu command)
987 */
988 void SVTK_InteractorStyle::startSpin()
989 {
990   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
991   {
992     onFinishOperation();
993     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
994   }
995   setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
996   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
997 }
998
999
1000
1001 /*!
1002   Starts Fit Area operation (e.g. through menu command)
1003 */
1004 void SVTK_InteractorStyle::startFitArea()
1005 {
1006   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1007   {
1008     onFinishOperation();
1009     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1010   }
1011   setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
1012   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
1013 }
1014
1015
1016 /*!
1017   Starts Global Panning operation (e.g. through menu command)
1018 */
1019 void SVTK_InteractorStyle::startGlobalPan()
1020 {
1021   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1022   {
1023     onFinishOperation();
1024     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1025   }
1026   setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
1027   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
1028
1029   // store current zoom scale
1030   myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
1031
1032   GetCurrentRenderer()->ResetCamera();
1033
1034   this->Render();
1035 }
1036
1037
1038 /*!
1039   Fits viewer contents to rect
1040 */
1041 void SVTK_InteractorStyle::fitRect(const int left, 
1042                                    const int top, 
1043                                    const int right, 
1044                                    const int bottom)
1045 {
1046   if (GetCurrentRenderer() == NULL) 
1047     return;
1048  
1049   // move camera
1050   int x = (left + right)/2;
1051   int y = (top + bottom)/2;
1052   int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1053   int oldX = aSize[0]/2;
1054   int oldY = aSize[1]/2;
1055   TranslateView(oldX, oldY, x, y);
1056
1057   // zoom camera
1058   double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
1059   double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
1060   double zoomFactor = (dxf + dyf)/2 ;
1061
1062   vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
1063   if(aCam->GetParallelProjection())
1064     aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
1065   else{
1066     aCam->Dolly(zoomFactor);
1067     GetCurrentRenderer()->ResetCameraClippingRange();
1068   }
1069   
1070   this->Render();
1071 }
1072
1073
1074 /*!
1075   Starts viewer operation (!internal usage!)
1076 */
1077 void SVTK_InteractorStyle::startOperation(int operation)
1078 {
1079   switch(operation)
1080   { 
1081   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1082   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1083   case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1084   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1085   case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1086   case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1087   case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1088   case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1089     if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1090       startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1091     State = operation;
1092     if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1093       setCursor(operation);
1094     onStartOperation();
1095     break;
1096   case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1097   default:
1098     setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1099     State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1100     break;
1101   }
1102 }
1103
1104
1105 /*!
1106   Sets proper cursor for window when viewer operation is activated
1107 */
1108 void SVTK_InteractorStyle::setCursor(const int operation)
1109 {
1110   if (!GetRenderWidget()) return;
1111   switch (operation)
1112   {
1113     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1114       GetRenderWidget()->setCursor(myZoomCursor); 
1115       myCursorState = true;
1116       break;
1117     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1118       GetRenderWidget()->setCursor(myPanCursor); 
1119       myCursorState = true;
1120       break;
1121     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1122       GetRenderWidget()->setCursor(myRotateCursor); 
1123       myCursorState = true;
1124       break;
1125     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1126       GetRenderWidget()->setCursor(mySpinCursor); 
1127       myCursorState = true;
1128       break;
1129     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1130       GetRenderWidget()->setCursor(myGlobalPanCursor); 
1131       myCursorState = true;
1132       break;
1133     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1134     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1135       GetRenderWidget()->setCursor(myHandCursor); 
1136       myCursorState = true;
1137       break;
1138     case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1139     default:
1140       if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1141            myCurrFocalPointType == SVTK::StartFocalPointSelection )
1142         GetRenderWidget()->setCursor(myHandCursor);
1143       else
1144         GetRenderWidget()->setCursor(myDefCursor); 
1145       myCursorState = false;
1146       break;
1147   }
1148 }
1149
1150
1151 /*!
1152   Called when viewer operation started (!put necessary initialization here!)
1153 */
1154 void SVTK_InteractorStyle::onStartOperation()
1155 {
1156   if (!GetRenderWidget()) 
1157     return;
1158
1159   vtkRenderWindowInteractor *aRWI = this->Interactor;
1160   vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1161   aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1162
1163   switch (State) {
1164     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1165     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1166     {
1167       if ( myPoligonState == InProcess )
1168         drawPolygon();
1169       else
1170         drawRect();
1171       break;
1172     }
1173     case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1174     {
1175       InteractiveSelection();
1176       break;
1177     }
1178     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1179     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1180     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1181     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1182     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1183       break;
1184   }
1185 }
1186
1187
1188 /*!
1189   Called when viewer operation finished (!put necessary post-processing here!)
1190 */
1191 void SVTK_InteractorStyle::onFinishOperation() 
1192 {
1193   if (!GetRenderWidget()) 
1194     return;
1195
1196   vtkRenderWindowInteractor *aRWI = this->Interactor;
1197   vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1198   aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1199
1200   SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1201
1202   switch (State) {
1203     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1204     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1205     {
1206       endDrawRect();
1207       QRect aRect(myPoint, myOtherPoint);
1208       aRect = aRect.normalized();
1209
1210       if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1211         // making fit rect opeation 
1212         int w, h;
1213         Interactor->GetSize(w, h);
1214         int x1 = aRect.left(); 
1215         int y1 = h - aRect.top() - 1;
1216         int x2 = aRect.right(); 
1217         int y2 = h - aRect.bottom() - 1;
1218         fitRect(x1, y1, x2, y2);
1219       }
1220       else {
1221         if (myPoint == myOtherPoint)
1222         {
1223           // process point selection
1224           this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1225           Interactor->StartPickCallback();
1226             
1227           SALOME_Actor* aHighlightedActor = NULL;
1228           vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1229
1230           aSelectionEvent->myIsRectangle = false;
1231           aSelectionEvent->myIsPolygon = false;
1232           if(!myShiftState)
1233             GetSelector()->ClearIObjects();
1234
1235           if( anActorCollection )
1236           {
1237             if( !myShiftState && 
1238                 anActorCollection->GetNumberOfItems () > 1 && 
1239                 myLastHighlitedActor.GetPointer() ) {
1240               anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
1241             }
1242             anActorCollection->InitTraversal();
1243             while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1244             {
1245               if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1246               {
1247                 if( anActor->Highlight( this, aSelectionEvent, true ) )
1248                 {
1249                   aHighlightedActor = anActor;
1250                   break;
1251                 }
1252               }
1253             }
1254           }
1255
1256           if( !aHighlightedActor )
1257           {
1258             if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1259               myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1260           }
1261           myLastHighlitedActor = aHighlightedActor;
1262         }
1263         else
1264         {
1265           if ( myPoligonState == InProcess || myPoligonState == Closed )
1266             aSelectionEvent->myIsPolygon = true;
1267           else
1268             aSelectionEvent->myIsRectangle = true;
1269
1270           //processing polygonal selection
1271           Interactor->StartPickCallback();
1272           GetSelector()->StartPickCallback();
1273
1274           if(!myShiftState)
1275             GetSelector()->ClearIObjects();
1276
1277           VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1278           vtkActorCollection* aListActors = aCopy.GetActors();
1279           aListActors->InitTraversal();
1280           while(vtkActor* aActor = aListActors->GetNextActor())
1281           {
1282             if(aActor->GetVisibility())
1283             {
1284               if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1285               {
1286                 if(aSActor->hasIO())
1287                   aSActor->Highlight( this, aSelectionEvent, true );
1288               }
1289             }
1290           }
1291         }
1292         aSelectionEvent->myIsRectangle = false;
1293         aSelectionEvent->myIsPolygon = false;
1294         aSelectionEvent->myPolygonPoints.clear();
1295         endDrawPolygon();
1296         Interactor->EndPickCallback();
1297         GetSelector()->EndPickCallback();
1298       } 
1299       break;
1300     }
1301     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1302     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1303     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1304     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1305       break;
1306     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1307     {
1308       int w, h, x, y;
1309       Interactor->GetSize(w, h);
1310       x = myPoint.x(); 
1311       y = h - myPoint.y() - 1;
1312       Place(x, y);
1313     }
1314     break;
1315   }
1316
1317   this->Render();
1318 }
1319
1320
1321 /*!
1322   Called during viewer operation when user moves mouse (!put necessary processing here!)
1323 */
1324 void SVTK_InteractorStyle::onOperation(QPoint mousePos) 
1325 {
1326   if (!GetRenderWidget()) 
1327     return;
1328
1329   switch (State) {
1330   case VTK_INTERACTOR_STYLE_CAMERA_PAN: 
1331     {
1332       this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1333       myPoint = mousePos;
1334       break;
1335     }
1336   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: 
1337     {    
1338       this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1339       myPoint = mousePos;
1340       break;
1341     }
1342   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: 
1343     {
1344       this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1345       myPoint = mousePos;
1346       break;
1347     }
1348   case VTK_INTERACTOR_STYLE_CAMERA_SPIN: 
1349     {
1350       this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1351       myPoint = mousePos;
1352       break;
1353     }
1354   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: 
1355     {    
1356       break;
1357     }
1358   case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1359     {
1360       if (!myCursorState)
1361         setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1362     } // fall through!
1363   case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1364     {
1365       myOtherPoint = mousePos;
1366       if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1367         drawPolygon();
1368       else if ( myPoligonState != Finished )
1369         drawRect();
1370       break;
1371     }
1372   case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1373           this->InteractiveSelection();
1374   }
1375 }
1376
1377 /*!
1378   Called when user moves mouse inside viewer window and there is no active viewer operation 
1379   (!put necessary processing here!)
1380 */
1381 void SVTK_InteractorStyle::onCursorMove(QPoint /*mousePos*/) 
1382 {
1383   if ( !GetSelector()->IsPreSelectionEnabled() ) 
1384     return;
1385
1386   // processing highlighting
1387   SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1388   this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1389
1390   bool anIsChanged = false;
1391
1392   SALOME_Actor* aPreHighlightedActor = NULL;
1393   vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1394
1395   if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1396   {
1397     myHighlightSelectionPointActor->SetVisibility( false );
1398
1399     if( anActorCollection )
1400     {
1401       anActorCollection->InitTraversal();
1402       while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1403       {
1404         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1405         {
1406           SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1407           myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1408           vtkIdType aVtkId = myPointPicker->GetPointId();
1409           if ( aVtkId >= 0 ) {
1410             vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
1411
1412             SVTK_TIndexedMapOfVtkId aMapIndex;
1413             aMapIndex.Add( anObjId );
1414             myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1415
1416             myHighlightSelectionPointActor->SetVisibility( true );
1417             anIsChanged = true;
1418             break;
1419           }
1420         }
1421       }
1422     }
1423   }
1424   else {
1425     if( anActorCollection )
1426     {
1427       anActorCollection->InitTraversal();
1428       while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1429       {
1430         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1431         {
1432           anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1433           if( anActor->isPreselected() )
1434           {
1435             aPreHighlightedActor = anActor;
1436             break;
1437           }
1438         }
1439       }
1440     }
1441
1442     if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1443       anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );   
1444
1445   }
1446   
1447   myLastPreHighlitedActor = aPreHighlightedActor;
1448
1449   if(anIsChanged)
1450     this->Render();
1451 }
1452
1453 /*!
1454   Called on finsh GlobalPan operation 
1455 */
1456 void SVTK_InteractorStyle::Place(const int theX, const int theY) 
1457 {
1458   if (GetCurrentRenderer() == NULL)
1459     return;
1460
1461   //translate view
1462   int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1463   int centerX = aSize[0]/2;
1464   int centerY = aSize[1]/2;
1465
1466   TranslateView(centerX, centerY, theX, theY);
1467
1468   // restore zoom scale
1469   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1470   cam->SetParallelScale(myScale);
1471   GetCurrentRenderer()->ResetCameraClippingRange();
1472
1473   this->Render();
1474 }
1475
1476
1477
1478 /*!
1479   Translates view from Point to Point
1480 */
1481 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1482 {
1483   if (GetCurrentRenderer() == NULL)
1484     return;
1485
1486   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1487   double viewFocus[4], focalDepth, viewPoint[3];
1488   double newPickPoint[4], oldPickPoint[4], motionVector[3];
1489   cam->GetFocalPoint(viewFocus);
1490
1491   this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1492                               viewFocus[2], viewFocus);
1493   focalDepth = viewFocus[2];
1494
1495   this->ComputeDisplayToWorld(double(toX), double(toY),
1496                               focalDepth, newPickPoint);
1497   this->ComputeDisplayToWorld(double(fromX),double(fromY),
1498                               focalDepth, oldPickPoint);
1499   
1500   // camera motion is reversed
1501   motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1502   motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1503   motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1504   
1505   cam->GetFocalPoint(viewFocus);
1506   cam->GetPosition(viewPoint);
1507   cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1508                      motionVector[1] + viewFocus[1],
1509                      motionVector[2] + viewFocus[2]);
1510   cam->SetPosition(motionVector[0] + viewPoint[0],
1511                    motionVector[1] + viewPoint[1],
1512                    motionVector[2] + viewPoint[2]);
1513 }
1514
1515 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1516 {
1517   this->PanXY( incrX, incrY, 0, 0 );
1518 }
1519
1520 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1521 {
1522   this->DollyXY( incr, incr );
1523 }
1524
1525 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1526 {
1527   this->RotateXY( incrX, -incrY );
1528 }
1529
1530 void SVTK_InteractorStyle::InteractiveSelection() 
1531 {
1532   if (vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera()) {
1533     int posX, posY;
1534     this->Interactor->GetEventPosition(posX, posY);
1535     double viewFocus[3], z;
1536     double* focalPointWorld = cam->GetFocalPoint();
1537           this->ComputeWorldToDisplay(focalPointWorld[0], focalPointWorld[1],
1538                   focalPointWorld[2], viewFocus);
1539           z = viewFocus[2];
1540
1541           this->ComputeDisplayToWorld(double(posX), double(posY),
1542                 z, this->myInteractivePoint);
1543           InvokeEvent(SVTK::InteractiveSelectionChanged, (void*)this->myInteractivePoint);
1544   }
1545 }
1546
1547 /*!
1548   Redefined in order to add an observer (callback) for custorm event (space mouse event)
1549 */
1550 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1551 {
1552   // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1553   Superclass::SetInteractor( theInteractor );
1554  
1555   myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1556
1557   if(theInteractor) { 
1558     // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1559     theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1560     theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1561     theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1562     theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1563     theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1564     theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1565     theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1566     theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1567     theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1568     theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1569     theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1570     theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1571     theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1572     theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1573     theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1574
1575     theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1576     theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1577     theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1578
1579     theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1580     theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1581     theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1582     theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1583     theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1584
1585     theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1586     theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1587
1588     theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1589
1590     theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1591     theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1592     theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1593           theInteractor->AddObserver( SVTK::StartInteractiveSelection, EventCallbackCommand, Priority);
1594     theInteractor->AddObserver( SVTK::StopCurrentOperation, EventCallbackCommand, Priority);
1595   }
1596 }
1597
1598 /*!
1599   To implement cached rendering
1600 */
1601 void SVTK_InteractorStyle::OnTimer() 
1602 {
1603   //vtkInteractorStyle::OnTimer();
1604   this->Interactor->Render();
1605   // check if bounding box was changed
1606   if ( GetCurrentRenderer() )
1607   {
1608 #ifdef VGL_WORKAROUND
1609     GetCurrentRenderer()->Render();
1610 #endif
1611     double aCurrBBCenter[3];
1612     if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1613     {
1614       if ( !myBBFirstCheck )
1615       {
1616         if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1617              fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1618              fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1619           // bounding box was changed => send SVTK::RotationPointChanged event
1620           // invoke event for update coordinates in SVTK_SetRotationPointDlg
1621           InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1622           for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1623         }
1624       }
1625       else 
1626       {
1627         for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1628         myBBFirstCheck = false;
1629       }
1630     }
1631   }
1632 }
1633
1634 /*!
1635   To invoke #vtkRenderWindowInteractor::CreateTimer
1636 */
1637 void SVTK_InteractorStyle::Render() 
1638 {
1639   this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1640 }
1641
1642 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1643 {
1644   // general things, do SetCurrentRenderer() within FindPokedRenderer() 
1645   int x, y;
1646   GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1647   FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1648   
1649   IncrementalZoom( (int)data[2] );        // 1. push toward / pull backward = zoom out / zoom in
1650   IncrementalPan(  (int)data[0],  (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1651   IncrementalRotate( 0,  (int)data[4] );   // 4. twist the control = rotate around Y axis
1652   IncrementalRotate( (int)data[3], 0  );   // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1653 }
1654
1655 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1656 {
1657   if( mySMDecreaseSpeedBtn == button ) {   
1658     ControllerIncrement()->Decrease();
1659   }
1660   if( mySMIncreaseSpeedBtn == button ) {    
1661     ControllerIncrement()->Increase();
1662   }
1663   if( mySMDominantCombinedSwitchBtn == button )    
1664     DominantCombinedSwitch();
1665 }
1666
1667 void SVTK_InteractorStyle::DominantCombinedSwitch()
1668 {
1669   printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1670 }
1671
1672 /*!
1673   Draws rectangle by starting and current points
1674 */
1675 void SVTK_InteractorStyle::drawRect()
1676 {
1677   if ( !myRectBand )
1678     myRectBand = new QtxRectRubberBand( GetRenderWidget() );
1679
1680   myRectBand->setUpdatesEnabled ( false );
1681
1682   // The mouse events were already scaled up with a pixel ratio for a proper selection,
1683   // but rubber band's implemented with QPainter scales them on its own.
1684   // So, we need to pass unscaled coordinates to get a rectangle painted in a right place.
1685   const double pixelRatio = ViewerTools_ScreenScaling::getPR();
1686   QRect aRect = SUIT_Tools::makeRect(
1687     myPoint.x() / pixelRatio,
1688     myPoint.y() / pixelRatio,
1689     myOtherPoint.x() / pixelRatio,
1690     myOtherPoint.y() / pixelRatio);
1691
1692   myRectBand->initGeometry( aRect );
1693
1694   if ( !myRectBand->isVisible() )
1695     myRectBand->show();
1696
1697   myRectBand->setUpdatesEnabled ( true );
1698 }
1699
1700 /*!
1701   \brief Delete rubber band on the end on the dragging operation.
1702 */
1703 void SVTK_InteractorStyle::endDrawRect()
1704 {
1705   if ( myRectBand ) {
1706     myRectBand->clearGeometry();
1707     myRectBand->hide();
1708   }
1709 }
1710
1711 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1712                   const QPoint& theStart2, const QPoint& theEnd2 )
1713 {
1714   if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1715        ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1716     return true;
1717
1718   if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1719       theStart1 == theEnd2 || theEnd1 == theEnd2 )
1720     return false;
1721
1722   double x11 = theStart1.x() * 1.0;
1723   double x12 = theEnd1.x() * 1.0;
1724   double y11 = theStart1.y() * 1.0;
1725   double y12 = theEnd1.y() * 1.0;
1726
1727   double x21 = theStart2.x() * 1.0;
1728   double x22 = theEnd2.x() * 1.0;
1729   double y21 = theStart2.y() * 1.0;
1730   double y22 = theEnd2.y() * 1.0;
1731
1732   double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1733   double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1734
1735   double b1 = y11 - k1 * x11;
1736   double b2 = y21 - k2 * x21;
1737
1738   if ( k1 == k2 )
1739   {
1740     if ( b1 != b2 )
1741       return false;
1742     else
1743       return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1744                   qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1745                 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1746                   qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1747   }
1748   else
1749   {
1750     double x0 = ( b2 - b1 ) / ( k1 - k2 );
1751     double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1752
1753     if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1754          qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1755          qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1756          qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1757       return true;
1758   }
1759   return false;
1760 }
1761
1762 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1763 {
1764   if ( !thePoints->count() )
1765     return true;
1766
1767   if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1768     return false;
1769
1770   const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1771
1772   if ( aLast == theCurrent )
1773     return true;
1774
1775   bool res = true;
1776   for ( int i = 0; i < thePoints->count() - 1 && res; i++ )
1777   {
1778     const QPoint& aStart = thePoints->point( i );
1779     const QPoint& anEnd  = thePoints->point( i + 1 );
1780     res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1781   }
1782   return res;
1783 }
1784
1785 /*!
1786   Draws polygon
1787 */
1788 void SVTK_InteractorStyle::drawPolygon()
1789 {
1790   // The mouse events were already scaled up with a pixel ratio for a proper selection,
1791   // but rubber band's implemented with QPainter scales them on its own.
1792   // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
1793   const double pixelRatio = ViewerTools_ScreenScaling::getPR();
1794   const QPoint myPointCopy(myPoint.x() / pixelRatio, myPoint.y() / pixelRatio);
1795   const QPoint myOtherPointCopy(myOtherPoint.x() / pixelRatio, myOtherPoint.y() / pixelRatio);
1796
1797   QSize aToler( 5, 5 );
1798   if ( !myPolygonBand ) {
1799     myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1800     QPalette palette;
1801     palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1802     myPolygonBand->setPalette( palette );
1803     myPolygonPoints.append(myPointCopy);
1804   }
1805   myPolygonBand->hide();
1806
1807   bool closed = false;
1808   bool valid = GetRenderWidget()->rect().contains(myOtherPointCopy);
1809   if ( !myPolygonPoints.at(0).isNull() )
1810   {
1811     QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1812                  2 * aToler.width(), 2 * aToler.height() );
1813     closed = aRect.contains(myOtherPointCopy);
1814   }
1815
1816   QPolygon* points = new QPolygon( myPolygonPoints );
1817   valid = valid && isValid(points, myOtherPointCopy);
1818   myPoligonState = valid ? InProcess : NotValid;
1819   delete points;
1820   if ( closed && !valid )
1821     closed = false;
1822
1823   if ( closed && myPolygonPoints.size() > 2 ) {
1824     GetRenderWidget()->setCursor( Qt::CrossCursor );
1825     myPoligonState = Closed;
1826   }
1827   else if ( valid )
1828     GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1829   else
1830     GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1831
1832   myPolygonPoints.append(myOtherPointCopy);
1833
1834   QPolygon aPolygon( myPolygonPoints );
1835   myPolygonBand->initGeometry( aPolygon );
1836   myPolygonBand->setVisible( true );
1837
1838   if ( myPolygonPoints.size() > 1 ) {
1839     myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1840   }
1841 }
1842
1843 /*!
1844   \brief Delete rubber band on the end on the dragging operation.
1845 */
1846 void SVTK_InteractorStyle::endDrawPolygon()
1847 {
1848   if ( myPolygonBand ) myPolygonBand->hide();
1849
1850   // RNV fix for : #19204 [CEA][Windows] VTK Viewer - Access violation while right clicking
1851   //delete myPolygonBand;
1852   myPolygonBand->deleteLater();
1853   myPolygonBand = 0;
1854
1855   myPolygonPoints.clear();
1856 }
1857
1858 /*!
1859   Main process event method (reimplemented from #vtkInteractorStyle)
1860 */
1861 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1862                                           unsigned long event,
1863                                           void* clientData, 
1864                                           void* callData )
1865 {
1866   if ( clientData ) {
1867     vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1868     SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1869     int aSpeedIncrement=self->ControllerIncrement()->Current();
1870     double aCenter[3];
1871     double* aSelectedPoint;
1872     if ( self ) {
1873       switch ( event ) {
1874       case SVTK::SpaceMouseMoveEvent : 
1875         self->onSpaceMouseMove( (double*)callData ); 
1876         return;
1877       case SVTK::SpaceMouseButtonEvent : 
1878         self->onSpaceMouseButton( *((int*)callData) ); 
1879         return;
1880       case SVTK::PanLeftEvent: 
1881         self->IncrementalPan(-aSpeedIncrement, 0);
1882         return;
1883       case SVTK::PanRightEvent:
1884         self->IncrementalPan(aSpeedIncrement, 0);
1885         return;
1886       case SVTK::PanUpEvent:
1887         self->IncrementalPan(0, aSpeedIncrement);
1888         return;
1889       case SVTK::PanDownEvent:
1890         self->IncrementalPan(0, -aSpeedIncrement);
1891         return;
1892       case SVTK::ZoomInEvent:
1893         self->IncrementalZoom(aSpeedIncrement);
1894         return;
1895       case SVTK::ZoomOutEvent:
1896         self->IncrementalZoom(-aSpeedIncrement);
1897         return;
1898       case SVTK::RotateLeftEvent: 
1899         self->IncrementalRotate(-aSpeedIncrement, 0);
1900         return;
1901       case SVTK::RotateRightEvent:
1902         self->IncrementalRotate(aSpeedIncrement, 0);
1903         return;
1904       case SVTK::RotateUpEvent:
1905         self->IncrementalRotate(0, -aSpeedIncrement);
1906         return;
1907       case SVTK::RotateDownEvent:
1908         self->IncrementalRotate(0, aSpeedIncrement);
1909         return;
1910       case SVTK::PlusSpeedIncrementEvent:
1911         self->ControllerIncrement()->Increase();
1912         return;
1913       case SVTK::MinusSpeedIncrementEvent:
1914         self->ControllerIncrement()->Decrease();
1915         return;
1916       case SVTK::SetSpeedIncrementEvent:
1917         self->ControllerIncrement()->SetStartValue(*((int*)callData));
1918         return;
1919
1920       case SVTK::SetSMDecreaseSpeedEvent:
1921         self->mySMDecreaseSpeedBtn = *((int*)callData);
1922         return;
1923       case SVTK::SetSMIncreaseSpeedEvent:
1924         self->mySMIncreaseSpeedBtn = *((int*)callData);
1925         return;
1926       case SVTK::SetSMDominantCombinedSwitchEvent:
1927         self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1928         return;
1929
1930       case SVTK::StartZoom:
1931         self->startZoom();
1932         return;
1933       case SVTK::StartPan:
1934         self->startPan();
1935         return;
1936       case SVTK::StartRotate:
1937         self->startRotate();
1938         return;
1939       case SVTK::StartGlobalPan:
1940         self->startGlobalPan();
1941         return;
1942       case SVTK::StartFitArea:
1943         self->startFitArea();
1944         return;
1945
1946       case SVTK::SetRotateGravity:
1947         if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1948         {
1949           self->myHighlightSelectionPointActor->SetVisibility( false );
1950           if( self->GetCurrentRenderer() != NULL )
1951             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1952           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1953         }
1954         self->myPrevRotationPointType = self->myCurrRotationPointType;
1955         self->myCurrRotationPointType = SVTK::SetRotateGravity;
1956         if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) 
1957           // invoke event for update coordinates in SVTK_SetRotationPointDlg
1958           self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1959         return;
1960       case SVTK::StartPointSelection:
1961         self->startPointSelection();
1962         return;
1963
1964       case SVTK::ChangeRotationPoint:
1965         if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1966         {
1967           self->myHighlightSelectionPointActor->SetVisibility( false );
1968           if( self->GetCurrentRenderer() != NULL )
1969             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1970           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1971         }
1972         self->myPrevRotationPointType = self->myCurrRotationPointType;
1973         self->myCurrRotationPointType = SVTK::SetRotateSelected;
1974         aSelectedPoint = (double*)callData;
1975         self->myRotationPointX = aSelectedPoint[0];
1976         self->myRotationPointY = aSelectedPoint[1];
1977         self->myRotationPointZ = aSelectedPoint[2];
1978         return;
1979
1980       case SVTK::SetFocalPointGravity:
1981         if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1982         {
1983           self->myHighlightSelectionPointActor->SetVisibility( false );
1984           if( self->GetCurrentRenderer() != NULL )
1985             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1986           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1987         }
1988         self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1989         if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1990           // invoke event for update coordinates in SVTK_ViewParameterDlg
1991           self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1992         }
1993         return;
1994       case SVTK::StartFocalPointSelection:
1995         self->startFocalPointSelection();
1996         return;
1997       case SVTK::StartInteractiveSelection:
1998         self->startInteractiveSelection();
1999         return;
2000       case SVTK::SetFocalPointSelected:
2001         if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
2002         {
2003           self->myHighlightSelectionPointActor->SetVisibility( false );
2004           if( self->GetCurrentRenderer() != NULL )
2005             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
2006           self->GetRenderWidget()->setCursor(self->myDefCursor); 
2007         }
2008         self->myPrevFocalPointType = self->myCurrFocalPointType;
2009         self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
2010         return;
2011       case SVTK::StopCurrentOperation:
2012         self->onFinishOperation();
2013         self->startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
2014       }
2015     }
2016   }
2017
2018   Superclass::ProcessEvents( object, event, clientData, callData );
2019 }
2020
2021 /*!
2022   To handle keyboard event (reimplemented from #vtkInteractorStyle)
2023 */
2024 void SVTK_InteractorStyle::OnChar()
2025 {
2026   char key = GetInteractor()->GetKeyCode();
2027   switch ( key ) {
2028   case '+': ControllerIncrement()->Increase(); break;
2029   case '-': ControllerIncrement()->Decrease(); break;
2030   }
2031 }
2032
2033 /*!
2034   Redefined vtkInteractorStyle::OnKeyDown
2035 */
2036 void SVTK_InteractorStyle::OnKeyDown()
2037 {
2038   bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
2039   if (bInvokeSuperclass){
2040     Superclass::OnKeyDown();
2041   }
2042 }
2043
2044 /*!
2045   Provide instructions for Picking
2046 */
2047 void SVTK_InteractorStyle::ActionPicking()
2048 {
2049   int x, y;
2050   Interactor->GetEventPosition( x, y ); 
2051   FindPokedRenderer( x, y ); 
2052   
2053   myOtherPoint = myPoint = QPoint(x, y);
2054   
2055   startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
2056   onFinishOperation();
2057   startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
2058 }
2059
2060 /*!
2061   To set current increment controller 
2062 */
2063 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
2064 {
2065   myControllerOnKeyDown=theController;
2066 }
2067
2068 /*!
2069   To get current OnKeyDown controller 
2070 */
2071 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
2072 {
2073   return myControllerOnKeyDown.GetPointer();
2074 }
2075
2076 /*!
2077   To set current increment controller
2078 */
2079 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
2080 {
2081   myControllerIncrement=theController;
2082 }
2083
2084 /*!
2085   To modify current increment controller
2086 */
2087 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2088 {
2089   SVTK_ControllerIncrement* c = 0;
2090   switch (theMode) {
2091   case 0: c = SVTK_ControllerIncrement::New(); break;
2092   case 1: c = SVTK_GeomControllerIncrement::New(); break;
2093   }
2094   c->SetStartValue(theValue);
2095
2096   SetControllerIncrement(c);
2097   c->Delete();
2098 }
2099
2100 /*!
2101   To get current increment controller 
2102 */
2103 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2104 {
2105   return myControllerIncrement.GetPointer();
2106 }
2107
2108 vtkStandardNewMacro(SVTK_ControllerIncrement)
2109 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2110 {
2111   myIncrement=10;
2112 }
2113 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2114 {
2115 }
2116 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2117 {
2118   myIncrement=theValue;
2119 }
2120 int SVTK_ControllerIncrement::Current()const
2121 {
2122   return myIncrement;
2123 }
2124 int SVTK_ControllerIncrement::Increase()
2125 {
2126   ++myIncrement;
2127   return myIncrement;
2128 }
2129 int SVTK_ControllerIncrement::Decrease()
2130 {
2131   if (myIncrement>1){
2132     --myIncrement;
2133   }
2134   return myIncrement;
2135 }
2136
2137 vtkStandardNewMacro(SVTK_GeomControllerIncrement)
2138 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2139 {
2140 }
2141 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2142 {
2143 }
2144 int SVTK_GeomControllerIncrement::Increase()
2145 {
2146   myIncrement*=2;
2147   return myIncrement;
2148 }
2149 int SVTK_GeomControllerIncrement::Decrease()
2150 {
2151   myIncrement/=2;
2152   if (myIncrement<1){
2153     myIncrement=1;
2154   }
2155   return myIncrement;
2156 }
2157
2158 vtkStandardNewMacro(SVTK_ControllerOnKeyDown)
2159
2160 /*!
2161   Constructor
2162 */
2163 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2164 {
2165 }
2166
2167 /*!
2168   Destructor
2169 */
2170 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2171 {
2172 }
2173
2174 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* /*theIS*/)
2175 {
2176   return true;
2177 }