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