1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME VTKViewer : build VTK viewer into Salome desktop
27 #include "SVTK_InteractorStyle.h"
29 #include "VTKViewer_Algorithm.h"
30 #include "VTKViewer_Utilities.h"
31 #include "SVTK_GenericRenderWindowInteractor.h"
33 #include "SVTK_Selection.h"
34 #include "SVTK_Event.h"
35 #include "SVTK_Selector.h"
36 #include "SVTK_Functor.h"
37 #include "SVTK_Actor.h"
39 #include "VTKViewer_Algorithm.h"
40 #include "SVTK_Functor.h"
42 #include "SUIT_Tools.h"
43 #include "SALOME_Actor.h"
44 #include "ViewerTools_ScreenScaling.h"
46 #include <vtkObjectFactory.h>
48 #include <vtkCommand.h>
49 #include <vtkCamera.h>
50 #include <vtkRenderer.h>
51 #include <vtkPointPicker.h>
52 #include <vtkCellPicker.h>
53 #include <vtkRenderWindow.h>
54 #include <vtkRenderWindowInteractor.h>
55 #include <vtkCallbackCommand.h>
56 #include <vtkRendererCollection.h>
57 #include <vtkDataSet.h>
58 #include <vtkPerspectiveTransform.h>
59 #include <vtkMatrix4x4.h>
61 #include <QtxRubberBand.h>
72 inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
76 theInteractor->GetEventPosition(theX,theY);
77 theY = theInteractor->GetSize()[1] - theY - 1;
82 vtkStandardNewMacro(SVTK_InteractorStyle)
88 SVTK_InteractorStyle::SVTK_InteractorStyle():
89 myLastHighlitedActor(NULL),
90 myLastPreHighlitedActor(NULL),
91 myControllerIncrement(SVTK_ControllerIncrement::New()),
92 myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
93 mySelectionEvent(new SVTK_SelectionEvent()),
94 myHighlightSelectionPointActor(SVTK_Actor::New()),
95 myPointPicker(vtkPointPicker::New()),
98 myPoligonState(Disable),
99 myIsAdvancedZoomingEnabled(false),
100 myInteractivePoint{0.0, 0.0, 0.0}
102 myPointPicker->Delete();
104 myPointPicker->SetTolerance(0.025);
106 this->MotionFactor = 10.0;
107 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
108 this->RadianToDegree = 180.0 / vtkMath::Pi();
109 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
113 // set custom event handling function (to handle 3d space mouse events)
114 EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
116 // set default values of properties. user may edit them in preferences.
117 mySMDecreaseSpeedBtn = 1;
118 mySMIncreaseSpeedBtn = 2;
119 mySMDominantCombinedSwitchBtn = 9;
121 myControllerIncrement->Delete();
122 myControllerOnKeyDown->Delete();
124 myCurrRotationPointType = SVTK::SetRotateGravity;
125 myPrevRotationPointType = myCurrRotationPointType;
127 myCurrFocalPointType = SVTK::SetFocalPointSelected;
128 myPrevFocalPointType = myCurrFocalPointType;
130 myHighlightSelectionPointActor->Delete();
131 myHighlightSelectionPointActor->Initialize();
132 myHighlightSelectionPointActor->PickableOff();
133 myHighlightSelectionPointActor->SetVisibility( false );
135 myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
136 myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
137 myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
139 myBBFirstCheck = true;
145 SVTK_InteractorStyle::~SVTK_InteractorStyle()
152 \return widget for rendering
154 QWidget* SVTK_InteractorStyle::GetRenderWidget()
156 return myInteractor->GetRenderWidget();
162 SVTK_Selector* SVTK_InteractorStyle::GetSelector()
164 return myInteractor->GetSelector();
170 void SVTK_InteractorStyle::FreeActors()
172 myLastHighlitedActor = NULL;
173 myLastPreHighlitedActor = NULL;
177 Generate special SVTK_SelectionEvent
179 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
181 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
183 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
184 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
186 mySelectionEvent->myLastX = mySelectionEvent->myX;
187 mySelectionEvent->myLastY = mySelectionEvent->myY;
189 GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
191 return mySelectionEvent.get();
195 Generate special SVTK_SelectionEvent with flipped Y coordinate
197 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
199 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
201 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
202 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
204 mySelectionEvent->myLastX = mySelectionEvent->myX;
205 mySelectionEvent->myLastY = mySelectionEvent->myY;
207 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
209 return mySelectionEvent.get();
212 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
214 /* if(GetCurrentRenderer() == NULL)
217 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
218 double aDeltaElevation = -20.0 / size[1];
219 double aDeltaAzimuth = -20.0 / size[0];
221 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
222 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
224 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
227 cam->OrthogonalizeViewUp();
229 GetCurrentRenderer()->ResetCameraClippingRange();
233 if(GetCurrentRenderer() == NULL)
236 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
238 double viewFP[3], viewPos[3];
239 cam->GetFocalPoint(viewFP);
240 cam->GetPosition(viewPos);
242 if ( myCurrRotationPointType == SVTK::SetRotateGravity )
245 if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) )
247 myRotationPointX = aCenter[0];
248 myRotationPointY = aCenter[1];
249 myRotationPointZ = aCenter[2];
253 // Calculate corresponding transformation
254 vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
255 aTransform->Identity();
256 aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
258 // Azimuth transformation
259 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
260 double aDeltaAzimuth = -20.0 / size[0];
262 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
263 aTransform->RotateWXYZ(rxf, cam->GetViewUp());
265 // Elevation transformation
266 double aDeltaElevation = -20.0 / size[1];
268 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
269 vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
270 const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
271 -aMatrix->GetElement(0,1),
272 -aMatrix->GetElement(0,2)};
274 aTransform->RotateWXYZ(ryf, anAxis);
276 aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
278 // To apply the transformation
279 cam->SetPosition(aTransform->TransformPoint(viewPos));
280 cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
281 aTransform->Delete();
283 cam->OrthogonalizeViewUp();
285 GetCurrentRenderer()->ResetCameraClippingRange();
288 this->InvokeEvent(SVTK::OperationFinished,NULL);
291 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
293 TranslateView(x, y, oldX, oldY);
295 this->InvokeEvent(SVTK::OperationFinished,NULL);
298 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
300 if (GetCurrentRenderer() == NULL)
303 double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
304 double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
306 double zoomFactor = pow((double)1.1, dxf + dyf);
308 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
309 if (aCam->GetParallelProjection()) {
310 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
311 if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
312 int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
317 x1 = myOtherPoint.x();
318 y1 = h - myOtherPoint.y();
319 TranslateView( x0, y0, x1, y1 );
321 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
322 if( IsAdvancedZoomingEnabled() )
323 TranslateView( x1, y1, x0, y0 );
326 aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
327 GetCurrentRenderer()->ResetCameraClippingRange();
331 this->InvokeEvent(SVTK::OperationFinished,NULL);
334 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
338 if (GetCurrentRenderer() == NULL)
341 double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
342 (double)(x - GetCurrentRenderer()->GetCenter()[0]));
343 double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
344 (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
346 newAngle *= this->RadianToDegree;
347 oldAngle *= this->RadianToDegree;
349 cam = GetCurrentRenderer()->GetActiveCamera();
350 cam->Roll(newAngle - oldAngle);
351 cam->OrthogonalizeViewUp();
354 this->InvokeEvent(SVTK::OperationFinished,NULL);
361 void SVTK_InteractorStyle::OnConfigure()
363 this->FindPokedRenderer(0,0);
364 this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
368 To handle mouse move event
370 void SVTK_InteractorStyle::OnMouseMove()
373 GetEventPosition( this->Interactor, x, y );
374 this->OnMouseMove( this->Interactor->GetControlKey(),
375 this->Interactor->GetShiftKey(),
380 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
382 void SVTK_InteractorStyle::OnLeftButtonDown()
385 GetEventPosition( this->Interactor, x, y );
386 this->OnLeftButtonDown( this->Interactor->GetControlKey(),
387 this->Interactor->GetShiftKey(),
392 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
394 void SVTK_InteractorStyle::OnLeftButtonUp()
397 GetEventPosition( this->Interactor, x, y );
398 this->OnLeftButtonUp( this->Interactor->GetControlKey(),
399 this->Interactor->GetShiftKey(),
404 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
406 void SVTK_InteractorStyle::OnMiddleButtonDown()
409 GetEventPosition( this->Interactor, x, y );
410 this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
411 this->Interactor->GetShiftKey(),
416 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
418 void SVTK_InteractorStyle::OnMiddleButtonUp()
421 GetEventPosition( this->Interactor, x, y );
422 this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
423 this->Interactor->GetShiftKey(),
428 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
430 void SVTK_InteractorStyle::OnRightButtonDown()
433 GetEventPosition( this->Interactor, x, y );
434 this->OnRightButtonDown( this->Interactor->GetControlKey(),
435 this->Interactor->GetShiftKey(),
440 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
442 void SVTK_InteractorStyle::OnRightButtonUp()
445 GetEventPosition( this->Interactor, x, y );
446 this->OnRightButtonUp( this->Interactor->GetControlKey(),
447 this->Interactor->GetShiftKey(),
452 To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
454 void SVTK_InteractorStyle::OnMouseWheelForward()
457 GetEventPosition( this->Interactor, x, y );
458 myOtherPoint = QPoint(x, y);
462 To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
464 void SVTK_InteractorStyle::OnMouseWheelBackward()
467 GetEventPosition( this->Interactor, x, y );
468 myOtherPoint = QPoint(x, y);
472 To handle mouse double click event
474 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
476 if( myPoligonState == InProcess ) {
478 myPoligonState = Finished;
483 To handle mouse move event
485 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
489 if ( myPoligonState == Start ) {
490 // if right button was pressed and mouse is moved
491 // we can to draw a polygon for polygonal selection
492 myPoligonState = InProcess;
493 startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
495 myShiftState = shift;
496 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
497 onOperation(QPoint(x, y));
498 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
499 onCursorMove(QPoint(x, y));
503 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
505 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
508 this->FindPokedRenderer(x, y);
509 if(GetCurrentRenderer() == NULL)
512 if ( myPoligonState != Disable )
515 myShiftState = shift;
516 // finishing current viewer operation
517 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
519 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
521 myOtherPoint = myPoint = QPoint(x, y);
522 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
523 startOperation(ForcedState);
526 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
527 else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
528 myCurrFocalPointType == SVTK::StartFocalPointSelection )
530 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
532 bool isPicked = false;
533 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
535 if( anActorCollection )
537 anActorCollection->InitTraversal();
538 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
540 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
542 Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
543 double* aCoords = NULL;
545 bool isTrueType = false;
547 if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
548 ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
550 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
551 myPointPicker->Pick( aSelectionEvent->myX,
552 aSelectionEvent->myY,
554 GetCurrentRenderer() );
555 aVtkId = myPointPicker->GetPointId();
558 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
559 aCoords = anActor->GetNodeCoord(anObjId);
564 if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection || aSelectionMode == VolumeSelection )
566 vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
567 aCellPicker->SetTolerance( 0.005 );
568 SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
569 aCellPicker->Pick( aSelectionEvent->myX,
570 aSelectionEvent->myY,
572 GetCurrentRenderer() );
573 aVtkId = aCellPicker->GetCellId();
574 vtkIdType aCellId = anActor->GetElemObjId( aVtkId );
576 if( aSelectionMode == EdgeSelection )
577 isTrueType = anActor->GetObjDimension( aCellId ) == 1;
578 else if( aSelectionMode == FaceSelection )
579 isTrueType = anActor->GetObjDimension( aCellId ) == 2;
580 else if( aSelectionMode == VolumeSelection )
581 isTrueType = anActor->GetObjDimension( aCellId ) == 3;
583 if ( aVtkId >= 0 && isTrueType )
584 aCoords = anActor->GetGravityCenter( aCellId );
589 if (myCurrRotationPointType == SVTK::StartPointSelection) {
590 myCurrRotationPointType = SVTK::SetRotateSelected;
591 // invoke event for update coordinates in SVTK_SetRotationPointDlg
593 InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
595 InvokeEvent(SVTK::RotationPointChanged);
596 GetSelector()->SetSelectionMode(ActorSelection);
598 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
599 myCurrFocalPointType = SVTK::SetFocalPointSelected;
601 // invoke event for update coordinates in SVTK_ViewParameterDlg
602 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
614 if (myCurrRotationPointType == SVTK::StartPointSelection) {
615 // invoke event with no data (for SVTK_SetRotationPointDlg)
616 InvokeEvent(SVTK::RotationPointChanged,0);
617 myCurrRotationPointType = myPrevRotationPointType;
618 GetSelector()->SetSelectionMode(ActorSelection);
620 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
621 // invoke event with no data (for SVTK_ViewParameterDlg)
622 InvokeEvent(SVTK::FocalPointChanged,0);
623 myCurrFocalPointType = myPrevFocalPointType;
627 myHighlightSelectionPointActor->SetVisibility( false );
628 if(GetCurrentRenderer() != NULL)
629 GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
631 GetRenderWidget()->setCursor(myDefCursor);
634 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
641 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
643 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
648 myShiftState = shift;
649 if( myPoligonState == InProcess ) { // add a new point of polygon
650 // The mouse events were already scaled up with a pixel ratio for a proper selection,
651 // but rubber band's implemented with QPainter scales them on its own.
652 // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
653 const double pixelRatio = ViewerTools_ScreenScaling::getPR();
655 myPolygonPoints.append(QPoint(x / pixelRatio, y / pixelRatio));
656 this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
657 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
660 else if ( myPoligonState == Closed ) { // close polygon and apply a selection
662 myPoligonState = Finished;
665 else if( myPoligonState == Finished || myPoligonState == NotValid )
667 // finishing current viewer operation
668 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
670 int lastOperation = State;
671 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
672 if (lastOperation == VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
673 InvokeEvent(SVTK::InteractiveSelectionFinished, nullptr);
679 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
681 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
685 this->FindPokedRenderer(x, y);
686 if(GetCurrentRenderer() == NULL)
689 if ( myPoligonState != Disable )
692 myShiftState = shift;
693 // finishing current viewer operation
694 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
696 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
698 myOtherPoint = myPoint = QPoint(x, y);
699 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
700 ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
701 startOperation(ForcedState);
705 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
711 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
713 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
718 if( myPoligonState == InProcess ) { // delete a point of polygon
719 if ( myPolygonPoints.size() > 2 ) {
720 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
721 mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
725 myShiftState = shift;
726 // finishing current viewer operation
727 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
729 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
735 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
737 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
741 this->FindPokedRenderer(x, y);
742 if(GetCurrentRenderer() == NULL)
745 myShiftState = shift;
748 myPoligonState = Start;
749 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
750 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
752 // finishing current viewer operation
753 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
755 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
757 myOtherPoint = myPoint = QPoint(x, y);
758 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
759 ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
760 startOperation(ForcedState);
764 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
769 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
771 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
776 if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
777 myPoligonState = Disable;
778 mySelectionEvent->myPolygonPoints.clear();
781 if( myPoligonState != Disable ) {
783 myPoligonState = Finished;
784 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
788 myShiftState = shift;
789 // finishing current viewer operation
790 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
792 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
797 const char* imageZoomCursor[] = {
802 "................................",
803 "................................",
804 ".#######........................",
805 "..aaaaaaa.......................",
806 "................................",
807 ".............#####..............",
808 "...........##.aaaa##............",
809 "..........#.aa.....a#...........",
810 ".........#.a.........#..........",
811 ".........#a..........#a.........",
812 "........#.a...........#.........",
813 "........#a............#a........",
814 "........#a............#a........",
815 "........#a............#a........",
816 "........#a............#a........",
817 ".........#...........#.a........",
818 ".........#a..........#a.........",
819 ".........##.........#.a.........",
820 "........#####.....##.a..........",
821 ".......###aaa#####.aa...........",
822 "......###aa...aaaaa.......#.....",
823 ".....###aa................#a....",
824 "....###aa.................#a....",
825 "...###aa...............#######..",
826 "....#aa.................aa#aaaa.",
827 ".....a....................#a....",
828 "..........................#a....",
829 "...........................a....",
830 "................................",
831 "................................",
832 "................................",
833 "................................"};
835 const char* imageRotateCursor[] = {
840 "................................",
841 "................................",
842 "................................",
843 "................................",
844 "........#.......................",
845 ".......#.a......................",
846 "......#######...................",
847 ".......#aaaaa#####..............",
848 "........#..##.a#aa##........##..",
849 ".........a#.aa..#..a#.....##.aa.",
850 ".........#.a.....#...#..##.aa...",
851 ".........#a.......#..###.aa.....",
852 "........#.a.......#a..#aa.......",
853 "........#a.........#..#a........",
854 "........#a.........#a.#a........",
855 "........#a.........#a.#a........",
856 "........#a.........#a.#a........",
857 ".........#.........#a#.a........",
858 "........##a........#a#a.........",
859 "......##.a#.......#.#.a.........",
860 "....##.aa..##.....##.a..........",
861 "..##.aa.....a#####.aa...........",
862 "...aa.........aaa#a.............",
863 "................#.a.............",
864 "...............#.a..............",
865 "..............#.a...............",
866 "...............a................",
867 "................................",
868 "................................",
869 "................................",
870 "................................",
871 "................................"};
875 loads cursors for viewer operations - zoom, pan, etc...
877 void SVTK_InteractorStyle::loadCursors()
879 myDefCursor = QCursor(Qt::ArrowCursor);
880 myHandCursor = QCursor(Qt::PointingHandCursor);
881 myPanCursor = QCursor(Qt::SizeAllCursor);
882 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
883 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
884 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
885 myGlobalPanCursor = QCursor(Qt::CrossCursor);
886 myCursorState = false;
891 Starts Zoom operation (e.g. through menu command)
893 void SVTK_InteractorStyle::startZoom()
895 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
898 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
900 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
901 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
906 Starts Pan operation (e.g. through menu command)
908 void SVTK_InteractorStyle::startPan()
910 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
913 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
915 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
916 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
920 Starts Rotate operation (e.g. through menu command)
922 void SVTK_InteractorStyle::startRotate()
924 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
927 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
929 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
930 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
934 Starts Interactive Selection operation
936 void SVTK_InteractorStyle::startInteractiveSelection()
938 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
941 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
943 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION;
948 Set rotation point selected by user
950 void SVTK_InteractorStyle::startPointSelection()
952 myCurrRotationPointType = SVTK::StartPointSelection;
954 if(GetCurrentRenderer() != NULL) {
955 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
957 GetCurrentRenderer()->GetBackground( aColor );
958 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
963 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
967 Set focal point selected by user
969 void SVTK_InteractorStyle::startFocalPointSelection()
971 myCurrFocalPointType = SVTK::StartFocalPointSelection;
973 if(GetCurrentRenderer() != NULL) {
974 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
976 GetCurrentRenderer()->GetBackground( aColor );
977 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
982 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
986 Starts Spin operation (e.g. through menu command)
988 void SVTK_InteractorStyle::startSpin()
990 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
993 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
995 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
996 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
1002 Starts Fit Area operation (e.g. through menu command)
1004 void SVTK_InteractorStyle::startFitArea()
1006 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1008 onFinishOperation();
1009 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1011 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
1012 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
1017 Starts Global Panning operation (e.g. through menu command)
1019 void SVTK_InteractorStyle::startGlobalPan()
1021 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1023 onFinishOperation();
1024 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1026 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
1027 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
1029 // store current zoom scale
1030 myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
1032 GetCurrentRenderer()->ResetCamera();
1039 Fits viewer contents to rect
1041 void SVTK_InteractorStyle::fitRect(const int left,
1046 if (GetCurrentRenderer() == NULL)
1050 int x = (left + right)/2;
1051 int y = (top + bottom)/2;
1052 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1053 int oldX = aSize[0]/2;
1054 int oldY = aSize[1]/2;
1055 TranslateView(oldX, oldY, x, y);
1058 double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
1059 double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
1060 double zoomFactor = (dxf + dyf)/2 ;
1062 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
1063 if(aCam->GetParallelProjection())
1064 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
1066 aCam->Dolly(zoomFactor);
1067 GetCurrentRenderer()->ResetCameraClippingRange();
1075 Starts viewer operation (!internal usage!)
1077 void SVTK_InteractorStyle::startOperation(int operation)
1081 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1082 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1083 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1084 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1085 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1086 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1087 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1088 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1089 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1090 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1092 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1093 setCursor(operation);
1096 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1098 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1099 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1106 Sets proper cursor for window when viewer operation is activated
1108 void SVTK_InteractorStyle::setCursor(const int operation)
1110 if (!GetRenderWidget()) return;
1113 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1114 GetRenderWidget()->setCursor(myZoomCursor);
1115 myCursorState = true;
1117 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1118 GetRenderWidget()->setCursor(myPanCursor);
1119 myCursorState = true;
1121 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1122 GetRenderWidget()->setCursor(myRotateCursor);
1123 myCursorState = true;
1125 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1126 GetRenderWidget()->setCursor(mySpinCursor);
1127 myCursorState = true;
1129 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1130 GetRenderWidget()->setCursor(myGlobalPanCursor);
1131 myCursorState = true;
1133 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1134 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1135 GetRenderWidget()->setCursor(myHandCursor);
1136 myCursorState = true;
1138 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1140 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1141 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1142 GetRenderWidget()->setCursor(myHandCursor);
1144 GetRenderWidget()->setCursor(myDefCursor);
1145 myCursorState = false;
1152 Called when viewer operation started (!put necessary initialization here!)
1154 void SVTK_InteractorStyle::onStartOperation()
1156 if (!GetRenderWidget())
1159 vtkRenderWindowInteractor *aRWI = this->Interactor;
1160 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1161 aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1164 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1165 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1167 if ( myPoligonState == InProcess )
1173 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1175 InteractiveSelection();
1178 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1179 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1180 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1181 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1182 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1189 Called when viewer operation finished (!put necessary post-processing here!)
1191 void SVTK_InteractorStyle::onFinishOperation()
1193 if (!GetRenderWidget())
1196 vtkRenderWindowInteractor *aRWI = this->Interactor;
1197 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1198 aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1200 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1203 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1204 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1207 QRect aRect(myPoint, myOtherPoint);
1208 aRect = aRect.normalized();
1210 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1211 // making fit rect opeation
1213 Interactor->GetSize(w, h);
1214 int x1 = aRect.left();
1215 int y1 = h - aRect.top() - 1;
1216 int x2 = aRect.right();
1217 int y2 = h - aRect.bottom() - 1;
1218 fitRect(x1, y1, x2, y2);
1221 if (myPoint == myOtherPoint)
1223 // process point selection
1224 this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1225 Interactor->StartPickCallback();
1227 SALOME_Actor* aHighlightedActor = NULL;
1228 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1230 aSelectionEvent->myIsRectangle = false;
1231 aSelectionEvent->myIsPolygon = false;
1233 GetSelector()->ClearIObjects();
1235 if( anActorCollection )
1237 if( !myShiftState &&
1238 anActorCollection->GetNumberOfItems () > 1 &&
1239 myLastHighlitedActor.GetPointer() ) {
1240 anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
1242 anActorCollection->InitTraversal();
1243 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1245 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1247 if( anActor->Highlight( this, aSelectionEvent, true ) )
1249 aHighlightedActor = anActor;
1256 if( !aHighlightedActor )
1258 if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1259 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1261 myLastHighlitedActor = aHighlightedActor;
1265 if ( myPoligonState == InProcess || myPoligonState == Closed )
1266 aSelectionEvent->myIsPolygon = true;
1268 aSelectionEvent->myIsRectangle = true;
1270 //processing polygonal selection
1271 Interactor->StartPickCallback();
1272 GetSelector()->StartPickCallback();
1275 GetSelector()->ClearIObjects();
1277 VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1278 vtkActorCollection* aListActors = aCopy.GetActors();
1279 aListActors->InitTraversal();
1280 while(vtkActor* aActor = aListActors->GetNextActor())
1282 if(aActor->GetVisibility())
1284 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1286 if(aSActor->hasIO())
1287 aSActor->Highlight( this, aSelectionEvent, true );
1292 aSelectionEvent->myIsRectangle = false;
1293 aSelectionEvent->myIsPolygon = false;
1294 aSelectionEvent->myPolygonPoints.clear();
1296 Interactor->EndPickCallback();
1297 GetSelector()->EndPickCallback();
1301 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1302 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1303 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1304 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1306 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1309 Interactor->GetSize(w, h);
1311 y = h - myPoint.y() - 1;
1322 Called during viewer operation when user moves mouse (!put necessary processing here!)
1324 void SVTK_InteractorStyle::onOperation(QPoint mousePos)
1326 if (!GetRenderWidget())
1330 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1332 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1336 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1338 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1342 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1344 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1348 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1350 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1354 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1358 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1361 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1363 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1365 myOtherPoint = mousePos;
1366 if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1368 else if ( myPoligonState != Finished )
1372 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1373 this->InteractiveSelection();
1378 Called when user moves mouse inside viewer window and there is no active viewer operation
1379 (!put necessary processing here!)
1381 void SVTK_InteractorStyle::onCursorMove(QPoint /*mousePos*/)
1383 if ( !GetSelector()->IsPreSelectionEnabled() )
1386 // processing highlighting
1387 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1388 this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1390 bool anIsChanged = false;
1392 SALOME_Actor* aPreHighlightedActor = NULL;
1393 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1395 if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1397 myHighlightSelectionPointActor->SetVisibility( false );
1399 if( anActorCollection )
1401 anActorCollection->InitTraversal();
1402 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1404 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1406 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1407 myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1408 vtkIdType aVtkId = myPointPicker->GetPointId();
1409 if ( aVtkId >= 0 ) {
1410 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
1412 SVTK_TIndexedMapOfVtkId aMapIndex;
1413 aMapIndex.Add( anObjId );
1414 myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1416 myHighlightSelectionPointActor->SetVisibility( true );
1425 if( anActorCollection )
1427 anActorCollection->InitTraversal();
1428 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1430 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1432 anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1433 if( anActor->isPreselected() )
1435 aPreHighlightedActor = anActor;
1442 if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1443 anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );
1447 myLastPreHighlitedActor = aPreHighlightedActor;
1454 Called on finsh GlobalPan operation
1456 void SVTK_InteractorStyle::Place(const int theX, const int theY)
1458 if (GetCurrentRenderer() == NULL)
1462 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1463 int centerX = aSize[0]/2;
1464 int centerY = aSize[1]/2;
1466 TranslateView(centerX, centerY, theX, theY);
1468 // restore zoom scale
1469 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1470 cam->SetParallelScale(myScale);
1471 GetCurrentRenderer()->ResetCameraClippingRange();
1479 Translates view from Point to Point
1481 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1483 if (GetCurrentRenderer() == NULL)
1486 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1487 double viewFocus[4], focalDepth, viewPoint[3];
1488 double newPickPoint[4], oldPickPoint[4], motionVector[3];
1489 cam->GetFocalPoint(viewFocus);
1491 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1492 viewFocus[2], viewFocus);
1493 focalDepth = viewFocus[2];
1495 this->ComputeDisplayToWorld(double(toX), double(toY),
1496 focalDepth, newPickPoint);
1497 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1498 focalDepth, oldPickPoint);
1500 // camera motion is reversed
1501 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1502 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1503 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1505 cam->GetFocalPoint(viewFocus);
1506 cam->GetPosition(viewPoint);
1507 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1508 motionVector[1] + viewFocus[1],
1509 motionVector[2] + viewFocus[2]);
1510 cam->SetPosition(motionVector[0] + viewPoint[0],
1511 motionVector[1] + viewPoint[1],
1512 motionVector[2] + viewPoint[2]);
1515 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1517 this->PanXY( incrX, incrY, 0, 0 );
1520 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1522 this->DollyXY( incr, incr );
1525 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1527 this->RotateXY( incrX, -incrY );
1530 void SVTK_InteractorStyle::InteractiveSelection()
1532 if (vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera()) {
1534 this->Interactor->GetEventPosition(posX, posY);
1535 double viewFocus[3], z;
1536 double* focalPointWorld = cam->GetFocalPoint();
1537 this->ComputeWorldToDisplay(focalPointWorld[0], focalPointWorld[1],
1538 focalPointWorld[2], viewFocus);
1541 this->ComputeDisplayToWorld(double(posX), double(posY),
1542 z, this->myInteractivePoint);
1543 InvokeEvent(SVTK::InteractiveSelectionChanged, (void*)this->myInteractivePoint);
1548 Redefined in order to add an observer (callback) for custorm event (space mouse event)
1550 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1552 // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1553 Superclass::SetInteractor( theInteractor );
1555 myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1558 // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1559 theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1560 theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1561 theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1562 theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1563 theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1564 theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1565 theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1566 theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1567 theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1568 theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1569 theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1570 theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1571 theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1572 theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1573 theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1575 theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1576 theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1577 theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1579 theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1580 theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1581 theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1582 theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1583 theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1585 theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1586 theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1588 theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1590 theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1591 theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1592 theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1593 theInteractor->AddObserver( SVTK::StartInteractiveSelection, EventCallbackCommand, Priority);
1594 theInteractor->AddObserver( SVTK::StopCurrentOperation, EventCallbackCommand, Priority);
1599 To implement cached rendering
1601 void SVTK_InteractorStyle::OnTimer()
1603 //vtkInteractorStyle::OnTimer();
1604 this->Interactor->Render();
1605 // check if bounding box was changed
1606 if ( GetCurrentRenderer() )
1608 #ifdef VGL_WORKAROUND
1609 GetCurrentRenderer()->Render();
1611 double aCurrBBCenter[3];
1612 if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1614 if ( !myBBFirstCheck )
1616 if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1617 fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1618 fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1619 // bounding box was changed => send SVTK::RotationPointChanged event
1620 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1621 InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1622 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1627 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1628 myBBFirstCheck = false;
1635 To invoke #vtkRenderWindowInteractor::CreateTimer
1637 void SVTK_InteractorStyle::Render()
1639 this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1642 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1644 // general things, do SetCurrentRenderer() within FindPokedRenderer()
1646 GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1647 FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1649 IncrementalZoom( (int)data[2] ); // 1. push toward / pull backward = zoom out / zoom in
1650 IncrementalPan( (int)data[0], (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1651 IncrementalRotate( 0, (int)data[4] ); // 4. twist the control = rotate around Y axis
1652 IncrementalRotate( (int)data[3], 0 ); // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1655 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1657 if( mySMDecreaseSpeedBtn == button ) {
1658 ControllerIncrement()->Decrease();
1660 if( mySMIncreaseSpeedBtn == button ) {
1661 ControllerIncrement()->Increase();
1663 if( mySMDominantCombinedSwitchBtn == button )
1664 DominantCombinedSwitch();
1667 void SVTK_InteractorStyle::DominantCombinedSwitch()
1669 printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1673 Draws rectangle by starting and current points
1675 void SVTK_InteractorStyle::drawRect()
1678 myRectBand = new QtxRectRubberBand( GetRenderWidget() );
1680 myRectBand->setUpdatesEnabled ( false );
1682 // The mouse events were already scaled up with a pixel ratio for a proper selection,
1683 // but rubber band's implemented with QPainter scales them on its own.
1684 // So, we need to pass unscaled coordinates to get a rectangle painted in a right place.
1685 const double pixelRatio = ViewerTools_ScreenScaling::getPR();
1686 QRect aRect = SUIT_Tools::makeRect(
1687 myPoint.x() / pixelRatio,
1688 myPoint.y() / pixelRatio,
1689 myOtherPoint.x() / pixelRatio,
1690 myOtherPoint.y() / pixelRatio);
1692 myRectBand->initGeometry( aRect );
1694 if ( !myRectBand->isVisible() )
1697 myRectBand->setUpdatesEnabled ( true );
1701 \brief Delete rubber band on the end on the dragging operation.
1703 void SVTK_InteractorStyle::endDrawRect()
1706 myRectBand->clearGeometry();
1711 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1712 const QPoint& theStart2, const QPoint& theEnd2 )
1714 if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1715 ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1718 if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1719 theStart1 == theEnd2 || theEnd1 == theEnd2 )
1722 double x11 = theStart1.x() * 1.0;
1723 double x12 = theEnd1.x() * 1.0;
1724 double y11 = theStart1.y() * 1.0;
1725 double y12 = theEnd1.y() * 1.0;
1727 double x21 = theStart2.x() * 1.0;
1728 double x22 = theEnd2.x() * 1.0;
1729 double y21 = theStart2.y() * 1.0;
1730 double y22 = theEnd2.y() * 1.0;
1732 double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1733 double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1735 double b1 = y11 - k1 * x11;
1736 double b2 = y21 - k2 * x21;
1743 return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1744 qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1745 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1746 qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1750 double x0 = ( b2 - b1 ) / ( k1 - k2 );
1751 double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1753 if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1754 qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1755 qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1756 qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1762 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1764 if ( !thePoints->count() )
1767 if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1770 const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1772 if ( aLast == theCurrent )
1776 for ( int i = 0; i < thePoints->count() - 1 && res; i++ )
1778 const QPoint& aStart = thePoints->point( i );
1779 const QPoint& anEnd = thePoints->point( i + 1 );
1780 res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1788 void SVTK_InteractorStyle::drawPolygon()
1790 // The mouse events were already scaled up with a pixel ratio for a proper selection,
1791 // but rubber band's implemented with QPainter scales them on its own.
1792 // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
1793 const double pixelRatio = ViewerTools_ScreenScaling::getPR();
1794 const QPoint myPointCopy(myPoint.x() / pixelRatio, myPoint.y() / pixelRatio);
1795 const QPoint myOtherPointCopy(myOtherPoint.x() / pixelRatio, myOtherPoint.y() / pixelRatio);
1797 QSize aToler( 5, 5 );
1798 if ( !myPolygonBand ) {
1799 myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1801 palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1802 myPolygonBand->setPalette( palette );
1803 myPolygonPoints.append(myPointCopy);
1805 myPolygonBand->hide();
1807 bool closed = false;
1808 bool valid = GetRenderWidget()->rect().contains(myOtherPointCopy);
1809 if ( !myPolygonPoints.at(0).isNull() )
1811 QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1812 2 * aToler.width(), 2 * aToler.height() );
1813 closed = aRect.contains(myOtherPointCopy);
1816 QPolygon* points = new QPolygon( myPolygonPoints );
1817 valid = valid && isValid(points, myOtherPointCopy);
1818 myPoligonState = valid ? InProcess : NotValid;
1820 if ( closed && !valid )
1823 if ( closed && myPolygonPoints.size() > 2 ) {
1824 GetRenderWidget()->setCursor( Qt::CrossCursor );
1825 myPoligonState = Closed;
1828 GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1830 GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1832 myPolygonPoints.append(myOtherPointCopy);
1834 QPolygon aPolygon( myPolygonPoints );
1835 myPolygonBand->initGeometry( aPolygon );
1836 myPolygonBand->setVisible( true );
1838 if ( myPolygonPoints.size() > 1 ) {
1839 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1844 \brief Delete rubber band on the end on the dragging operation.
1846 void SVTK_InteractorStyle::endDrawPolygon()
1848 if ( myPolygonBand ) myPolygonBand->hide();
1850 // RNV fix for : #19204 [CEA][Windows] VTK Viewer - Access violation while right clicking
1851 //delete myPolygonBand;
1852 myPolygonBand->deleteLater();
1855 myPolygonPoints.clear();
1859 Main process event method (reimplemented from #vtkInteractorStyle)
1861 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1862 unsigned long event,
1867 vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1868 SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1869 int aSpeedIncrement=self->ControllerIncrement()->Current();
1871 double* aSelectedPoint;
1874 case SVTK::SpaceMouseMoveEvent :
1875 self->onSpaceMouseMove( (double*)callData );
1877 case SVTK::SpaceMouseButtonEvent :
1878 self->onSpaceMouseButton( *((int*)callData) );
1880 case SVTK::PanLeftEvent:
1881 self->IncrementalPan(-aSpeedIncrement, 0);
1883 case SVTK::PanRightEvent:
1884 self->IncrementalPan(aSpeedIncrement, 0);
1886 case SVTK::PanUpEvent:
1887 self->IncrementalPan(0, aSpeedIncrement);
1889 case SVTK::PanDownEvent:
1890 self->IncrementalPan(0, -aSpeedIncrement);
1892 case SVTK::ZoomInEvent:
1893 self->IncrementalZoom(aSpeedIncrement);
1895 case SVTK::ZoomOutEvent:
1896 self->IncrementalZoom(-aSpeedIncrement);
1898 case SVTK::RotateLeftEvent:
1899 self->IncrementalRotate(-aSpeedIncrement, 0);
1901 case SVTK::RotateRightEvent:
1902 self->IncrementalRotate(aSpeedIncrement, 0);
1904 case SVTK::RotateUpEvent:
1905 self->IncrementalRotate(0, -aSpeedIncrement);
1907 case SVTK::RotateDownEvent:
1908 self->IncrementalRotate(0, aSpeedIncrement);
1910 case SVTK::PlusSpeedIncrementEvent:
1911 self->ControllerIncrement()->Increase();
1913 case SVTK::MinusSpeedIncrementEvent:
1914 self->ControllerIncrement()->Decrease();
1916 case SVTK::SetSpeedIncrementEvent:
1917 self->ControllerIncrement()->SetStartValue(*((int*)callData));
1920 case SVTK::SetSMDecreaseSpeedEvent:
1921 self->mySMDecreaseSpeedBtn = *((int*)callData);
1923 case SVTK::SetSMIncreaseSpeedEvent:
1924 self->mySMIncreaseSpeedBtn = *((int*)callData);
1926 case SVTK::SetSMDominantCombinedSwitchEvent:
1927 self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1930 case SVTK::StartZoom:
1933 case SVTK::StartPan:
1936 case SVTK::StartRotate:
1937 self->startRotate();
1939 case SVTK::StartGlobalPan:
1940 self->startGlobalPan();
1942 case SVTK::StartFitArea:
1943 self->startFitArea();
1946 case SVTK::SetRotateGravity:
1947 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1949 self->myHighlightSelectionPointActor->SetVisibility( false );
1950 if( self->GetCurrentRenderer() != NULL )
1951 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1952 self->GetRenderWidget()->setCursor(self->myDefCursor);
1954 self->myPrevRotationPointType = self->myCurrRotationPointType;
1955 self->myCurrRotationPointType = SVTK::SetRotateGravity;
1956 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) )
1957 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1958 self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1960 case SVTK::StartPointSelection:
1961 self->startPointSelection();
1964 case SVTK::ChangeRotationPoint:
1965 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1967 self->myHighlightSelectionPointActor->SetVisibility( false );
1968 if( self->GetCurrentRenderer() != NULL )
1969 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1970 self->GetRenderWidget()->setCursor(self->myDefCursor);
1972 self->myPrevRotationPointType = self->myCurrRotationPointType;
1973 self->myCurrRotationPointType = SVTK::SetRotateSelected;
1974 aSelectedPoint = (double*)callData;
1975 self->myRotationPointX = aSelectedPoint[0];
1976 self->myRotationPointY = aSelectedPoint[1];
1977 self->myRotationPointZ = aSelectedPoint[2];
1980 case SVTK::SetFocalPointGravity:
1981 if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1983 self->myHighlightSelectionPointActor->SetVisibility( false );
1984 if( self->GetCurrentRenderer() != NULL )
1985 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1986 self->GetRenderWidget()->setCursor(self->myDefCursor);
1988 self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1989 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1990 // invoke event for update coordinates in SVTK_ViewParameterDlg
1991 self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1994 case SVTK::StartFocalPointSelection:
1995 self->startFocalPointSelection();
1997 case SVTK::StartInteractiveSelection:
1998 self->startInteractiveSelection();
2000 case SVTK::SetFocalPointSelected:
2001 if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
2003 self->myHighlightSelectionPointActor->SetVisibility( false );
2004 if( self->GetCurrentRenderer() != NULL )
2005 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
2006 self->GetRenderWidget()->setCursor(self->myDefCursor);
2008 self->myPrevFocalPointType = self->myCurrFocalPointType;
2009 self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
2011 case SVTK::StopCurrentOperation:
2012 self->onFinishOperation();
2013 self->startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
2018 Superclass::ProcessEvents( object, event, clientData, callData );
2022 To handle keyboard event (reimplemented from #vtkInteractorStyle)
2024 void SVTK_InteractorStyle::OnChar()
2026 char key = GetInteractor()->GetKeyCode();
2028 case '+': ControllerIncrement()->Increase(); break;
2029 case '-': ControllerIncrement()->Decrease(); break;
2034 Redefined vtkInteractorStyle::OnKeyDown
2036 void SVTK_InteractorStyle::OnKeyDown()
2038 bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
2039 if (bInvokeSuperclass){
2040 Superclass::OnKeyDown();
2045 Provide instructions for Picking
2047 void SVTK_InteractorStyle::ActionPicking()
2050 Interactor->GetEventPosition( x, y );
2051 FindPokedRenderer( x, y );
2053 myOtherPoint = myPoint = QPoint(x, y);
2055 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
2056 onFinishOperation();
2057 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
2061 To set current increment controller
2063 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
2065 myControllerOnKeyDown=theController;
2069 To get current OnKeyDown controller
2071 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
2073 return myControllerOnKeyDown.GetPointer();
2077 To set current increment controller
2079 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
2081 myControllerIncrement=theController;
2085 To modify current increment controller
2087 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2089 SVTK_ControllerIncrement* c = 0;
2091 case 0: c = SVTK_ControllerIncrement::New(); break;
2092 case 1: c = SVTK_GeomControllerIncrement::New(); break;
2094 c->SetStartValue(theValue);
2096 SetControllerIncrement(c);
2101 To get current increment controller
2103 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2105 return myControllerIncrement.GetPointer();
2108 vtkStandardNewMacro(SVTK_ControllerIncrement)
2109 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2113 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2116 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2118 myIncrement=theValue;
2120 int SVTK_ControllerIncrement::Current()const
2124 int SVTK_ControllerIncrement::Increase()
2129 int SVTK_ControllerIncrement::Decrease()
2137 vtkStandardNewMacro(SVTK_GeomControllerIncrement)
2138 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2141 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2144 int SVTK_GeomControllerIncrement::Increase()
2149 int SVTK_GeomControllerIncrement::Decrease()
2158 vtkStandardNewMacro(SVTK_ControllerOnKeyDown)
2163 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2170 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2174 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* /*theIS*/)