1 // Copyright (C) 2007-2013 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.
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 <vtkRenderWindow.h>
52 #include <vtkRenderWindowInteractor.h>
53 #include <vtkCallbackCommand.h>
54 #include <vtkRendererCollection.h>
55 #include <vtkDataSet.h>
56 #include <vtkPerspectiveTransform.h>
57 #include <vtkMatrix4x4.h>
61 #include <QRubberBand>
69 inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
73 theInteractor->GetEventPosition(theX,theY);
74 theY = theInteractor->GetSize()[1] - theY - 1;
79 vtkStandardNewMacro(SVTK_InteractorStyle);
85 SVTK_InteractorStyle::SVTK_InteractorStyle():
86 mySelectionEvent(new SVTK_SelectionEvent()),
87 myPointPicker(vtkPointPicker::New()),
88 myLastHighlitedActor(NULL),
89 myLastPreHighlitedActor(NULL),
90 myControllerIncrement(SVTK_ControllerIncrement::New()),
91 myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
92 myHighlightSelectionPointActor(SVTK_Actor::New()),
95 myIsAdvancedZoomingEnabled(false),
96 myPoligonState( Disable )
98 myPointPicker->Delete();
100 myPointPicker->SetTolerance(0.025);
102 this->MotionFactor = 10.0;
103 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
104 this->RadianToDegree = 180.0 / vtkMath::Pi();
105 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
109 // set custom event handling function (to handle 3d space mouse events)
110 EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
112 // set default values of properties. user may edit them in preferences.
113 mySMDecreaseSpeedBtn = 1;
114 mySMIncreaseSpeedBtn = 2;
115 mySMDominantCombinedSwitchBtn = 9;
117 myControllerIncrement->Delete();
118 myControllerOnKeyDown->Delete();
120 myCurrRotationPointType = SVTK::SetRotateGravity;
121 myPrevRotationPointType = myCurrRotationPointType;
123 myCurrFocalPointType = SVTK::SetFocalPointSelected;
124 myPrevFocalPointType = myCurrFocalPointType;
126 myHighlightSelectionPointActor->Delete();
127 myHighlightSelectionPointActor->Initialize();
128 myHighlightSelectionPointActor->PickableOff();
129 myHighlightSelectionPointActor->SetVisibility( false );
131 myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
132 myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
133 myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
135 myBBFirstCheck = true;
141 SVTK_InteractorStyle::~SVTK_InteractorStyle()
148 \return widget for rendering
150 QWidget* SVTK_InteractorStyle::GetRenderWidget()
152 return myInteractor->GetRenderWidget();
158 SVTK_Selector* SVTK_InteractorStyle::GetSelector()
160 return myInteractor->GetSelector();
166 void SVTK_InteractorStyle::FreeActors()
168 myLastHighlitedActor = NULL;
169 myLastPreHighlitedActor = NULL;
173 Generate special SVTK_SelectionEvent
175 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
177 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
179 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
180 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
182 mySelectionEvent->myLastX = mySelectionEvent->myX;
183 mySelectionEvent->myLastY = mySelectionEvent->myY;
185 GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
187 return mySelectionEvent.get();
191 Generate special SVTK_SelectionEvent with flipped Y coordinate
193 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
195 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
197 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
198 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
200 mySelectionEvent->myLastX = mySelectionEvent->myX;
201 mySelectionEvent->myLastY = mySelectionEvent->myY;
203 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
205 return mySelectionEvent.get();
208 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
210 /* if(GetCurrentRenderer() == NULL)
213 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
214 double aDeltaElevation = -20.0 / size[1];
215 double aDeltaAzimuth = -20.0 / size[0];
217 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
218 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
220 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
223 cam->OrthogonalizeViewUp();
225 GetCurrentRenderer()->ResetCameraClippingRange();
229 if(GetCurrentRenderer() == NULL)
232 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
234 double viewFP[3], viewPos[3];
235 cam->GetFocalPoint(viewFP);
236 cam->GetPosition(viewPos);
238 if ( myCurrRotationPointType == SVTK::SetRotateGravity )
241 if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) )
243 myRotationPointX = aCenter[0];
244 myRotationPointY = aCenter[1];
245 myRotationPointZ = aCenter[2];
249 // Calculate corresponding transformation
250 vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
251 aTransform->Identity();
252 aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
254 // Azimuth transformation
255 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
256 double aDeltaAzimuth = -20.0 / size[0];
258 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
259 aTransform->RotateWXYZ(rxf, cam->GetViewUp());
261 // Elevation transformation
262 double aDeltaElevation = -20.0 / size[1];
264 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
265 vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
266 const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
267 -aMatrix->GetElement(0,1),
268 -aMatrix->GetElement(0,2)};
270 aTransform->RotateWXYZ(ryf, anAxis);
272 aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
274 // To apply the transformation
275 cam->SetPosition(aTransform->TransformPoint(viewPos));
276 cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
277 aTransform->Delete();
279 cam->OrthogonalizeViewUp();
281 GetCurrentRenderer()->ResetCameraClippingRange();
284 this->InvokeEvent(SVTK::OperationFinished,NULL);
287 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
289 TranslateView(x, y, oldX, oldY);
291 this->InvokeEvent(SVTK::OperationFinished,NULL);
294 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
296 if (GetCurrentRenderer() == NULL)
299 double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
300 double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
302 double zoomFactor = pow((double)1.1, dxf + dyf);
304 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
305 if (aCam->GetParallelProjection()) {
306 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
307 if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
308 int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
313 x1 = myOtherPoint.x();
314 y1 = h - myOtherPoint.y();
315 TranslateView( x0, y0, x1, y1 );
317 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
318 if( IsAdvancedZoomingEnabled() )
319 TranslateView( x1, y1, x0, y0 );
322 aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
323 GetCurrentRenderer()->ResetCameraClippingRange();
327 this->InvokeEvent(SVTK::OperationFinished,NULL);
330 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
334 if (GetCurrentRenderer() == NULL)
337 double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
338 (double)(x - GetCurrentRenderer()->GetCenter()[0]));
339 double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
340 (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
342 newAngle *= this->RadianToDegree;
343 oldAngle *= this->RadianToDegree;
345 cam = GetCurrentRenderer()->GetActiveCamera();
346 cam->Roll(newAngle - oldAngle);
347 cam->OrthogonalizeViewUp();
350 this->InvokeEvent(SVTK::OperationFinished,NULL);
357 void SVTK_InteractorStyle::OnConfigure()
359 this->FindPokedRenderer(0,0);
360 this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
364 To handle mouse move event
366 void SVTK_InteractorStyle::OnMouseMove()
369 GetEventPosition( this->Interactor, x, y );
370 this->OnMouseMove( this->Interactor->GetControlKey(),
371 this->Interactor->GetShiftKey(),
376 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
378 void SVTK_InteractorStyle::OnLeftButtonDown()
381 GetEventPosition( this->Interactor, x, y );
382 this->OnLeftButtonDown( this->Interactor->GetControlKey(),
383 this->Interactor->GetShiftKey(),
388 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
390 void SVTK_InteractorStyle::OnLeftButtonUp()
393 GetEventPosition( this->Interactor, x, y );
394 this->OnLeftButtonUp( this->Interactor->GetControlKey(),
395 this->Interactor->GetShiftKey(),
400 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
402 void SVTK_InteractorStyle::OnMiddleButtonDown()
405 GetEventPosition( this->Interactor, x, y );
406 this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
407 this->Interactor->GetShiftKey(),
412 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
414 void SVTK_InteractorStyle::OnMiddleButtonUp()
417 GetEventPosition( this->Interactor, x, y );
418 this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
419 this->Interactor->GetShiftKey(),
424 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
426 void SVTK_InteractorStyle::OnRightButtonDown()
429 GetEventPosition( this->Interactor, x, y );
430 this->OnRightButtonDown( this->Interactor->GetControlKey(),
431 this->Interactor->GetShiftKey(),
436 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
438 void SVTK_InteractorStyle::OnRightButtonUp()
441 GetEventPosition( this->Interactor, x, y );
442 this->OnRightButtonUp( this->Interactor->GetControlKey(),
443 this->Interactor->GetShiftKey(),
448 To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
450 void SVTK_InteractorStyle::OnMouseWheelForward()
453 GetEventPosition( this->Interactor, x, y );
454 myOtherPoint = QPoint(x, y);
458 To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
460 void SVTK_InteractorStyle::OnMouseWheelBackward()
463 GetEventPosition( this->Interactor, x, y );
464 myOtherPoint = QPoint(x, y);
468 To handle mouse double click event
470 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
472 if( myPoligonState == InProcess ) {
474 myPoligonState = Finished;
479 To handle mouse move event
481 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
485 if ( myPoligonState == Start ) {
486 // if right button was pressed and mouse is moved
487 // we can to draw a polygon for polygonal selection
488 myPoligonState = InProcess;
489 startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
491 myShiftState = shift;
492 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
493 onOperation(QPoint(x, y));
494 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
495 onCursorMove(QPoint(x, y));
499 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
501 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
504 this->FindPokedRenderer(x, y);
505 if(GetCurrentRenderer() == NULL)
508 if ( myPoligonState != Disable )
511 myShiftState = shift;
512 // finishing current viewer operation
513 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
515 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
517 myOtherPoint = myPoint = QPoint(x, y);
518 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
519 startOperation(ForcedState);
522 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
523 else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
524 myCurrFocalPointType == SVTK::StartFocalPointSelection )
526 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
528 bool isPicked = false;
529 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
531 if( anActorCollection )
533 anActorCollection->InitTraversal();
534 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
536 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
538 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
539 myPointPicker->Pick( aSelectionEvent->myX,
540 aSelectionEvent->myY,
542 GetCurrentRenderer() );
543 int aVtkId = myPointPicker->GetPointId();
546 int anObjId = anActor->GetNodeObjId( aVtkId );
547 double* aCoords = anActor->GetNodeCoord(anObjId);
549 if (myCurrRotationPointType == SVTK::StartPointSelection) {
550 myCurrRotationPointType = SVTK::SetRotateSelected;
552 // invoke event for update coordinates in SVTK_SetRotationPointDlg
553 InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
555 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
556 myCurrFocalPointType = SVTK::SetFocalPointSelected;
558 // invoke event for update coordinates in SVTK_ViewParameterDlg
559 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
571 if (myCurrRotationPointType == SVTK::StartPointSelection) {
572 // invoke event with no data (for SVTK_SetRotationPointDlg)
573 InvokeEvent(SVTK::RotationPointChanged,0);
574 myCurrRotationPointType = myPrevRotationPointType;
576 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
577 // invoke event with no data (for SVTK_ViewParameterDlg)
578 InvokeEvent(SVTK::FocalPointChanged,0);
579 myCurrFocalPointType = myPrevFocalPointType;
583 myHighlightSelectionPointActor->SetVisibility( false );
584 if(GetCurrentRenderer() != NULL)
585 GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
587 GetRenderWidget()->setCursor(myDefCursor);
590 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
597 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
599 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
604 myShiftState = shift;
605 if( myPoligonState == InProcess ) { // add a new point of polygon
606 myPolygonPoints.append( QPoint( x, y ) );
607 this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
608 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
611 else if ( myPoligonState == Closed ) { // close polygon and apply a selection
613 myPoligonState = Finished;
616 else if( myPoligonState == Finished || myPoligonState == NotValid )
618 // finishing current viewer operation
619 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
621 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
626 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
628 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
632 this->FindPokedRenderer(x, y);
633 if(GetCurrentRenderer() == NULL)
636 if ( myPoligonState != Disable )
639 myShiftState = shift;
640 // finishing current viewer operation
641 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
643 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
645 myOtherPoint = myPoint = QPoint(x, y);
646 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
647 startOperation(ForcedState);
651 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
657 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
659 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
664 if( myPoligonState == InProcess ) { // delete a point of polygon
665 if ( myPolygonPoints.size() > 2 ) {
666 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
667 mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
671 myShiftState = shift;
672 // finishing current viewer operation
673 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
675 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
681 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
683 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
687 this->FindPokedRenderer(x, y);
688 if(GetCurrentRenderer() == NULL)
691 myShiftState = shift;
694 myPoligonState = Start;
695 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
696 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
698 // finishing current viewer operation
699 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
701 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
703 myOtherPoint = myPoint = QPoint(x, y);
704 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
705 startOperation(ForcedState);
709 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
714 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
716 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
721 if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
722 myPoligonState = Disable;
723 mySelectionEvent->myPolygonPoints.clear();
726 if( myPoligonState != Disable ) {
728 myPoligonState = Finished;
729 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
733 myShiftState = shift;
734 // finishing current viewer operation
735 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
737 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
742 const char* imageZoomCursor[] = {
747 "................................",
748 "................................",
749 ".#######........................",
750 "..aaaaaaa.......................",
751 "................................",
752 ".............#####..............",
753 "...........##.aaaa##............",
754 "..........#.aa.....a#...........",
755 ".........#.a.........#..........",
756 ".........#a..........#a.........",
757 "........#.a...........#.........",
758 "........#a............#a........",
759 "........#a............#a........",
760 "........#a............#a........",
761 "........#a............#a........",
762 ".........#...........#.a........",
763 ".........#a..........#a.........",
764 ".........##.........#.a.........",
765 "........#####.....##.a..........",
766 ".......###aaa#####.aa...........",
767 "......###aa...aaaaa.......#.....",
768 ".....###aa................#a....",
769 "....###aa.................#a....",
770 "...###aa...............#######..",
771 "....#aa.................aa#aaaa.",
772 ".....a....................#a....",
773 "..........................#a....",
774 "...........................a....",
775 "................................",
776 "................................",
777 "................................",
778 "................................"};
780 const char* imageRotateCursor[] = {
785 "................................",
786 "................................",
787 "................................",
788 "................................",
789 "........#.......................",
790 ".......#.a......................",
791 "......#######...................",
792 ".......#aaaaa#####..............",
793 "........#..##.a#aa##........##..",
794 ".........a#.aa..#..a#.....##.aa.",
795 ".........#.a.....#...#..##.aa...",
796 ".........#a.......#..###.aa.....",
797 "........#.a.......#a..#aa.......",
798 "........#a.........#..#a........",
799 "........#a.........#a.#a........",
800 "........#a.........#a.#a........",
801 "........#a.........#a.#a........",
802 ".........#.........#a#.a........",
803 "........##a........#a#a.........",
804 "......##.a#.......#.#.a.........",
805 "....##.aa..##.....##.a..........",
806 "..##.aa.....a#####.aa...........",
807 "...aa.........aaa#a.............",
808 "................#.a.............",
809 "...............#.a..............",
810 "..............#.a...............",
811 "...............a................",
812 "................................",
813 "................................",
814 "................................",
815 "................................",
816 "................................"};
820 loads cursors for viewer operations - zoom, pan, etc...
822 void SVTK_InteractorStyle::loadCursors()
824 myDefCursor = QCursor(Qt::ArrowCursor);
825 myHandCursor = QCursor(Qt::PointingHandCursor);
826 myPanCursor = QCursor(Qt::SizeAllCursor);
827 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
828 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
829 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
830 myGlobalPanCursor = QCursor(Qt::CrossCursor);
831 myCursorState = false;
836 Starts Zoom operation (e.g. through menu command)
838 void SVTK_InteractorStyle::startZoom()
840 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
843 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
845 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
846 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
851 Starts Pan operation (e.g. through menu command)
853 void SVTK_InteractorStyle::startPan()
855 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
858 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
860 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
861 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
865 Starts Rotate operation (e.g. through menu command)
867 void SVTK_InteractorStyle::startRotate()
869 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
872 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
874 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
875 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
879 Set rotation point selected by user
881 void SVTK_InteractorStyle::startPointSelection()
883 myCurrRotationPointType = SVTK::StartPointSelection;
885 if(GetCurrentRenderer() != NULL) {
886 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
888 GetCurrentRenderer()->GetBackground( aColor );
889 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
894 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
898 Set focal point selected by user
900 void SVTK_InteractorStyle::startFocalPointSelection()
902 myCurrFocalPointType = SVTK::StartFocalPointSelection;
904 if(GetCurrentRenderer() != NULL) {
905 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
907 GetCurrentRenderer()->GetBackground( aColor );
908 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
913 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
917 Starts Spin operation (e.g. through menu command)
919 void SVTK_InteractorStyle::startSpin()
921 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
924 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
926 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
927 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
933 Starts Fit Area operation (e.g. through menu command)
935 void SVTK_InteractorStyle::startFitArea()
937 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
940 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
942 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
943 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
948 Starts Global Panning operation (e.g. through menu command)
950 void SVTK_InteractorStyle::startGlobalPan()
952 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
955 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
957 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
958 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
960 // store current zoom scale
961 myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
963 GetCurrentRenderer()->ResetCamera();
970 Fits viewer contents to rect
972 void SVTK_InteractorStyle::fitRect(const int left,
977 if (GetCurrentRenderer() == NULL)
981 int x = (left + right)/2;
982 int y = (top + bottom)/2;
983 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
984 int oldX = aSize[0]/2;
985 int oldY = aSize[1]/2;
986 TranslateView(oldX, oldY, x, y);
989 double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
990 double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
991 double zoomFactor = (dxf + dyf)/2 ;
993 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
994 if(aCam->GetParallelProjection())
995 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
997 aCam->Dolly(zoomFactor);
998 GetCurrentRenderer()->ResetCameraClippingRange();
1006 Starts viewer operation (!internal usage!)
1008 void SVTK_InteractorStyle::startOperation(int operation)
1012 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1013 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1014 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1015 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1016 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1017 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1018 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1019 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1020 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1022 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1023 setCursor(operation);
1026 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1028 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1029 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1036 Sets proper cursor for window when viewer operation is activated
1038 void SVTK_InteractorStyle::setCursor(const int operation)
1040 if (!GetRenderWidget()) return;
1043 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1044 GetRenderWidget()->setCursor(myZoomCursor);
1045 myCursorState = true;
1047 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1048 GetRenderWidget()->setCursor(myPanCursor);
1049 myCursorState = true;
1051 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1052 GetRenderWidget()->setCursor(myRotateCursor);
1053 myCursorState = true;
1055 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1056 GetRenderWidget()->setCursor(mySpinCursor);
1057 myCursorState = true;
1059 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1060 GetRenderWidget()->setCursor(myGlobalPanCursor);
1061 myCursorState = true;
1063 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1064 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1065 GetRenderWidget()->setCursor(myHandCursor);
1066 myCursorState = true;
1068 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1070 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1071 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1072 GetRenderWidget()->setCursor(myHandCursor);
1074 GetRenderWidget()->setCursor(myDefCursor);
1075 myCursorState = false;
1082 Called when viewer operation started (!put necessary initialization here!)
1084 void SVTK_InteractorStyle::onStartOperation()
1086 if (!GetRenderWidget())
1089 vtkRenderWindowInteractor *aRWI = this->Interactor;
1090 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1091 aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1094 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1095 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1097 if ( myPoligonState == InProcess )
1103 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1104 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1105 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1106 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1107 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1114 Called when viewer operation finished (!put necessary post-processing here!)
1116 void SVTK_InteractorStyle::onFinishOperation()
1118 if (!GetRenderWidget())
1121 vtkRenderWindowInteractor *aRWI = this->Interactor;
1122 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1123 aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1125 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1128 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1129 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1132 QRect aRect(myPoint, myOtherPoint);
1133 aRect = aRect.normalized();
1135 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1136 // making fit rect opeation
1138 Interactor->GetSize(w, h);
1139 int x1 = aRect.left();
1140 int y1 = h - aRect.top() - 1;
1141 int x2 = aRect.right();
1142 int y2 = h - aRect.bottom() - 1;
1143 fitRect(x1, y1, x2, y2);
1146 if (myPoint == myOtherPoint)
1148 // process point selection
1149 this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1150 Interactor->StartPickCallback();
1152 SALOME_Actor* aHighlightedActor = NULL;
1153 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1155 aSelectionEvent->myIsRectangle = false;
1156 aSelectionEvent->myIsPolygon = false;
1158 GetSelector()->ClearIObjects();
1160 if( anActorCollection )
1162 anActorCollection->InitTraversal();
1163 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1165 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1167 if( anActor->Highlight( this, aSelectionEvent, true ) )
1169 aHighlightedActor = anActor;
1176 if( !aHighlightedActor )
1178 if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1179 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1181 myLastHighlitedActor = aHighlightedActor;
1185 if ( myPoligonState == InProcess || myPoligonState == Closed )
1186 aSelectionEvent->myIsPolygon = true;
1188 aSelectionEvent->myIsRectangle = true;
1190 //processing polygonal selection
1191 Interactor->StartPickCallback();
1192 GetSelector()->StartPickCallback();
1195 GetSelector()->ClearIObjects();
1197 VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1198 vtkActorCollection* aListActors = aCopy.GetActors();
1199 aListActors->InitTraversal();
1200 while(vtkActor* aActor = aListActors->GetNextActor())
1202 if(aActor->GetVisibility())
1204 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1206 if(aSActor->hasIO())
1207 aSActor->Highlight( this, aSelectionEvent, true );
1212 aSelectionEvent->myIsRectangle = false;
1213 aSelectionEvent->myIsPolygon = false;
1214 aSelectionEvent->myPolygonPoints.clear();
1216 Interactor->EndPickCallback();
1217 GetSelector()->EndPickCallback();
1221 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1222 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1223 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1224 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1226 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1229 Interactor->GetSize(w, h);
1231 y = h - myPoint.y() - 1;
1242 Called during viewer operation when user moves mouse (!put necessary processing here!)
1244 void SVTK_InteractorStyle::onOperation(QPoint mousePos)
1246 if (!GetRenderWidget())
1250 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1252 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1256 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1258 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1262 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1264 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1268 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1270 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1274 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1278 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1281 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1283 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1285 myOtherPoint = mousePos;
1286 if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1288 else if ( myPoligonState != Finished )
1296 Called when user moves mouse inside viewer window and there is no active viewer operation
1297 (!put necessary processing here!)
1299 void SVTK_InteractorStyle::onCursorMove(QPoint mousePos)
1301 if ( !GetSelector()->IsPreSelectionEnabled() )
1304 // processing highlighting
1305 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1306 this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1308 bool anIsChanged = false;
1310 SALOME_Actor* aPreHighlightedActor = NULL;
1311 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1313 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1314 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1316 myHighlightSelectionPointActor->SetVisibility( false );
1318 if( anActorCollection )
1320 anActorCollection->InitTraversal();
1321 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1323 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1325 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1326 myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1327 int aVtkId = myPointPicker->GetPointId();
1328 if ( aVtkId >= 0 ) {
1329 int anObjId = anActor->GetNodeObjId( aVtkId );
1331 TColStd_IndexedMapOfInteger aMapIndex;
1332 aMapIndex.Add( anObjId );
1333 myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1335 myHighlightSelectionPointActor->SetVisibility( true );
1344 if( anActorCollection )
1346 anActorCollection->InitTraversal();
1347 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1349 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1351 anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1352 if( anActor->isPreselected() )
1354 aPreHighlightedActor = anActor;
1361 if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1362 anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );
1366 myLastPreHighlitedActor = aPreHighlightedActor;
1373 Called on finsh GlobalPan operation
1375 void SVTK_InteractorStyle::Place(const int theX, const int theY)
1377 if (GetCurrentRenderer() == NULL)
1381 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1382 int centerX = aSize[0]/2;
1383 int centerY = aSize[1]/2;
1385 TranslateView(centerX, centerY, theX, theY);
1387 // restore zoom scale
1388 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1389 cam->SetParallelScale(myScale);
1390 GetCurrentRenderer()->ResetCameraClippingRange();
1398 Translates view from Point to Point
1400 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1402 if (GetCurrentRenderer() == NULL)
1405 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1406 double viewFocus[4], focalDepth, viewPoint[3];
1407 double newPickPoint[4], oldPickPoint[4], motionVector[3];
1408 cam->GetFocalPoint(viewFocus);
1410 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1411 viewFocus[2], viewFocus);
1412 focalDepth = viewFocus[2];
1414 this->ComputeDisplayToWorld(double(toX), double(toY),
1415 focalDepth, newPickPoint);
1416 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1417 focalDepth, oldPickPoint);
1419 // camera motion is reversed
1420 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1421 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1422 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1424 cam->GetFocalPoint(viewFocus);
1425 cam->GetPosition(viewPoint);
1426 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1427 motionVector[1] + viewFocus[1],
1428 motionVector[2] + viewFocus[2]);
1429 cam->SetPosition(motionVector[0] + viewPoint[0],
1430 motionVector[1] + viewPoint[1],
1431 motionVector[2] + viewPoint[2]);
1434 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1436 this->PanXY( incrX, incrY, 0, 0 );
1439 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1441 this->DollyXY( incr, incr );
1444 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1446 this->RotateXY( incrX, -incrY );
1450 Redefined in order to add an observer (callback) for custorm event (space mouse event)
1452 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1454 // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1455 Superclass::SetInteractor( theInteractor );
1457 myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1460 // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1461 theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1462 theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1463 theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1464 theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1465 theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1466 theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1467 theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1468 theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1469 theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1470 theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1471 theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1472 theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1473 theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1474 theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1475 theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1477 theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1478 theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1479 theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1481 theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1482 theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1483 theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1484 theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1485 theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1487 theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1488 theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1490 theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1492 theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1493 theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1494 theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1499 To implement cached rendering
1501 void SVTK_InteractorStyle::OnTimer()
1503 //vtkInteractorStyle::OnTimer();
1504 this->Interactor->Render();
1505 // check if bounding box was changed
1506 if ( GetCurrentRenderer() )
1508 double aCurrBBCenter[3];
1509 if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1511 if ( !myBBFirstCheck )
1513 if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1514 fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1515 fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1516 // bounding box was changed => send SVTK::RotationPointChanged event
1517 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1518 InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1519 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1524 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1525 myBBFirstCheck = false;
1532 To invoke #vtkRenderWindowInteractor::CreateTimer
1534 void SVTK_InteractorStyle::Render()
1536 this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1539 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1541 // general things, do SetCurrentRenderer() within FindPokedRenderer()
1543 GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1544 FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1546 IncrementalZoom( (int)data[2] ); // 1. push toward / pull backward = zoom out / zoom in
1547 IncrementalPan( (int)data[0], (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1548 IncrementalRotate( 0, (int)data[4] ); // 4. twist the control = rotate around Y axis
1549 IncrementalRotate( (int)data[3], 0 ); // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1552 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1554 if( mySMDecreaseSpeedBtn == button ) {
1555 ControllerIncrement()->Decrease();
1557 if( mySMIncreaseSpeedBtn == button ) {
1558 ControllerIncrement()->Increase();
1560 if( mySMDominantCombinedSwitchBtn == button )
1561 DominantCombinedSwitch();
1564 void SVTK_InteractorStyle::DominantCombinedSwitch()
1566 printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1570 Draws rectangle by starting and current points
1572 void SVTK_InteractorStyle::drawRect()
1574 if ( !myRectBand ) {
1575 myRectBand = new QRubberBand( QRubberBand::Rectangle, GetRenderWidget() );
1577 palette.setColor(myRectBand->foregroundRole(), Qt::white);
1578 myRectBand->setPalette(palette);
1582 QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
1583 myRectBand->setGeometry( aRect );
1584 myRectBand->setVisible( aRect.isValid() );
1587 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1588 const QPoint& theStart2, const QPoint& theEnd2 )
1590 if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1591 ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1594 if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1595 theStart1 == theEnd2 || theEnd1 == theEnd2 )
1598 double x11 = theStart1.x() * 1.0;
1599 double x12 = theEnd1.x() * 1.0;
1600 double y11 = theStart1.y() * 1.0;
1601 double y12 = theEnd1.y() * 1.0;
1603 double x21 = theStart2.x() * 1.0;
1604 double x22 = theEnd2.x() * 1.0;
1605 double y21 = theStart2.y() * 1.0;
1606 double y22 = theEnd2.y() * 1.0;
1608 double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1609 double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1611 double b1 = y11 - k1 * x11;
1612 double b2 = y21 - k2 * x21;
1619 return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1620 qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1621 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1622 qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1626 double x0 = ( b2 - b1 ) / ( k1 - k2 );
1627 double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1629 if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1630 qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1631 qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1632 qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1638 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1640 if ( !thePoints->count() )
1643 if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1646 const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1648 if ( aLast == theCurrent )
1652 for ( uint i = 0; i < thePoints->count() - 1 && res; i++ )
1654 const QPoint& aStart = thePoints->point( i );
1655 const QPoint& anEnd = thePoints->point( i + 1 );
1656 res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1664 void SVTK_InteractorStyle::drawPolygon()
1666 QSize aToler( 5, 5 );
1667 if ( !myPolygonBand ) {
1668 myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1670 palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1671 myPolygonBand->setPalette( palette );
1672 myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) );
1674 myPolygonBand->hide();
1676 bool closed = false;
1677 bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1678 if ( !myPolygonPoints.at(0).isNull() )
1680 QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1681 2 * aToler.width(), 2 * aToler.height() );
1682 closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1685 QPolygon* points = new QPolygon( myPolygonPoints );
1686 valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1687 myPoligonState = valid ? InProcess : NotValid;
1689 if ( closed && !valid )
1692 if ( closed && myPolygonPoints.size() > 2 ) {
1693 GetRenderWidget()->setCursor( Qt::CrossCursor );
1694 myPoligonState = Closed;
1697 GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1699 GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1701 myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1703 QPolygon aPolygon( myPolygonPoints );
1704 myPolygonBand->initGeometry( aPolygon );
1705 myPolygonBand->setVisible( true );
1707 if ( myPolygonPoints.size() > 1 ) {
1708 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1713 \brief Delete rubber band on the end on the dragging operation.
1715 void SVTK_InteractorStyle::endDrawRect()
1717 if ( myRectBand ) myRectBand->hide();
1724 \brief Delete rubber band on the end on the dragging operation.
1726 void SVTK_InteractorStyle::endDrawPolygon()
1728 if ( myPolygonBand ) myPolygonBand->hide();
1730 delete myPolygonBand;
1733 myPolygonPoints.clear();
1737 Main process event method (reimplemented from #vtkInteractorStyle)
1739 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1740 unsigned long event,
1745 vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1746 SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1747 int aSpeedIncrement=self->ControllerIncrement()->Current();
1749 double* aSelectedPoint;
1752 case SVTK::SpaceMouseMoveEvent :
1753 self->onSpaceMouseMove( (double*)callData );
1755 case SVTK::SpaceMouseButtonEvent :
1756 self->onSpaceMouseButton( *((int*)callData) );
1758 case SVTK::PanLeftEvent:
1759 self->IncrementalPan(-aSpeedIncrement, 0);
1761 case SVTK::PanRightEvent:
1762 self->IncrementalPan(aSpeedIncrement, 0);
1764 case SVTK::PanUpEvent:
1765 self->IncrementalPan(0, aSpeedIncrement);
1767 case SVTK::PanDownEvent:
1768 self->IncrementalPan(0, -aSpeedIncrement);
1770 case SVTK::ZoomInEvent:
1771 self->IncrementalZoom(aSpeedIncrement);
1773 case SVTK::ZoomOutEvent:
1774 self->IncrementalZoom(-aSpeedIncrement);
1776 case SVTK::RotateLeftEvent:
1777 self->IncrementalRotate(-aSpeedIncrement, 0);
1779 case SVTK::RotateRightEvent:
1780 self->IncrementalRotate(aSpeedIncrement, 0);
1782 case SVTK::RotateUpEvent:
1783 self->IncrementalRotate(0, -aSpeedIncrement);
1785 case SVTK::RotateDownEvent:
1786 self->IncrementalRotate(0, aSpeedIncrement);
1788 case SVTK::PlusSpeedIncrementEvent:
1789 self->ControllerIncrement()->Increase();
1791 case SVTK::MinusSpeedIncrementEvent:
1792 self->ControllerIncrement()->Decrease();
1794 case SVTK::SetSpeedIncrementEvent:
1795 self->ControllerIncrement()->SetStartValue(*((int*)callData));
1798 case SVTK::SetSMDecreaseSpeedEvent:
1799 self->mySMDecreaseSpeedBtn = *((int*)callData);
1801 case SVTK::SetSMIncreaseSpeedEvent:
1802 self->mySMIncreaseSpeedBtn = *((int*)callData);
1804 case SVTK::SetSMDominantCombinedSwitchEvent:
1805 self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1808 case SVTK::StartZoom:
1811 case SVTK::StartPan:
1814 case SVTK::StartRotate:
1815 self->startRotate();
1817 case SVTK::StartGlobalPan:
1818 self->startGlobalPan();
1820 case SVTK::StartFitArea:
1821 self->startFitArea();
1824 case SVTK::SetRotateGravity:
1825 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1827 self->myHighlightSelectionPointActor->SetVisibility( false );
1828 if( self->GetCurrentRenderer() != NULL )
1829 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1830 self->GetRenderWidget()->setCursor(self->myDefCursor);
1832 self->myPrevRotationPointType = self->myCurrRotationPointType;
1833 self->myCurrRotationPointType = SVTK::SetRotateGravity;
1834 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) )
1835 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1836 self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1838 case SVTK::StartPointSelection:
1839 self->startPointSelection();
1842 case SVTK::ChangeRotationPoint:
1843 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1845 self->myHighlightSelectionPointActor->SetVisibility( false );
1846 if( self->GetCurrentRenderer() != NULL )
1847 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1848 self->GetRenderWidget()->setCursor(self->myDefCursor);
1850 self->myPrevRotationPointType = self->myCurrRotationPointType;
1851 self->myCurrRotationPointType = SVTK::SetRotateSelected;
1852 aSelectedPoint = (double*)callData;
1853 self->myRotationPointX = aSelectedPoint[0];
1854 self->myRotationPointY = aSelectedPoint[1];
1855 self->myRotationPointZ = aSelectedPoint[2];
1858 case SVTK::SetFocalPointGravity:
1859 if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1861 self->myHighlightSelectionPointActor->SetVisibility( false );
1862 if( self->GetCurrentRenderer() != NULL )
1863 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1864 self->GetRenderWidget()->setCursor(self->myDefCursor);
1866 self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1867 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1868 // invoke event for update coordinates in SVTK_ViewParameterDlg
1869 self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1872 case SVTK::StartFocalPointSelection:
1873 self->startFocalPointSelection();
1876 case SVTK::SetFocalPointSelected:
1877 if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
1879 self->myHighlightSelectionPointActor->SetVisibility( false );
1880 if( self->GetCurrentRenderer() != NULL )
1881 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1882 self->GetRenderWidget()->setCursor(self->myDefCursor);
1884 self->myPrevFocalPointType = self->myCurrFocalPointType;
1885 self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
1891 Superclass::ProcessEvents( object, event, clientData, callData );
1895 To handle keyboard event (reimplemented from #vtkInteractorStyle)
1897 void SVTK_InteractorStyle::OnChar()
1899 char key = GetInteractor()->GetKeyCode();
1901 case '+': ControllerIncrement()->Increase(); break;
1902 case '-': ControllerIncrement()->Decrease(); break;
1907 Redefined vtkInteractorStyle::OnKeyDown
1909 void SVTK_InteractorStyle::OnKeyDown()
1911 bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
1912 if (bInvokeSuperclass){
1913 Superclass::OnKeyDown();
1918 Provide instructions for Picking
1920 void SVTK_InteractorStyle::ActionPicking()
1923 Interactor->GetEventPosition( x, y );
1924 FindPokedRenderer( x, y );
1926 myOtherPoint = myPoint = QPoint(x, y);
1928 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1929 onFinishOperation();
1930 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1934 To set current increment controller
1936 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
1938 myControllerOnKeyDown=theController;
1942 To get current OnKeyDown controller
1944 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
1946 return myControllerOnKeyDown.GetPointer();
1950 To set current increment controller
1952 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
1954 myControllerIncrement=theController;
1958 To modify current increment controller
1960 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
1962 SVTK_ControllerIncrement* c = 0;
1964 case 0: c = SVTK_ControllerIncrement::New(); break;
1965 case 1: c = SVTK_GeomControllerIncrement::New(); break;
1967 c->SetStartValue(theValue);
1969 SetControllerIncrement(c);
1974 To get current increment controller
1976 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
1978 return myControllerIncrement.GetPointer();
1981 vtkStandardNewMacro(SVTK_ControllerIncrement);
1982 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
1986 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
1989 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
1991 myIncrement=theValue;
1993 int SVTK_ControllerIncrement::Current()const
1997 int SVTK_ControllerIncrement::Increase()
2002 int SVTK_ControllerIncrement::Decrease()
2010 vtkStandardNewMacro(SVTK_GeomControllerIncrement);
2011 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2014 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2017 int SVTK_GeomControllerIncrement::Increase()
2022 int SVTK_GeomControllerIncrement::Decrease()
2031 vtkStandardNewMacro(SVTK_ControllerOnKeyDown);
2036 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2043 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2047 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* theIS)