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