Salome HOME
Merge remote branch 'origin/hydro/imps_2015'
[modules/gui.git] / src / SVTK / SVTK_InteractorStyle.cxx
1 // Copyright (C) 2007-2015  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             if( !myShiftState && 
1204                 anActorCollection->GetNumberOfItems () > 1 && 
1205                 myLastHighlitedActor.GetPointer() ) {
1206               anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
1207             }
1208             anActorCollection->InitTraversal();
1209             while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1210             {
1211               if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1212               {
1213                 if( anActor->Highlight( this, aSelectionEvent, true ) )
1214                 {
1215                   aHighlightedActor = anActor;
1216                   break;
1217                 }
1218               }
1219             }
1220           }
1221
1222           if( !aHighlightedActor )
1223           {
1224             if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1225               myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1226           }
1227           myLastHighlitedActor = aHighlightedActor;
1228         }
1229         else
1230         {
1231           if ( myPoligonState == InProcess || myPoligonState == Closed )
1232             aSelectionEvent->myIsPolygon = true;
1233           else
1234             aSelectionEvent->myIsRectangle = true;
1235
1236           //processing polygonal selection
1237           Interactor->StartPickCallback();
1238           GetSelector()->StartPickCallback();
1239
1240           if(!myShiftState)
1241             GetSelector()->ClearIObjects();
1242
1243           VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1244           vtkActorCollection* aListActors = aCopy.GetActors();
1245           aListActors->InitTraversal();
1246           while(vtkActor* aActor = aListActors->GetNextActor())
1247           {
1248             if(aActor->GetVisibility())
1249             {
1250               if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1251               {
1252                 if(aSActor->hasIO())
1253                   aSActor->Highlight( this, aSelectionEvent, true );
1254               }
1255             }
1256           }
1257         }
1258         aSelectionEvent->myIsRectangle = false;
1259         aSelectionEvent->myIsPolygon = false;
1260         aSelectionEvent->myPolygonPoints.clear();
1261         endDrawPolygon();
1262         Interactor->EndPickCallback();
1263         GetSelector()->EndPickCallback();
1264       } 
1265       break;
1266     }
1267     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1268     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1269     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1270     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1271       break;
1272     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1273     {
1274       int w, h, x, y;
1275       Interactor->GetSize(w, h);
1276       x = myPoint.x(); 
1277       y = h - myPoint.y() - 1;
1278       Place(x, y);
1279     }
1280     break;
1281   }
1282
1283   this->Render();
1284 }
1285
1286
1287 /*!
1288   Called during viewer operation when user moves mouse (!put necessary processing here!)
1289 */
1290 void SVTK_InteractorStyle::onOperation(QPoint mousePos) 
1291 {
1292   if (!GetRenderWidget()) 
1293     return;
1294
1295   switch (State) {
1296   case VTK_INTERACTOR_STYLE_CAMERA_PAN: 
1297     {
1298       this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1299       myPoint = mousePos;
1300       break;
1301     }
1302   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: 
1303     {    
1304       this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1305       myPoint = mousePos;
1306       break;
1307     }
1308   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: 
1309     {
1310       this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1311       myPoint = mousePos;
1312       break;
1313     }
1314   case VTK_INTERACTOR_STYLE_CAMERA_SPIN: 
1315     {
1316       this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1317       myPoint = mousePos;
1318       break;
1319     }
1320   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: 
1321     {    
1322       break;
1323     }
1324   case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1325     {
1326       if (!myCursorState)
1327         setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1328     }
1329   case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1330     {
1331       myOtherPoint = mousePos;
1332       if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1333         drawPolygon();
1334       else if ( myPoligonState != Finished )
1335         drawRect();
1336       break;
1337     }
1338   }
1339 }
1340
1341 /*!
1342   Called when user moves mouse inside viewer window and there is no active viewer operation 
1343   (!put necessary processing here!)
1344 */
1345 void SVTK_InteractorStyle::onCursorMove(QPoint mousePos) 
1346 {
1347   if ( !GetSelector()->IsPreSelectionEnabled() ) 
1348     return;
1349
1350   // processing highlighting
1351   SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1352   this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1353
1354   bool anIsChanged = false;
1355
1356   SALOME_Actor* aPreHighlightedActor = NULL;
1357   vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1358
1359   if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1360   {
1361     myHighlightSelectionPointActor->SetVisibility( false );
1362
1363     if( anActorCollection )
1364     {
1365       anActorCollection->InitTraversal();
1366       while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1367       {
1368         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1369         {
1370           SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1371           myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1372           int aVtkId = myPointPicker->GetPointId();
1373           if ( aVtkId >= 0 ) {
1374             int anObjId = anActor->GetNodeObjId( aVtkId );
1375
1376             TColStd_IndexedMapOfInteger aMapIndex;
1377             aMapIndex.Add( anObjId );
1378             myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1379
1380             myHighlightSelectionPointActor->SetVisibility( true );
1381             anIsChanged = true;
1382             break;
1383           }
1384         }
1385       }
1386     }
1387   }
1388   else {
1389     if( anActorCollection )
1390     {
1391       anActorCollection->InitTraversal();
1392       while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1393       {
1394         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1395         {
1396           anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1397           if( anActor->isPreselected() )
1398           {
1399             aPreHighlightedActor = anActor;
1400             break;
1401           }
1402         }
1403       }
1404     }
1405
1406     if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1407       anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );   
1408
1409   }
1410   
1411   myLastPreHighlitedActor = aPreHighlightedActor;
1412
1413   if(anIsChanged)
1414     this->Render();
1415 }
1416
1417 /*!
1418   Called on finsh GlobalPan operation 
1419 */
1420 void SVTK_InteractorStyle::Place(const int theX, const int theY) 
1421 {
1422   if (GetCurrentRenderer() == NULL)
1423     return;
1424
1425   //translate view
1426   int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1427   int centerX = aSize[0]/2;
1428   int centerY = aSize[1]/2;
1429
1430   TranslateView(centerX, centerY, theX, theY);
1431
1432   // restore zoom scale
1433   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1434   cam->SetParallelScale(myScale);
1435   GetCurrentRenderer()->ResetCameraClippingRange();
1436
1437   this->Render();
1438 }
1439
1440
1441
1442 /*!
1443   Translates view from Point to Point
1444 */
1445 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1446 {
1447   if (GetCurrentRenderer() == NULL)
1448     return;
1449
1450   vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1451   double viewFocus[4], focalDepth, viewPoint[3];
1452   double newPickPoint[4], oldPickPoint[4], motionVector[3];
1453   cam->GetFocalPoint(viewFocus);
1454
1455   this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1456                               viewFocus[2], viewFocus);
1457   focalDepth = viewFocus[2];
1458
1459   this->ComputeDisplayToWorld(double(toX), double(toY),
1460                               focalDepth, newPickPoint);
1461   this->ComputeDisplayToWorld(double(fromX),double(fromY),
1462                               focalDepth, oldPickPoint);
1463   
1464   // camera motion is reversed
1465   motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1466   motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1467   motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1468   
1469   cam->GetFocalPoint(viewFocus);
1470   cam->GetPosition(viewPoint);
1471   cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1472                      motionVector[1] + viewFocus[1],
1473                      motionVector[2] + viewFocus[2]);
1474   cam->SetPosition(motionVector[0] + viewPoint[0],
1475                    motionVector[1] + viewPoint[1],
1476                    motionVector[2] + viewPoint[2]);
1477 }
1478
1479 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1480 {
1481   this->PanXY( incrX, incrY, 0, 0 );
1482 }
1483
1484 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1485 {
1486   this->DollyXY( incr, incr );
1487 }
1488
1489 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1490 {
1491   this->RotateXY( incrX, -incrY );
1492 }
1493
1494 /*!
1495   Redefined in order to add an observer (callback) for custorm event (space mouse event)
1496 */
1497 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1498 {
1499   // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1500   Superclass::SetInteractor( theInteractor );
1501  
1502   myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1503
1504   if(theInteractor) { 
1505     // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1506     theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1507     theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1508     theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1509     theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1510     theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1511     theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1512     theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1513     theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1514     theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1515     theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1516     theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1517     theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1518     theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1519     theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1520     theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1521
1522     theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1523     theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1524     theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1525
1526     theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1527     theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1528     theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1529     theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1530     theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1531
1532     theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1533     theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1534
1535     theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1536
1537     theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1538     theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1539     theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1540   }
1541 }
1542
1543 /*!
1544   To implement cached rendering
1545 */
1546 void SVTK_InteractorStyle::OnTimer() 
1547 {
1548   //vtkInteractorStyle::OnTimer();
1549   this->Interactor->Render();
1550   // check if bounding box was changed
1551   if ( GetCurrentRenderer() )
1552   {
1553     double aCurrBBCenter[3];
1554     if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1555     {
1556       if ( !myBBFirstCheck )
1557       {
1558         if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1559              fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1560              fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1561           // bounding box was changed => send SVTK::RotationPointChanged event
1562           // invoke event for update coordinates in SVTK_SetRotationPointDlg
1563           InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1564           for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1565         }
1566       }
1567       else 
1568       {
1569         for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1570         myBBFirstCheck = false;
1571       }
1572     }
1573   }
1574 }
1575
1576 /*!
1577   To invoke #vtkRenderWindowInteractor::CreateTimer
1578 */
1579 void SVTK_InteractorStyle::Render() 
1580 {
1581   this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1582 }
1583
1584 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1585 {
1586   // general things, do SetCurrentRenderer() within FindPokedRenderer() 
1587   int x, y;
1588   GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1589   FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1590   
1591   IncrementalZoom( (int)data[2] );        // 1. push toward / pull backward = zoom out / zoom in
1592   IncrementalPan(  (int)data[0],  (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1593   IncrementalRotate( 0,  (int)data[4] );   // 4. twist the control = rotate around Y axis
1594   IncrementalRotate( (int)data[3], 0  );   // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1595 }
1596
1597 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1598 {
1599   if( mySMDecreaseSpeedBtn == button ) {   
1600     ControllerIncrement()->Decrease();
1601   }
1602   if( mySMIncreaseSpeedBtn == button ) {    
1603     ControllerIncrement()->Increase();
1604   }
1605   if( mySMDominantCombinedSwitchBtn == button )    
1606     DominantCombinedSwitch();
1607 }
1608
1609 void SVTK_InteractorStyle::DominantCombinedSwitch()
1610 {
1611   printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1612 }
1613
1614 /*!
1615   Draws rectangle by starting and current points
1616 */
1617 void SVTK_InteractorStyle::drawRect()
1618 {
1619   if ( !myRectBand ) {
1620     myRectBand = new QRubberBand( QRubberBand::Rectangle, GetRenderWidget() );
1621     QPalette palette;
1622     palette.setColor(myRectBand->foregroundRole(), Qt::white);
1623     myRectBand->setPalette(palette);
1624   }
1625   myRectBand->hide();
1626
1627   QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
1628   myRectBand->setGeometry( aRect );
1629   myRectBand->setVisible( aRect.isValid() );
1630 }
1631
1632 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1633                   const QPoint& theStart2, const QPoint& theEnd2 )
1634 {
1635   if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1636        ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1637     return true;
1638
1639   if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1640       theStart1 == theEnd2 || theEnd1 == theEnd2 )
1641     return false;
1642
1643   double x11 = theStart1.x() * 1.0;
1644   double x12 = theEnd1.x() * 1.0;
1645   double y11 = theStart1.y() * 1.0;
1646   double y12 = theEnd1.y() * 1.0;
1647
1648   double x21 = theStart2.x() * 1.0;
1649   double x22 = theEnd2.x() * 1.0;
1650   double y21 = theStart2.y() * 1.0;
1651   double y22 = theEnd2.y() * 1.0;
1652
1653   double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1654   double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1655
1656   double b1 = y11 - k1 * x11;
1657   double b2 = y21 - k2 * x21;
1658
1659   if ( k1 == k2 )
1660   {
1661     if ( b1 != b2 )
1662       return false;
1663     else
1664       return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1665                   qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1666                 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1667                   qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1668   }
1669   else
1670   {
1671     double x0 = ( b2 - b1 ) / ( k1 - k2 );
1672     double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1673
1674     if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1675          qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1676          qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1677          qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1678       return true;
1679   }
1680   return false;
1681 }
1682
1683 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1684 {
1685   if ( !thePoints->count() )
1686     return true;
1687
1688   if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1689     return false;
1690
1691   const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1692
1693   if ( aLast == theCurrent )
1694     return true;
1695
1696   bool res = true;
1697   for ( uint i = 0; i < thePoints->count() - 1 && res; i++ )
1698   {
1699     const QPoint& aStart = thePoints->point( i );
1700     const QPoint& anEnd  = thePoints->point( i + 1 );
1701     res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1702   }
1703   return res;
1704 }
1705
1706 /*!
1707   Draws polygon
1708 */
1709 void SVTK_InteractorStyle::drawPolygon()
1710 {
1711   QSize aToler( 5, 5 );
1712   if ( !myPolygonBand ) {
1713     myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1714     QPalette palette;
1715     palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1716     myPolygonBand->setPalette( palette );
1717     myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) );
1718   }
1719   myPolygonBand->hide();
1720
1721   bool closed = false;
1722   bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1723   if ( !myPolygonPoints.at(0).isNull() )
1724   {
1725     QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1726                  2 * aToler.width(), 2 * aToler.height() );
1727     closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1728   }
1729
1730   QPolygon* points = new QPolygon( myPolygonPoints );
1731   valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1732   myPoligonState = valid ? InProcess : NotValid;
1733   delete points;
1734   if ( closed && !valid )
1735     closed = false;
1736
1737   if ( closed && myPolygonPoints.size() > 2 ) {
1738     GetRenderWidget()->setCursor( Qt::CrossCursor );
1739     myPoligonState = Closed;
1740   }
1741   else if ( valid )
1742     GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1743   else
1744     GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1745
1746   myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1747
1748   QPolygon aPolygon( myPolygonPoints );
1749   myPolygonBand->initGeometry( aPolygon );
1750   myPolygonBand->setVisible( true );
1751
1752   if ( myPolygonPoints.size() > 1 ) {
1753     myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1754   }
1755 }
1756
1757 /*!
1758   \brief Delete rubber band on the end on the dragging operation.
1759 */
1760 void SVTK_InteractorStyle::endDrawRect()
1761 {
1762   if ( myRectBand ) myRectBand->hide();
1763
1764   delete myRectBand;
1765   myRectBand = 0;
1766 }
1767
1768 /*!
1769   \brief Delete rubber band on the end on the dragging operation.
1770 */
1771 void SVTK_InteractorStyle::endDrawPolygon()
1772 {
1773   if ( myPolygonBand ) myPolygonBand->hide();
1774
1775   delete myPolygonBand;
1776   myPolygonBand = 0;
1777
1778   myPolygonPoints.clear();
1779 }
1780
1781 /*!
1782   Main process event method (reimplemented from #vtkInteractorStyle)
1783 */
1784 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1785                                           unsigned long event,
1786                                           void* clientData, 
1787                                           void* callData )
1788 {
1789   if ( clientData ) {
1790     vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1791     SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1792     int aSpeedIncrement=self->ControllerIncrement()->Current();
1793     double aCenter[3];
1794     double* aSelectedPoint;
1795     if ( self ) {
1796       switch ( event ) {
1797       case SVTK::SpaceMouseMoveEvent : 
1798         self->onSpaceMouseMove( (double*)callData ); 
1799         return;
1800       case SVTK::SpaceMouseButtonEvent : 
1801         self->onSpaceMouseButton( *((int*)callData) ); 
1802         return;
1803       case SVTK::PanLeftEvent: 
1804         self->IncrementalPan(-aSpeedIncrement, 0);
1805         return;
1806       case SVTK::PanRightEvent:
1807         self->IncrementalPan(aSpeedIncrement, 0);
1808         return;
1809       case SVTK::PanUpEvent:
1810         self->IncrementalPan(0, aSpeedIncrement);
1811         return;
1812       case SVTK::PanDownEvent:
1813         self->IncrementalPan(0, -aSpeedIncrement);
1814         return;
1815       case SVTK::ZoomInEvent:
1816         self->IncrementalZoom(aSpeedIncrement);
1817         return;
1818       case SVTK::ZoomOutEvent:
1819         self->IncrementalZoom(-aSpeedIncrement);
1820         return;
1821       case SVTK::RotateLeftEvent: 
1822         self->IncrementalRotate(-aSpeedIncrement, 0);
1823         return;
1824       case SVTK::RotateRightEvent:
1825         self->IncrementalRotate(aSpeedIncrement, 0);
1826         return;
1827       case SVTK::RotateUpEvent:
1828         self->IncrementalRotate(0, -aSpeedIncrement);
1829         return;
1830       case SVTK::RotateDownEvent:
1831         self->IncrementalRotate(0, aSpeedIncrement);
1832         return;
1833       case SVTK::PlusSpeedIncrementEvent:
1834         self->ControllerIncrement()->Increase();
1835         return;
1836       case SVTK::MinusSpeedIncrementEvent:
1837         self->ControllerIncrement()->Decrease();
1838         return;
1839       case SVTK::SetSpeedIncrementEvent:
1840         self->ControllerIncrement()->SetStartValue(*((int*)callData));
1841         return;
1842
1843       case SVTK::SetSMDecreaseSpeedEvent:
1844         self->mySMDecreaseSpeedBtn = *((int*)callData);
1845         return;
1846       case SVTK::SetSMIncreaseSpeedEvent:
1847         self->mySMIncreaseSpeedBtn = *((int*)callData);
1848         return;
1849       case SVTK::SetSMDominantCombinedSwitchEvent:
1850         self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1851         return;
1852
1853       case SVTK::StartZoom:
1854         self->startZoom();
1855         return;
1856       case SVTK::StartPan:
1857         self->startPan();
1858         return;
1859       case SVTK::StartRotate:
1860         self->startRotate();
1861         return;
1862       case SVTK::StartGlobalPan:
1863         self->startGlobalPan();
1864         return;
1865       case SVTK::StartFitArea:
1866         self->startFitArea();
1867         return;
1868
1869       case SVTK::SetRotateGravity:
1870         if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1871         {
1872           self->myHighlightSelectionPointActor->SetVisibility( false );
1873           if( self->GetCurrentRenderer() != NULL )
1874             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1875           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1876         }
1877         self->myPrevRotationPointType = self->myCurrRotationPointType;
1878         self->myCurrRotationPointType = SVTK::SetRotateGravity;
1879         if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) 
1880           // invoke event for update coordinates in SVTK_SetRotationPointDlg
1881           self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1882         return;
1883       case SVTK::StartPointSelection:
1884         self->startPointSelection();
1885         return;
1886
1887       case SVTK::ChangeRotationPoint:
1888         if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1889         {
1890           self->myHighlightSelectionPointActor->SetVisibility( false );
1891           if( self->GetCurrentRenderer() != NULL )
1892             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1893           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1894         }
1895         self->myPrevRotationPointType = self->myCurrRotationPointType;
1896         self->myCurrRotationPointType = SVTK::SetRotateSelected;
1897         aSelectedPoint = (double*)callData;
1898         self->myRotationPointX = aSelectedPoint[0];
1899         self->myRotationPointY = aSelectedPoint[1];
1900         self->myRotationPointZ = aSelectedPoint[2];
1901         return;
1902
1903       case SVTK::SetFocalPointGravity:
1904         if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1905         {
1906           self->myHighlightSelectionPointActor->SetVisibility( false );
1907           if( self->GetCurrentRenderer() != NULL )
1908             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1909           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1910         }
1911         self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1912         if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1913           // invoke event for update coordinates in SVTK_ViewParameterDlg
1914           self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1915         }
1916         return;
1917       case SVTK::StartFocalPointSelection:
1918         self->startFocalPointSelection();
1919         return;
1920
1921       case SVTK::SetFocalPointSelected:
1922         if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
1923         {
1924           self->myHighlightSelectionPointActor->SetVisibility( false );
1925           if( self->GetCurrentRenderer() != NULL )
1926             self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1927           self->GetRenderWidget()->setCursor(self->myDefCursor); 
1928         }
1929         self->myPrevFocalPointType = self->myCurrFocalPointType;
1930         self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
1931         return;
1932       }
1933     }
1934   }
1935
1936   Superclass::ProcessEvents( object, event, clientData, callData );
1937 }
1938
1939 /*!
1940   To handle keyboard event (reimplemented from #vtkInteractorStyle)
1941 */
1942 void SVTK_InteractorStyle::OnChar()
1943 {
1944   char key = GetInteractor()->GetKeyCode();
1945   switch ( key ) {
1946   case '+': ControllerIncrement()->Increase(); break;
1947   case '-': ControllerIncrement()->Decrease(); break;
1948   }
1949 }
1950
1951 /*!
1952   Redefined vtkInteractorStyle::OnKeyDown
1953 */
1954 void SVTK_InteractorStyle::OnKeyDown()
1955 {
1956   bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
1957   if (bInvokeSuperclass){
1958     Superclass::OnKeyDown();
1959   }
1960 }
1961
1962 /*!
1963   Provide instructions for Picking
1964 */
1965 void SVTK_InteractorStyle::ActionPicking()
1966 {
1967   int x, y;
1968   Interactor->GetEventPosition( x, y ); 
1969   FindPokedRenderer( x, y ); 
1970   
1971   myOtherPoint = myPoint = QPoint(x, y);
1972   
1973   startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1974   onFinishOperation();
1975   startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1976 }
1977
1978 /*!
1979   To set current increment controller 
1980 */
1981 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
1982 {
1983   myControllerOnKeyDown=theController;
1984 }
1985
1986 /*!
1987   To get current OnKeyDown controller 
1988 */
1989 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
1990 {
1991   return myControllerOnKeyDown.GetPointer();
1992 }
1993
1994 /*!
1995   To set current increment controller
1996 */
1997 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
1998 {
1999   myControllerIncrement=theController;
2000 }
2001
2002 /*!
2003   To modify current increment controller
2004 */
2005 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2006 {
2007   SVTK_ControllerIncrement* c = 0;
2008   switch (theMode) {
2009   case 0: c = SVTK_ControllerIncrement::New(); break;
2010   case 1: c = SVTK_GeomControllerIncrement::New(); break;
2011   }
2012   c->SetStartValue(theValue);
2013
2014   SetControllerIncrement(c);
2015   c->Delete();
2016 }
2017
2018 /*!
2019   To get current increment controller 
2020 */
2021 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2022 {
2023   return myControllerIncrement.GetPointer();
2024 }
2025
2026 vtkStandardNewMacro(SVTK_ControllerIncrement);
2027 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2028 {
2029   myIncrement=10;
2030 }
2031 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2032 {
2033 }
2034 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2035 {
2036   myIncrement=theValue;
2037 }
2038 int SVTK_ControllerIncrement::Current()const
2039 {
2040   return myIncrement;
2041 }
2042 int SVTK_ControllerIncrement::Increase()
2043 {
2044   ++myIncrement;
2045   return myIncrement;
2046 }
2047 int SVTK_ControllerIncrement::Decrease()
2048 {
2049   if (myIncrement>1){
2050     --myIncrement;
2051   }
2052   return myIncrement;
2053 }
2054
2055 vtkStandardNewMacro(SVTK_GeomControllerIncrement);
2056 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2057 {
2058 }
2059 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2060 {
2061 }
2062 int SVTK_GeomControllerIncrement::Increase()
2063 {
2064   myIncrement*=2;
2065   return myIncrement;
2066 }
2067 int SVTK_GeomControllerIncrement::Decrease()
2068 {
2069   myIncrement/=2;
2070   if (myIncrement<1){
2071     myIncrement=1;
2072   }
2073   return myIncrement;
2074 }
2075
2076 vtkStandardNewMacro(SVTK_ControllerOnKeyDown);
2077
2078 /*!
2079   Constructor
2080 */
2081 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2082 {
2083 }
2084
2085 /*!
2086   Destructor
2087 */
2088 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2089 {
2090 }
2091
2092 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* theIS)
2093 {
2094   return true;
2095 }