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 "VTKViewer_CellRectPicker.h"
33 #include "VTKViewer_Utilities.h"
34 #include "VTKViewer_RectPicker.h"
36 #include "SVTK_RenderWindowInteractor.h"
37 #include "SVTK_RenderWindow.h"
38 #include "SVTK_ViewWindow.h"
40 #include "SALOME_Actor.h"
41 #include "SVTK_Actor.h"
42 #include "SVTK_Selector.h"
44 #include "SALOME_ListIteratorOfListIO.hxx"
45 #include "SALOME_ListIO.hxx"
47 #include "SUIT_Session.h"
48 #include "CAM_Application.h"
50 #include <vtkObjectFactory.h>
52 #include <vtkCommand.h>
53 #include <vtkCamera.h>
54 #include <vtkRenderer.h>
55 #include <vtkPicker.h>
56 #include <vtkPointPicker.h>
57 #include <vtkCellPicker.h>
59 #include <vtkMapper.h>
60 #include <vtkDataSet.h>
61 #include <vtkSmartPointer.h>
62 #include <vtkRenderWindow.h>
64 #include <qapplication.h>
65 //VRV: porting on Qt 3.0.5
66 #if QT_VERSION >= 0x030005
69 //VRV: porting on Qt 3.0.5
78 GetEdgeId(vtkPicker *thePicker, SALOME_Actor *theActor, int theObjId)
81 if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
82 float aPickPosition[3];
83 thePicker->GetPickPosition(aPickPosition);
84 float aMinDist = 1000000.0, aDist = 0;
85 for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
86 if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
87 int subId; float pcoords[3], closestPoint[3], weights[3];
88 aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
89 if (aDist < aMinDist) {
101 bool CheckDimensionId(Selection_Mode theMode, SALOME_Actor *theActor, vtkIdType theObjId){
106 return ( theActor->GetObjDimension( theObjId ) == 1 );
108 return ( theActor->GetObjDimension( theObjId ) == 2 );
109 case VolumeSelection:
110 return ( theActor->GetObjDimension( theObjId ) == 3 );
116 //----------------------------------------------------------------------------
117 vtkStandardNewMacro(SVTK_InteractorStyle);
118 //----------------------------------------------------------------------------
121 ::SVTK_InteractorStyle()
124 this->MotionFactor = 10.0;
125 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
126 this->RadianToDegree = 180.0 / vtkMath::Pi();
127 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
130 myPreSelectionActor = SVTK_Actor::New();
131 myPreSelectionActor->GetProperty()->SetColor(0,1,1);
132 myPreSelectionActor->GetProperty()->SetLineWidth(5);
133 myPreSelectionActor->GetProperty()->SetPointSize(5);
135 OnSelectionModeChanged();
138 //----------------------------------------------------------------------------
140 ::~SVTK_InteractorStyle()
142 myViewWindow->RemoveActor(myPreSelectionActor);
145 //----------------------------------------------------------------------------
150 return myViewWindow->GetSelector();
153 //----------------------------------------------------------------------------
156 ::setPreselectionProp(const double& theRed,
157 const double& theGreen,
158 const double& theBlue,
161 if ( myPreSelectionActor->GetProperty() == 0 )
163 myPreSelectionActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
164 myPreSelectionActor->GetProperty()->SetLineWidth(theWidth);
165 myPreSelectionActor->GetProperty()->SetPointSize(theWidth);
168 //----------------------------------------------------------------------------
171 ::SetInteractor(vtkRenderWindowInteractor *theInteractor)
173 myInteractor = dynamic_cast<SVTK_RenderWindowInteractor*>(theInteractor);
174 Superclass::SetInteractor(theInteractor);
177 //----------------------------------------------------------------------------
182 return State | ForcedState;
185 //----------------------------------------------------------------------------
188 ::setViewWindow(SVTK_ViewWindow* theViewWindow)
190 myViewWindow = theViewWindow;
191 myViewWindow->AddActor(myPreSelectionActor);
192 myPreSelectionActor->Delete();
195 //----------------------------------------------------------------------------
198 ::setGUIWindow(QWidget* theWindow)
200 myGUIWindow = theWindow;
203 //----------------------------------------------------------------------------
206 ::RotateXY(int dx, int dy)
212 if (this->CurrentRenderer == NULL)
217 int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
218 this->DeltaElevation = -20.0 / size[1];
219 this->DeltaAzimuth = -20.0 / size[0];
221 rxf = (double)dx * this->DeltaAzimuth * this->MotionFactor;
222 ryf = (double)dy * this->DeltaElevation * this->MotionFactor;
224 cam = this->CurrentRenderer->GetActiveCamera();
227 cam->OrthogonalizeViewUp();
228 ::ResetCameraClippingRange(this->CurrentRenderer);
229 //this->Interactor->Render();
230 myGUIWindow->update();
233 //----------------------------------------------------------------------------
236 ::PanXY(int x, int y, int oldX, int oldY)
238 TranslateView(x, y, oldX, oldY);
239 //this->Interactor->Render();
240 myGUIWindow->update();
244 //----------------------------------------------------------------------------
247 ::DollyXY(int dx, int dy)
249 if (this->CurrentRenderer == NULL) return;
251 double dxf = this->MotionFactor * (double)(dx) / (double)(this->CurrentRenderer->GetCenter()[1]);
252 double dyf = this->MotionFactor * (double)(dy) / (double)(this->CurrentRenderer->GetCenter()[1]);
254 double zoomFactor = pow((double)1.1, dxf + dyf);
256 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
257 if (aCam->GetParallelProjection())
258 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
260 aCam->Dolly(zoomFactor);
261 ::ResetCameraClippingRange(this->CurrentRenderer);
264 //this->Interactor->Render();
265 myGUIWindow->update();
268 //----------------------------------------------------------------------------
271 ::SpinXY(int x, int y, int oldX, int oldY)
275 if (this->CurrentRenderer == NULL)
280 double newAngle = atan2((double)(y - this->CurrentRenderer->GetCenter()[1]),
281 (double)(x - this->CurrentRenderer->GetCenter()[0]));
282 double oldAngle = atan2((double)(oldY -this->CurrentRenderer->GetCenter()[1]),
283 (double)(oldX - this->CurrentRenderer->GetCenter()[0]));
285 newAngle *= this->RadianToDegree;
286 oldAngle *= this->RadianToDegree;
288 cam = this->CurrentRenderer->GetActiveCamera();
289 cam->Roll(newAngle - oldAngle);
290 cam->OrthogonalizeViewUp();
292 //this->Interactor->Render();
293 myGUIWindow->update();
297 //----------------------------------------------------------------------------
300 ::OnMouseMove(int vtkNotUsed(ctrl),
304 myShiftState = shift;
305 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
306 onOperation(QPoint(x, y));
307 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
308 onCursorMove(QPoint(x, y));
312 //----------------------------------------------------------------------------
315 ::OnLeftButtonDown(int ctrl, int shift,
318 if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) {
319 this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
322 this->FindPokedRenderer(x, y);
323 if (this->CurrentRenderer == NULL) {
326 myShiftState = shift;
327 // finishing current viewer operation
328 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
330 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
332 myOtherPoint = myPoint = QPoint(x, y);
333 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
334 startOperation(ForcedState);
337 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
339 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
345 //----------------------------------------------------------------------------
348 ::OnLeftButtonUp(int vtkNotUsed(ctrl),
353 myShiftState = shift;
354 // finishing current viewer operation
355 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
357 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
362 //----------------------------------------------------------------------------
365 ::OnMiddleButtonDown(int ctrl,
369 if (this->HasObserver(vtkCommand::MiddleButtonPressEvent))
371 this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
374 this->FindPokedRenderer(x, y);
375 if (this->CurrentRenderer == NULL)
379 myShiftState = shift;
380 // finishing current viewer operation
381 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
383 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
385 myOtherPoint = myPoint = QPoint(x, y);
386 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
387 startOperation(ForcedState);
391 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
396 //----------------------------------------------------------------------------
399 ::OnMiddleButtonUp(int vtkNotUsed(ctrl),
404 myShiftState = shift;
405 // finishing current viewer operation
406 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
408 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
413 //----------------------------------------------------------------------------
416 ::OnRightButtonDown(int ctrl,
420 if (this->HasObserver(vtkCommand::RightButtonPressEvent))
422 this->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
425 this->FindPokedRenderer(x, y);
426 if (this->CurrentRenderer == NULL)
430 myShiftState = shift;
431 // finishing current viewer operation
432 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
434 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
436 myOtherPoint = myPoint = QPoint(x, y);
437 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
438 startOperation(ForcedState);
442 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
446 //----------------------------------------------------------------------------
449 ::OnRightButtonUp(int vtkNotUsed(ctrl),
454 myShiftState = shift;
455 // finishing current viewer operation
456 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
458 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
462 //----------------------------------------------------------------------------
464 const char* imageZoomCursor[] = {
469 "................................",
470 "................................",
471 ".#######........................",
472 "..aaaaaaa.......................",
473 "................................",
474 ".............#####..............",
475 "...........##.aaaa##............",
476 "..........#.aa.....a#...........",
477 ".........#.a.........#..........",
478 ".........#a..........#a.........",
479 "........#.a...........#.........",
480 "........#a............#a........",
481 "........#a............#a........",
482 "........#a............#a........",
483 "........#a............#a........",
484 ".........#...........#.a........",
485 ".........#a..........#a.........",
486 ".........##.........#.a.........",
487 "........#####.....##.a..........",
488 ".......###aaa#####.aa...........",
489 "......###aa...aaaaa.......#.....",
490 ".....###aa................#a....",
491 "....###aa.................#a....",
492 "...###aa...............#######..",
493 "....#aa.................aa#aaaa.",
494 ".....a....................#a....",
495 "..........................#a....",
496 "...........................a....",
497 "................................",
498 "................................",
499 "................................",
500 "................................"};
502 const char* imageRotateCursor[] = {
507 "................................",
508 "................................",
509 "................................",
510 "................................",
511 "........#.......................",
512 ".......#.a......................",
513 "......#######...................",
514 ".......#aaaaa#####..............",
515 "........#..##.a#aa##........##..",
516 ".........a#.aa..#..a#.....##.aa.",
517 ".........#.a.....#...#..##.aa...",
518 ".........#a.......#..###.aa.....",
519 "........#.a.......#a..#aa.......",
520 "........#a.........#..#a........",
521 "........#a.........#a.#a........",
522 "........#a.........#a.#a........",
523 "........#a.........#a.#a........",
524 ".........#.........#a#.a........",
525 "........##a........#a#a.........",
526 "......##.a#.......#.#.a.........",
527 "....##.aa..##.....##.a..........",
528 "..##.aa.....a#####.aa...........",
529 "...aa.........aaa#a.............",
530 "................#.a.............",
531 "...............#.a..............",
532 "..............#.a...............",
533 "...............a................",
534 "................................",
535 "................................",
536 "................................",
537 "................................",
538 "................................"};
541 //----------------------------------------------------------------------------
542 // loads cursors for viewer operations - zoom, pan, etc...
547 myDefCursor = QCursor(ArrowCursor);
548 myHandCursor = QCursor(PointingHandCursor);
549 myPanCursor = QCursor(SizeAllCursor);
550 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
551 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
552 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
553 myGlobalPanCursor = QCursor(CrossCursor);
554 myCursorState = false;
558 //----------------------------------------------------------------------------
559 // event filter - controls mouse and keyboard events during viewer operations
562 ::eventFilter(QObject* object, QEvent* event)
564 if (!myGUIWindow) return false;
565 if ( (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress) && object != myGUIWindow)
567 qApp->removeEventFilter(this);
568 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
570 return QObject::eventFilter(object, event);
574 //----------------------------------------------------------------------------
575 // starts Zoom operation (e.g. through menu command)
580 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
583 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
585 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
586 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
587 qApp->installEventFilter(this);
591 //----------------------------------------------------------------------------
592 // starts Pan operation (e.g. through menu command)
597 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
600 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
602 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
603 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
604 qApp->installEventFilter(this);
607 //----------------------------------------------------------------------------
608 // starts Rotate operation (e.g. through menu command)
613 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
616 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
618 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
619 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
620 qApp->installEventFilter(this);
624 //----------------------------------------------------------------------------
625 // starts Spin operation (e.g. through menu command)
630 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
633 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
635 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
636 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
637 qApp->installEventFilter(this);
642 //----------------------------------------------------------------------------
643 // starts Fit Area operation (e.g. through menu command)
648 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
651 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
653 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
654 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
655 qApp->installEventFilter(this);
659 //----------------------------------------------------------------------------
660 // starts Global Panning operation (e.g. through menu command)
665 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
668 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
670 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
671 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
673 // store current zoom scale
674 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
675 myScale = cam->GetParallelScale();
677 if (myViewWindow) myViewWindow->onFitAll();
679 if (myGUIWindow) myGUIWindow->update();
681 qApp->installEventFilter(this);
685 //----------------------------------------------------------------------------
686 // returns TRUE if needs redrawing
691 return State == VTK_INTERACTOR_STYLE_CAMERA_ZOOM ||
692 State == VTK_INTERACTOR_STYLE_CAMERA_PAN ||
693 State == VTK_INTERACTOR_STYLE_CAMERA_ROTATE ||
694 State == VTK_INTERACTOR_STYLE_CAMERA_SPIN ||
695 State == VTK_INTERACTOR_STYLE_CAMERA_NONE;
699 //----------------------------------------------------------------------------
700 // fits viewer contents to rect
703 ::fitRect(const int left,
708 if (this->CurrentRenderer == NULL) return;
711 int x = (left + right)/2;
712 int y = (top + bottom)/2;
713 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
714 int oldX = aSize[0]/2;
715 int oldY = aSize[1]/2;
716 TranslateView(oldX, oldY, x, y);
719 double dxf = (double)(aSize[0]) / (double)(abs(right - left));
720 double dyf = (double)(aSize[1]) / (double)(abs(bottom - top));
721 double zoomFactor = (dxf + dyf)/2 ;
723 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
724 if(aCam->GetParallelProjection())
725 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
727 aCam->Dolly(zoomFactor);
728 ::ResetCameraClippingRange(this->CurrentRenderer);
731 myGUIWindow->update();
735 //----------------------------------------------------------------------------
736 // starts viewer operation (!internal usage!)
739 ::startOperation(int operation)
743 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
744 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
745 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
746 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
747 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
748 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
749 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
750 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
751 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
753 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
754 setCursor(operation);
757 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
759 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
760 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
766 //----------------------------------------------------------------------------
767 // sets proper cursor for window when viewer operation is activated
770 ::setCursor(const int operation)
772 if (!myGUIWindow) return;
775 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
776 myGUIWindow->setCursor(myZoomCursor);
777 myCursorState = true;
779 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
780 myGUIWindow->setCursor(myPanCursor);
781 myCursorState = true;
783 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
784 myGUIWindow->setCursor(myRotateCursor);
785 myCursorState = true;
787 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
788 myGUIWindow->setCursor(mySpinCursor);
789 myCursorState = true;
791 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
792 myGUIWindow->setCursor(myGlobalPanCursor);
793 myCursorState = true;
795 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
796 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
797 myGUIWindow->setCursor(myHandCursor);
798 myCursorState = true;
800 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
802 myGUIWindow->setCursor(myDefCursor);
803 myCursorState = false;
809 //----------------------------------------------------------------------------
810 // called when viewer operation started (!put necessary initialization here!)
815 if (!myGUIWindow) return;
816 // VSV: LOD actor activisation
817 // this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
819 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
820 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
822 QPainter p(myGUIWindow);
823 p.setPen(Qt::lightGray);
824 p.setRasterOp(Qt::XorROP);
825 p.drawRect(QRect(myPoint, myOtherPoint));
828 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
829 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
830 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
831 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
832 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
838 //----------------------------------------------------------------------------
839 // called when viewer operation finished (!put necessary post-processing here!)
842 ::onFinishOperation()
847 // VSV: LOD actor activisation
848 // rwi->GetRenderWindow()->SetDesiredUpdateRate(rwi->GetStillUpdateRate());
850 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
851 bool aSelActiveCompOnly = false;
853 QString aComponentDataType;
854 if(SUIT_Session* aSession = SUIT_Session::session())
855 if(SUIT_Application* aSUITApp = aSession->activeApplication())
856 if(CAM_Application* aCAMApp = dynamic_cast<CAM_Application*>(aSUITApp))
857 if(CAM_Module* aModule = aCAMApp->activeModule())
858 aComponentDataType = aModule->name();
861 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
862 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
864 QPainter p(myGUIWindow);
865 p.setPen(Qt::lightGray);
866 p.setRasterOp(Qt::XorROP);
867 QRect rect(myPoint, myOtherPoint);
869 rect = rect.normalize();
870 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
871 // making fit rect opeation
873 myInteractor->GetSize(w, h);
876 y1 = h - rect.top() - 1;
878 y2 = h - rect.bottom() - 1;
879 fitRect(x1, y1, x2, y2);
882 if (myPoint == myOtherPoint) {
883 // process point selection
885 myInteractor->GetSize(w, h);
887 y = h - myPoint.y() - 1;
889 this->FindPokedRenderer(x, y);
890 myInteractor->StartPickCallback();
892 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
893 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
895 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
897 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
898 int aVtkId = picker->GetCellId();
899 if ( aVtkId >= 0 && aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
900 int anObjId = aSActor->GetElemObjId(aVtkId);
902 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
903 if(aSelectionMode != EdgeOfCellSelection) {
904 if(CheckDimensionId(aSelectionMode,aSActor,anObjId)){
905 if (GetSelector()->IsSelected(anIO)) {
906 // This IO is already in the selection
907 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
910 this->HighlightProp( NULL );
911 GetSelector()->ClearIObjects();
913 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
914 GetSelector()->AddIObject(aSActor);
919 this->HighlightProp( NULL );
920 GetSelector()->ClearIObjects();
922 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
924 GetSelector()->AddOrRemoveIndex(anIO,anObjId,false);
925 GetSelector()->AddOrRemoveIndex(anIO,-anEdgeId-1,true);
926 GetSelector()->AddIObject(aSActor);
931 this->HighlightProp( NULL );
932 GetSelector()->ClearIObjects();
934 } else if ( vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker) ) {
935 int aVtkId = picker->GetPointId();
936 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
937 if ( aSActor && aSActor->hasIO() ) {
938 int anObjId = aSActor->GetNodeObjId(aVtkId);
940 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
941 if(GetSelector()->IsSelected(anIO)) {
942 // This IO is already in the selection
943 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
946 this->HighlightProp( NULL );
947 GetSelector()->ClearIObjects();
949 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
950 GetSelector()->AddIObject(aSActor);
955 this->HighlightProp( NULL );
956 GetSelector()->ClearIObjects();
959 if ( aSActor && aSActor->hasIO() ) {
961 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
962 if(GetSelector()->IsSelected(anIO)) {
963 // This IO is already in the selection
965 GetSelector()->RemoveIObject(aSActor);
970 this->HighlightProp( NULL );
971 GetSelector()->ClearIObjects();
973 GetSelector()->AddIObject(aSActor);
976 // No selection clear all
977 this->PropPicked = 0;
978 this->HighlightProp( NULL );
979 GetSelector()->ClearIObjects();
982 myInteractor->EndPickCallback();
984 //processing rectangle selection
985 if(aSelActiveCompOnly && aComponentDataType.isEmpty()) return;
986 myInteractor->StartPickCallback();
989 this->PropPicked = 0;
990 this->HighlightProp( NULL );
991 GetSelector()->ClearIObjects();
995 // vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
996 QRect rect(myPoint, myOtherPoint);
997 rect = rect.normalize();
999 myInteractor->GetSize(w, h);
1002 y1 = h - rect.top() - 1;
1004 y2 = h - rect.bottom() - 1;
1006 switch (aSelectionMode) {
1007 case NodeSelection: {
1008 if ( vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(myInteractor->GetPicker()) ) {
1009 vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
1010 aListActors->InitTraversal();
1011 while (vtkActor* aActor = aListActors->GetNextActor()) {
1012 if (!aActor->GetVisibility())
1014 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1015 if (aSActor->hasIO()) {
1016 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1019 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1021 if (vtkDataSet* aDataSet = aSActor->GetInput()) {
1022 TColStd_MapOfInteger anIndices;
1023 for(int i = 0; i < aDataSet->GetNumberOfPoints(); i++) {
1025 aDataSet->GetPoint(i,aPoint);
1026 if (IsInRect(aPoint,x1,y1,x2,y2)){
1028 ComputeWorldToDisplay(aPoint[0],aPoint[1],aPoint[2],aDisp);
1029 if(aPointPicker->Pick(aDisp[0],aDisp[1],0.0,CurrentRenderer)){
1030 if(vtkActorCollection *anActorCollection = aPointPicker->GetActors()){
1031 if(anActorCollection->IsItemPresent(aSActor)){
1032 float aPickedPoint[3];
1033 aPointPicker->GetMapperPosition(aPickedPoint);
1034 vtkIdType aVtkId = aDataSet->FindPoint(aPickedPoint);
1035 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ){
1036 int anObjId = aSActor->GetNodeObjId(aVtkId);
1037 anIndices.Add(anObjId);
1044 if (!anIndices.IsEmpty()) {
1045 GetSelector()->AddOrRemoveIndex(anIO,anIndices,true); // ENK false to true
1046 GetSelector()->AddIObject(aSActor);
1049 GetSelector()->RemoveIObject(aSActor);
1059 case EdgeOfCellSelection:
1062 case VolumeSelection:
1064 vtkSmartPointer<VTKViewer_CellRectPicker> picker = VTKViewer_CellRectPicker::New();
1065 picker->SetTolerance(0.001);
1066 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1068 vtkActorCollection* aListActors = picker->GetActors();
1069 aListActors->InitTraversal();
1070 while(vtkActor* aActor = aListActors->GetNextActor()) {
1071 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1072 if (aSActor->hasIO()) {
1073 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1074 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1076 VTKViewer_CellDataSet cellList = picker->GetCellData(aActor);
1077 if ( !cellList.empty() ) {
1078 TColStd_MapOfInteger anIndexes;
1079 VTKViewer_CellDataSet::iterator it;
1080 for ( it = cellList.begin(); it != cellList.end(); ++it ) {
1081 int aCellId = (*it).cellId;
1083 if ( !IsValid( aSActor, aCellId ) )
1086 int anObjId = aSActor->GetElemObjId(aCellId);
1088 if ( CheckDimensionId(aSelectionMode,aSActor,anObjId) ) {
1089 anIndexes.Add(anObjId);
1093 GetSelector()->AddOrRemoveIndex(anIO,anIndexes,true);
1094 GetSelector()->AddIObject(aSActor);
1101 case ActorSelection: // objects selection
1103 vtkSmartPointer<VTKViewer_RectPicker> picker = VTKViewer_RectPicker::New();
1104 picker->SetTolerance(0.001);
1105 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1107 vtkActorCollection* aListActors = picker->GetActors();
1108 aListActors->InitTraversal();
1109 while(vtkActor* aActor = aListActors->GetNextActor()) {
1110 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1111 if (aSActor->hasIO()) {
1112 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1113 GetSelector()->AddIObject(aSActor);
1120 myInteractor->EndPickCallback();
1122 myViewWindow->onSelectionChanged();
1126 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1127 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1128 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1129 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1131 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1134 myInteractor->GetSize(w, h);
1136 y = h - myPoint.y() - 1;
1141 if (myGUIWindow) myGUIWindow->update();
1146 // called during viewer operation when user moves mouse (!put necessary processing here!)
1148 SVTK_InteractorStyle
1149 ::onOperation(QPoint mousePos)
1151 if (!myGUIWindow) return;
1153 GetInteractor()->GetSize(w, h);
1155 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1157 // processing panning
1158 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1159 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1163 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1165 // processing zooming
1166 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1167 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1171 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1173 // processing rotation
1174 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1175 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1179 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1181 // processing spinning
1182 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1183 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1187 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1191 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1194 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1196 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1198 QPainter p(myGUIWindow);
1199 p.setPen(Qt::lightGray);
1200 p.setRasterOp(Qt::XorROP);
1201 p.drawRect(QRect(myPoint, myOtherPoint));
1202 myOtherPoint = mousePos;
1203 p.drawRect(QRect(myPoint, myOtherPoint));
1207 this->LastPos[0] = mousePos.x();
1208 this->LastPos[1] = h - mousePos.y() - 1;
1211 // called when selection mode changed (!put necessary initialization here!)
1213 SVTK_InteractorStyle
1214 ::OnSelectionModeChanged()
1217 myPreSelectionActor->SetVisibility(false);
1218 myElemId = myEdgeId = myNodeId = -1;
1219 mySelectedActor = NULL;
1222 // called when user moves mouse inside viewer window and there is no active viewer operation
1223 // (!put necessary processing here!)
1225 SVTK_InteractorStyle
1226 ::onCursorMove(QPoint mousePos)
1228 // processing highlighting
1229 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
1232 myInteractor->GetSize(w, h);
1233 x = mousePos.x(); y = h - mousePos.y() - 1;
1235 this->FindPokedRenderer(x,y);
1236 myInteractor->StartPickCallback();
1237 myPreSelectionActor->SetVisibility(false);
1239 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
1240 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
1242 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
1244 if (aSActor && myPreSelectionActor){
1246 aSActor->GetPosition(aPos);
1247 myPreSelectionActor->SetPosition(aPos);
1250 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
1251 int aVtkId = picker->GetCellId();
1252 if ( aVtkId >= 0 ) {
1253 int anObjId = aSActor->GetElemObjId(aVtkId);
1254 if ( aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
1255 bool anIsSameObjId = (mySelectedActor == aSActor && myElemId == anObjId);
1256 bool aResult = anIsSameObjId;
1257 if(!anIsSameObjId) {
1258 if(aSelectionMode != EdgeOfCellSelection) {
1259 aResult = CheckDimensionId(aSelectionMode,aSActor,anObjId);
1261 mySelectedActor = aSActor;
1263 myInteractor->setCellData(anObjId,aSActor,myPreSelectionActor);
1267 if(aSelectionMode == EdgeOfCellSelection){
1268 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
1269 bool anIsSameEdgeId = (myEdgeId != anEdgeId) && anIsSameObjId;
1270 aResult = anIsSameEdgeId;
1271 if(!anIsSameEdgeId) {
1272 aResult = (anEdgeId >= 0);
1274 mySelectedActor = aSActor;
1275 myEdgeId = anEdgeId;
1277 myInteractor->setEdgeData(anObjId,aSActor,-anEdgeId-1,myPreSelectionActor);
1282 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1283 myPreSelectionActor->SetVisibility(true);
1288 else if (vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker)) {
1289 int aVtkId = picker->GetPointId();
1290 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
1291 if ( aSActor && aSActor->hasIO() ) {
1292 int anObjId = aSActor->GetNodeObjId(aVtkId);
1293 bool anIsSameObjId = (mySelectedActor == aSActor && myNodeId == anObjId);
1294 if(!anIsSameObjId) {
1295 mySelectedActor = aSActor;
1297 myInteractor->setPointData(anObjId,aSActor,myPreSelectionActor);
1299 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1300 myPreSelectionActor->SetVisibility(true);
1304 else if ( vtkPicker::SafeDownCast(aPicker) ) {
1306 if ( myPreViewActor != aSActor ) {
1307 if ( myPreViewActor != NULL ) {
1308 myPreViewActor->SetPreSelected( false );
1310 myPreViewActor = aSActor;
1312 if ( aSActor->hasIO() ) {
1313 Handle( SALOME_InteractiveObject) IO = aSActor->getIO();
1314 if ( !GetSelector()->IsSelected(IO) ) {
1315 // Find All actors with same IO
1316 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1317 theActors->InitTraversal();
1318 while( vtkActor *ac = theActors->GetNextActor() ) {
1319 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1320 if ( anActor->hasIO() ) {
1321 Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
1322 if(IO->isSame(IOS)) {
1323 anActor->SetPreSelected( true );
1332 myPreViewActor = NULL;
1333 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1334 theActors->InitTraversal();
1335 while( vtkActor *ac = theActors->GetNextActor() ) {
1336 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1337 anActor->SetPreSelected( false );
1342 myInteractor->EndPickCallback();
1343 //myInteractor->Render();
1344 myGUIWindow->update();
1346 this->LastPos[0] = x;
1347 this->LastPos[1] = y;
1350 // called on finsh GlobalPan operation
1352 SVTK_InteractorStyle
1353 ::Place(const int theX, const int theY)
1355 if (this->CurrentRenderer == NULL) {
1360 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
1361 int centerX = aSize[0]/2;
1362 int centerY = aSize[1]/2;
1364 TranslateView(centerX, centerY, theX, theY);
1366 // restore zoom scale
1367 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1368 cam->SetParallelScale(myScale);
1369 ::ResetCameraClippingRange(this->CurrentRenderer);
1371 if (myGUIWindow) myGUIWindow->update();
1377 // Translates view from Point to Point
1379 SVTK_InteractorStyle
1380 ::TranslateView(int toX, int toY, int fromX, int fromY)
1382 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1383 double viewFocus[4], focalDepth, viewPoint[3];
1384 float newPickPoint[4], oldPickPoint[4], motionVector[3];
1385 cam->GetFocalPoint(viewFocus);
1387 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1388 viewFocus[2], viewFocus);
1389 focalDepth = viewFocus[2];
1391 this->ComputeDisplayToWorld(double(toX), double(toY),
1392 focalDepth, newPickPoint);
1393 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1394 focalDepth, oldPickPoint);
1396 // camera motion is reversed
1397 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1398 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1399 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1401 cam->GetFocalPoint(viewFocus);
1402 cam->GetPosition(viewPoint);
1403 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1404 motionVector[1] + viewFocus[1],
1405 motionVector[2] + viewFocus[2]);
1406 cam->SetPosition(motionVector[0] + viewPoint[0],
1407 motionVector[1] + viewPoint[1],
1408 motionVector[2] + viewPoint[2]);
1412 /// Checks: is the given Actor within display coordinates?
1414 SVTK_InteractorStyle
1415 ::IsInRect(vtkActor* theActor,
1416 const int left, const int top,
1417 const int right, const int bottom)
1419 float* aBounds = theActor->GetBounds();
1420 float aMin[3], aMax[3];
1421 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1422 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1423 if (aMin[0] > aMax[0]) {
1424 float aBuf = aMin[0];
1428 if (aMin[1] > aMax[1]) {
1429 float aBuf = aMin[1];
1434 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1438 /// Checks: is the given Cell within display coordinates?
1440 SVTK_InteractorStyle
1441 ::IsInRect(vtkCell* theCell,
1442 const int left, const int top,
1443 const int right, const int bottom)
1445 float* aBounds = theCell->GetBounds();
1446 float aMin[3], aMax[3];
1447 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1448 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1449 if (aMin[0] > aMax[0]) {
1450 float aBuf = aMin[0];
1454 if (aMin[1] > aMax[1]) {
1455 float aBuf = aMin[1];
1460 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1465 SVTK_InteractorStyle
1466 ::IsInRect(float* thePoint,
1467 const int left, const int top,
1468 const int right, const int bottom)
1471 ComputeWorldToDisplay(thePoint[0], thePoint[1], thePoint[2], aPnt);
1473 return ((aPnt[0]>left) && (aPnt[0]<right) && (aPnt[1]>bottom) && (aPnt[1]<top));
1477 SVTK_InteractorStyle
1478 ::SetFilter( const Handle(VTKViewer_Filter)& theFilter )
1480 myFilters[ theFilter->GetId() ] = theFilter;
1484 SVTK_InteractorStyle
1485 ::IsFilterPresent( const int theId )
1487 return myFilters.find( theId ) != myFilters.end();
1491 SVTK_InteractorStyle
1492 ::RemoveFilter( const int theId )
1494 if ( IsFilterPresent( theId ) )
1495 myFilters.erase( theId );
1500 SVTK_InteractorStyle
1501 ::IsValid( SALOME_Actor* theActor,
1503 const bool theIsNode )
1505 std::map<int, Handle(VTKViewer_Filter)>::const_iterator anIter;
1506 for ( anIter = myFilters.begin(); anIter != myFilters.end(); ++anIter )
1508 const Handle(VTKViewer_Filter)& aFilter = anIter->second;
1509 if ( theIsNode == aFilter->IsNodeFilter() &&
1510 !aFilter->IsValid( theActor, theId ) )
1516 Handle(VTKViewer_Filter)
1517 SVTK_InteractorStyle
1518 ::GetFilter( const int theId )
1520 return IsFilterPresent( theId ) ? myFilters[ theId ] : Handle(VTKViewer_Filter)();
1524 SVTK_InteractorStyle
1525 ::IncrementalPan( const int incrX, const int incrY )
1527 this->PanXY( incrX, incrY, 0, 0 );
1531 SVTK_InteractorStyle
1532 ::IncrementalZoom( const int incr )
1534 this->DollyXY( incr, incr );
1538 SVTK_InteractorStyle
1539 ::IncrementalRotate( const int incrX, const int incrY )
1541 this->RotateXY( incrX, -incrY );