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