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