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