1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SVTK_InteractorStyle.cxx
25 // Author : Christophe ATTANASIO
30 #include "SVTK_InteractorStyle.h"
32 #include "utilities.h"
34 #include "VTKViewer_CellRectPicker.h"
35 #include "VTKViewer_Utilities.h"
36 #include "VTKViewer_RectPicker.h"
38 #include "SVTK_RenderWindowInteractor.h"
39 #include "SVTK_RenderWindow.h"
40 #include "SVTK_ViewWindow.h"
42 #include "SALOME_Actor.h"
43 #include "SVTK_Actor.h"
44 #include "SVTK_Selector.h"
46 #include "SALOME_ListIteratorOfListIO.hxx"
47 #include "SALOME_ListIO.hxx"
49 #include "SUIT_Session.h"
50 #include "CAM_Application.h"
52 #include <vtkObjectFactory.h>
54 #include <vtkCommand.h>
55 #include <vtkCamera.h>
56 #include <vtkRenderer.h>
57 #include <vtkPicker.h>
58 #include <vtkPointPicker.h>
59 #include <vtkCellPicker.h>
61 #include <vtkMapper.h>
62 #include <vtkDataSet.h>
63 #include <vtkSmartPointer.h>
64 #include <vtkRenderWindow.h>
66 #include <qapplication.h>
67 //VRV: porting on Qt 3.0.5
68 #if QT_VERSION >= 0x030005
71 //VRV: porting on Qt 3.0.5
78 static int MYDEBUG = 0;
80 static int MYDEBUG = 0;
86 GetEdgeId(vtkPicker *thePicker, SALOME_Actor *theActor, int theObjId)
89 if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
90 float aPickPosition[3];
91 thePicker->GetPickPosition(aPickPosition);
92 float aMinDist = 1000000.0, aDist = 0;
93 for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
94 if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
95 int subId; float pcoords[3], closestPoint[3], weights[3];
96 aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
97 if (aDist < aMinDist) {
109 bool CheckDimensionId(Selection_Mode theMode, SALOME_Actor *theActor, vtkIdType theObjId){
114 return ( theActor->GetObjDimension( theObjId ) == 1 );
116 return ( theActor->GetObjDimension( theObjId ) == 2 );
117 case VolumeSelection:
118 return ( theActor->GetObjDimension( theObjId ) == 3 );
124 //----------------------------------------------------------------------------
125 vtkStandardNewMacro(SVTK_InteractorStyle);
126 //----------------------------------------------------------------------------
129 ::SVTK_InteractorStyle()
132 this->MotionFactor = 10.0;
133 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
134 this->RadianToDegree = 180.0 / vtkMath::Pi();
135 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
138 myPreSelectionActor = SVTK_Actor::New();
139 myPreSelectionActor->GetProperty()->SetColor(0,1,1);
140 myPreSelectionActor->GetProperty()->SetLineWidth(5);
141 myPreSelectionActor->GetProperty()->SetPointSize(5);
143 OnSelectionModeChanged();
146 //----------------------------------------------------------------------------
148 ::~SVTK_InteractorStyle()
150 if(MYDEBUG) INFOS("SVTK_InteractorStyle::~SVTK_InteractorStyle()");
151 myViewWindow->RemoveActor(myPreSelectionActor);
154 //----------------------------------------------------------------------------
159 return myViewWindow->GetSelector();
162 //----------------------------------------------------------------------------
165 ::setPreselectionProp(const double& theRed,
166 const double& theGreen,
167 const double& theBlue,
170 if ( myPreSelectionActor->GetProperty() == 0 )
172 myPreSelectionActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
173 myPreSelectionActor->GetProperty()->SetLineWidth(theWidth);
174 myPreSelectionActor->GetProperty()->SetPointSize(theWidth);
177 //----------------------------------------------------------------------------
180 ::SetInteractor(vtkRenderWindowInteractor *theInteractor)
182 myInteractor = dynamic_cast<SVTK_RenderWindowInteractor*>(theInteractor);
183 Superclass::SetInteractor(theInteractor);
186 //----------------------------------------------------------------------------
191 return State | ForcedState;
194 //----------------------------------------------------------------------------
197 ::setViewWindow(SVTK_ViewWindow* theViewWindow)
199 myViewWindow = theViewWindow;
200 myViewWindow->AddActor(myPreSelectionActor);
201 myPreSelectionActor->Delete();
204 //----------------------------------------------------------------------------
207 ::setGUIWindow(QWidget* theWindow)
209 myGUIWindow = theWindow;
212 //----------------------------------------------------------------------------
215 ::RotateXY(int dx, int dy)
221 if (this->CurrentRenderer == NULL)
226 int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
227 this->DeltaElevation = -20.0 / size[1];
228 this->DeltaAzimuth = -20.0 / size[0];
230 rxf = (double)dx * this->DeltaAzimuth * this->MotionFactor;
231 ryf = (double)dy * this->DeltaElevation * this->MotionFactor;
233 cam = this->CurrentRenderer->GetActiveCamera();
236 cam->OrthogonalizeViewUp();
237 ::ResetCameraClippingRange(this->CurrentRenderer);
238 //this->Interactor->Render();
239 myGUIWindow->update();
242 //----------------------------------------------------------------------------
245 ::PanXY(int x, int y, int oldX, int oldY)
247 TranslateView(x, y, oldX, oldY);
248 //this->Interactor->Render();
249 myGUIWindow->update();
253 //----------------------------------------------------------------------------
256 ::DollyXY(int dx, int dy)
258 if (this->CurrentRenderer == NULL) return;
260 double dxf = this->MotionFactor * (double)(dx) / (double)(this->CurrentRenderer->GetCenter()[1]);
261 double dyf = this->MotionFactor * (double)(dy) / (double)(this->CurrentRenderer->GetCenter()[1]);
263 double zoomFactor = pow((double)1.1, dxf + dyf);
265 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
266 if (aCam->GetParallelProjection())
267 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
269 aCam->Dolly(zoomFactor);
270 ::ResetCameraClippingRange(this->CurrentRenderer);
273 //this->Interactor->Render();
274 myGUIWindow->update();
277 //----------------------------------------------------------------------------
280 ::SpinXY(int x, int y, int oldX, int oldY)
284 if (this->CurrentRenderer == NULL)
289 double newAngle = atan2((double)(y - this->CurrentRenderer->GetCenter()[1]),
290 (double)(x - this->CurrentRenderer->GetCenter()[0]));
291 double oldAngle = atan2((double)(oldY -this->CurrentRenderer->GetCenter()[1]),
292 (double)(oldX - this->CurrentRenderer->GetCenter()[0]));
294 newAngle *= this->RadianToDegree;
295 oldAngle *= this->RadianToDegree;
297 cam = this->CurrentRenderer->GetActiveCamera();
298 cam->Roll(newAngle - oldAngle);
299 cam->OrthogonalizeViewUp();
301 //this->Interactor->Render();
302 myGUIWindow->update();
306 //----------------------------------------------------------------------------
309 ::OnMouseMove(int vtkNotUsed(ctrl),
313 myShiftState = shift;
314 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
315 onOperation(QPoint(x, y));
316 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
317 onCursorMove(QPoint(x, y));
321 //----------------------------------------------------------------------------
324 ::OnLeftButtonDown(int ctrl, int shift,
327 if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) {
328 this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
331 this->FindPokedRenderer(x, y);
332 if (this->CurrentRenderer == NULL) {
335 myShiftState = shift;
336 // finishing current viewer operation
337 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
339 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
341 myOtherPoint = myPoint = QPoint(x, y);
342 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
343 startOperation(ForcedState);
346 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
348 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
354 //----------------------------------------------------------------------------
357 ::OnLeftButtonUp(int vtkNotUsed(ctrl),
362 myShiftState = shift;
363 // finishing current viewer operation
364 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
366 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
371 //----------------------------------------------------------------------------
374 ::OnMiddleButtonDown(int ctrl,
378 if (this->HasObserver(vtkCommand::MiddleButtonPressEvent))
380 this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
383 this->FindPokedRenderer(x, y);
384 if (this->CurrentRenderer == NULL)
388 myShiftState = shift;
389 // finishing current viewer operation
390 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
392 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
394 myOtherPoint = myPoint = QPoint(x, y);
395 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
396 startOperation(ForcedState);
400 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
405 //----------------------------------------------------------------------------
408 ::OnMiddleButtonUp(int vtkNotUsed(ctrl),
413 myShiftState = shift;
414 // finishing current viewer operation
415 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
417 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
422 //----------------------------------------------------------------------------
425 ::OnRightButtonDown(int ctrl,
429 if (this->HasObserver(vtkCommand::RightButtonPressEvent))
431 this->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
434 this->FindPokedRenderer(x, y);
435 if (this->CurrentRenderer == NULL)
439 myShiftState = shift;
440 // finishing current viewer operation
441 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
443 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
445 myOtherPoint = myPoint = QPoint(x, y);
446 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
447 startOperation(ForcedState);
451 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
455 //----------------------------------------------------------------------------
458 ::OnRightButtonUp(int vtkNotUsed(ctrl),
463 myShiftState = shift;
464 // finishing current viewer operation
465 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
467 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
471 //----------------------------------------------------------------------------
473 const char* imageZoomCursor[] = {
478 "................................",
479 "................................",
480 ".#######........................",
481 "..aaaaaaa.......................",
482 "................................",
483 ".............#####..............",
484 "...........##.aaaa##............",
485 "..........#.aa.....a#...........",
486 ".........#.a.........#..........",
487 ".........#a..........#a.........",
488 "........#.a...........#.........",
489 "........#a............#a........",
490 "........#a............#a........",
491 "........#a............#a........",
492 "........#a............#a........",
493 ".........#...........#.a........",
494 ".........#a..........#a.........",
495 ".........##.........#.a.........",
496 "........#####.....##.a..........",
497 ".......###aaa#####.aa...........",
498 "......###aa...aaaaa.......#.....",
499 ".....###aa................#a....",
500 "....###aa.................#a....",
501 "...###aa...............#######..",
502 "....#aa.................aa#aaaa.",
503 ".....a....................#a....",
504 "..........................#a....",
505 "...........................a....",
506 "................................",
507 "................................",
508 "................................",
509 "................................"};
511 const char* imageRotateCursor[] = {
516 "................................",
517 "................................",
518 "................................",
519 "................................",
520 "........#.......................",
521 ".......#.a......................",
522 "......#######...................",
523 ".......#aaaaa#####..............",
524 "........#..##.a#aa##........##..",
525 ".........a#.aa..#..a#.....##.aa.",
526 ".........#.a.....#...#..##.aa...",
527 ".........#a.......#..###.aa.....",
528 "........#.a.......#a..#aa.......",
529 "........#a.........#..#a........",
530 "........#a.........#a.#a........",
531 "........#a.........#a.#a........",
532 "........#a.........#a.#a........",
533 ".........#.........#a#.a........",
534 "........##a........#a#a.........",
535 "......##.a#.......#.#.a.........",
536 "....##.aa..##.....##.a..........",
537 "..##.aa.....a#####.aa...........",
538 "...aa.........aaa#a.............",
539 "................#.a.............",
540 "...............#.a..............",
541 "..............#.a...............",
542 "...............a................",
543 "................................",
544 "................................",
545 "................................",
546 "................................",
547 "................................"};
550 //----------------------------------------------------------------------------
551 // loads cursors for viewer operations - zoom, pan, etc...
556 myDefCursor = QCursor(ArrowCursor);
557 myHandCursor = QCursor(PointingHandCursor);
558 myPanCursor = QCursor(SizeAllCursor);
559 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
560 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
561 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
562 myGlobalPanCursor = QCursor(CrossCursor);
563 myCursorState = false;
567 //----------------------------------------------------------------------------
568 // event filter - controls mouse and keyboard events during viewer operations
571 ::eventFilter(QObject* object, QEvent* event)
573 if (!myGUIWindow) return false;
574 if ( (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress) && object != myGUIWindow)
576 qApp->removeEventFilter(this);
577 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
579 return QObject::eventFilter(object, event);
583 //----------------------------------------------------------------------------
584 // starts Zoom operation (e.g. through menu command)
589 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
592 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
594 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
595 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
596 qApp->installEventFilter(this);
600 //----------------------------------------------------------------------------
601 // starts Pan operation (e.g. through menu command)
606 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
609 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
611 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
612 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
613 qApp->installEventFilter(this);
616 //----------------------------------------------------------------------------
617 // starts Rotate operation (e.g. through menu command)
622 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
625 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
627 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
628 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
629 qApp->installEventFilter(this);
633 //----------------------------------------------------------------------------
634 // starts Spin operation (e.g. through menu command)
639 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
642 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
644 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
645 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
646 qApp->installEventFilter(this);
651 //----------------------------------------------------------------------------
652 // starts Fit Area operation (e.g. through menu command)
657 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
660 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
662 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
663 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
664 qApp->installEventFilter(this);
668 //----------------------------------------------------------------------------
669 // starts Global Panning operation (e.g. through menu command)
674 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
677 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
679 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
680 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
682 // store current zoom scale
683 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
684 myScale = cam->GetParallelScale();
686 if (myViewWindow) myViewWindow->onFitAll();
688 if (myGUIWindow) myGUIWindow->update();
690 qApp->installEventFilter(this);
694 //----------------------------------------------------------------------------
695 // returns TRUE if needs redrawing
700 return State == VTK_INTERACTOR_STYLE_CAMERA_ZOOM ||
701 State == VTK_INTERACTOR_STYLE_CAMERA_PAN ||
702 State == VTK_INTERACTOR_STYLE_CAMERA_ROTATE ||
703 State == VTK_INTERACTOR_STYLE_CAMERA_SPIN ||
704 State == VTK_INTERACTOR_STYLE_CAMERA_NONE;
708 //----------------------------------------------------------------------------
709 // fits viewer contents to rect
712 ::fitRect(const int left,
717 if (this->CurrentRenderer == NULL) return;
720 int x = (left + right)/2;
721 int y = (top + bottom)/2;
722 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
723 int oldX = aSize[0]/2;
724 int oldY = aSize[1]/2;
725 TranslateView(oldX, oldY, x, y);
728 double dxf = (double)(aSize[0]) / (double)(abs(right - left));
729 double dyf = (double)(aSize[1]) / (double)(abs(bottom - top));
730 double zoomFactor = (dxf + dyf)/2 ;
732 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
733 if(aCam->GetParallelProjection())
734 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
736 aCam->Dolly(zoomFactor);
737 ::ResetCameraClippingRange(this->CurrentRenderer);
740 myGUIWindow->update();
744 //----------------------------------------------------------------------------
745 // starts viewer operation (!internal usage!)
748 ::startOperation(int operation)
752 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
753 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
754 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
755 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
756 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
757 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
758 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
759 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
760 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
762 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
763 setCursor(operation);
766 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
768 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
769 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
775 //----------------------------------------------------------------------------
776 // sets proper cursor for window when viewer operation is activated
779 ::setCursor(const int operation)
781 if (!myGUIWindow) return;
784 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
785 myGUIWindow->setCursor(myZoomCursor);
786 myCursorState = true;
788 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
789 myGUIWindow->setCursor(myPanCursor);
790 myCursorState = true;
792 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
793 myGUIWindow->setCursor(myRotateCursor);
794 myCursorState = true;
796 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
797 myGUIWindow->setCursor(mySpinCursor);
798 myCursorState = true;
800 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
801 myGUIWindow->setCursor(myGlobalPanCursor);
802 myCursorState = true;
804 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
805 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
806 myGUIWindow->setCursor(myHandCursor);
807 myCursorState = true;
809 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
811 myGUIWindow->setCursor(myDefCursor);
812 myCursorState = false;
818 //----------------------------------------------------------------------------
819 // called when viewer operation started (!put necessary initialization here!)
824 if (!myGUIWindow) return;
825 // VSV: LOD actor activisation
826 // this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
828 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
829 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
831 QPainter p(myGUIWindow);
832 p.setPen(Qt::lightGray);
833 p.setRasterOp(Qt::XorROP);
834 p.drawRect(QRect(myPoint, myOtherPoint));
837 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
838 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
839 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
840 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
841 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
847 //----------------------------------------------------------------------------
848 // called when viewer operation finished (!put necessary post-processing here!)
851 ::onFinishOperation()
856 // VSV: LOD actor activisation
857 // rwi->GetRenderWindow()->SetDesiredUpdateRate(rwi->GetStillUpdateRate());
859 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
860 bool aSelActiveCompOnly = false;
862 QString aComponentDataType;
863 if(SUIT_Session* aSession = SUIT_Session::session())
864 if(SUIT_Application* aSUITApp = aSession->activeApplication())
865 if(CAM_Application* aCAMApp = dynamic_cast<CAM_Application*>(aSUITApp))
866 if(CAM_Module* aModule = aCAMApp->activeModule())
867 aComponentDataType = aModule->name();
870 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
871 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
873 QPainter p(myGUIWindow);
874 p.setPen(Qt::lightGray);
875 p.setRasterOp(Qt::XorROP);
876 QRect rect(myPoint, myOtherPoint);
878 rect = rect.normalize();
879 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
880 // making fit rect opeation
882 myInteractor->GetSize(w, h);
885 y1 = h - rect.top() - 1;
887 y2 = h - rect.bottom() - 1;
888 fitRect(x1, y1, x2, y2);
891 if (myPoint == myOtherPoint) {
892 // process point selection
894 myInteractor->GetSize(w, h);
896 y = h - myPoint.y() - 1;
898 this->FindPokedRenderer(x, y);
899 myInteractor->StartPickCallback();
901 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
902 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
904 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
906 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
907 int aVtkId = picker->GetCellId();
908 if ( aVtkId >= 0 && aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
909 int anObjId = aSActor->GetElemObjId(aVtkId);
911 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
912 if(aSelectionMode != EdgeOfCellSelection) {
913 if(CheckDimensionId(aSelectionMode,aSActor,anObjId)){
914 if(MYDEBUG) INFOS(" CellId : "<<anObjId);
915 if (GetSelector()->IsSelected(anIO)) {
916 // This IO is already in the selection
917 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
920 this->HighlightProp( NULL );
921 GetSelector()->ClearIObjects();
923 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
924 GetSelector()->AddIObject(aSActor);
929 this->HighlightProp( NULL );
930 GetSelector()->ClearIObjects();
932 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
934 if(MYDEBUG) INFOS(" CellId : "<<anObjId<<"; EdgeId : "<<anEdgeId);
935 GetSelector()->AddOrRemoveIndex(anIO,anObjId,false);
936 GetSelector()->AddOrRemoveIndex(anIO,-anEdgeId-1,true);
937 GetSelector()->AddIObject(aSActor);
942 this->HighlightProp( NULL );
943 GetSelector()->ClearIObjects();
945 } else if ( vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker) ) {
946 int aVtkId = picker->GetPointId();
947 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
948 if ( aSActor && aSActor->hasIO() ) {
949 int anObjId = aSActor->GetNodeObjId(aVtkId);
951 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
952 if(GetSelector()->IsSelected(anIO)) {
953 // This IO is already in the selection
954 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
957 this->HighlightProp( NULL );
958 GetSelector()->ClearIObjects();
960 if(MYDEBUG) INFOS(" PointId : "<<anObjId);
961 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
962 GetSelector()->AddIObject(aSActor);
967 this->HighlightProp( NULL );
968 GetSelector()->ClearIObjects();
971 if ( aSActor && aSActor->hasIO() ) {
973 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
974 if(GetSelector()->IsSelected(anIO)) {
975 // This IO is already in the selection
977 GetSelector()->RemoveIObject(aSActor);
982 this->HighlightProp( NULL );
983 GetSelector()->ClearIObjects();
985 GetSelector()->AddIObject(aSActor);
988 // No selection clear all
989 this->PropPicked = 0;
990 this->HighlightProp( NULL );
991 GetSelector()->ClearIObjects();
994 myInteractor->EndPickCallback();
996 //processing rectangle selection
997 if(aSelActiveCompOnly && aComponentDataType.isEmpty()) return;
998 myInteractor->StartPickCallback();
1000 if (!myShiftState) {
1001 this->PropPicked = 0;
1002 this->HighlightProp( NULL );
1003 GetSelector()->ClearIObjects();
1007 // vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1008 QRect rect(myPoint, myOtherPoint);
1009 rect = rect.normalize();
1011 myInteractor->GetSize(w, h);
1014 y1 = h - rect.top() - 1;
1016 y2 = h - rect.bottom() - 1;
1018 switch (aSelectionMode) {
1019 case NodeSelection: {
1020 if ( vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(myInteractor->GetPicker()) ) {
1021 vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
1022 aListActors->InitTraversal();
1023 while (vtkActor* aActor = aListActors->GetNextActor()) {
1024 if (!aActor->GetVisibility())
1026 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1027 if (aSActor->hasIO()) {
1028 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1031 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1033 if (vtkDataSet* aDataSet = aSActor->GetInput()) {
1034 TColStd_MapOfInteger anIndices;
1035 for(int i = 0; i < aDataSet->GetNumberOfPoints(); i++) {
1037 aDataSet->GetPoint(i,aPoint);
1038 if (IsInRect(aPoint,x1,y1,x2,y2)){
1040 ComputeWorldToDisplay(aPoint[0],aPoint[1],aPoint[2],aDisp);
1041 if(aPointPicker->Pick(aDisp[0],aDisp[1],0.0,CurrentRenderer)){
1042 if(vtkActorCollection *anActorCollection = aPointPicker->GetActors()){
1043 if(anActorCollection->IsItemPresent(aSActor)){
1044 float aPickedPoint[3];
1045 aPointPicker->GetMapperPosition(aPickedPoint);
1046 vtkIdType aVtkId = aDataSet->FindPoint(aPickedPoint);
1047 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ){
1048 int anObjId = aSActor->GetNodeObjId(aVtkId);
1049 anIndices.Add(anObjId);
1056 if (!anIndices.IsEmpty()) {
1057 GetSelector()->AddOrRemoveIndex(anIO,anIndices,false);
1058 GetSelector()->AddIObject(aSActor);
1061 GetSelector()->RemoveIObject(aSActor);
1071 case EdgeOfCellSelection:
1074 case VolumeSelection:
1076 vtkSmartPointer<VTKViewer_CellRectPicker> picker = VTKViewer_CellRectPicker::New();
1077 picker->SetTolerance(0.001);
1078 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1080 vtkActorCollection* aListActors = picker->GetActors();
1081 aListActors->InitTraversal();
1082 while(vtkActor* aActor = aListActors->GetNextActor()) {
1083 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1084 if (aSActor->hasIO()) {
1085 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1086 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1088 VTKViewer_CellDataSet cellList = picker->GetCellData(aActor);
1089 if ( !cellList.empty() ) {
1090 if(MYDEBUG) INFOS ( " NAME Actor : " << aSActor->getName() );
1091 TColStd_MapOfInteger anIndexes;
1092 VTKViewer_CellDataSet::iterator it;
1093 for ( it = cellList.begin(); it != cellList.end(); ++it ) {
1094 int aCellId = (*it).cellId;
1096 if ( !IsValid( aSActor, aCellId ) )
1099 int anObjId = aSActor->GetElemObjId(aCellId);
1101 if ( CheckDimensionId(aSelectionMode,aSActor,anObjId) ) {
1102 anIndexes.Add(anObjId);
1106 GetSelector()->AddOrRemoveIndex(anIO,anIndexes,true);
1107 GetSelector()->AddIObject(aSActor);
1114 case ActorSelection: // objects selection
1116 vtkSmartPointer<VTKViewer_RectPicker> picker = VTKViewer_RectPicker::New();
1117 picker->SetTolerance(0.001);
1118 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1120 vtkActorCollection* aListActors = picker->GetActors();
1121 aListActors->InitTraversal();
1122 while(vtkActor* aActor = aListActors->GetNextActor()) {
1123 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1124 if (aSActor->hasIO()) {
1125 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1126 GetSelector()->AddIObject(aSActor);
1133 myInteractor->EndPickCallback();
1135 myViewWindow->onSelectionChanged();
1139 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1140 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1141 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1142 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1144 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1147 myInteractor->GetSize(w, h);
1149 y = h - myPoint.y() - 1;
1154 if (myGUIWindow) myGUIWindow->update();
1159 // called during viewer operation when user moves mouse (!put necessary processing here!)
1161 SVTK_InteractorStyle
1162 ::onOperation(QPoint mousePos)
1164 if (!myGUIWindow) return;
1166 GetInteractor()->GetSize(w, h);
1168 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1170 // processing panning
1171 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1172 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1176 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1178 // processing zooming
1179 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1180 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1184 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1186 // processing rotation
1187 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1188 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1192 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1194 // processing spinning
1195 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1196 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1200 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1204 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1207 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1209 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1211 QPainter p(myGUIWindow);
1212 p.setPen(Qt::lightGray);
1213 p.setRasterOp(Qt::XorROP);
1214 p.drawRect(QRect(myPoint, myOtherPoint));
1215 myOtherPoint = mousePos;
1216 p.drawRect(QRect(myPoint, myOtherPoint));
1220 this->LastPos[0] = mousePos.x();
1221 this->LastPos[1] = h - mousePos.y() - 1;
1224 // called when selection mode changed (!put necessary initialization here!)
1226 SVTK_InteractorStyle
1227 ::OnSelectionModeChanged()
1230 myPreSelectionActor->SetVisibility(false);
1231 myElemId = myEdgeId = myNodeId = -1;
1232 mySelectedActor = NULL;
1235 // called when user moves mouse inside viewer window and there is no active viewer operation
1236 // (!put necessary processing here!)
1238 SVTK_InteractorStyle
1239 ::onCursorMove(QPoint mousePos)
1241 // processing highlighting
1242 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
1245 myInteractor->GetSize(w, h);
1246 x = mousePos.x(); y = h - mousePos.y() - 1;
1248 this->FindPokedRenderer(x,y);
1249 myInteractor->StartPickCallback();
1250 myPreSelectionActor->SetVisibility(false);
1252 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
1253 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
1255 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
1257 if (aSActor && myPreSelectionActor){
1259 aSActor->GetPosition(aPos);
1260 myPreSelectionActor->SetPosition(aPos);
1263 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
1264 int aVtkId = picker->GetCellId();
1265 if ( aVtkId >= 0 ) {
1266 int anObjId = aSActor->GetElemObjId(aVtkId);
1267 if ( aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
1268 bool anIsSameObjId = (mySelectedActor == aSActor && myElemId == anObjId);
1269 bool aResult = anIsSameObjId;
1270 if(!anIsSameObjId) {
1271 if(aSelectionMode != EdgeOfCellSelection) {
1272 aResult = CheckDimensionId(aSelectionMode,aSActor,anObjId);
1274 mySelectedActor = aSActor;
1276 if(MYDEBUG) INFOS(" CellId : "<<anObjId);
1277 myInteractor->setCellData(anObjId,aSActor,myPreSelectionActor);
1281 if(aSelectionMode == EdgeOfCellSelection){
1282 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
1283 bool anIsSameEdgeId = (myEdgeId != anEdgeId) && anIsSameObjId;
1284 aResult = anIsSameEdgeId;
1285 if(!anIsSameEdgeId) {
1286 aResult = (anEdgeId >= 0);
1288 mySelectedActor = aSActor;
1289 myEdgeId = anEdgeId;
1291 if(MYDEBUG) INFOS(" CellId : "<<anObjId<<"; EdgeId : "<<anEdgeId);
1292 myInteractor->setEdgeData(anObjId,aSActor,-anEdgeId-1,myPreSelectionActor);
1297 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1298 myPreSelectionActor->SetVisibility(true);
1303 else if (vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker)) {
1304 int aVtkId = picker->GetPointId();
1305 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
1306 if ( aSActor && aSActor->hasIO() ) {
1307 int anObjId = aSActor->GetNodeObjId(aVtkId);
1308 bool anIsSameObjId = (mySelectedActor == aSActor && myNodeId == anObjId);
1309 if(!anIsSameObjId) {
1310 mySelectedActor = aSActor;
1312 if(MYDEBUG) INFOS(" PointId : "<<anObjId);
1313 myInteractor->setPointData(anObjId,aSActor,myPreSelectionActor);
1315 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1316 myPreSelectionActor->SetVisibility(true);
1320 else if ( vtkPicker::SafeDownCast(aPicker) ) {
1322 if ( myPreViewActor != aSActor ) {
1323 if ( myPreViewActor != NULL ) {
1324 myPreViewActor->SetPreSelected( false );
1326 myPreViewActor = aSActor;
1328 if ( aSActor->hasIO() ) {
1329 Handle( SALOME_InteractiveObject) IO = aSActor->getIO();
1330 if ( !GetSelector()->IsSelected(IO) ) {
1331 // Find All actors with same IO
1332 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1333 theActors->InitTraversal();
1334 while( vtkActor *ac = theActors->GetNextActor() ) {
1335 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1336 if ( anActor->hasIO() ) {
1337 Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
1338 if(IO->isSame(IOS)) {
1339 anActor->SetPreSelected( true );
1348 myPreViewActor = NULL;
1349 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1350 theActors->InitTraversal();
1351 while( vtkActor *ac = theActors->GetNextActor() ) {
1352 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1353 anActor->SetPreSelected( false );
1358 myInteractor->EndPickCallback();
1359 //myInteractor->Render();
1360 myGUIWindow->update();
1362 this->LastPos[0] = x;
1363 this->LastPos[1] = y;
1366 // called on finsh GlobalPan operation
1368 SVTK_InteractorStyle
1369 ::Place(const int theX, const int theY)
1371 if (this->CurrentRenderer == NULL) {
1376 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
1377 int centerX = aSize[0]/2;
1378 int centerY = aSize[1]/2;
1380 TranslateView(centerX, centerY, theX, theY);
1382 // restore zoom scale
1383 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1384 cam->SetParallelScale(myScale);
1385 ::ResetCameraClippingRange(this->CurrentRenderer);
1387 if (myGUIWindow) myGUIWindow->update();
1393 // Translates view from Point to Point
1395 SVTK_InteractorStyle
1396 ::TranslateView(int toX, int toY, int fromX, int fromY)
1398 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1399 double viewFocus[4], focalDepth, viewPoint[3];
1400 float newPickPoint[4], oldPickPoint[4], motionVector[3];
1401 cam->GetFocalPoint(viewFocus);
1403 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1404 viewFocus[2], viewFocus);
1405 focalDepth = viewFocus[2];
1407 this->ComputeDisplayToWorld(double(toX), double(toY),
1408 focalDepth, newPickPoint);
1409 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1410 focalDepth, oldPickPoint);
1412 // camera motion is reversed
1413 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1414 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1415 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1417 cam->GetFocalPoint(viewFocus);
1418 cam->GetPosition(viewPoint);
1419 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1420 motionVector[1] + viewFocus[1],
1421 motionVector[2] + viewFocus[2]);
1422 cam->SetPosition(motionVector[0] + viewPoint[0],
1423 motionVector[1] + viewPoint[1],
1424 motionVector[2] + viewPoint[2]);
1428 /// Checks: is the given Actor within display coordinates?
1430 SVTK_InteractorStyle
1431 ::IsInRect(vtkActor* theActor,
1432 const int left, const int top,
1433 const int right, const int bottom)
1435 float* aBounds = theActor->GetBounds();
1436 float aMin[3], aMax[3];
1437 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1438 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1439 if (aMin[0] > aMax[0]) {
1440 float aBuf = aMin[0];
1444 if (aMin[1] > aMax[1]) {
1445 float aBuf = aMin[1];
1450 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1454 /// Checks: is the given Cell within display coordinates?
1456 SVTK_InteractorStyle
1457 ::IsInRect(vtkCell* theCell,
1458 const int left, const int top,
1459 const int right, const int bottom)
1461 float* aBounds = theCell->GetBounds();
1462 float aMin[3], aMax[3];
1463 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1464 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1465 if (aMin[0] > aMax[0]) {
1466 float aBuf = aMin[0];
1470 if (aMin[1] > aMax[1]) {
1471 float aBuf = aMin[1];
1476 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1481 SVTK_InteractorStyle
1482 ::IsInRect(float* thePoint,
1483 const int left, const int top,
1484 const int right, const int bottom)
1487 ComputeWorldToDisplay(thePoint[0], thePoint[1], thePoint[2], aPnt);
1489 return ((aPnt[0]>left) && (aPnt[0]<right) && (aPnt[1]>bottom) && (aPnt[1]<top));
1493 SVTK_InteractorStyle
1494 ::SetFilter( const Handle(VTKViewer_Filter)& theFilter )
1496 myFilters[ theFilter->GetId() ] = theFilter;
1500 SVTK_InteractorStyle
1501 ::IsFilterPresent( const int theId )
1503 return myFilters.find( theId ) != myFilters.end();
1507 SVTK_InteractorStyle
1508 ::RemoveFilter( const int theId )
1510 if ( IsFilterPresent( theId ) )
1511 myFilters.erase( theId );
1516 SVTK_InteractorStyle
1517 ::IsValid( SALOME_Actor* theActor,
1519 const bool theIsNode )
1521 std::map<int, Handle(VTKViewer_Filter)>::const_iterator anIter;
1522 for ( anIter = myFilters.begin(); anIter != myFilters.end(); ++anIter )
1524 const Handle(VTKViewer_Filter)& aFilter = anIter->second;
1525 if ( theIsNode == aFilter->IsNodeFilter() &&
1526 !aFilter->IsValid( theActor, theId ) )
1532 Handle(VTKViewer_Filter)
1533 SVTK_InteractorStyle
1534 ::GetFilter( const int theId )
1536 return IsFilterPresent( theId ) ? myFilters[ theId ] : Handle(VTKViewer_Filter)();
1540 SVTK_InteractorStyle
1541 ::IncrementalPan( const int incrX, const int incrY )
1543 this->PanXY( incrX, incrY, 0, 0 );
1547 SVTK_InteractorStyle
1548 ::IncrementalZoom( const int incr )
1550 this->DollyXY( incr, incr );
1554 SVTK_InteractorStyle
1555 ::IncrementalRotate( const int incrX, const int incrY )
1557 this->RotateXY( incrX, -incrY );