Salome HOME
NRI : Temporary modification for reading catalog of modules.
[modules/kernel.git] / src / VTKViewer / VTKViewer_InteractorStyleSALOME.cxx
1 using namespace std;
2 //  File      : VTKViewer_InteractorStyleSALOME.cxx
3 //  Created   : Wed Mar 20 11:37:34 2002
4 //  Author    : Christophe ATTANASIO
5 //  Project   : SALOME
6 //  Module    : VTKViewer
7 //  Copyright : Open CASCADE 2002
8 //  $Header$
9
10 #include "VTKViewer_InteractorStyleSALOME.h"
11 #include "VTKViewer_RenderWindow.h"
12
13 #include <qapplication.h>
14 #include "QAD_Application.h"
15 #include "QAD_Desktop.h"
16
17 #include "SALOME_Selection.h"
18 #include "SALOME_Actor.h"
19 #include "SALOME_ListIteratorOfListIO.hxx"
20
21 #include <vtkObjectFactory.h>
22 #include <vtkMath.h>
23 #include <vtkCommand.h>
24 #include <vtkAssemblyNode.h>
25 #include <vtkPicker.h>
26 #include <vtkPointPicker.h>
27 #include <vtkCellPicker.h>
28 #include <vtkLine.h> 
29 #include <vtkUnstructuredGrid.h> 
30 #include <vtkExtractEdges.h>
31 #include <vtkPolyDataMapper.h>
32 #include <vtkDataSetCollection.h>
33
34 //VRV: porting on Qt 3.0.5
35 #if QT_VERSION >= 0x030005
36 #include <qpainter.h>
37 #endif
38 //VRV: porting on Qt 3.0.5
39
40 //----------------------------------------------------------------------------
41 VTKViewer_InteractorStyleSALOME *VTKViewer_InteractorStyleSALOME::New() 
42 {
43   // First try to create the object from the vtkObjectFactory
44   vtkObject* ret = vtkObjectFactory::CreateInstance("VTKViewer_InteractorStyleSALOME");
45   if(ret)
46     {
47       return (VTKViewer_InteractorStyleSALOME*)ret;
48     }
49   // If the factory was unable to create the object, then create it here.
50   return new VTKViewer_InteractorStyleSALOME;
51 }
52
53
54 //----------------------------------------------------------------------------
55 VTKViewer_InteractorStyleSALOME::VTKViewer_InteractorStyleSALOME() 
56 {
57   m_Triedron = 0;
58   this->MotionFactor = 10.0;
59   this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
60   this->RadianToDegree = 180.0 / vtkMath::Pi();
61   this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
62   loadCursors();
63 }
64
65 //----------------------------------------------------------------------------
66 VTKViewer_InteractorStyleSALOME::~VTKViewer_InteractorStyleSALOME() 
67 {
68 }
69
70 //----------------------------------------------------------------------------
71 void VTKViewer_InteractorStyleSALOME::setTriedron( vtkActorCollection* triedron )
72 {
73   m_Triedron = triedron;
74 }
75
76 //----------------------------------------------------------------------------
77 void VTKViewer_InteractorStyleSALOME::RotateXY(int dx, int dy)
78 {
79   double rxf;
80   double ryf;
81   vtkCamera *cam;
82   
83   if (this->CurrentRenderer == NULL)
84     {
85       return;
86     }
87   
88   int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
89   this->DeltaElevation = -20.0 / size[1];
90   this->DeltaAzimuth = -20.0 / size[0];
91   
92   rxf = (double)dx * this->DeltaAzimuth *  this->MotionFactor;
93   ryf = (double)dy * this->DeltaElevation * this->MotionFactor;
94   
95   cam = this->CurrentRenderer->GetActiveCamera();
96   cam->Azimuth(rxf);
97   cam->Elevation(ryf);
98   cam->OrthogonalizeViewUp();
99   this->CurrentRenderer->ResetCameraClippingRange();
100   vtkRenderWindowInteractor *rwi = this->Interactor;
101   if (this->CurrentLight)
102     {
103       // get the first light
104       this->CurrentLight->SetPosition(cam->GetPosition());
105       this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
106     }   
107   rwi->Render();
108 }
109
110 //----------------------------------------------------------------------------
111 void VTKViewer_InteractorStyleSALOME::PanXY(int x, int y, int oldX, int oldY)
112 {
113   TranslateView(x, y, oldX, oldY);   
114   vtkRenderWindowInteractor *rwi = this->Interactor;
115   if (this->CurrentLight)
116     {
117       /* get the first light */
118       vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
119       this->CurrentLight->SetPosition(cam->GetPosition());
120       this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
121     }
122     
123   rwi->Render();
124 }
125
126 //----------------------------------------------------------------------------
127 void VTKViewer_InteractorStyleSALOME::DollyXY(int dx, int dy)
128 {
129   vtkCamera *cam;
130   double dxf = this->MotionFactor * (double)(dx) / (double)(this->Center[1]);
131   double dyf = this->MotionFactor * (double)(dy) / (double)(this->Center[1]);
132
133   double zoomFactor = pow((double)1.1, dxf + dyf);
134   
135   if (this->CurrentRenderer == NULL)
136     {
137       return;
138     }
139   
140   cam = this->CurrentRenderer->GetActiveCamera();
141     if (cam->GetParallelProjection())
142     {
143       cam->SetParallelScale(cam->GetParallelScale()/zoomFactor);
144     }
145   else
146     {
147       cam->Dolly(zoomFactor);
148       this->CurrentRenderer->ResetCameraClippingRange();
149     }
150   
151   if (this->CurrentLight)
152     {
153       /* get the first light */
154       this->CurrentLight->SetPosition(cam->GetPosition());
155       this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
156     }
157   
158   this->Interactor->Render();
159 }
160
161 //----------------------------------------------------------------------------
162 void VTKViewer_InteractorStyleSALOME::SpinXY(int x, int y, int oldX, int oldY)
163 {
164   vtkRenderWindowInteractor *rwi = this->Interactor;
165   vtkCamera *cam;
166
167   if (this->CurrentRenderer == NULL)
168     {
169       return;
170     }
171
172   double newAngle = atan2((double)(y - this->Center[1]),
173                           (double)(x - this->Center[0]));
174   double oldAngle = atan2((double)(oldY -this->Center[1]),
175                           (double)(oldX - this->Center[0]));
176   
177   newAngle *= this->RadianToDegree;
178   oldAngle *= this->RadianToDegree;
179
180   cam = this->CurrentRenderer->GetActiveCamera();
181   cam->Roll(newAngle - oldAngle);
182   cam->OrthogonalizeViewUp();
183       
184   rwi->Render();
185 }
186
187
188 //----------------------------------------------------------------------------
189 void VTKViewer_InteractorStyleSALOME::OnMouseMove(int vtkNotUsed(ctrl), 
190                                                   int shift,
191                                                   int x, int y) 
192 {
193   myShiftState = shift;
194   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
195     onOperation(QPoint(x, y));
196   else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
197     onCursorMove(QPoint(x, y));
198 }
199
200
201 //----------------------------------------------------------------------------
202 void VTKViewer_InteractorStyleSALOME::OnLeftButtonDown(int ctrl, int shift, 
203                                                        int x, int y) 
204 {
205   if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) 
206     {
207     this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
208     return;
209     }
210   this->FindPokedRenderer(x, y);
211   if (this->CurrentRenderer == NULL)
212     {
213     return;
214     }
215   myShiftState = shift;
216   // finishing current viewer operation
217   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
218     onFinishOperation();
219     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
220   }
221   myOtherPoint = myPoint = QPoint(x, y);
222   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
223     startOperation(ForcedState);
224   }
225   else {
226     if (ctrl)
227       startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
228     else
229       startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
230   }
231   return;
232 }
233 //----------------------------------------------------------------------------
234 void VTKViewer_InteractorStyleSALOME::OnLeftButtonUp(int vtkNotUsed(ctrl),
235                                                      int shift, 
236                                                      int vtkNotUsed(x),
237                                                      int vtkNotUsed(y))
238 {
239   myShiftState = shift;
240   // finishing current viewer operation
241   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
242     onFinishOperation();
243     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
244   }
245 }
246
247 //----------------------------------------------------------------------------
248 void VTKViewer_InteractorStyleSALOME::OnMiddleButtonDown(int ctrl,
249                                                          int shift, 
250                                                          int x, int y) 
251 {
252   if (this->HasObserver(vtkCommand::MiddleButtonPressEvent)) 
253     {
254       this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
255       return;
256     }
257   this->FindPokedRenderer(x, y);
258   if (this->CurrentRenderer == NULL)
259     {
260       return;
261     }
262   myShiftState = shift;
263   // finishing current viewer operation
264   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
265     onFinishOperation();
266     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
267   }
268   myOtherPoint = myPoint = QPoint(x, y);
269   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
270     startOperation(ForcedState);
271   }
272   else {
273     if (ctrl)
274       startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
275   }
276 }
277 //----------------------------------------------------------------------------
278 void VTKViewer_InteractorStyleSALOME::OnMiddleButtonUp(int vtkNotUsed(ctrl),
279                                                        int shift, 
280                                                        int vtkNotUsed(x),
281                                                        int vtkNotUsed(y))
282 {
283   myShiftState = shift;
284   // finishing current viewer operation
285   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
286     onFinishOperation();
287     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
288   }
289 }
290
291 //----------------------------------------------------------------------------
292 void VTKViewer_InteractorStyleSALOME::OnRightButtonDown(int ctrl,
293                                                         int shift, 
294                                                         int x, int y) 
295 {
296   if (this->HasObserver(vtkCommand::RightButtonPressEvent)) 
297     {
298       this->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
299       return;
300     }
301   this->FindPokedRenderer(x, y);
302   if (this->CurrentRenderer == NULL)
303     {
304       return;
305     }
306   myShiftState = shift;
307   // finishing current viewer operation
308   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
309     onFinishOperation();
310     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
311   }
312   myOtherPoint = myPoint = QPoint(x, y);
313   if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
314     startOperation(ForcedState);
315   }
316   else {
317     if (ctrl)
318       startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);  
319   }
320 }
321
322 //----------------------------------------------------------------------------
323 void VTKViewer_InteractorStyleSALOME::OnRightButtonUp(int vtkNotUsed(ctrl),
324                                                       int shift, 
325                                                       int vtkNotUsed(x),
326                                                       int vtkNotUsed(y))
327 {
328   myShiftState = shift;
329   // finishing current viewer operation
330   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
331     onFinishOperation();
332     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
333   }
334 }
335
336 //----------------------------------------------------------------------------
337 void VTKViewer_InteractorStyleSALOME::PrintSelf(ostream& os, vtkIndent indent)
338 {
339   vtkInteractorStyle::PrintSelf(os,indent);
340
341 }
342
343 /* XPM */
344 const char* imageZoomCursor[] = { 
345 "32 32 3 1",
346 ". c None",
347 "a c #000000",
348 "# c #ffffff",
349 "................................",
350 "................................",
351 ".#######........................",
352 "..aaaaaaa.......................",
353 "................................",
354 ".............#####..............",
355 "...........##.aaaa##............",
356 "..........#.aa.....a#...........",
357 ".........#.a.........#..........",
358 ".........#a..........#a.........",
359 "........#.a...........#.........",
360 "........#a............#a........",
361 "........#a............#a........",
362 "........#a............#a........",
363 "........#a............#a........",
364 ".........#...........#.a........",
365 ".........#a..........#a.........",
366 ".........##.........#.a.........",
367 "........#####.....##.a..........",
368 ".......###aaa#####.aa...........",
369 "......###aa...aaaaa.......#.....",
370 ".....###aa................#a....",
371 "....###aa.................#a....",
372 "...###aa...............#######..",
373 "....#aa.................aa#aaaa.",
374 ".....a....................#a....",
375 "..........................#a....",
376 "...........................a....",
377 "................................",
378 "................................",
379 "................................",
380 "................................"};
381
382 const char* imageRotateCursor[] = { 
383 "32 32 3 1",
384 ". c None",
385 "a c #000000",
386 "# c #ffffff",
387 "................................",
388 "................................",
389 "................................",
390 "................................",
391 "........#.......................",
392 ".......#.a......................",
393 "......#######...................",
394 ".......#aaaaa#####..............",
395 "........#..##.a#aa##........##..",
396 ".........a#.aa..#..a#.....##.aa.",
397 ".........#.a.....#...#..##.aa...",
398 ".........#a.......#..###.aa.....",
399 "........#.a.......#a..#aa.......",
400 "........#a.........#..#a........",
401 "........#a.........#a.#a........",
402 "........#a.........#a.#a........",
403 "........#a.........#a.#a........",
404 ".........#.........#a#.a........",
405 "........##a........#a#a.........",
406 "......##.a#.......#.#.a.........",
407 "....##.aa..##.....##.a..........",
408 "..##.aa.....a#####.aa...........",
409 "...aa.........aaa#a.............",
410 "................#.a.............",
411 "...............#.a..............",
412 "..............#.a...............",
413 "...............a................",
414 "................................",
415 "................................",
416 "................................",
417 "................................",
418 "................................"};
419
420 // loads cursors for viewer operations - zoom, pan, etc...
421 void VTKViewer_InteractorStyleSALOME::loadCursors()
422 {
423   myDefCursor       = QCursor(ArrowCursor);
424   myHandCursor      = QCursor(PointingHandCursor);
425   myPanCursor       = QCursor(SizeAllCursor);
426   myZoomCursor      = QCursor(QPixmap(imageZoomCursor));
427   myRotateCursor    = QCursor(QPixmap(imageRotateCursor));
428   mySpinCursor      = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
429   myGlobalPanCursor = QCursor(CrossCursor);
430   myCursorState     = false;
431 }
432
433 // event filter - controls mouse and keyboard events during viewer operations
434 bool VTKViewer_InteractorStyleSALOME::eventFilter(QObject* object, QEvent* event)
435 {
436   VTKViewer_RenderWindow* wnd = dynamic_cast<VTKViewer_RenderWindow*>(GetInteractor()->GetRenderWindow());
437   if ( (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress) && object != wnd)
438   {
439     qApp->removeEventFilter(this);
440     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
441   }
442   return QObject::eventFilter(object, event);
443 }
444
445 // starts Zoom operation (e.g. through menu command)
446 void VTKViewer_InteractorStyleSALOME::startZoom()
447 {
448   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
449   {
450     onFinishOperation();
451     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
452   }
453   setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
454   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
455   qApp->installEventFilter(this);
456 }
457
458 // starts Pan operation (e.g. through menu command)
459 void VTKViewer_InteractorStyleSALOME::startPan()
460 {
461   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
462   {
463     onFinishOperation();
464     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
465   }
466   setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
467   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
468   qApp->installEventFilter(this);
469 }
470
471 // starts Rotate operation (e.g. through menu command)
472 void VTKViewer_InteractorStyleSALOME::startRotate()
473 {
474   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
475   {
476     onFinishOperation();
477     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
478   }
479   setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
480   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
481   qApp->installEventFilter(this);
482 }
483
484 // starts Spin operation (e.g. through menu command)
485 void VTKViewer_InteractorStyleSALOME::startSpin()
486 {
487   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
488   {
489     onFinishOperation();
490     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
491   }
492   setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
493   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
494   qApp->installEventFilter(this);
495 }
496
497
498 // starts Fit Area operation (e.g. through menu command)
499 void VTKViewer_InteractorStyleSALOME::startFitArea()
500 {
501   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
502   {
503     onFinishOperation();
504     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
505   }
506   setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
507   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
508   qApp->installEventFilter(this);
509 }
510
511 // starts Global Panning operation (e.g. through menu command)
512 void VTKViewer_InteractorStyleSALOME::startGlobalPan()
513 {
514   if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
515   {
516     onFinishOperation();
517     startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
518   }
519   setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
520   ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
521
522   // store current zoom scale
523   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
524   myScale = cam->GetParallelScale();
525
526   // make fit all
527   Standard_Boolean TriedronWasVisible = false;
528   if ( m_Triedron ) {
529     m_Triedron->InitTraversal();
530     vtkActor *ac = m_Triedron->GetNextActor();
531     while(!(ac==NULL)) {
532       if(ac->GetVisibility()) {
533         TriedronWasVisible = true;
534         ac->VisibilityOff();
535       }
536       ac = m_Triedron->GetNextActor();
537     }
538   }
539   this->CurrentRenderer->ResetCamera();
540   this->CurrentRenderer->ResetCameraClippingRange();
541   if( m_Triedron && TriedronWasVisible ) {
542     m_Triedron->InitTraversal();
543     vtkActor *ac = m_Triedron->GetNextActor();
544     while(!(ac==NULL)) {
545       ac->VisibilityOn();
546       ac = m_Triedron->GetNextActor();
547     }
548   }
549   VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(this->Interactor->GetRenderWindow());
550   if (aRW) aRW->updateGL();
551   
552   qApp->installEventFilter(this);
553 }
554
555 // returns TRUE if needs redrawing
556 bool VTKViewer_InteractorStyleSALOME::needsRedrawing()
557 {
558   return State == VTK_INTERACTOR_STYLE_CAMERA_ZOOM   ||
559          State == VTK_INTERACTOR_STYLE_CAMERA_PAN    ||
560          State == VTK_INTERACTOR_STYLE_CAMERA_ROTATE ||
561          State == VTK_INTERACTOR_STYLE_CAMERA_SPIN   ||
562          State == VTK_INTERACTOR_STYLE_CAMERA_NONE;
563 }
564
565 // fits viewer contents to rect
566 void VTKViewer_InteractorStyleSALOME::fitRect(const int left, 
567                                        const int top, 
568                                        const int right, 
569                                        const int bottom)
570 {
571   if (this->CurrentRenderer == NULL) {
572     return;
573   }
574   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
575
576   // move camera
577   int x = (left + right)/2;
578   int y = (top + bottom)/2;
579   int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
580   int oldX = aSize[0]/2;
581   int oldY = aSize[1]/2;
582   TranslateView(oldX, oldY, x, y);
583       
584   // zoom camera
585   double dxf = (double)(aSize[0]) / (double)(abs(right - left));
586   double dyf = (double)(aSize[1]) / (double)(abs(bottom - top));
587   double zoomFactor = (dxf + dyf)/2 ;
588
589   if (cam->GetParallelProjection()) {
590     cam->SetParallelScale(cam->GetParallelScale()/zoomFactor);
591   } else {
592     cam->Dolly(zoomFactor);
593     this->CurrentRenderer->ResetCameraClippingRange();
594   }
595   
596   vtkRenderWindowInteractor *rwi = this->Interactor;
597   if (this->CurrentLight) {
598     /* get the first light */
599     this->CurrentLight->SetPosition(cam->GetPosition());
600     this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
601   }
602   //  rwi->Render();
603   VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(rwi->GetRenderWindow());
604   if (aRW) aRW->updateGL();
605 }
606
607
608
609 // starts viewer operation (!internal usage!)
610 void VTKViewer_InteractorStyleSALOME::startOperation(int operation)
611 {
612   switch(operation)
613   { 
614   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
615   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
616   case VTK_INTERACTOR_STYLE_CAMERA_PAN:
617   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
618   case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
619   case VTK_INTERACTOR_STYLE_CAMERA_FIT:
620   case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
621     if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
622       startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
623     State = operation;
624     if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
625       setCursor(operation);
626     onStartOperation();
627     break;
628   case VTK_INTERACTOR_STYLE_CAMERA_NONE:
629   default:
630     setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
631     State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
632     break;
633   }
634 }
635
636 // sets proper cursor for window when viewer operation is activated
637 void VTKViewer_InteractorStyleSALOME::setCursor(const int operation)
638 {
639    VTKViewer_RenderWindow* wnd = dynamic_cast< VTKViewer_RenderWindow*>(GetInteractor()->GetRenderWindow());
640   switch (operation)
641   {
642     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
643       wnd->setCursor(myZoomCursor); 
644       myCursorState = true;
645       break;
646     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
647       wnd->setCursor(myPanCursor); 
648       myCursorState = true;
649       break;
650     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
651       wnd->setCursor(myRotateCursor); 
652       myCursorState = true;
653       break;
654     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
655       wnd->setCursor(mySpinCursor); 
656       myCursorState = true;
657       break;
658     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
659       wnd->setCursor(myGlobalPanCursor); 
660       myCursorState = true;
661       break;
662     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
663     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
664       wnd->setCursor(myHandCursor); 
665       myCursorState = true;
666       break;
667     case VTK_INTERACTOR_STYLE_CAMERA_NONE:
668     default:
669       wnd->setCursor(myDefCursor); 
670       myCursorState = false;
671       break;
672   }
673 }
674
675 // called when viewer operation started (!put necessary initialization here!)
676 void VTKViewer_InteractorStyleSALOME::onStartOperation()
677 {
678    VTKViewer_RenderWindow* wnd = dynamic_cast< VTKViewer_RenderWindow*>(GetInteractor()->GetRenderWindow());
679   switch (State) {
680     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
681     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
682     {
683       QPainter p(wnd);
684       p.setPen(Qt::lightGray);
685       p.setRasterOp(Qt::XorROP);
686       p.drawRect(QRect(myPoint, myOtherPoint));
687       break;
688     }
689     case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
690     case VTK_INTERACTOR_STYLE_CAMERA_PAN:
691     case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
692     case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
693     case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
694       break;
695   }
696 }
697
698 // called when viewer operation finished (!put necessary post-processing here!)
699 void VTKViewer_InteractorStyleSALOME::onFinishOperation() 
700 {
701   QAD_Study* aActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
702   SALOME_Selection* aSel    = SALOME_Selection::Selection( aActiveStudy->getSelection() );
703   VTKViewer_RenderWindow* wnd = dynamic_cast< VTKViewer_RenderWindow*>(GetInteractor()->GetRenderWindow());
704   vtkRenderWindowInteractor *rwi = this->Interactor;
705
706   int aSelectionMode = aSel->SelectionMode();
707   bool aSelActiveCompOnly = aSel->IsSelectActiveCompOnly();
708   SALOMEDS::SComponent_var aActiveComponent = SALOMEDS::SComponent::_narrow(
709      aActiveStudy->getStudyDocument()->FindObject(QAD_Application::getDesktop()->getActiveComponent()));
710
711   switch (State) {
712     case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
713     case VTK_INTERACTOR_STYLE_CAMERA_FIT:
714     {
715       QPainter p(wnd);
716       p.setPen(Qt::lightGray);
717       p.setRasterOp(Qt::XorROP);
718       QRect rect(myPoint, myOtherPoint);
719       p.drawRect(rect);
720       rect = rect.normalize();
721       if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
722         // making fit rect opeation 
723         int w, h, x, y;
724         rwi->GetSize(w, h);
725         int x1, y1, x2, y2;
726         x1 = rect.left(); 
727         y1 = h - rect.top() - 1;
728         x2 = rect.right(); 
729         y2 = h - rect.bottom() - 1;
730         fitRect(x1, y1, x2, y2);
731       }
732       else {
733         if (myPoint == myOtherPoint) {
734         // process point selection
735           int w, h, x, y;
736           rwi->GetSize(w, h);
737           x = myPoint.x(); 
738           y = h - myPoint.y() - 1;
739           vtkActorCollection* listactors = NULL;
740           this->FindPokedRenderer(x, y);
741           rwi->StartPickCallback();
742           rwi->GetPicker()->Pick(x, y, 0.0, this->CurrentRenderer);
743     
744           if ( rwi->GetPicker()->IsA("vtkCellPicker") ) {
745             vtkCellPicker* picker;
746             if ( (picker = vtkCellPicker::SafeDownCast(rwi->GetPicker())) ) {
747               MESSAGE ( " CellId : " << picker->GetCellId() );
748               if ( picker->GetCellId() >= 0 ) {
749                 vtkActor* ac = picker->GetActor();
750                 if ( ac->IsA("SALOME_Actor") ) {
751                   SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
752                   MESSAGE ( " NAME Actor : " << SActor->getName() );
753
754                   //Cell selection //////////////////////////////////// NB
755                   if ( aSelectionMode == 3 ) {
756                     if ( SActor->hasIO() ) {
757                       Handle(SALOME_InteractiveObject) IO = SActor->getIO();
758                       // Look in the current selection
759                       SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
760                       Standard_Boolean IsSelected = false;
761                       for(;It.More();It.Next()) {
762                         Handle(SALOME_InteractiveObject) IOS = It.Value();
763                         if(IO->isSame(IOS)) {
764                           IsSelected = true;
765                           IO = IOS; //Added by SRN, fix SAL1307
766                           break;
767                         }
768                       }
769                       if(IsSelected) {
770                         // This IO is already in the selection
771                         //if(shift) {
772                           bool add = aSel->AddOrRemoveIndex( IO, picker->GetCellId(), myShiftState, false );
773                           //Sel->RemoveIObject(IO);
774                         //}
775                       } else {
776                         if(!myShiftState) {
777                           this->HighlightProp( NULL );
778                           aSel->ClearIObjects();
779                         }
780                         bool add = aSel->AddOrRemoveIndex( IO, picker->GetCellId(), myShiftState, false );
781                         aSel->AddIObject( IO, false );
782                       }
783                     }
784                   }
785                   //Edge selection ////////////////////////// NB
786                   else if ( aSelectionMode == 2 ) {
787                     if ( SActor->hasIO() ) {
788                       Handle(SALOME_InteractiveObject) IO = SActor->getIO();
789                       float pickPosition[3],pcoords[3],closestPoint[3],weights[3],dist1=1000000.0,dist2=0;
790                       int subId,edgeId,pickedID,result;
791                       pickedID = picker->GetCellId();
792                       picker->GetPickPosition(pickPosition);
793                        MESSAGE("Position = "<<pickPosition[0]<<" "<<pickPosition[1]<<" "<<pickPosition[2]);
794                       vtkUnstructuredGrid* UGrid = vtkUnstructuredGrid::SafeDownCast( SActor->GetMapper()->GetInput());
795                       if (!UGrid) break;
796                       vtkCell* pickedCell = UGrid->GetCell(pickedID);
797                       if (!pickedCell) break;
798                       vtkCell* edge;
799                       vtkLine* line;
800                       for (int i=0;i<pickedCell->GetNumberOfEdges();i++) {
801                         edge = pickedCell->GetEdge(i);
802                         if (edge->GetCellType() == 3) { //3 for VTK_LINE
803                           line = (vtkLine*)edge;
804                           result = line->EvaluatePosition(pickPosition,closestPoint,subId,pcoords,dist2,weights);
805                           MESSAGE("edge "<< i <<" dist = " << dist2);
806                           if (dist2 < dist1) {
807                             dist1  = dist2;
808                             edgeId = i;
809                           }
810                         }
811                       }
812                       MESSAGE("edgeID transformed = "<<edgeId);
813                       // Look in the current selection
814                       SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
815                       Standard_Boolean IsSelected = false;
816                       for(;It.More();It.Next()) {
817                         Handle(SALOME_InteractiveObject) IOS = It.Value();
818                         if(IO->isSame(IOS)) {
819                           IO = IOS; //Added by SRN, fix SAL1307
820                           IsSelected = true;
821                           break;
822                         }
823                       }
824                       if(!myShiftState) {
825                         this->HighlightProp( NULL );
826                         aSel->ClearIObjects();
827                       }
828                       aSel->SetSelectionMode(3, true);
829                       bool add = aSel->AddOrRemoveIndex( IO, pickedID, 0 );
830                       aSel->SetSelectionMode(2, true);
831                       edgeId = -edgeId;
832                       add = aSel->AddOrRemoveIndex( IO, edgeId, 0, false );
833                       aSel->AddIObject( IO, false );
834                     }
835                   }
836                 } else {
837                   this->HighlightProp( NULL );
838                   aSel->ClearIObjects();
839                 }
840               }
841             }
842           } else if ( rwi->GetPicker()->IsA("vtkPointPicker") ) {
843             vtkPointPicker* picker;
844             if ( (picker = vtkPointPicker::SafeDownCast(rwi->GetPicker())) ) {
845               MESSAGE ( " PointId : " << picker->GetPointId() );
846               if ( picker->GetPointId() >= 0 ) {
847                 vtkActor* ac = picker->GetActor();
848                 if ( ac->IsA("SALOME_Actor") ) {
849                   SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
850                   MESSAGE ( " NAME Actor : " << SActor->getName() );
851                   if ( SActor->hasIO() ) {
852                     Handle(SALOME_InteractiveObject) IO = SActor->getIO();
853 /*                  if (IO.IsNull()) 
854                       break;
855                     if (aSelActiveCompOnly && 
856                         strcmp(aActiveComponent->ComponentDataType(), IO->getComponentDataType()) != 0) {
857                       break;
858                     }*/
859                     // Look in the current selection
860                     SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
861                     Standard_Boolean IsSelected = false;
862                     for(;It.More();It.Next()) {
863                       Handle(SALOME_InteractiveObject) IOS = It.Value();
864                       if(IO->isSame(IOS)) {
865                         IO = IOS; //Added by SRN, fix SAL1307
866                         IsSelected = true;
867                         break;
868                       }
869                     }
870                     if(IsSelected) {
871                       // This IO is already in the selection
872                       bool add = aSel->AddOrRemoveIndex( IO, picker->GetPointId(), myShiftState, false );
873                     } else {
874                       if(!myShiftState) {
875                         this->HighlightProp( NULL );
876                         aSel->ClearIObjects();
877                       }
878                       bool add = aSel->AddOrRemoveIndex( IO, picker->GetPointId(), myShiftState, false );
879                       aSel->AddIObject( IO, false );
880                     }
881                   }
882                 } 
883               } else {
884                 this->HighlightProp( NULL );
885                 aSel->ClearIObjects();
886               } 
887             }
888           } else {
889             vtkPicker* picker;
890             if ( (picker = vtkPicker::SafeDownCast(rwi->GetPicker())) ) {
891               listactors = picker->GetActors();
892             }
893             if ( listactors->GetNumberOfItems() == 0 ) {
894               // No selection clear all
895               this->PropPicked = 0;
896               this->HighlightProp( NULL );
897               aSel->ClearIObjects();
898             } else {
899               vtkActor* ac;
900               listactors->InitTraversal();
901               ac = listactors->GetNextActor();
902               if ( ac->IsA("SALOME_Actor") ) {
903                 SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
904                 if ( SActor->hasIO() ) {      
905                   this->PropPicked++;
906                   Handle(SALOME_InteractiveObject) IO = SActor->getIO();
907                   // Look in the current selection
908                   SALOME_ListIteratorOfListIO It(aSel->StoredIObjects());
909                   Standard_Boolean IsSelected = false;
910                   for(;It.More();It.Next()) {
911                     Handle(SALOME_InteractiveObject) IOS = It.Value();
912                     if( IO->isSame(IOS) ) {
913                       IO = IOS; //Added by SRN, fix SAL1307
914                       IsSelected = true;
915                       break;
916                     }
917                   }
918                   if(IsSelected) {
919                     // This IO is already in the selection
920                     if(myShiftState) {
921                       aSel->RemoveIObject(IO);
922                     }
923                   }
924                   else {
925                     if(!myShiftState) {
926                       this->HighlightProp( NULL );
927                       aSel->ClearIObjects();
928                     }
929                     aSel->AddIObject( IO, false );
930                   }
931                 }
932               }
933             }
934             rwi->EndPickCallback();
935           }
936         } else {
937           //processing rectangle selection
938           rwi->StartPickCallback();
939
940           if (!myShiftState) {
941             this->PropPicked = 0;
942             this->HighlightProp( NULL );
943             aSel->ClearIObjects();
944           }
945
946           // Compute bounds
947           vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
948           QRect rect(myPoint, myOtherPoint);
949           rect = rect.normalize();
950           int w, h, x, y;
951           rwi->GetSize(w, h);
952           int x1, y1, x2, y2;
953           x1 = rect.left(); 
954           y1 = h - rect.top() - 1;
955           x2 = rect.right(); 
956           y2 = h - rect.bottom() - 1;
957
958           switch (aSelectionMode) {
959           case 1: // Nodes selection
960             {
961               if (! rwi->GetPicker()->IsA("vtkPointPicker") ) break;
962               vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(rwi->GetPicker());
963               vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
964               aListActors->InitTraversal();
965               vtkActor* aActor;
966               for (int k = 0; k < aListActors->GetNumberOfItems(); k++) {
967                 aActor = aListActors->GetNextActor();
968                 if (aActor != NULL) {
969                   if (aActor->GetVisibility() == 0) 
970                     continue;
971                   vtkAbstractMapper3D* aMapper3D = aActor->GetMapper();
972                   if ((aMapper3D != NULL) && (aActor->IsA("SALOME_Actor"))) {
973                     SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor);
974
975                     if ((SActor != NULL) && (SActor->hasIO())) {
976                       Handle(SALOME_InteractiveObject) IO = SActor->getIO();
977                       if (IO.IsNull()) 
978                         continue;
979                       if (aSelActiveCompOnly && 
980                               strcmp(aActiveComponent->ComponentDataType(), IO->getComponentDataType()) != 0) {
981                         continue;
982                       }
983
984                       vtkMapper*       aMapper;
985                       vtkVolumeMapper* aVolumeMapper;
986                       vtkDataSet*      aDataSet;
987                       
988                       if ( (aMapper = vtkMapper::SafeDownCast(aMapper3D)) != NULL ) {
989                         aDataSet = aMapper->GetInput();
990                       } else if ((aVolumeMapper = vtkVolumeMapper::SafeDownCast(aMapper3D)) != NULL ){
991                         aDataSet = aVolumeMapper->GetInput();
992                       } else {
993                         continue;
994                       }
995                       if (aDataSet) {
996                         for (int i=0; i < aDataSet->GetNumberOfPoints(); i++) {
997                           float* aPoint;
998                           aPoint = aDataSet->GetPoint(i);
999                           if (IsInRect(aPoint,  x1, y1, x2, y2)) {
1000                             float aDisp[3];
1001                             ComputeWorldToDisplay(aPoint[0],
1002                                                   aPoint[1],
1003                                                   aPoint[2], aDisp);
1004                             aPointPicker->Pick(aDisp[0], aDisp[1], 0.0, CurrentRenderer);
1005                             if ( aPointPicker->GetPointId() >= 0) { // && (!aSel->IsIndexSelected(IO, aPointPicker->GetPointId()))) {
1006                               aSel->AddOrRemoveIndex(IO, aPointPicker->GetPointId(), true, false);
1007                               aSel->AddIObject(IO, false);
1008                             }
1009                           }
1010                         }
1011                       }
1012                     }
1013                   }
1014                 }
1015               }
1016             }
1017             break;
1018           case 2: // edges selection
1019           case 3: // triangles selection
1020             {
1021               if (! rwi->GetPicker()->IsA("vtkCellPicker") ) break;
1022               vtkCellPicker* aCellPicker = vtkCellPicker::SafeDownCast(rwi->GetPicker());
1023               vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
1024               aListActors->InitTraversal();
1025               vtkActor* aActor;
1026               for (int k = 0; k < aListActors->GetNumberOfItems(); k++) {
1027                 aActor = aListActors->GetNextActor();
1028                 if (aActor != NULL) {
1029                   if (aActor->GetVisibility() == 0) 
1030                     continue;
1031                   vtkAbstractMapper3D* aMapper3D = aActor->GetMapper();
1032                   if ((aMapper3D != NULL) && (aActor->IsA("SALOME_Actor"))) {
1033                     SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor);
1034
1035                     if ((SActor != NULL) && (SActor->hasIO())) {
1036                       Handle(SALOME_InteractiveObject) IO = SActor->getIO();
1037                       if (IO.IsNull()) 
1038                         continue;
1039                       if (aSelActiveCompOnly && 
1040                               strcmp(aActiveComponent->ComponentDataType(), IO->getComponentDataType()) != 0) {
1041                         continue;
1042                       }
1043
1044                       vtkMapper*       aMapper;
1045                       vtkVolumeMapper* aVolumeMapper;
1046                       vtkDataSet*      aDataSet;
1047                       
1048                       if ( (aMapper = vtkMapper::SafeDownCast(aMapper3D)) != NULL ) {
1049                         aDataSet = aMapper->GetInput();
1050                       } else if ((aVolumeMapper = vtkVolumeMapper::SafeDownCast(aMapper3D)) != NULL ){
1051                         aDataSet = aVolumeMapper->GetInput();
1052                       } else {
1053                         continue;
1054                       }
1055                       if (aDataSet) {
1056                         for (int i=0; i < aDataSet->GetNumberOfCells(); i++) {
1057                           vtkCell* aCell = aDataSet->GetCell(i);
1058                           if (aCell != NULL) {
1059                             if (IsInRect(aCell,  x1, y1, x2, y2)) {
1060                               float* aBounds = aCell->GetBounds();
1061                               float aCenter[3];
1062                               aCenter[0] =(aBounds[0] + aBounds[1])/2; // Center X
1063                               aCenter[1] =(aBounds[2] + aBounds[3])/2; // Center Y
1064                               aCenter[2] =(aBounds[4] + aBounds[5])/2; // Center Z
1065                               float aDisp[3];
1066                               ComputeWorldToDisplay(aCenter[0],
1067                                                     aCenter[1],
1068                                                     aCenter[2], aDisp);
1069                               aCellPicker->Pick(aDisp[0], aDisp[1], 0.0, CurrentRenderer);
1070                               if (aSelectionMode == 3) {
1071                                 if ( aCellPicker->GetCellId() >= 0 && 
1072                                     (!aSel->IsIndexSelected(IO, aCellPicker->GetCellId()))) {
1073                                   aSel->AddOrRemoveIndex( IO, aCellPicker->GetCellId(), true, false);
1074                                   aSel->AddIObject( IO, false );
1075                                 }
1076                               } else {
1077                                 vtkCell* aTriangleCell = aDataSet->GetCell(aCellPicker->GetCellId());
1078                                 vtkCell* aEdge;
1079                                 if (!aSel->IsIndexSelected(IO, aCellPicker->GetCellId())) {
1080                                   aSel->SetSelectionMode(3, true);
1081                                   aSel->AddOrRemoveIndex(IO, aCellPicker->GetCellId(), true, false);
1082                                 }
1083                                 aSel->SetSelectionMode(2, true);
1084                                 for (int i=0; i < aTriangleCell->GetNumberOfEdges(); i++) {
1085                                   aSel->AddOrRemoveIndex( IO, i, true, false);
1086                                 }
1087                                 aSel->AddIObject( IO, false );
1088                               }
1089                             }
1090                           }
1091                         }
1092                       }
1093                     }
1094                   }
1095                 }
1096               }
1097             }
1098             break;
1099           case 4: // objects selection
1100             {
1101               vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
1102               aListActors->InitTraversal();
1103               vtkActor* aActor;
1104               SALOME_ListIO aListIO;
1105               for (int k = 0; k < aListActors->GetNumberOfItems(); k++) {
1106                 aActor = aListActors->GetNextActor();
1107                 if (aActor) {
1108                   if (aActor->GetVisibility() == 0) 
1109                     continue;
1110                   if ( aActor->IsA("SALOME_Actor") ) {
1111                     SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor);
1112                     if ( aSActor->hasIO() && IsInRect(aSActor, x1, y1, x2, y2)) {   
1113                       Handle(SALOME_InteractiveObject) aIO = aSActor->getIO();
1114                       if (aIO.IsNull())
1115                         continue;
1116                       if (aSelActiveCompOnly && 
1117                               strcmp(aActiveComponent->ComponentDataType(), aIO->getComponentDataType()) != 0) {
1118                         continue;
1119                       }
1120                       if (aListIO.IsEmpty()) {
1121                         aListIO.Append( aIO );
1122                       } else {
1123                         SALOME_ListIteratorOfListIO It(aListIO);
1124                         bool isStored = false;
1125                         for(;It.More();It.Next()) {
1126                           Handle(SALOME_InteractiveObject) IOS = It.Value();
1127                           if( aIO->isSame(IOS) ) {
1128                             aIO = IOS; //Added by SRN, fix SAL1307
1129                             isStored = true;
1130                             break;
1131                           }
1132                         }
1133                         if (!isStored)
1134                           aListIO.Append( aIO );
1135                       }
1136                     }
1137                   }
1138                 }
1139               }
1140               if (!aListIO.IsEmpty()) {
1141                 SALOME_ListIteratorOfListIO It(aListIO);
1142                 for(;It.More();It.Next()) {
1143                   Handle(SALOME_InteractiveObject) IOS = It.Value();
1144                   this->PropPicked++;
1145                   aSel->AddIObject( IOS, false );
1146                 }
1147               }
1148             } // end case 4
1149           } //end switch
1150           rwi->EndPickCallback();
1151         }
1152         aActiveStudy->update3dViewers();
1153       } 
1154     } 
1155     break;
1156   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1157   case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1158   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1159   case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1160     break;
1161   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: 
1162     {
1163       int w, h, x, y;
1164       rwi->GetSize(w, h);
1165       x = myPoint.x(); 
1166       y = h - myPoint.y() - 1;
1167       Place(x, y);
1168     }
1169     break;
1170   }
1171 }
1172
1173 // called during viewer operation when user moves mouse (!put necessary processing here!)
1174 void VTKViewer_InteractorStyleSALOME::onOperation(QPoint mousePos) 
1175 {
1176   int w, h;
1177   GetInteractor()->GetSize(w, h);
1178    VTKViewer_RenderWindow* wnd = dynamic_cast< VTKViewer_RenderWindow*>(GetInteractor()->GetRenderWindow());
1179   switch (State) {
1180   case VTK_INTERACTOR_STYLE_CAMERA_PAN: 
1181     {
1182       // processing panning
1183       this->FindPokedCamera(mousePos.x(), mousePos.y());
1184       this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1185       myPoint = mousePos;
1186       break;
1187     }
1188   case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: 
1189     {    
1190       // processing zooming
1191       this->FindPokedCamera(mousePos.x(), mousePos.y());
1192       this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1193       myPoint = mousePos;
1194       break;
1195     }
1196   case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: 
1197     {
1198       // processing rotation
1199       this->FindPokedCamera(mousePos.x(), mousePos.y());
1200       this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1201       myPoint = mousePos;
1202       break;
1203     }
1204   case VTK_INTERACTOR_STYLE_CAMERA_SPIN: 
1205     {
1206       // processing spinning
1207       this->FindPokedCamera(mousePos.x(), mousePos.y());
1208       this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1209       myPoint = mousePos;
1210       break;
1211     }
1212   case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: 
1213     {    
1214       break;
1215     }
1216   case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1217     {
1218       if (!myCursorState)
1219         setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1220     }
1221   case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1222     {
1223       QPainter p(wnd);
1224       p.setPen(Qt::lightGray);
1225       p.setRasterOp(Qt::XorROP);
1226       p.drawRect(QRect(myPoint, myOtherPoint));
1227       myOtherPoint = mousePos;
1228       p.drawRect(QRect(myPoint, myOtherPoint));
1229       break;
1230     }
1231   }
1232   this->LastPos[0] = mousePos.x();
1233   this->LastPos[1] = h - mousePos.y() - 1;
1234 }
1235
1236 // called when user moves mouse inside viewer window and there is no active viewer operation 
1237 // (!put necessary processing here!)
1238 void VTKViewer_InteractorStyleSALOME::onCursorMove(QPoint mousePos) {
1239   // processing highlighting
1240   QAD_Study* myActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
1241   SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
1242       
1243   vtkRenderWindowInteractor *rwi = this->Interactor;
1244   int w, h, x, y;
1245   rwi->GetSize(w, h);
1246   x = mousePos.x(); y = h - mousePos.y() - 1;
1247
1248   this->FindPokedRenderer(x,y);
1249   rwi->StartPickCallback();
1250   rwi->GetPicker()->Pick(x, y, 0.0, this->CurrentRenderer);
1251
1252   if ( rwi->GetPicker()->IsA("vtkPicker") ) {
1253     vtkPicker* picker = vtkPicker::SafeDownCast(rwi->GetPicker());
1254     vtkActor* ac = picker->GetActor();
1255     
1256     if ( ac != NULL ) {
1257       if ( ac->IsA("SALOME_Actor") ) {
1258         SALOME_Actor* SActor = SALOME_Actor::SafeDownCast( ac );
1259         if ( preview != SActor ) {
1260           if ( preview != NULL ) {
1261             preview->SetPreSelected( false );
1262           }
1263           preview = SActor;
1264               
1265           if ( SActor->hasIO() ) {
1266             Handle( SALOME_InteractiveObject) IO = SActor->getIO();
1267
1268             SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
1269             Standard_Boolean IsSelected = false;
1270             for(;It.More();It.Next()) {
1271               Handle(SALOME_InteractiveObject) IOS = It.Value();
1272               if(IO->isSame(IOS)) {
1273                 IsSelected = true;
1274                 break;
1275               }
1276             }
1277
1278             if ( !IsSelected ) {
1279             // Find All actors with same IO
1280               vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1281               theActors->InitTraversal();
1282               vtkActor *ac = theActors->GetNextActor();
1283               while( ac ) {
1284                 if ( ac->IsA("SALOME_Actor") ) {
1285                   SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
1286                   if ( anActor->hasIO() ) {
1287                     Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
1288                     if(IO->isSame(IOS)) {
1289                       anActor->SetPreSelected( true );
1290                     }
1291                   }
1292                 }
1293                 ac = theActors->GetNextActor();
1294               }
1295               // MESSAGE ( " NAME PREVIEW " << SActor->getName() );
1296             }
1297           }
1298         }
1299       }
1300     } else {
1301       preview = NULL;
1302       vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1303       theActors->InitTraversal();
1304       vtkActor *ac = theActors->GetNextActor();
1305       while( ac ) {
1306         if ( ac->IsA("SALOME_Actor") ) {
1307           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
1308           anActor->SetPreSelected( false );
1309         }
1310         ac = theActors->GetNextActor();
1311       }
1312     }
1313   }
1314   this->LastPos[0] = x;
1315   this->LastPos[1] = y;
1316 }
1317
1318 // called on finsh GlobalPan operation 
1319 void VTKViewer_InteractorStyleSALOME::Place(const int theX, const int theY) 
1320 {
1321   if (this->CurrentRenderer == NULL) {
1322     return;
1323   }
1324
1325   //translate view
1326   int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
1327   int centerX = aSize[0]/2;
1328   int centerY = aSize[1]/2;
1329
1330   TranslateView(centerX, centerY, theX, theY);
1331
1332   // restore zoom scale
1333   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1334   cam->SetParallelScale(myScale);
1335   this->CurrentRenderer->ResetCameraClippingRange();
1336
1337   if (this->CurrentLight) {
1338     this->CurrentLight->SetPosition(cam->GetPosition());
1339     this->CurrentLight->SetFocalPoint(cam->GetFocalPoint());
1340   }
1341   VTKViewer_RenderWindow* aRW = dynamic_cast<VTKViewer_RenderWindow*>(this->Interactor->GetRenderWindow());
1342   if (aRW) aRW->updateGL();
1343 }
1344
1345
1346
1347 // Translates view from Point to Point
1348 void VTKViewer_InteractorStyleSALOME::TranslateView(int toX, int toY, int fromX, int fromY)
1349 {
1350   vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1351   double viewFocus[4], focalDepth, viewPoint[3];
1352   float newPickPoint[4], oldPickPoint[4], motionVector[3];
1353   cam->GetFocalPoint(viewFocus);
1354
1355   this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1356                               viewFocus[2], viewFocus);
1357   focalDepth = viewFocus[2];
1358
1359   this->ComputeDisplayToWorld(double(toX), double(toY),
1360                               focalDepth, newPickPoint);
1361   this->ComputeDisplayToWorld(double(fromX),double(fromY),
1362                               focalDepth, oldPickPoint);
1363   
1364   // camera motion is reversed
1365   motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1366   motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1367   motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1368   
1369   cam->GetFocalPoint(viewFocus);
1370   cam->GetPosition(viewPoint);
1371   cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1372                      motionVector[1] + viewFocus[1],
1373                      motionVector[2] + viewFocus[2]);
1374   cam->SetPosition(motionVector[0] + viewPoint[0],
1375                    motionVector[1] + viewPoint[1],
1376                    motionVector[2] + viewPoint[2]);
1377 }
1378
1379
1380 /// Checks: is the given Actor within display coordinates?
1381 bool VTKViewer_InteractorStyleSALOME::IsInRect(vtkActor* theActor, 
1382                                                const int left, const int top, 
1383                                                const int right, const int bottom)
1384 {
1385   float* aBounds = theActor->GetBounds();
1386   float aMin[3], aMax[3];
1387   ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1388   ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1389   if (aMin[0] > aMax[0]) {
1390     float aBuf = aMin[0];
1391     aMin[0] = aMax[0];
1392     aMax[0] = aBuf;
1393   }
1394   if (aMin[1] > aMax[1]) {
1395     float aBuf = aMin[1];
1396     aMin[1] = aMax[1];
1397     aMax[1] = aBuf;    
1398   }
1399
1400   return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1401 }
1402
1403
1404 /// Checks: is the given Cell within display coordinates?
1405 bool VTKViewer_InteractorStyleSALOME::IsInRect(vtkCell* theCell, 
1406                                                const int left, const int top, 
1407                                                const int right, const int bottom)
1408 {
1409   float* aBounds = theCell->GetBounds();
1410   float aMin[3], aMax[3];
1411   ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1412   ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1413   if (aMin[0] > aMax[0]) {
1414     float aBuf = aMin[0];
1415     aMin[0] = aMax[0];
1416     aMax[0] = aBuf;
1417   }
1418   if (aMin[1] > aMax[1]) {
1419     float aBuf = aMin[1];
1420     aMin[1] = aMax[1];
1421     aMax[1] = aBuf;    
1422   }
1423
1424   return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1425 }
1426
1427
1428 bool VTKViewer_InteractorStyleSALOME::IsInRect(float* thePoint, 
1429                                                const int left, const int top, 
1430                                                const int right, const int bottom)
1431 {
1432   float aPnt[3];
1433   ComputeWorldToDisplay(thePoint[0], thePoint[1], thePoint[2], aPnt);
1434
1435   return ((aPnt[0]>left) && (aPnt[0]<right) && (aPnt[1]>bottom) && (aPnt[1]<top));
1436 }