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