1 // Copyright (C) 2007-2015 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>
62 #include <QRubberBand>
70 inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
74 theInteractor->GetEventPosition(theX,theY);
75 theY = theInteractor->GetSize()[1] - theY - 1;
80 vtkStandardNewMacro(SVTK_InteractorStyle);
86 SVTK_InteractorStyle::SVTK_InteractorStyle():
87 mySelectionEvent(new SVTK_SelectionEvent()),
88 myPointPicker(vtkPointPicker::New()),
89 myLastHighlitedActor(NULL),
90 myLastPreHighlitedActor(NULL),
91 myControllerIncrement(SVTK_ControllerIncrement::New()),
92 myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
93 myHighlightSelectionPointActor(SVTK_Actor::New()),
96 myIsAdvancedZoomingEnabled(false),
97 myPoligonState( Disable )
99 myPointPicker->Delete();
101 myPointPicker->SetTolerance(0.025);
103 this->MotionFactor = 10.0;
104 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
105 this->RadianToDegree = 180.0 / vtkMath::Pi();
106 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
110 // set custom event handling function (to handle 3d space mouse events)
111 EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
113 // set default values of properties. user may edit them in preferences.
114 mySMDecreaseSpeedBtn = 1;
115 mySMIncreaseSpeedBtn = 2;
116 mySMDominantCombinedSwitchBtn = 9;
118 myControllerIncrement->Delete();
119 myControllerOnKeyDown->Delete();
121 myCurrRotationPointType = SVTK::SetRotateGravity;
122 myPrevRotationPointType = myCurrRotationPointType;
124 myCurrFocalPointType = SVTK::SetFocalPointSelected;
125 myPrevFocalPointType = myCurrFocalPointType;
127 myHighlightSelectionPointActor->Delete();
128 myHighlightSelectionPointActor->Initialize();
129 myHighlightSelectionPointActor->PickableOff();
130 myHighlightSelectionPointActor->SetVisibility( false );
132 myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
133 myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
134 myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
136 myBBFirstCheck = true;
142 SVTK_InteractorStyle::~SVTK_InteractorStyle()
149 \return widget for rendering
151 QWidget* SVTK_InteractorStyle::GetRenderWidget()
153 return myInteractor->GetRenderWidget();
159 SVTK_Selector* SVTK_InteractorStyle::GetSelector()
161 return myInteractor->GetSelector();
167 void SVTK_InteractorStyle::FreeActors()
169 myLastHighlitedActor = NULL;
170 myLastPreHighlitedActor = NULL;
174 Generate special SVTK_SelectionEvent
176 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
178 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
180 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
181 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
183 mySelectionEvent->myLastX = mySelectionEvent->myX;
184 mySelectionEvent->myLastY = mySelectionEvent->myY;
186 GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
188 return mySelectionEvent.get();
192 Generate special SVTK_SelectionEvent with flipped Y coordinate
194 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
196 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
198 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
199 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
201 mySelectionEvent->myLastX = mySelectionEvent->myX;
202 mySelectionEvent->myLastY = mySelectionEvent->myY;
204 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
206 return mySelectionEvent.get();
209 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
211 /* if(GetCurrentRenderer() == NULL)
214 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
215 double aDeltaElevation = -20.0 / size[1];
216 double aDeltaAzimuth = -20.0 / size[0];
218 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
219 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
221 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
224 cam->OrthogonalizeViewUp();
226 GetCurrentRenderer()->ResetCameraClippingRange();
230 if(GetCurrentRenderer() == NULL)
233 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
235 double viewFP[3], viewPos[3];
236 cam->GetFocalPoint(viewFP);
237 cam->GetPosition(viewPos);
239 if ( myCurrRotationPointType == SVTK::SetRotateGravity )
242 if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) )
244 myRotationPointX = aCenter[0];
245 myRotationPointY = aCenter[1];
246 myRotationPointZ = aCenter[2];
250 // Calculate corresponding transformation
251 vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
252 aTransform->Identity();
253 aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
255 // Azimuth transformation
256 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
257 double aDeltaAzimuth = -20.0 / size[0];
259 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
260 aTransform->RotateWXYZ(rxf, cam->GetViewUp());
262 // Elevation transformation
263 double aDeltaElevation = -20.0 / size[1];
265 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
266 vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
267 const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
268 -aMatrix->GetElement(0,1),
269 -aMatrix->GetElement(0,2)};
271 aTransform->RotateWXYZ(ryf, anAxis);
273 aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
275 // To apply the transformation
276 cam->SetPosition(aTransform->TransformPoint(viewPos));
277 cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
278 aTransform->Delete();
280 cam->OrthogonalizeViewUp();
282 GetCurrentRenderer()->ResetCameraClippingRange();
285 this->InvokeEvent(SVTK::OperationFinished,NULL);
288 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
290 TranslateView(x, y, oldX, oldY);
292 this->InvokeEvent(SVTK::OperationFinished,NULL);
295 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
297 if (GetCurrentRenderer() == NULL)
300 double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
301 double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
303 double zoomFactor = pow((double)1.1, dxf + dyf);
305 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
306 if (aCam->GetParallelProjection()) {
307 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
308 if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
309 int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
314 x1 = myOtherPoint.x();
315 y1 = h - myOtherPoint.y();
316 TranslateView( x0, y0, x1, y1 );
318 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
319 if( IsAdvancedZoomingEnabled() )
320 TranslateView( x1, y1, x0, y0 );
323 aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
324 GetCurrentRenderer()->ResetCameraClippingRange();
328 this->InvokeEvent(SVTK::OperationFinished,NULL);
331 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
335 if (GetCurrentRenderer() == NULL)
338 double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
339 (double)(x - GetCurrentRenderer()->GetCenter()[0]));
340 double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
341 (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
343 newAngle *= this->RadianToDegree;
344 oldAngle *= this->RadianToDegree;
346 cam = GetCurrentRenderer()->GetActiveCamera();
347 cam->Roll(newAngle - oldAngle);
348 cam->OrthogonalizeViewUp();
351 this->InvokeEvent(SVTK::OperationFinished,NULL);
358 void SVTK_InteractorStyle::OnConfigure()
360 this->FindPokedRenderer(0,0);
361 this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
365 To handle mouse move event
367 void SVTK_InteractorStyle::OnMouseMove()
370 GetEventPosition( this->Interactor, x, y );
371 this->OnMouseMove( this->Interactor->GetControlKey(),
372 this->Interactor->GetShiftKey(),
377 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
379 void SVTK_InteractorStyle::OnLeftButtonDown()
382 GetEventPosition( this->Interactor, x, y );
383 this->OnLeftButtonDown( this->Interactor->GetControlKey(),
384 this->Interactor->GetShiftKey(),
389 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
391 void SVTK_InteractorStyle::OnLeftButtonUp()
394 GetEventPosition( this->Interactor, x, y );
395 this->OnLeftButtonUp( this->Interactor->GetControlKey(),
396 this->Interactor->GetShiftKey(),
401 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
403 void SVTK_InteractorStyle::OnMiddleButtonDown()
406 GetEventPosition( this->Interactor, x, y );
407 this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
408 this->Interactor->GetShiftKey(),
413 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
415 void SVTK_InteractorStyle::OnMiddleButtonUp()
418 GetEventPosition( this->Interactor, x, y );
419 this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
420 this->Interactor->GetShiftKey(),
425 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
427 void SVTK_InteractorStyle::OnRightButtonDown()
430 GetEventPosition( this->Interactor, x, y );
431 this->OnRightButtonDown( this->Interactor->GetControlKey(),
432 this->Interactor->GetShiftKey(),
437 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
439 void SVTK_InteractorStyle::OnRightButtonUp()
442 GetEventPosition( this->Interactor, x, y );
443 this->OnRightButtonUp( this->Interactor->GetControlKey(),
444 this->Interactor->GetShiftKey(),
449 To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
451 void SVTK_InteractorStyle::OnMouseWheelForward()
454 GetEventPosition( this->Interactor, x, y );
455 myOtherPoint = QPoint(x, y);
459 To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
461 void SVTK_InteractorStyle::OnMouseWheelBackward()
464 GetEventPosition( this->Interactor, x, y );
465 myOtherPoint = QPoint(x, y);
469 To handle mouse double click event
471 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
473 if( myPoligonState == InProcess ) {
475 myPoligonState = Finished;
480 To handle mouse move event
482 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
486 if ( myPoligonState == Start ) {
487 // if right button was pressed and mouse is moved
488 // we can to draw a polygon for polygonal selection
489 myPoligonState = InProcess;
490 startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
492 myShiftState = shift;
493 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
494 onOperation(QPoint(x, y));
495 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
496 onCursorMove(QPoint(x, y));
500 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
502 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
505 this->FindPokedRenderer(x, y);
506 if(GetCurrentRenderer() == NULL)
509 if ( myPoligonState != Disable )
512 myShiftState = shift;
513 // finishing current viewer operation
514 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
516 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
518 myOtherPoint = myPoint = QPoint(x, y);
519 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
520 startOperation(ForcedState);
523 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
524 else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
525 myCurrFocalPointType == SVTK::StartFocalPointSelection )
527 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
529 bool isPicked = false;
530 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
532 if( anActorCollection )
534 anActorCollection->InitTraversal();
535 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
537 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
539 Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
542 bool isTrueType = false;
544 if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
545 ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
547 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
548 myPointPicker->Pick( aSelectionEvent->myX,
549 aSelectionEvent->myY,
551 GetCurrentRenderer() );
552 aVtkId = myPointPicker->GetPointId();
555 int anObjId = anActor->GetNodeObjId( aVtkId );
556 aCoords = anActor->GetNodeCoord(anObjId);
561 if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection || aSelectionMode == VolumeSelection )
563 vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
564 aCellPicker->SetTolerance( 0.005 );
565 SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
566 aCellPicker->Pick( aSelectionEvent->myX,
567 aSelectionEvent->myY,
569 GetCurrentRenderer() );
570 aVtkId = aCellPicker->GetCellId();
571 int aCellId = anActor->GetElemObjId( aVtkId );
573 if( aSelectionMode == EdgeSelection )
574 isTrueType = anActor->GetObjDimension( aCellId ) == 1;
575 else if( aSelectionMode == FaceSelection )
576 isTrueType = anActor->GetObjDimension( aCellId ) == 2;
577 else if( aSelectionMode == VolumeSelection )
578 isTrueType = anActor->GetObjDimension( aCellId ) == 3;
580 if ( aVtkId >= 0 && isTrueType )
581 aCoords = anActor->GetGravityCenter( aCellId );
586 if (myCurrRotationPointType == SVTK::StartPointSelection) {
587 myCurrRotationPointType = SVTK::SetRotateSelected;
588 // invoke event for update coordinates in SVTK_SetRotationPointDlg
590 InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
592 InvokeEvent(SVTK::RotationPointChanged);
593 GetSelector()->SetSelectionMode(ActorSelection);
595 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
596 myCurrFocalPointType = SVTK::SetFocalPointSelected;
598 // invoke event for update coordinates in SVTK_ViewParameterDlg
599 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
611 if (myCurrRotationPointType == SVTK::StartPointSelection) {
612 // invoke event with no data (for SVTK_SetRotationPointDlg)
613 InvokeEvent(SVTK::RotationPointChanged,0);
614 myCurrRotationPointType = myPrevRotationPointType;
615 GetSelector()->SetSelectionMode(ActorSelection);
617 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
618 // invoke event with no data (for SVTK_ViewParameterDlg)
619 InvokeEvent(SVTK::FocalPointChanged,0);
620 myCurrFocalPointType = myPrevFocalPointType;
624 myHighlightSelectionPointActor->SetVisibility( false );
625 if(GetCurrentRenderer() != NULL)
626 GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
628 GetRenderWidget()->setCursor(myDefCursor);
631 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
638 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
640 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
645 myShiftState = shift;
646 if( myPoligonState == InProcess ) { // add a new point of polygon
647 myPolygonPoints.append( QPoint( x, y ) );
648 this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
649 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
652 else if ( myPoligonState == Closed ) { // close polygon and apply a selection
654 myPoligonState = Finished;
657 else if( myPoligonState == Finished || myPoligonState == NotValid )
659 // finishing current viewer operation
660 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
662 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
667 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
669 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
673 this->FindPokedRenderer(x, y);
674 if(GetCurrentRenderer() == NULL)
677 if ( myPoligonState != Disable )
680 myShiftState = shift;
681 // finishing current viewer operation
682 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
684 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
686 myOtherPoint = myPoint = QPoint(x, y);
687 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
688 startOperation(ForcedState);
692 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
698 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
700 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
705 if( myPoligonState == InProcess ) { // delete a point of polygon
706 if ( myPolygonPoints.size() > 2 ) {
707 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
708 mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
712 myShiftState = shift;
713 // finishing current viewer operation
714 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
716 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
722 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
724 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
728 this->FindPokedRenderer(x, y);
729 if(GetCurrentRenderer() == NULL)
732 myShiftState = shift;
735 myPoligonState = Start;
736 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
737 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
739 // finishing current viewer operation
740 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
742 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
744 myOtherPoint = myPoint = QPoint(x, y);
745 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
746 startOperation(ForcedState);
750 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
755 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
757 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
762 if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
763 myPoligonState = Disable;
764 mySelectionEvent->myPolygonPoints.clear();
767 if( myPoligonState != Disable ) {
769 myPoligonState = Finished;
770 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
774 myShiftState = shift;
775 // finishing current viewer operation
776 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
778 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
783 const char* imageZoomCursor[] = {
788 "................................",
789 "................................",
790 ".#######........................",
791 "..aaaaaaa.......................",
792 "................................",
793 ".............#####..............",
794 "...........##.aaaa##............",
795 "..........#.aa.....a#...........",
796 ".........#.a.........#..........",
797 ".........#a..........#a.........",
798 "........#.a...........#.........",
799 "........#a............#a........",
800 "........#a............#a........",
801 "........#a............#a........",
802 "........#a............#a........",
803 ".........#...........#.a........",
804 ".........#a..........#a.........",
805 ".........##.........#.a.........",
806 "........#####.....##.a..........",
807 ".......###aaa#####.aa...........",
808 "......###aa...aaaaa.......#.....",
809 ".....###aa................#a....",
810 "....###aa.................#a....",
811 "...###aa...............#######..",
812 "....#aa.................aa#aaaa.",
813 ".....a....................#a....",
814 "..........................#a....",
815 "...........................a....",
816 "................................",
817 "................................",
818 "................................",
819 "................................"};
821 const char* imageRotateCursor[] = {
826 "................................",
827 "................................",
828 "................................",
829 "................................",
830 "........#.......................",
831 ".......#.a......................",
832 "......#######...................",
833 ".......#aaaaa#####..............",
834 "........#..##.a#aa##........##..",
835 ".........a#.aa..#..a#.....##.aa.",
836 ".........#.a.....#...#..##.aa...",
837 ".........#a.......#..###.aa.....",
838 "........#.a.......#a..#aa.......",
839 "........#a.........#..#a........",
840 "........#a.........#a.#a........",
841 "........#a.........#a.#a........",
842 "........#a.........#a.#a........",
843 ".........#.........#a#.a........",
844 "........##a........#a#a.........",
845 "......##.a#.......#.#.a.........",
846 "....##.aa..##.....##.a..........",
847 "..##.aa.....a#####.aa...........",
848 "...aa.........aaa#a.............",
849 "................#.a.............",
850 "...............#.a..............",
851 "..............#.a...............",
852 "...............a................",
853 "................................",
854 "................................",
855 "................................",
856 "................................",
857 "................................"};
861 loads cursors for viewer operations - zoom, pan, etc...
863 void SVTK_InteractorStyle::loadCursors()
865 myDefCursor = QCursor(Qt::ArrowCursor);
866 myHandCursor = QCursor(Qt::PointingHandCursor);
867 myPanCursor = QCursor(Qt::SizeAllCursor);
868 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
869 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
870 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
871 myGlobalPanCursor = QCursor(Qt::CrossCursor);
872 myCursorState = false;
877 Starts Zoom operation (e.g. through menu command)
879 void SVTK_InteractorStyle::startZoom()
881 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
884 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
886 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
887 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
892 Starts Pan operation (e.g. through menu command)
894 void SVTK_InteractorStyle::startPan()
896 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
899 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
901 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
902 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
906 Starts Rotate operation (e.g. through menu command)
908 void SVTK_InteractorStyle::startRotate()
910 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
913 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
915 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
916 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
920 Set rotation point selected by user
922 void SVTK_InteractorStyle::startPointSelection()
924 myCurrRotationPointType = SVTK::StartPointSelection;
926 if(GetCurrentRenderer() != NULL) {
927 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
929 GetCurrentRenderer()->GetBackground( aColor );
930 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
935 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
939 Set focal point selected by user
941 void SVTK_InteractorStyle::startFocalPointSelection()
943 myCurrFocalPointType = SVTK::StartFocalPointSelection;
945 if(GetCurrentRenderer() != NULL) {
946 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
948 GetCurrentRenderer()->GetBackground( aColor );
949 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
954 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
958 Starts Spin operation (e.g. through menu command)
960 void SVTK_InteractorStyle::startSpin()
962 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
965 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
967 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
968 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
974 Starts Fit Area operation (e.g. through menu command)
976 void SVTK_InteractorStyle::startFitArea()
978 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
981 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
983 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
984 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
989 Starts Global Panning operation (e.g. through menu command)
991 void SVTK_InteractorStyle::startGlobalPan()
993 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
996 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
998 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
999 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
1001 // store current zoom scale
1002 myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
1004 GetCurrentRenderer()->ResetCamera();
1011 Fits viewer contents to rect
1013 void SVTK_InteractorStyle::fitRect(const int left,
1018 if (GetCurrentRenderer() == NULL)
1022 int x = (left + right)/2;
1023 int y = (top + bottom)/2;
1024 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1025 int oldX = aSize[0]/2;
1026 int oldY = aSize[1]/2;
1027 TranslateView(oldX, oldY, x, y);
1030 double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
1031 double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
1032 double zoomFactor = (dxf + dyf)/2 ;
1034 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
1035 if(aCam->GetParallelProjection())
1036 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
1038 aCam->Dolly(zoomFactor);
1039 GetCurrentRenderer()->ResetCameraClippingRange();
1047 Starts viewer operation (!internal usage!)
1049 void SVTK_InteractorStyle::startOperation(int operation)
1053 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1054 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1055 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1056 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1057 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1058 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1059 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1060 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1061 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1063 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1064 setCursor(operation);
1067 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1069 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1070 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1077 Sets proper cursor for window when viewer operation is activated
1079 void SVTK_InteractorStyle::setCursor(const int operation)
1081 if (!GetRenderWidget()) return;
1084 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1085 GetRenderWidget()->setCursor(myZoomCursor);
1086 myCursorState = true;
1088 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1089 GetRenderWidget()->setCursor(myPanCursor);
1090 myCursorState = true;
1092 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1093 GetRenderWidget()->setCursor(myRotateCursor);
1094 myCursorState = true;
1096 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1097 GetRenderWidget()->setCursor(mySpinCursor);
1098 myCursorState = true;
1100 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1101 GetRenderWidget()->setCursor(myGlobalPanCursor);
1102 myCursorState = true;
1104 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1105 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1106 GetRenderWidget()->setCursor(myHandCursor);
1107 myCursorState = true;
1109 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1111 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1112 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1113 GetRenderWidget()->setCursor(myHandCursor);
1115 GetRenderWidget()->setCursor(myDefCursor);
1116 myCursorState = false;
1123 Called when viewer operation started (!put necessary initialization here!)
1125 void SVTK_InteractorStyle::onStartOperation()
1127 if (!GetRenderWidget())
1130 vtkRenderWindowInteractor *aRWI = this->Interactor;
1131 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1132 aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1135 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1136 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1138 if ( myPoligonState == InProcess )
1144 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1145 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1146 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1147 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1148 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1155 Called when viewer operation finished (!put necessary post-processing here!)
1157 void SVTK_InteractorStyle::onFinishOperation()
1159 if (!GetRenderWidget())
1162 vtkRenderWindowInteractor *aRWI = this->Interactor;
1163 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1164 aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1166 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1169 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1170 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1173 QRect aRect(myPoint, myOtherPoint);
1174 aRect = aRect.normalized();
1176 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1177 // making fit rect opeation
1179 Interactor->GetSize(w, h);
1180 int x1 = aRect.left();
1181 int y1 = h - aRect.top() - 1;
1182 int x2 = aRect.right();
1183 int y2 = h - aRect.bottom() - 1;
1184 fitRect(x1, y1, x2, y2);
1187 if (myPoint == myOtherPoint)
1189 // process point selection
1190 this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1191 Interactor->StartPickCallback();
1193 SALOME_Actor* aHighlightedActor = NULL;
1194 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1196 aSelectionEvent->myIsRectangle = false;
1197 aSelectionEvent->myIsPolygon = false;
1199 GetSelector()->ClearIObjects();
1201 if( anActorCollection )
1203 anActorCollection->InitTraversal();
1204 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1206 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1208 if( anActor->Highlight( this, aSelectionEvent, true ) )
1210 aHighlightedActor = anActor;
1217 if( !aHighlightedActor )
1219 if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1220 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1222 myLastHighlitedActor = aHighlightedActor;
1226 if ( myPoligonState == InProcess || myPoligonState == Closed )
1227 aSelectionEvent->myIsPolygon = true;
1229 aSelectionEvent->myIsRectangle = true;
1231 //processing polygonal selection
1232 Interactor->StartPickCallback();
1233 GetSelector()->StartPickCallback();
1236 GetSelector()->ClearIObjects();
1238 VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1239 vtkActorCollection* aListActors = aCopy.GetActors();
1240 aListActors->InitTraversal();
1241 while(vtkActor* aActor = aListActors->GetNextActor())
1243 if(aActor->GetVisibility())
1245 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1247 if(aSActor->hasIO())
1248 aSActor->Highlight( this, aSelectionEvent, true );
1253 aSelectionEvent->myIsRectangle = false;
1254 aSelectionEvent->myIsPolygon = false;
1255 aSelectionEvent->myPolygonPoints.clear();
1257 Interactor->EndPickCallback();
1258 GetSelector()->EndPickCallback();
1262 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1263 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1264 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1265 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1267 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1270 Interactor->GetSize(w, h);
1272 y = h - myPoint.y() - 1;
1283 Called during viewer operation when user moves mouse (!put necessary processing here!)
1285 void SVTK_InteractorStyle::onOperation(QPoint mousePos)
1287 if (!GetRenderWidget())
1291 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1293 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1297 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1299 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1303 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1305 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1309 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1311 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1315 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1319 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1322 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1324 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1326 myOtherPoint = mousePos;
1327 if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1329 else if ( myPoligonState != Finished )
1337 Called when user moves mouse inside viewer window and there is no active viewer operation
1338 (!put necessary processing here!)
1340 void SVTK_InteractorStyle::onCursorMove(QPoint mousePos)
1342 if ( !GetSelector()->IsPreSelectionEnabled() )
1345 // processing highlighting
1346 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1347 this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1349 bool anIsChanged = false;
1351 SALOME_Actor* aPreHighlightedActor = NULL;
1352 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1354 if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1356 myHighlightSelectionPointActor->SetVisibility( false );
1358 if( anActorCollection )
1360 anActorCollection->InitTraversal();
1361 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1363 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1365 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1366 myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1367 int aVtkId = myPointPicker->GetPointId();
1368 if ( aVtkId >= 0 ) {
1369 int anObjId = anActor->GetNodeObjId( aVtkId );
1371 TColStd_IndexedMapOfInteger aMapIndex;
1372 aMapIndex.Add( anObjId );
1373 myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1375 myHighlightSelectionPointActor->SetVisibility( true );
1384 if( anActorCollection )
1386 anActorCollection->InitTraversal();
1387 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1389 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1391 anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1392 if( anActor->isPreselected() )
1394 aPreHighlightedActor = anActor;
1401 if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1402 anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );
1406 myLastPreHighlitedActor = aPreHighlightedActor;
1413 Called on finsh GlobalPan operation
1415 void SVTK_InteractorStyle::Place(const int theX, const int theY)
1417 if (GetCurrentRenderer() == NULL)
1421 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1422 int centerX = aSize[0]/2;
1423 int centerY = aSize[1]/2;
1425 TranslateView(centerX, centerY, theX, theY);
1427 // restore zoom scale
1428 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1429 cam->SetParallelScale(myScale);
1430 GetCurrentRenderer()->ResetCameraClippingRange();
1438 Translates view from Point to Point
1440 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1442 if (GetCurrentRenderer() == NULL)
1445 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1446 double viewFocus[4], focalDepth, viewPoint[3];
1447 double newPickPoint[4], oldPickPoint[4], motionVector[3];
1448 cam->GetFocalPoint(viewFocus);
1450 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1451 viewFocus[2], viewFocus);
1452 focalDepth = viewFocus[2];
1454 this->ComputeDisplayToWorld(double(toX), double(toY),
1455 focalDepth, newPickPoint);
1456 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1457 focalDepth, oldPickPoint);
1459 // camera motion is reversed
1460 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1461 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1462 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1464 cam->GetFocalPoint(viewFocus);
1465 cam->GetPosition(viewPoint);
1466 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1467 motionVector[1] + viewFocus[1],
1468 motionVector[2] + viewFocus[2]);
1469 cam->SetPosition(motionVector[0] + viewPoint[0],
1470 motionVector[1] + viewPoint[1],
1471 motionVector[2] + viewPoint[2]);
1474 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1476 this->PanXY( incrX, incrY, 0, 0 );
1479 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1481 this->DollyXY( incr, incr );
1484 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1486 this->RotateXY( incrX, -incrY );
1490 Redefined in order to add an observer (callback) for custorm event (space mouse event)
1492 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1494 // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1495 Superclass::SetInteractor( theInteractor );
1497 myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1500 // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1501 theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1502 theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1503 theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1504 theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1505 theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1506 theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1507 theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1508 theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1509 theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1510 theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1511 theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1512 theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1513 theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1514 theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1515 theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1517 theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1518 theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1519 theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1521 theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1522 theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1523 theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1524 theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1525 theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1527 theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1528 theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1530 theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1532 theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1533 theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1534 theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1539 To implement cached rendering
1541 void SVTK_InteractorStyle::OnTimer()
1543 //vtkInteractorStyle::OnTimer();
1544 this->Interactor->Render();
1545 // check if bounding box was changed
1546 if ( GetCurrentRenderer() )
1548 double aCurrBBCenter[3];
1549 if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1551 if ( !myBBFirstCheck )
1553 if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1554 fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1555 fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1556 // bounding box was changed => send SVTK::RotationPointChanged event
1557 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1558 InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1559 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1564 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1565 myBBFirstCheck = false;
1572 To invoke #vtkRenderWindowInteractor::CreateTimer
1574 void SVTK_InteractorStyle::Render()
1576 this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1579 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1581 // general things, do SetCurrentRenderer() within FindPokedRenderer()
1583 GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1584 FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1586 IncrementalZoom( (int)data[2] ); // 1. push toward / pull backward = zoom out / zoom in
1587 IncrementalPan( (int)data[0], (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1588 IncrementalRotate( 0, (int)data[4] ); // 4. twist the control = rotate around Y axis
1589 IncrementalRotate( (int)data[3], 0 ); // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1592 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1594 if( mySMDecreaseSpeedBtn == button ) {
1595 ControllerIncrement()->Decrease();
1597 if( mySMIncreaseSpeedBtn == button ) {
1598 ControllerIncrement()->Increase();
1600 if( mySMDominantCombinedSwitchBtn == button )
1601 DominantCombinedSwitch();
1604 void SVTK_InteractorStyle::DominantCombinedSwitch()
1606 printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1610 Draws rectangle by starting and current points
1612 void SVTK_InteractorStyle::drawRect()
1614 if ( !myRectBand ) {
1615 myRectBand = new QRubberBand( QRubberBand::Rectangle, GetRenderWidget() );
1617 palette.setColor(myRectBand->foregroundRole(), Qt::white);
1618 myRectBand->setPalette(palette);
1622 QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
1623 myRectBand->setGeometry( aRect );
1624 myRectBand->setVisible( aRect.isValid() );
1627 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1628 const QPoint& theStart2, const QPoint& theEnd2 )
1630 if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1631 ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1634 if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1635 theStart1 == theEnd2 || theEnd1 == theEnd2 )
1638 double x11 = theStart1.x() * 1.0;
1639 double x12 = theEnd1.x() * 1.0;
1640 double y11 = theStart1.y() * 1.0;
1641 double y12 = theEnd1.y() * 1.0;
1643 double x21 = theStart2.x() * 1.0;
1644 double x22 = theEnd2.x() * 1.0;
1645 double y21 = theStart2.y() * 1.0;
1646 double y22 = theEnd2.y() * 1.0;
1648 double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1649 double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1651 double b1 = y11 - k1 * x11;
1652 double b2 = y21 - k2 * x21;
1659 return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1660 qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1661 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1662 qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1666 double x0 = ( b2 - b1 ) / ( k1 - k2 );
1667 double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1669 if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1670 qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1671 qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1672 qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1678 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1680 if ( !thePoints->count() )
1683 if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1686 const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1688 if ( aLast == theCurrent )
1692 for ( uint i = 0; i < thePoints->count() - 1 && res; i++ )
1694 const QPoint& aStart = thePoints->point( i );
1695 const QPoint& anEnd = thePoints->point( i + 1 );
1696 res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1704 void SVTK_InteractorStyle::drawPolygon()
1706 QSize aToler( 5, 5 );
1707 if ( !myPolygonBand ) {
1708 myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1710 palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1711 myPolygonBand->setPalette( palette );
1712 myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) );
1714 myPolygonBand->hide();
1716 bool closed = false;
1717 bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1718 if ( !myPolygonPoints.at(0).isNull() )
1720 QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1721 2 * aToler.width(), 2 * aToler.height() );
1722 closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1725 QPolygon* points = new QPolygon( myPolygonPoints );
1726 valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1727 myPoligonState = valid ? InProcess : NotValid;
1729 if ( closed && !valid )
1732 if ( closed && myPolygonPoints.size() > 2 ) {
1733 GetRenderWidget()->setCursor( Qt::CrossCursor );
1734 myPoligonState = Closed;
1737 GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1739 GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1741 myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1743 QPolygon aPolygon( myPolygonPoints );
1744 myPolygonBand->initGeometry( aPolygon );
1745 myPolygonBand->setVisible( true );
1747 if ( myPolygonPoints.size() > 1 ) {
1748 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1753 \brief Delete rubber band on the end on the dragging operation.
1755 void SVTK_InteractorStyle::endDrawRect()
1757 if ( myRectBand ) myRectBand->hide();
1764 \brief Delete rubber band on the end on the dragging operation.
1766 void SVTK_InteractorStyle::endDrawPolygon()
1768 if ( myPolygonBand ) myPolygonBand->hide();
1770 delete myPolygonBand;
1773 myPolygonPoints.clear();
1777 Main process event method (reimplemented from #vtkInteractorStyle)
1779 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1780 unsigned long event,
1785 vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1786 SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1787 int aSpeedIncrement=self->ControllerIncrement()->Current();
1789 double* aSelectedPoint;
1792 case SVTK::SpaceMouseMoveEvent :
1793 self->onSpaceMouseMove( (double*)callData );
1795 case SVTK::SpaceMouseButtonEvent :
1796 self->onSpaceMouseButton( *((int*)callData) );
1798 case SVTK::PanLeftEvent:
1799 self->IncrementalPan(-aSpeedIncrement, 0);
1801 case SVTK::PanRightEvent:
1802 self->IncrementalPan(aSpeedIncrement, 0);
1804 case SVTK::PanUpEvent:
1805 self->IncrementalPan(0, aSpeedIncrement);
1807 case SVTK::PanDownEvent:
1808 self->IncrementalPan(0, -aSpeedIncrement);
1810 case SVTK::ZoomInEvent:
1811 self->IncrementalZoom(aSpeedIncrement);
1813 case SVTK::ZoomOutEvent:
1814 self->IncrementalZoom(-aSpeedIncrement);
1816 case SVTK::RotateLeftEvent:
1817 self->IncrementalRotate(-aSpeedIncrement, 0);
1819 case SVTK::RotateRightEvent:
1820 self->IncrementalRotate(aSpeedIncrement, 0);
1822 case SVTK::RotateUpEvent:
1823 self->IncrementalRotate(0, -aSpeedIncrement);
1825 case SVTK::RotateDownEvent:
1826 self->IncrementalRotate(0, aSpeedIncrement);
1828 case SVTK::PlusSpeedIncrementEvent:
1829 self->ControllerIncrement()->Increase();
1831 case SVTK::MinusSpeedIncrementEvent:
1832 self->ControllerIncrement()->Decrease();
1834 case SVTK::SetSpeedIncrementEvent:
1835 self->ControllerIncrement()->SetStartValue(*((int*)callData));
1838 case SVTK::SetSMDecreaseSpeedEvent:
1839 self->mySMDecreaseSpeedBtn = *((int*)callData);
1841 case SVTK::SetSMIncreaseSpeedEvent:
1842 self->mySMIncreaseSpeedBtn = *((int*)callData);
1844 case SVTK::SetSMDominantCombinedSwitchEvent:
1845 self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1848 case SVTK::StartZoom:
1851 case SVTK::StartPan:
1854 case SVTK::StartRotate:
1855 self->startRotate();
1857 case SVTK::StartGlobalPan:
1858 self->startGlobalPan();
1860 case SVTK::StartFitArea:
1861 self->startFitArea();
1864 case SVTK::SetRotateGravity:
1865 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1867 self->myHighlightSelectionPointActor->SetVisibility( false );
1868 if( self->GetCurrentRenderer() != NULL )
1869 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1870 self->GetRenderWidget()->setCursor(self->myDefCursor);
1872 self->myPrevRotationPointType = self->myCurrRotationPointType;
1873 self->myCurrRotationPointType = SVTK::SetRotateGravity;
1874 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) )
1875 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1876 self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1878 case SVTK::StartPointSelection:
1879 self->startPointSelection();
1882 case SVTK::ChangeRotationPoint:
1883 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1885 self->myHighlightSelectionPointActor->SetVisibility( false );
1886 if( self->GetCurrentRenderer() != NULL )
1887 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1888 self->GetRenderWidget()->setCursor(self->myDefCursor);
1890 self->myPrevRotationPointType = self->myCurrRotationPointType;
1891 self->myCurrRotationPointType = SVTK::SetRotateSelected;
1892 aSelectedPoint = (double*)callData;
1893 self->myRotationPointX = aSelectedPoint[0];
1894 self->myRotationPointY = aSelectedPoint[1];
1895 self->myRotationPointZ = aSelectedPoint[2];
1898 case SVTK::SetFocalPointGravity:
1899 if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1901 self->myHighlightSelectionPointActor->SetVisibility( false );
1902 if( self->GetCurrentRenderer() != NULL )
1903 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1904 self->GetRenderWidget()->setCursor(self->myDefCursor);
1906 self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1907 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1908 // invoke event for update coordinates in SVTK_ViewParameterDlg
1909 self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1912 case SVTK::StartFocalPointSelection:
1913 self->startFocalPointSelection();
1916 case SVTK::SetFocalPointSelected:
1917 if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
1919 self->myHighlightSelectionPointActor->SetVisibility( false );
1920 if( self->GetCurrentRenderer() != NULL )
1921 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1922 self->GetRenderWidget()->setCursor(self->myDefCursor);
1924 self->myPrevFocalPointType = self->myCurrFocalPointType;
1925 self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
1931 Superclass::ProcessEvents( object, event, clientData, callData );
1935 To handle keyboard event (reimplemented from #vtkInteractorStyle)
1937 void SVTK_InteractorStyle::OnChar()
1939 char key = GetInteractor()->GetKeyCode();
1941 case '+': ControllerIncrement()->Increase(); break;
1942 case '-': ControllerIncrement()->Decrease(); break;
1947 Redefined vtkInteractorStyle::OnKeyDown
1949 void SVTK_InteractorStyle::OnKeyDown()
1951 bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
1952 if (bInvokeSuperclass){
1953 Superclass::OnKeyDown();
1958 Provide instructions for Picking
1960 void SVTK_InteractorStyle::ActionPicking()
1963 Interactor->GetEventPosition( x, y );
1964 FindPokedRenderer( x, y );
1966 myOtherPoint = myPoint = QPoint(x, y);
1968 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1969 onFinishOperation();
1970 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1974 To set current increment controller
1976 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
1978 myControllerOnKeyDown=theController;
1982 To get current OnKeyDown controller
1984 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
1986 return myControllerOnKeyDown.GetPointer();
1990 To set current increment controller
1992 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
1994 myControllerIncrement=theController;
1998 To modify current increment controller
2000 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2002 SVTK_ControllerIncrement* c = 0;
2004 case 0: c = SVTK_ControllerIncrement::New(); break;
2005 case 1: c = SVTK_GeomControllerIncrement::New(); break;
2007 c->SetStartValue(theValue);
2009 SetControllerIncrement(c);
2014 To get current increment controller
2016 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2018 return myControllerIncrement.GetPointer();
2021 vtkStandardNewMacro(SVTK_ControllerIncrement);
2022 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2026 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2029 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2031 myIncrement=theValue;
2033 int SVTK_ControllerIncrement::Current()const
2037 int SVTK_ControllerIncrement::Increase()
2042 int SVTK_ControllerIncrement::Decrease()
2050 vtkStandardNewMacro(SVTK_GeomControllerIncrement);
2051 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2054 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2057 int SVTK_GeomControllerIncrement::Increase()
2062 int SVTK_GeomControllerIncrement::Decrease()
2071 vtkStandardNewMacro(SVTK_ControllerOnKeyDown);
2076 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2083 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2087 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* theIS)