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