1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, 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"
45 #include <vtkObjectFactory.h>
47 #include <vtkCommand.h>
48 #include <vtkCamera.h>
49 #include <vtkRenderer.h>
50 #include <vtkPointPicker.h>
51 #include <vtkCellPicker.h>
52 #include <vtkRenderWindow.h>
53 #include <vtkRenderWindowInteractor.h>
54 #include <vtkCallbackCommand.h>
55 #include <vtkRendererCollection.h>
56 #include <vtkDataSet.h>
57 #include <vtkPerspectiveTransform.h>
58 #include <vtkMatrix4x4.h>
60 #include <QtxRubberBand.h>
71 inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
75 theInteractor->GetEventPosition(theX,theY);
76 theY = theInteractor->GetSize()[1] - theY - 1;
81 vtkStandardNewMacro(SVTK_InteractorStyle)
87 SVTK_InteractorStyle::SVTK_InteractorStyle():
88 myLastHighlitedActor(NULL),
89 myLastPreHighlitedActor(NULL),
90 myControllerIncrement(SVTK_ControllerIncrement::New()),
91 myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
92 mySelectionEvent(new SVTK_SelectionEvent()),
93 myHighlightSelectionPointActor(SVTK_Actor::New()),
94 myPointPicker(vtkPointPicker::New()),
97 myPoligonState(Disable),
98 myIsAdvancedZoomingEnabled(false),
99 myInteractivePoint{0.0, 0.0, 0.0}
101 myPointPicker->Delete();
103 myPointPicker->SetTolerance(0.025);
105 this->MotionFactor = 10.0;
106 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
107 this->RadianToDegree = 180.0 / vtkMath::Pi();
108 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
112 // set custom event handling function (to handle 3d space mouse events)
113 EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
115 // set default values of properties. user may edit them in preferences.
116 mySMDecreaseSpeedBtn = 1;
117 mySMIncreaseSpeedBtn = 2;
118 mySMDominantCombinedSwitchBtn = 9;
120 myControllerIncrement->Delete();
121 myControllerOnKeyDown->Delete();
123 myCurrRotationPointType = SVTK::SetRotateGravity;
124 myPrevRotationPointType = myCurrRotationPointType;
126 myCurrFocalPointType = SVTK::SetFocalPointSelected;
127 myPrevFocalPointType = myCurrFocalPointType;
129 myHighlightSelectionPointActor->Delete();
130 myHighlightSelectionPointActor->Initialize();
131 myHighlightSelectionPointActor->PickableOff();
132 myHighlightSelectionPointActor->SetVisibility( false );
134 myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
135 myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
136 myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
138 myBBFirstCheck = true;
144 SVTK_InteractorStyle::~SVTK_InteractorStyle()
151 \return widget for rendering
153 QWidget* SVTK_InteractorStyle::GetRenderWidget()
155 return myInteractor->GetRenderWidget();
161 SVTK_Selector* SVTK_InteractorStyle::GetSelector()
163 return myInteractor->GetSelector();
169 void SVTK_InteractorStyle::FreeActors()
171 myLastHighlitedActor = NULL;
172 myLastPreHighlitedActor = NULL;
176 Generate special SVTK_SelectionEvent
178 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
180 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
182 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
183 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
185 mySelectionEvent->myLastX = mySelectionEvent->myX;
186 mySelectionEvent->myLastY = mySelectionEvent->myY;
188 GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
190 return mySelectionEvent.get();
194 Generate special SVTK_SelectionEvent with flipped Y coordinate
196 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
198 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
200 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
201 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
203 mySelectionEvent->myLastX = mySelectionEvent->myX;
204 mySelectionEvent->myLastY = mySelectionEvent->myY;
206 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
208 return mySelectionEvent.get();
211 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
213 /* if(GetCurrentRenderer() == NULL)
216 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
217 double aDeltaElevation = -20.0 / size[1];
218 double aDeltaAzimuth = -20.0 / size[0];
220 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
221 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
223 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
226 cam->OrthogonalizeViewUp();
228 GetCurrentRenderer()->ResetCameraClippingRange();
232 if(GetCurrentRenderer() == NULL)
235 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
237 double viewFP[3], viewPos[3];
238 cam->GetFocalPoint(viewFP);
239 cam->GetPosition(viewPos);
241 if ( myCurrRotationPointType == SVTK::SetRotateGravity )
244 if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) )
246 myRotationPointX = aCenter[0];
247 myRotationPointY = aCenter[1];
248 myRotationPointZ = aCenter[2];
252 // Calculate corresponding transformation
253 vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
254 aTransform->Identity();
255 aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
257 // Azimuth transformation
258 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
259 double aDeltaAzimuth = -20.0 / size[0];
261 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
262 aTransform->RotateWXYZ(rxf, cam->GetViewUp());
264 // Elevation transformation
265 double aDeltaElevation = -20.0 / size[1];
267 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
268 vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
269 const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
270 -aMatrix->GetElement(0,1),
271 -aMatrix->GetElement(0,2)};
273 aTransform->RotateWXYZ(ryf, anAxis);
275 aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
277 // To apply the transformation
278 cam->SetPosition(aTransform->TransformPoint(viewPos));
279 cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
280 aTransform->Delete();
282 cam->OrthogonalizeViewUp();
284 GetCurrentRenderer()->ResetCameraClippingRange();
287 this->InvokeEvent(SVTK::OperationFinished,NULL);
290 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
292 TranslateView(x, y, oldX, oldY);
294 this->InvokeEvent(SVTK::OperationFinished,NULL);
297 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
299 if (GetCurrentRenderer() == NULL)
302 double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
303 double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
305 double zoomFactor = pow((double)1.1, dxf + dyf);
307 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
308 if (aCam->GetParallelProjection()) {
309 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
310 if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
311 int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
316 x1 = myOtherPoint.x();
317 y1 = h - myOtherPoint.y();
318 TranslateView( x0, y0, x1, y1 );
320 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
321 if( IsAdvancedZoomingEnabled() )
322 TranslateView( x1, y1, x0, y0 );
325 aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
326 GetCurrentRenderer()->ResetCameraClippingRange();
330 this->InvokeEvent(SVTK::OperationFinished,NULL);
333 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
337 if (GetCurrentRenderer() == NULL)
340 double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
341 (double)(x - GetCurrentRenderer()->GetCenter()[0]));
342 double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
343 (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
345 newAngle *= this->RadianToDegree;
346 oldAngle *= this->RadianToDegree;
348 cam = GetCurrentRenderer()->GetActiveCamera();
349 cam->Roll(newAngle - oldAngle);
350 cam->OrthogonalizeViewUp();
353 this->InvokeEvent(SVTK::OperationFinished,NULL);
360 void SVTK_InteractorStyle::OnConfigure()
362 this->FindPokedRenderer(0,0);
363 this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
367 To handle mouse move event
369 void SVTK_InteractorStyle::OnMouseMove()
372 GetEventPosition( this->Interactor, x, y );
373 this->OnMouseMove( this->Interactor->GetControlKey(),
374 this->Interactor->GetShiftKey(),
379 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
381 void SVTK_InteractorStyle::OnLeftButtonDown()
384 GetEventPosition( this->Interactor, x, y );
385 this->OnLeftButtonDown( this->Interactor->GetControlKey(),
386 this->Interactor->GetShiftKey(),
391 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
393 void SVTK_InteractorStyle::OnLeftButtonUp()
396 GetEventPosition( this->Interactor, x, y );
397 this->OnLeftButtonUp( this->Interactor->GetControlKey(),
398 this->Interactor->GetShiftKey(),
403 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
405 void SVTK_InteractorStyle::OnMiddleButtonDown()
408 GetEventPosition( this->Interactor, x, y );
409 this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
410 this->Interactor->GetShiftKey(),
415 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
417 void SVTK_InteractorStyle::OnMiddleButtonUp()
420 GetEventPosition( this->Interactor, x, y );
421 this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
422 this->Interactor->GetShiftKey(),
427 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
429 void SVTK_InteractorStyle::OnRightButtonDown()
432 GetEventPosition( this->Interactor, x, y );
433 this->OnRightButtonDown( this->Interactor->GetControlKey(),
434 this->Interactor->GetShiftKey(),
439 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
441 void SVTK_InteractorStyle::OnRightButtonUp()
444 GetEventPosition( this->Interactor, x, y );
445 this->OnRightButtonUp( this->Interactor->GetControlKey(),
446 this->Interactor->GetShiftKey(),
451 To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
453 void SVTK_InteractorStyle::OnMouseWheelForward()
456 GetEventPosition( this->Interactor, x, y );
457 myOtherPoint = QPoint(x, y);
461 To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
463 void SVTK_InteractorStyle::OnMouseWheelBackward()
466 GetEventPosition( this->Interactor, x, y );
467 myOtherPoint = QPoint(x, y);
471 To handle mouse double click event
473 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
475 if( myPoligonState == InProcess ) {
477 myPoligonState = Finished;
482 To handle mouse move event
484 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
488 if ( myPoligonState == Start ) {
489 // if right button was pressed and mouse is moved
490 // we can to draw a polygon for polygonal selection
491 myPoligonState = InProcess;
492 startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
494 myShiftState = shift;
495 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
496 onOperation(QPoint(x, y));
497 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
498 onCursorMove(QPoint(x, y));
502 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
504 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
507 this->FindPokedRenderer(x, y);
508 if(GetCurrentRenderer() == NULL)
511 if ( myPoligonState != Disable )
514 myShiftState = shift;
515 // finishing current viewer operation
516 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
518 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
520 myOtherPoint = myPoint = QPoint(x, y);
521 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
522 startOperation(ForcedState);
525 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
526 else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
527 myCurrFocalPointType == SVTK::StartFocalPointSelection )
529 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
531 bool isPicked = false;
532 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
534 if( anActorCollection )
536 anActorCollection->InitTraversal();
537 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
539 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
541 Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
542 double* aCoords = NULL;
544 bool isTrueType = false;
546 if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
547 ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
549 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
550 myPointPicker->Pick( aSelectionEvent->myX,
551 aSelectionEvent->myY,
553 GetCurrentRenderer() );
554 aVtkId = myPointPicker->GetPointId();
557 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
558 aCoords = anActor->GetNodeCoord(anObjId);
563 if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection || aSelectionMode == VolumeSelection )
565 vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
566 aCellPicker->SetTolerance( 0.005 );
567 SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
568 aCellPicker->Pick( aSelectionEvent->myX,
569 aSelectionEvent->myY,
571 GetCurrentRenderer() );
572 aVtkId = aCellPicker->GetCellId();
573 vtkIdType aCellId = anActor->GetElemObjId( aVtkId );
575 if( aSelectionMode == EdgeSelection )
576 isTrueType = anActor->GetObjDimension( aCellId ) == 1;
577 else if( aSelectionMode == FaceSelection )
578 isTrueType = anActor->GetObjDimension( aCellId ) == 2;
579 else if( aSelectionMode == VolumeSelection )
580 isTrueType = anActor->GetObjDimension( aCellId ) == 3;
582 if ( aVtkId >= 0 && isTrueType )
583 aCoords = anActor->GetGravityCenter( aCellId );
588 if (myCurrRotationPointType == SVTK::StartPointSelection) {
589 myCurrRotationPointType = SVTK::SetRotateSelected;
590 // invoke event for update coordinates in SVTK_SetRotationPointDlg
592 InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
594 InvokeEvent(SVTK::RotationPointChanged);
595 GetSelector()->SetSelectionMode(ActorSelection);
597 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
598 myCurrFocalPointType = SVTK::SetFocalPointSelected;
600 // invoke event for update coordinates in SVTK_ViewParameterDlg
601 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
613 if (myCurrRotationPointType == SVTK::StartPointSelection) {
614 // invoke event with no data (for SVTK_SetRotationPointDlg)
615 InvokeEvent(SVTK::RotationPointChanged,0);
616 myCurrRotationPointType = myPrevRotationPointType;
617 GetSelector()->SetSelectionMode(ActorSelection);
619 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
620 // invoke event with no data (for SVTK_ViewParameterDlg)
621 InvokeEvent(SVTK::FocalPointChanged,0);
622 myCurrFocalPointType = myPrevFocalPointType;
626 myHighlightSelectionPointActor->SetVisibility( false );
627 if(GetCurrentRenderer() != NULL)
628 GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
630 GetRenderWidget()->setCursor(myDefCursor);
633 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
640 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
642 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
647 myShiftState = shift;
648 if( myPoligonState == InProcess ) { // add a new point of polygon
649 myPolygonPoints.append( QPoint( x, y ) );
650 this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
651 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
654 else if ( myPoligonState == Closed ) { // close polygon and apply a selection
656 myPoligonState = Finished;
659 else if( myPoligonState == Finished || myPoligonState == NotValid )
661 // finishing current viewer operation
662 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
664 int lastOperation = State;
665 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
666 if (lastOperation == VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
667 InvokeEvent(SVTK::InteractiveSelectionFinished, nullptr);
673 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
675 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
679 this->FindPokedRenderer(x, y);
680 if(GetCurrentRenderer() == NULL)
683 if ( myPoligonState != Disable )
686 myShiftState = shift;
687 // finishing current viewer operation
688 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
690 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
692 myOtherPoint = myPoint = QPoint(x, y);
693 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
694 ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
695 startOperation(ForcedState);
699 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
705 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
707 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
712 if( myPoligonState == InProcess ) { // delete a point of polygon
713 if ( myPolygonPoints.size() > 2 ) {
714 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
715 mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
719 myShiftState = shift;
720 // finishing current viewer operation
721 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
723 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
729 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
731 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
735 this->FindPokedRenderer(x, y);
736 if(GetCurrentRenderer() == NULL)
739 myShiftState = shift;
742 myPoligonState = Start;
743 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
744 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
746 // finishing current viewer operation
747 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
749 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
751 myOtherPoint = myPoint = QPoint(x, y);
752 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
753 ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
754 startOperation(ForcedState);
758 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
763 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
765 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
770 if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
771 myPoligonState = Disable;
772 mySelectionEvent->myPolygonPoints.clear();
775 if( myPoligonState != Disable ) {
777 myPoligonState = Finished;
778 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
782 myShiftState = shift;
783 // finishing current viewer operation
784 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
786 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
791 const char* imageZoomCursor[] = {
796 "................................",
797 "................................",
798 ".#######........................",
799 "..aaaaaaa.......................",
800 "................................",
801 ".............#####..............",
802 "...........##.aaaa##............",
803 "..........#.aa.....a#...........",
804 ".........#.a.........#..........",
805 ".........#a..........#a.........",
806 "........#.a...........#.........",
807 "........#a............#a........",
808 "........#a............#a........",
809 "........#a............#a........",
810 "........#a............#a........",
811 ".........#...........#.a........",
812 ".........#a..........#a.........",
813 ".........##.........#.a.........",
814 "........#####.....##.a..........",
815 ".......###aaa#####.aa...........",
816 "......###aa...aaaaa.......#.....",
817 ".....###aa................#a....",
818 "....###aa.................#a....",
819 "...###aa...............#######..",
820 "....#aa.................aa#aaaa.",
821 ".....a....................#a....",
822 "..........................#a....",
823 "...........................a....",
824 "................................",
825 "................................",
826 "................................",
827 "................................"};
829 const char* imageRotateCursor[] = {
834 "................................",
835 "................................",
836 "................................",
837 "................................",
838 "........#.......................",
839 ".......#.a......................",
840 "......#######...................",
841 ".......#aaaaa#####..............",
842 "........#..##.a#aa##........##..",
843 ".........a#.aa..#..a#.....##.aa.",
844 ".........#.a.....#...#..##.aa...",
845 ".........#a.......#..###.aa.....",
846 "........#.a.......#a..#aa.......",
847 "........#a.........#..#a........",
848 "........#a.........#a.#a........",
849 "........#a.........#a.#a........",
850 "........#a.........#a.#a........",
851 ".........#.........#a#.a........",
852 "........##a........#a#a.........",
853 "......##.a#.......#.#.a.........",
854 "....##.aa..##.....##.a..........",
855 "..##.aa.....a#####.aa...........",
856 "...aa.........aaa#a.............",
857 "................#.a.............",
858 "...............#.a..............",
859 "..............#.a...............",
860 "...............a................",
861 "................................",
862 "................................",
863 "................................",
864 "................................",
865 "................................"};
869 loads cursors for viewer operations - zoom, pan, etc...
871 void SVTK_InteractorStyle::loadCursors()
873 myDefCursor = QCursor(Qt::ArrowCursor);
874 myHandCursor = QCursor(Qt::PointingHandCursor);
875 myPanCursor = QCursor(Qt::SizeAllCursor);
876 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
877 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
878 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
879 myGlobalPanCursor = QCursor(Qt::CrossCursor);
880 myCursorState = false;
885 Starts Zoom operation (e.g. through menu command)
887 void SVTK_InteractorStyle::startZoom()
889 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
892 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
894 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
895 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
900 Starts Pan operation (e.g. through menu command)
902 void SVTK_InteractorStyle::startPan()
904 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
907 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
909 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
910 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
914 Starts Rotate operation (e.g. through menu command)
916 void SVTK_InteractorStyle::startRotate()
918 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
921 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
923 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
924 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
928 Starts Interactive Selection operation
930 void SVTK_InteractorStyle::startInteractiveSelection()
932 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
935 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
937 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION;
942 Set rotation point selected by user
944 void SVTK_InteractorStyle::startPointSelection()
946 myCurrRotationPointType = SVTK::StartPointSelection;
948 if(GetCurrentRenderer() != NULL) {
949 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
951 GetCurrentRenderer()->GetBackground( aColor );
952 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
957 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
961 Set focal point selected by user
963 void SVTK_InteractorStyle::startFocalPointSelection()
965 myCurrFocalPointType = SVTK::StartFocalPointSelection;
967 if(GetCurrentRenderer() != NULL) {
968 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
970 GetCurrentRenderer()->GetBackground( aColor );
971 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
976 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
980 Starts Spin operation (e.g. through menu command)
982 void SVTK_InteractorStyle::startSpin()
984 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
987 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
989 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
990 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
996 Starts Fit Area operation (e.g. through menu command)
998 void SVTK_InteractorStyle::startFitArea()
1000 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1002 onFinishOperation();
1003 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1005 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
1006 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
1011 Starts Global Panning operation (e.g. through menu command)
1013 void SVTK_InteractorStyle::startGlobalPan()
1015 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1017 onFinishOperation();
1018 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1020 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
1021 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
1023 // store current zoom scale
1024 myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
1026 GetCurrentRenderer()->ResetCamera();
1033 Fits viewer contents to rect
1035 void SVTK_InteractorStyle::fitRect(const int left,
1040 if (GetCurrentRenderer() == NULL)
1044 int x = (left + right)/2;
1045 int y = (top + bottom)/2;
1046 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1047 int oldX = aSize[0]/2;
1048 int oldY = aSize[1]/2;
1049 TranslateView(oldX, oldY, x, y);
1052 double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
1053 double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
1054 double zoomFactor = (dxf + dyf)/2 ;
1056 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
1057 if(aCam->GetParallelProjection())
1058 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
1060 aCam->Dolly(zoomFactor);
1061 GetCurrentRenderer()->ResetCameraClippingRange();
1069 Starts viewer operation (!internal usage!)
1071 void SVTK_InteractorStyle::startOperation(int operation)
1075 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1076 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1077 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1078 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1079 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1080 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1081 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1082 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1083 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1084 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1086 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1087 setCursor(operation);
1090 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1092 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1093 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1100 Sets proper cursor for window when viewer operation is activated
1102 void SVTK_InteractorStyle::setCursor(const int operation)
1104 if (!GetRenderWidget()) return;
1107 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1108 GetRenderWidget()->setCursor(myZoomCursor);
1109 myCursorState = true;
1111 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1112 GetRenderWidget()->setCursor(myPanCursor);
1113 myCursorState = true;
1115 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1116 GetRenderWidget()->setCursor(myRotateCursor);
1117 myCursorState = true;
1119 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1120 GetRenderWidget()->setCursor(mySpinCursor);
1121 myCursorState = true;
1123 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1124 GetRenderWidget()->setCursor(myGlobalPanCursor);
1125 myCursorState = true;
1127 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1128 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1129 GetRenderWidget()->setCursor(myHandCursor);
1130 myCursorState = true;
1132 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1134 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1135 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1136 GetRenderWidget()->setCursor(myHandCursor);
1138 GetRenderWidget()->setCursor(myDefCursor);
1139 myCursorState = false;
1146 Called when viewer operation started (!put necessary initialization here!)
1148 void SVTK_InteractorStyle::onStartOperation()
1150 if (!GetRenderWidget())
1153 vtkRenderWindowInteractor *aRWI = this->Interactor;
1154 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1155 aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1158 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1159 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1161 if ( myPoligonState == InProcess )
1167 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1169 InteractiveSelection();
1172 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1173 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1174 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1175 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1176 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1183 Called when viewer operation finished (!put necessary post-processing here!)
1185 void SVTK_InteractorStyle::onFinishOperation()
1187 if (!GetRenderWidget())
1190 vtkRenderWindowInteractor *aRWI = this->Interactor;
1191 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1192 aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1194 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1197 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1198 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1201 QRect aRect(myPoint, myOtherPoint);
1202 aRect = aRect.normalized();
1204 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1205 // making fit rect opeation
1207 Interactor->GetSize(w, h);
1208 int x1 = aRect.left();
1209 int y1 = h - aRect.top() - 1;
1210 int x2 = aRect.right();
1211 int y2 = h - aRect.bottom() - 1;
1212 fitRect(x1, y1, x2, y2);
1215 if (myPoint == myOtherPoint)
1217 // process point selection
1218 this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1219 Interactor->StartPickCallback();
1221 SALOME_Actor* aHighlightedActor = NULL;
1222 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1224 aSelectionEvent->myIsRectangle = false;
1225 aSelectionEvent->myIsPolygon = false;
1227 GetSelector()->ClearIObjects();
1229 if( anActorCollection )
1231 if( !myShiftState &&
1232 anActorCollection->GetNumberOfItems () > 1 &&
1233 myLastHighlitedActor.GetPointer() ) {
1234 anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
1236 anActorCollection->InitTraversal();
1237 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1239 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1241 if( anActor->Highlight( this, aSelectionEvent, true ) )
1243 aHighlightedActor = anActor;
1250 if( !aHighlightedActor )
1252 if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1253 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1255 myLastHighlitedActor = aHighlightedActor;
1259 if ( myPoligonState == InProcess || myPoligonState == Closed )
1260 aSelectionEvent->myIsPolygon = true;
1262 aSelectionEvent->myIsRectangle = true;
1264 //processing polygonal selection
1265 Interactor->StartPickCallback();
1266 GetSelector()->StartPickCallback();
1269 GetSelector()->ClearIObjects();
1271 VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1272 vtkActorCollection* aListActors = aCopy.GetActors();
1273 aListActors->InitTraversal();
1274 while(vtkActor* aActor = aListActors->GetNextActor())
1276 if(aActor->GetVisibility())
1278 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1280 if(aSActor->hasIO())
1281 aSActor->Highlight( this, aSelectionEvent, true );
1286 aSelectionEvent->myIsRectangle = false;
1287 aSelectionEvent->myIsPolygon = false;
1288 aSelectionEvent->myPolygonPoints.clear();
1290 Interactor->EndPickCallback();
1291 GetSelector()->EndPickCallback();
1295 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1296 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1297 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1298 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1300 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1303 Interactor->GetSize(w, h);
1305 y = h - myPoint.y() - 1;
1316 Called during viewer operation when user moves mouse (!put necessary processing here!)
1318 void SVTK_InteractorStyle::onOperation(QPoint mousePos)
1320 if (!GetRenderWidget())
1324 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1326 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1330 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1332 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1336 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1338 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1342 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1344 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1348 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1352 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1355 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1357 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1359 myOtherPoint = mousePos;
1360 if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1362 else if ( myPoligonState != Finished )
1366 case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
1367 this->InteractiveSelection();
1372 Called when user moves mouse inside viewer window and there is no active viewer operation
1373 (!put necessary processing here!)
1375 void SVTK_InteractorStyle::onCursorMove(QPoint /*mousePos*/)
1377 if ( !GetSelector()->IsPreSelectionEnabled() )
1380 // processing highlighting
1381 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1382 this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1384 bool anIsChanged = false;
1386 SALOME_Actor* aPreHighlightedActor = NULL;
1387 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1389 if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1391 myHighlightSelectionPointActor->SetVisibility( false );
1393 if( anActorCollection )
1395 anActorCollection->InitTraversal();
1396 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1398 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1400 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1401 myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1402 vtkIdType aVtkId = myPointPicker->GetPointId();
1403 if ( aVtkId >= 0 ) {
1404 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
1406 SVTK_TIndexedMapOfVtkId aMapIndex;
1407 aMapIndex.Add( anObjId );
1408 myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1410 myHighlightSelectionPointActor->SetVisibility( true );
1419 if( anActorCollection )
1421 anActorCollection->InitTraversal();
1422 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1424 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1426 anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1427 if( anActor->isPreselected() )
1429 aPreHighlightedActor = anActor;
1436 if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1437 anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );
1441 myLastPreHighlitedActor = aPreHighlightedActor;
1448 Called on finsh GlobalPan operation
1450 void SVTK_InteractorStyle::Place(const int theX, const int theY)
1452 if (GetCurrentRenderer() == NULL)
1456 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1457 int centerX = aSize[0]/2;
1458 int centerY = aSize[1]/2;
1460 TranslateView(centerX, centerY, theX, theY);
1462 // restore zoom scale
1463 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1464 cam->SetParallelScale(myScale);
1465 GetCurrentRenderer()->ResetCameraClippingRange();
1473 Translates view from Point to Point
1475 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1477 if (GetCurrentRenderer() == NULL)
1480 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1481 double viewFocus[4], focalDepth, viewPoint[3];
1482 double newPickPoint[4], oldPickPoint[4], motionVector[3];
1483 cam->GetFocalPoint(viewFocus);
1485 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1486 viewFocus[2], viewFocus);
1487 focalDepth = viewFocus[2];
1489 this->ComputeDisplayToWorld(double(toX), double(toY),
1490 focalDepth, newPickPoint);
1491 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1492 focalDepth, oldPickPoint);
1494 // camera motion is reversed
1495 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1496 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1497 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1499 cam->GetFocalPoint(viewFocus);
1500 cam->GetPosition(viewPoint);
1501 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1502 motionVector[1] + viewFocus[1],
1503 motionVector[2] + viewFocus[2]);
1504 cam->SetPosition(motionVector[0] + viewPoint[0],
1505 motionVector[1] + viewPoint[1],
1506 motionVector[2] + viewPoint[2]);
1509 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1511 this->PanXY( incrX, incrY, 0, 0 );
1514 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1516 this->DollyXY( incr, incr );
1519 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1521 this->RotateXY( incrX, -incrY );
1524 void SVTK_InteractorStyle::InteractiveSelection()
1526 if (vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera()) {
1528 this->Interactor->GetEventPosition(posX, posY);
1529 double viewFocus[3], z;
1530 double* focalPointWorld = cam->GetFocalPoint();
1531 this->ComputeWorldToDisplay(focalPointWorld[0], focalPointWorld[1],
1532 focalPointWorld[2], viewFocus);
1535 this->ComputeDisplayToWorld(double(posX), double(posY),
1536 z, this->myInteractivePoint);
1537 InvokeEvent(SVTK::InteractiveSelectionChanged, (void*)this->myInteractivePoint);
1542 Redefined in order to add an observer (callback) for custorm event (space mouse event)
1544 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1546 // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1547 Superclass::SetInteractor( theInteractor );
1549 myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1552 // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1553 theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1554 theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1555 theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1556 theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1557 theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1558 theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1559 theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1560 theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1561 theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1562 theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1563 theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1564 theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1565 theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1566 theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1567 theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1569 theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1570 theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1571 theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1573 theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1574 theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1575 theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1576 theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1577 theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1579 theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1580 theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1582 theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1584 theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1585 theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1586 theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1587 theInteractor->AddObserver( SVTK::StartInteractiveSelection, EventCallbackCommand, Priority);
1588 theInteractor->AddObserver( SVTK::StopCurrentOperation, EventCallbackCommand, Priority);
1593 To implement cached rendering
1595 void SVTK_InteractorStyle::OnTimer()
1597 //vtkInteractorStyle::OnTimer();
1598 this->Interactor->Render();
1599 // check if bounding box was changed
1600 if ( GetCurrentRenderer() )
1602 #ifdef VGL_WORKAROUND
1603 GetCurrentRenderer()->Render();
1605 double aCurrBBCenter[3];
1606 if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1608 if ( !myBBFirstCheck )
1610 if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1611 fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1612 fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1613 // bounding box was changed => send SVTK::RotationPointChanged event
1614 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1615 InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1616 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1621 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1622 myBBFirstCheck = false;
1629 To invoke #vtkRenderWindowInteractor::CreateTimer
1631 void SVTK_InteractorStyle::Render()
1633 this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1636 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1638 // general things, do SetCurrentRenderer() within FindPokedRenderer()
1640 GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1641 FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1643 IncrementalZoom( (int)data[2] ); // 1. push toward / pull backward = zoom out / zoom in
1644 IncrementalPan( (int)data[0], (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1645 IncrementalRotate( 0, (int)data[4] ); // 4. twist the control = rotate around Y axis
1646 IncrementalRotate( (int)data[3], 0 ); // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1649 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1651 if( mySMDecreaseSpeedBtn == button ) {
1652 ControllerIncrement()->Decrease();
1654 if( mySMIncreaseSpeedBtn == button ) {
1655 ControllerIncrement()->Increase();
1657 if( mySMDominantCombinedSwitchBtn == button )
1658 DominantCombinedSwitch();
1661 void SVTK_InteractorStyle::DominantCombinedSwitch()
1663 printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1667 Draws rectangle by starting and current points
1669 void SVTK_InteractorStyle::drawRect()
1672 myRectBand = new QtxRectRubberBand( GetRenderWidget() );
1674 myRectBand->setUpdatesEnabled ( false );
1675 QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
1676 myRectBand->initGeometry( aRect );
1678 if ( !myRectBand->isVisible() )
1681 myRectBand->setUpdatesEnabled ( true );
1685 \brief Delete rubber band on the end on the dragging operation.
1687 void SVTK_InteractorStyle::endDrawRect()
1690 myRectBand->clearGeometry();
1695 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1696 const QPoint& theStart2, const QPoint& theEnd2 )
1698 if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1699 ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1702 if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1703 theStart1 == theEnd2 || theEnd1 == theEnd2 )
1706 double x11 = theStart1.x() * 1.0;
1707 double x12 = theEnd1.x() * 1.0;
1708 double y11 = theStart1.y() * 1.0;
1709 double y12 = theEnd1.y() * 1.0;
1711 double x21 = theStart2.x() * 1.0;
1712 double x22 = theEnd2.x() * 1.0;
1713 double y21 = theStart2.y() * 1.0;
1714 double y22 = theEnd2.y() * 1.0;
1716 double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1717 double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1719 double b1 = y11 - k1 * x11;
1720 double b2 = y21 - k2 * x21;
1727 return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1728 qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1729 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1730 qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1734 double x0 = ( b2 - b1 ) / ( k1 - k2 );
1735 double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1737 if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1738 qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1739 qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1740 qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1746 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1748 if ( !thePoints->count() )
1751 if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1754 const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1756 if ( aLast == theCurrent )
1760 for ( int i = 0; i < thePoints->count() - 1 && res; i++ )
1762 const QPoint& aStart = thePoints->point( i );
1763 const QPoint& anEnd = thePoints->point( i + 1 );
1764 res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1772 void SVTK_InteractorStyle::drawPolygon()
1774 QSize aToler( 5, 5 );
1775 if ( !myPolygonBand ) {
1776 myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1778 palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1779 myPolygonBand->setPalette( palette );
1780 myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) );
1782 myPolygonBand->hide();
1784 bool closed = false;
1785 bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1786 if ( !myPolygonPoints.at(0).isNull() )
1788 QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1789 2 * aToler.width(), 2 * aToler.height() );
1790 closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1793 QPolygon* points = new QPolygon( myPolygonPoints );
1794 valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1795 myPoligonState = valid ? InProcess : NotValid;
1797 if ( closed && !valid )
1800 if ( closed && myPolygonPoints.size() > 2 ) {
1801 GetRenderWidget()->setCursor( Qt::CrossCursor );
1802 myPoligonState = Closed;
1805 GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1807 GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1809 myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1811 QPolygon aPolygon( myPolygonPoints );
1812 myPolygonBand->initGeometry( aPolygon );
1813 myPolygonBand->setVisible( true );
1815 if ( myPolygonPoints.size() > 1 ) {
1816 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1821 \brief Delete rubber band on the end on the dragging operation.
1823 void SVTK_InteractorStyle::endDrawPolygon()
1825 if ( myPolygonBand ) myPolygonBand->hide();
1827 // RNV fix for : #19204 [CEA][Windows] VTK Viewer - Access violation while right clicking
1828 //delete myPolygonBand;
1829 myPolygonBand->deleteLater();
1832 myPolygonPoints.clear();
1836 Main process event method (reimplemented from #vtkInteractorStyle)
1838 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1839 unsigned long event,
1844 vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1845 SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1846 int aSpeedIncrement=self->ControllerIncrement()->Current();
1848 double* aSelectedPoint;
1851 case SVTK::SpaceMouseMoveEvent :
1852 self->onSpaceMouseMove( (double*)callData );
1854 case SVTK::SpaceMouseButtonEvent :
1855 self->onSpaceMouseButton( *((int*)callData) );
1857 case SVTK::PanLeftEvent:
1858 self->IncrementalPan(-aSpeedIncrement, 0);
1860 case SVTK::PanRightEvent:
1861 self->IncrementalPan(aSpeedIncrement, 0);
1863 case SVTK::PanUpEvent:
1864 self->IncrementalPan(0, aSpeedIncrement);
1866 case SVTK::PanDownEvent:
1867 self->IncrementalPan(0, -aSpeedIncrement);
1869 case SVTK::ZoomInEvent:
1870 self->IncrementalZoom(aSpeedIncrement);
1872 case SVTK::ZoomOutEvent:
1873 self->IncrementalZoom(-aSpeedIncrement);
1875 case SVTK::RotateLeftEvent:
1876 self->IncrementalRotate(-aSpeedIncrement, 0);
1878 case SVTK::RotateRightEvent:
1879 self->IncrementalRotate(aSpeedIncrement, 0);
1881 case SVTK::RotateUpEvent:
1882 self->IncrementalRotate(0, -aSpeedIncrement);
1884 case SVTK::RotateDownEvent:
1885 self->IncrementalRotate(0, aSpeedIncrement);
1887 case SVTK::PlusSpeedIncrementEvent:
1888 self->ControllerIncrement()->Increase();
1890 case SVTK::MinusSpeedIncrementEvent:
1891 self->ControllerIncrement()->Decrease();
1893 case SVTK::SetSpeedIncrementEvent:
1894 self->ControllerIncrement()->SetStartValue(*((int*)callData));
1897 case SVTK::SetSMDecreaseSpeedEvent:
1898 self->mySMDecreaseSpeedBtn = *((int*)callData);
1900 case SVTK::SetSMIncreaseSpeedEvent:
1901 self->mySMIncreaseSpeedBtn = *((int*)callData);
1903 case SVTK::SetSMDominantCombinedSwitchEvent:
1904 self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1907 case SVTK::StartZoom:
1910 case SVTK::StartPan:
1913 case SVTK::StartRotate:
1914 self->startRotate();
1916 case SVTK::StartGlobalPan:
1917 self->startGlobalPan();
1919 case SVTK::StartFitArea:
1920 self->startFitArea();
1923 case SVTK::SetRotateGravity:
1924 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1926 self->myHighlightSelectionPointActor->SetVisibility( false );
1927 if( self->GetCurrentRenderer() != NULL )
1928 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1929 self->GetRenderWidget()->setCursor(self->myDefCursor);
1931 self->myPrevRotationPointType = self->myCurrRotationPointType;
1932 self->myCurrRotationPointType = SVTK::SetRotateGravity;
1933 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) )
1934 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1935 self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1937 case SVTK::StartPointSelection:
1938 self->startPointSelection();
1941 case SVTK::ChangeRotationPoint:
1942 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1944 self->myHighlightSelectionPointActor->SetVisibility( false );
1945 if( self->GetCurrentRenderer() != NULL )
1946 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1947 self->GetRenderWidget()->setCursor(self->myDefCursor);
1949 self->myPrevRotationPointType = self->myCurrRotationPointType;
1950 self->myCurrRotationPointType = SVTK::SetRotateSelected;
1951 aSelectedPoint = (double*)callData;
1952 self->myRotationPointX = aSelectedPoint[0];
1953 self->myRotationPointY = aSelectedPoint[1];
1954 self->myRotationPointZ = aSelectedPoint[2];
1957 case SVTK::SetFocalPointGravity:
1958 if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1960 self->myHighlightSelectionPointActor->SetVisibility( false );
1961 if( self->GetCurrentRenderer() != NULL )
1962 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1963 self->GetRenderWidget()->setCursor(self->myDefCursor);
1965 self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1966 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1967 // invoke event for update coordinates in SVTK_ViewParameterDlg
1968 self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1971 case SVTK::StartFocalPointSelection:
1972 self->startFocalPointSelection();
1974 case SVTK::StartInteractiveSelection:
1975 self->startInteractiveSelection();
1977 case SVTK::SetFocalPointSelected:
1978 if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
1980 self->myHighlightSelectionPointActor->SetVisibility( false );
1981 if( self->GetCurrentRenderer() != NULL )
1982 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1983 self->GetRenderWidget()->setCursor(self->myDefCursor);
1985 self->myPrevFocalPointType = self->myCurrFocalPointType;
1986 self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
1988 case SVTK::StopCurrentOperation:
1989 self->onFinishOperation();
1990 self->startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1995 Superclass::ProcessEvents( object, event, clientData, callData );
1999 To handle keyboard event (reimplemented from #vtkInteractorStyle)
2001 void SVTK_InteractorStyle::OnChar()
2003 char key = GetInteractor()->GetKeyCode();
2005 case '+': ControllerIncrement()->Increase(); break;
2006 case '-': ControllerIncrement()->Decrease(); break;
2011 Redefined vtkInteractorStyle::OnKeyDown
2013 void SVTK_InteractorStyle::OnKeyDown()
2015 bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
2016 if (bInvokeSuperclass){
2017 Superclass::OnKeyDown();
2022 Provide instructions for Picking
2024 void SVTK_InteractorStyle::ActionPicking()
2027 Interactor->GetEventPosition( x, y );
2028 FindPokedRenderer( x, y );
2030 myOtherPoint = myPoint = QPoint(x, y);
2032 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
2033 onFinishOperation();
2034 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
2038 To set current increment controller
2040 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
2042 myControllerOnKeyDown=theController;
2046 To get current OnKeyDown controller
2048 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
2050 return myControllerOnKeyDown.GetPointer();
2054 To set current increment controller
2056 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
2058 myControllerIncrement=theController;
2062 To modify current increment controller
2064 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2066 SVTK_ControllerIncrement* c = 0;
2068 case 0: c = SVTK_ControllerIncrement::New(); break;
2069 case 1: c = SVTK_GeomControllerIncrement::New(); break;
2071 c->SetStartValue(theValue);
2073 SetControllerIncrement(c);
2078 To get current increment controller
2080 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2082 return myControllerIncrement.GetPointer();
2085 vtkStandardNewMacro(SVTK_ControllerIncrement)
2086 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2090 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2093 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2095 myIncrement=theValue;
2097 int SVTK_ControllerIncrement::Current()const
2101 int SVTK_ControllerIncrement::Increase()
2106 int SVTK_ControllerIncrement::Decrease()
2114 vtkStandardNewMacro(SVTK_GeomControllerIncrement)
2115 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2118 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2121 int SVTK_GeomControllerIncrement::Increase()
2126 int SVTK_GeomControllerIncrement::Decrease()
2135 vtkStandardNewMacro(SVTK_ControllerOnKeyDown)
2140 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2147 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2151 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* /*theIS*/)