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