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