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