1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME VTKViewer : build VTK viewer into Salome desktop
27 #include "SVTK_InteractorStyle.h"
29 #include "VTKViewer_Algorithm.h"
30 #include "VTKViewer_Utilities.h"
31 #include "SVTK_GenericRenderWindowInteractor.h"
33 #include "SVTK_Selection.h"
34 #include "SVTK_Event.h"
35 #include "SVTK_Selector.h"
36 #include "SVTK_Functor.h"
37 #include "SVTK_Actor.h"
39 #include "VTKViewer_Algorithm.h"
40 #include "SVTK_Functor.h"
42 #include "SUIT_Tools.h"
43 #include "SALOME_Actor.h"
45 #include <vtkObjectFactory.h>
47 #include <vtkCommand.h>
48 #include <vtkCamera.h>
49 #include <vtkRenderer.h>
50 #include <vtkPointPicker.h>
51 #include <vtkCellPicker.h>
52 #include <vtkRenderWindow.h>
53 #include <vtkRenderWindowInteractor.h>
54 #include <vtkCallbackCommand.h>
55 #include <vtkRendererCollection.h>
56 #include <vtkDataSet.h>
57 #include <vtkPerspectiveTransform.h>
58 #include <vtkMatrix4x4.h>
60 #include <QtxRubberBand.h>
71 inline void GetEventPosition(vtkRenderWindowInteractor* theInteractor,
75 theInteractor->GetEventPosition(theX,theY);
76 theY = theInteractor->GetSize()[1] - theY - 1;
81 vtkStandardNewMacro(SVTK_InteractorStyle)
87 SVTK_InteractorStyle::SVTK_InteractorStyle():
88 myLastHighlitedActor(NULL),
89 myLastPreHighlitedActor(NULL),
90 myControllerIncrement(SVTK_ControllerIncrement::New()),
91 myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
92 mySelectionEvent(new SVTK_SelectionEvent()),
93 myHighlightSelectionPointActor(SVTK_Actor::New()),
94 myPointPicker(vtkPointPicker::New()),
97 myPoligonState(Disable),
98 myIsAdvancedZoomingEnabled(false)
100 myPointPicker->Delete();
102 myPointPicker->SetTolerance(0.025);
104 this->MotionFactor = 10.0;
105 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
106 this->RadianToDegree = 180.0 / vtkMath::Pi();
107 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
111 // set custom event handling function (to handle 3d space mouse events)
112 EventCallbackCommand->SetCallback( SVTK_InteractorStyle::ProcessEvents );
114 // set default values of properties. user may edit them in preferences.
115 mySMDecreaseSpeedBtn = 1;
116 mySMIncreaseSpeedBtn = 2;
117 mySMDominantCombinedSwitchBtn = 9;
119 myControllerIncrement->Delete();
120 myControllerOnKeyDown->Delete();
122 myCurrRotationPointType = SVTK::SetRotateGravity;
123 myPrevRotationPointType = myCurrRotationPointType;
125 myCurrFocalPointType = SVTK::SetFocalPointSelected;
126 myPrevFocalPointType = myCurrFocalPointType;
128 myHighlightSelectionPointActor->Delete();
129 myHighlightSelectionPointActor->Initialize();
130 myHighlightSelectionPointActor->PickableOff();
131 myHighlightSelectionPointActor->SetVisibility( false );
133 myHighlightSelectionPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2);
134 myHighlightSelectionPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2);
135 myHighlightSelectionPointActor->GetProperty()->SetRepresentationToPoints();
137 myBBFirstCheck = true;
143 SVTK_InteractorStyle::~SVTK_InteractorStyle()
150 \return widget for rendering
152 QWidget* SVTK_InteractorStyle::GetRenderWidget()
154 return myInteractor->GetRenderWidget();
160 SVTK_Selector* SVTK_InteractorStyle::GetSelector()
162 return myInteractor->GetSelector();
168 void SVTK_InteractorStyle::FreeActors()
170 myLastHighlitedActor = NULL;
171 myLastPreHighlitedActor = NULL;
175 Generate special SVTK_SelectionEvent
177 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEvent()
179 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
181 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
182 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
184 mySelectionEvent->myLastX = mySelectionEvent->myX;
185 mySelectionEvent->myLastY = mySelectionEvent->myY;
187 GetEventPosition( this->Interactor, mySelectionEvent->myX, mySelectionEvent->myY );
189 return mySelectionEvent.get();
193 Generate special SVTK_SelectionEvent with flipped Y coordinate
195 SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY()
197 mySelectionEvent->mySelectionMode = GetSelector()->SelectionMode();
199 mySelectionEvent->myIsCtrl = Interactor->GetControlKey();
200 mySelectionEvent->myIsShift = Interactor->GetShiftKey();
202 mySelectionEvent->myLastX = mySelectionEvent->myX;
203 mySelectionEvent->myLastY = mySelectionEvent->myY;
205 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
207 return mySelectionEvent.get();
210 void SVTK_InteractorStyle::RotateXY(int dx, int dy)
212 /* if(GetCurrentRenderer() == NULL)
215 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
216 double aDeltaElevation = -20.0 / size[1];
217 double aDeltaAzimuth = -20.0 / size[0];
219 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
220 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
222 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
225 cam->OrthogonalizeViewUp();
227 GetCurrentRenderer()->ResetCameraClippingRange();
231 if(GetCurrentRenderer() == NULL)
234 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
236 double viewFP[3], viewPos[3];
237 cam->GetFocalPoint(viewFP);
238 cam->GetPosition(viewPos);
240 if ( myCurrRotationPointType == SVTK::SetRotateGravity )
243 if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) )
245 myRotationPointX = aCenter[0];
246 myRotationPointY = aCenter[1];
247 myRotationPointZ = aCenter[2];
251 // Calculate corresponding transformation
252 vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New();
253 aTransform->Identity();
254 aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ);
256 // Azimuth transformation
257 int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
258 double aDeltaAzimuth = -20.0 / size[0];
260 double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor;
261 aTransform->RotateWXYZ(rxf, cam->GetViewUp());
263 // Elevation transformation
264 double aDeltaElevation = -20.0 / size[1];
266 double ryf = double(dy) * aDeltaElevation * this->MotionFactor;
267 vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix();
268 const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer.
269 -aMatrix->GetElement(0,1),
270 -aMatrix->GetElement(0,2)};
272 aTransform->RotateWXYZ(ryf, anAxis);
274 aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ);
276 // To apply the transformation
277 cam->SetPosition(aTransform->TransformPoint(viewPos));
278 cam->SetFocalPoint(aTransform->TransformPoint(viewFP));
279 aTransform->Delete();
281 cam->OrthogonalizeViewUp();
283 GetCurrentRenderer()->ResetCameraClippingRange();
286 this->InvokeEvent(SVTK::OperationFinished,NULL);
289 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
291 TranslateView(x, y, oldX, oldY);
293 this->InvokeEvent(SVTK::OperationFinished,NULL);
296 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
298 if (GetCurrentRenderer() == NULL)
301 double dxf = this->MotionFactor * (double)(dx) / (double)(GetCurrentRenderer()->GetCenter()[1]);
302 double dyf = this->MotionFactor * (double)(dy) / (double)(GetCurrentRenderer()->GetCenter()[1]);
304 double zoomFactor = pow((double)1.1, dxf + dyf);
306 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
307 if (aCam->GetParallelProjection()) {
308 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
309 if( IsAdvancedZoomingEnabled() ) { // zoom relatively to the cursor
310 int* aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
315 x1 = myOtherPoint.x();
316 y1 = h - myOtherPoint.y();
317 TranslateView( x0, y0, x1, y1 );
319 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
320 if( IsAdvancedZoomingEnabled() )
321 TranslateView( x1, y1, x0, y0 );
324 aCam->Dolly(zoomFactor); // Move camera in/out along projection direction
325 GetCurrentRenderer()->ResetCameraClippingRange();
329 this->InvokeEvent(SVTK::OperationFinished,NULL);
332 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
336 if (GetCurrentRenderer() == NULL)
339 double newAngle = atan2((double)(y - GetCurrentRenderer()->GetCenter()[1]),
340 (double)(x - GetCurrentRenderer()->GetCenter()[0]));
341 double oldAngle = atan2((double)(oldY -GetCurrentRenderer()->GetCenter()[1]),
342 (double)(oldX - GetCurrentRenderer()->GetCenter()[0]));
344 newAngle *= this->RadianToDegree;
345 oldAngle *= this->RadianToDegree;
347 cam = GetCurrentRenderer()->GetActiveCamera();
348 cam->Roll(newAngle - oldAngle);
349 cam->OrthogonalizeViewUp();
352 this->InvokeEvent(SVTK::OperationFinished,NULL);
359 void SVTK_InteractorStyle::OnConfigure()
361 this->FindPokedRenderer(0,0);
362 this->GetCurrentRenderer()->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
366 To handle mouse move event
368 void SVTK_InteractorStyle::OnMouseMove()
371 GetEventPosition( this->Interactor, x, y );
372 this->OnMouseMove( this->Interactor->GetControlKey(),
373 this->Interactor->GetShiftKey(),
378 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
380 void SVTK_InteractorStyle::OnLeftButtonDown()
383 GetEventPosition( this->Interactor, x, y );
384 this->OnLeftButtonDown( this->Interactor->GetControlKey(),
385 this->Interactor->GetShiftKey(),
390 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
392 void SVTK_InteractorStyle::OnLeftButtonUp()
395 GetEventPosition( this->Interactor, x, y );
396 this->OnLeftButtonUp( this->Interactor->GetControlKey(),
397 this->Interactor->GetShiftKey(),
402 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
404 void SVTK_InteractorStyle::OnMiddleButtonDown()
407 GetEventPosition( this->Interactor, x, y );
408 this->OnMiddleButtonDown( this->Interactor->GetControlKey(),
409 this->Interactor->GetShiftKey(),
414 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
416 void SVTK_InteractorStyle::OnMiddleButtonUp()
419 GetEventPosition( this->Interactor, x, y );
420 this->OnMiddleButtonUp( this->Interactor->GetControlKey(),
421 this->Interactor->GetShiftKey(),
426 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
428 void SVTK_InteractorStyle::OnRightButtonDown()
431 GetEventPosition( this->Interactor, x, y );
432 this->OnRightButtonDown( this->Interactor->GetControlKey(),
433 this->Interactor->GetShiftKey(),
438 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
440 void SVTK_InteractorStyle::OnRightButtonUp()
443 GetEventPosition( this->Interactor, x, y );
444 this->OnRightButtonUp( this->Interactor->GetControlKey(),
445 this->Interactor->GetShiftKey(),
450 To handle mouse wheel forward event (reimplemented from #vtkInteractorStyle)
452 void SVTK_InteractorStyle::OnMouseWheelForward()
455 GetEventPosition( this->Interactor, x, y );
456 myOtherPoint = QPoint(x, y);
460 To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle)
462 void SVTK_InteractorStyle::OnMouseWheelBackward()
465 GetEventPosition( this->Interactor, x, y );
466 myOtherPoint = QPoint(x, y);
470 To handle mouse double click event
472 void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
474 if( myPoligonState == InProcess ) {
476 myPoligonState = Finished;
481 To handle mouse move event
483 void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl),
487 if ( myPoligonState == Start ) {
488 // if right button was pressed and mouse is moved
489 // we can to draw a polygon for polygonal selection
490 myPoligonState = InProcess;
491 startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
493 myShiftState = shift;
494 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
495 onOperation(QPoint(x, y));
496 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
497 onCursorMove(QPoint(x, y));
501 To handle left mouse button down event (reimplemented from vtkInteractorStyle)
503 void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift,
506 this->FindPokedRenderer(x, y);
507 if(GetCurrentRenderer() == NULL)
510 if ( myPoligonState != Disable )
513 myShiftState = shift;
514 // finishing current viewer operation
515 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
517 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
519 myOtherPoint = myPoint = QPoint(x, y);
520 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
521 startOperation(ForcedState);
524 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
525 else if ( myCurrRotationPointType == SVTK::StartPointSelection ||
526 myCurrFocalPointType == SVTK::StartFocalPointSelection )
528 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
530 bool isPicked = false;
531 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
533 if( anActorCollection )
535 anActorCollection->InitTraversal();
536 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
538 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
540 Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
541 double* aCoords = NULL;
543 bool isTrueType = false;
545 if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
546 ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
548 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
549 myPointPicker->Pick( aSelectionEvent->myX,
550 aSelectionEvent->myY,
552 GetCurrentRenderer() );
553 aVtkId = myPointPicker->GetPointId();
556 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
557 aCoords = anActor->GetNodeCoord(anObjId);
562 if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection || aSelectionMode == VolumeSelection )
564 vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
565 aCellPicker->SetTolerance( 0.005 );
566 SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
567 aCellPicker->Pick( aSelectionEvent->myX,
568 aSelectionEvent->myY,
570 GetCurrentRenderer() );
571 aVtkId = aCellPicker->GetCellId();
572 vtkIdType aCellId = anActor->GetElemObjId( aVtkId );
574 if( aSelectionMode == EdgeSelection )
575 isTrueType = anActor->GetObjDimension( aCellId ) == 1;
576 else if( aSelectionMode == FaceSelection )
577 isTrueType = anActor->GetObjDimension( aCellId ) == 2;
578 else if( aSelectionMode == VolumeSelection )
579 isTrueType = anActor->GetObjDimension( aCellId ) == 3;
581 if ( aVtkId >= 0 && isTrueType )
582 aCoords = anActor->GetGravityCenter( aCellId );
587 if (myCurrRotationPointType == SVTK::StartPointSelection) {
588 myCurrRotationPointType = SVTK::SetRotateSelected;
589 // invoke event for update coordinates in SVTK_SetRotationPointDlg
591 InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
593 InvokeEvent(SVTK::RotationPointChanged);
594 GetSelector()->SetSelectionMode(ActorSelection);
596 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
597 myCurrFocalPointType = SVTK::SetFocalPointSelected;
599 // invoke event for update coordinates in SVTK_ViewParameterDlg
600 InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords);
612 if (myCurrRotationPointType == SVTK::StartPointSelection) {
613 // invoke event with no data (for SVTK_SetRotationPointDlg)
614 InvokeEvent(SVTK::RotationPointChanged,0);
615 myCurrRotationPointType = myPrevRotationPointType;
616 GetSelector()->SetSelectionMode(ActorSelection);
618 else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
619 // invoke event with no data (for SVTK_ViewParameterDlg)
620 InvokeEvent(SVTK::FocalPointChanged,0);
621 myCurrFocalPointType = myPrevFocalPointType;
625 myHighlightSelectionPointActor->SetVisibility( false );
626 if(GetCurrentRenderer() != NULL)
627 GetCurrentRenderer()->RemoveActor( myHighlightSelectionPointActor.GetPointer() );
629 GetRenderWidget()->setCursor(myDefCursor);
632 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
639 To handle left mouse button up event (reimplemented from vtkInteractorStyle)
641 void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
646 myShiftState = shift;
647 if( myPoligonState == InProcess ) { // add a new point of polygon
648 myPolygonPoints.append( QPoint( x, y ) );
649 this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
650 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
653 else if ( myPoligonState == Closed ) { // close polygon and apply a selection
655 myPoligonState = Finished;
658 else if( myPoligonState == Finished || myPoligonState == NotValid )
660 // finishing current viewer operation
661 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
663 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
668 To handle middle mouse button down event (reimplemented from vtkInteractorStyle)
670 void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl,
674 this->FindPokedRenderer(x, y);
675 if(GetCurrentRenderer() == NULL)
678 if ( myPoligonState != Disable )
681 myShiftState = shift;
682 // finishing current viewer operation
683 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
685 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
687 myOtherPoint = myPoint = QPoint(x, y);
688 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
689 startOperation(ForcedState);
693 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
699 To handle middle mouse button up event (reimplemented from vtkInteractorStyle)
701 void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl),
706 if( myPoligonState == InProcess ) { // delete a point of polygon
707 if ( myPolygonPoints.size() > 2 ) {
708 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
709 mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
713 myShiftState = shift;
714 // finishing current viewer operation
715 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
717 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
723 To handle right mouse button down event (reimplemented from vtkInteractorStyle)
725 void SVTK_InteractorStyle::OnRightButtonDown(int ctrl,
729 this->FindPokedRenderer(x, y);
730 if(GetCurrentRenderer() == NULL)
733 myShiftState = shift;
736 myPoligonState = Start;
737 this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
738 mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
740 // finishing current viewer operation
741 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
743 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
745 myOtherPoint = myPoint = QPoint(x, y);
746 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
747 startOperation(ForcedState);
751 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
756 To handle right mouse button up event (reimplemented from vtkInteractorStyle)
758 void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl),
763 if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
764 myPoligonState = Disable;
765 mySelectionEvent->myPolygonPoints.clear();
768 if( myPoligonState != Disable ) {
770 myPoligonState = Finished;
771 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
775 myShiftState = shift;
776 // finishing current viewer operation
777 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
779 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
784 const char* imageZoomCursor[] = {
789 "................................",
790 "................................",
791 ".#######........................",
792 "..aaaaaaa.......................",
793 "................................",
794 ".............#####..............",
795 "...........##.aaaa##............",
796 "..........#.aa.....a#...........",
797 ".........#.a.........#..........",
798 ".........#a..........#a.........",
799 "........#.a...........#.........",
800 "........#a............#a........",
801 "........#a............#a........",
802 "........#a............#a........",
803 "........#a............#a........",
804 ".........#...........#.a........",
805 ".........#a..........#a.........",
806 ".........##.........#.a.........",
807 "........#####.....##.a..........",
808 ".......###aaa#####.aa...........",
809 "......###aa...aaaaa.......#.....",
810 ".....###aa................#a....",
811 "....###aa.................#a....",
812 "...###aa...............#######..",
813 "....#aa.................aa#aaaa.",
814 ".....a....................#a....",
815 "..........................#a....",
816 "...........................a....",
817 "................................",
818 "................................",
819 "................................",
820 "................................"};
822 const char* imageRotateCursor[] = {
827 "................................",
828 "................................",
829 "................................",
830 "................................",
831 "........#.......................",
832 ".......#.a......................",
833 "......#######...................",
834 ".......#aaaaa#####..............",
835 "........#..##.a#aa##........##..",
836 ".........a#.aa..#..a#.....##.aa.",
837 ".........#.a.....#...#..##.aa...",
838 ".........#a.......#..###.aa.....",
839 "........#.a.......#a..#aa.......",
840 "........#a.........#..#a........",
841 "........#a.........#a.#a........",
842 "........#a.........#a.#a........",
843 "........#a.........#a.#a........",
844 ".........#.........#a#.a........",
845 "........##a........#a#a.........",
846 "......##.a#.......#.#.a.........",
847 "....##.aa..##.....##.a..........",
848 "..##.aa.....a#####.aa...........",
849 "...aa.........aaa#a.............",
850 "................#.a.............",
851 "...............#.a..............",
852 "..............#.a...............",
853 "...............a................",
854 "................................",
855 "................................",
856 "................................",
857 "................................",
858 "................................"};
862 loads cursors for viewer operations - zoom, pan, etc...
864 void SVTK_InteractorStyle::loadCursors()
866 myDefCursor = QCursor(Qt::ArrowCursor);
867 myHandCursor = QCursor(Qt::PointingHandCursor);
868 myPanCursor = QCursor(Qt::SizeAllCursor);
869 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
870 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
871 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
872 myGlobalPanCursor = QCursor(Qt::CrossCursor);
873 myCursorState = false;
878 Starts Zoom operation (e.g. through menu command)
880 void SVTK_InteractorStyle::startZoom()
882 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
885 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
887 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
888 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
893 Starts Pan operation (e.g. through menu command)
895 void SVTK_InteractorStyle::startPan()
897 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
900 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
902 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
903 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
907 Starts Rotate operation (e.g. through menu command)
909 void SVTK_InteractorStyle::startRotate()
911 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
914 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
916 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
917 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
921 Set rotation point selected by user
923 void SVTK_InteractorStyle::startPointSelection()
925 myCurrRotationPointType = SVTK::StartPointSelection;
927 if(GetCurrentRenderer() != NULL) {
928 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
930 GetCurrentRenderer()->GetBackground( aColor );
931 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
936 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
940 Set focal point selected by user
942 void SVTK_InteractorStyle::startFocalPointSelection()
944 myCurrFocalPointType = SVTK::StartFocalPointSelection;
946 if(GetCurrentRenderer() != NULL) {
947 GetCurrentRenderer()->AddActor( myHighlightSelectionPointActor.GetPointer() );
949 GetCurrentRenderer()->GetBackground( aColor );
950 myHighlightSelectionPointActor->GetProperty()->SetColor(1. - aColor[0],
955 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
959 Starts Spin operation (e.g. through menu command)
961 void SVTK_InteractorStyle::startSpin()
963 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
966 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
968 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
969 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
975 Starts Fit Area operation (e.g. through menu command)
977 void SVTK_InteractorStyle::startFitArea()
979 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
982 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
984 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
985 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
990 Starts Global Panning operation (e.g. through menu command)
992 void SVTK_InteractorStyle::startGlobalPan()
994 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
997 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
999 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
1000 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
1002 // store current zoom scale
1003 myScale = GetCurrentRenderer()->GetActiveCamera()->GetParallelScale();
1005 GetCurrentRenderer()->ResetCamera();
1012 Fits viewer contents to rect
1014 void SVTK_InteractorStyle::fitRect(const int left,
1019 if (GetCurrentRenderer() == NULL)
1023 int x = (left + right)/2;
1024 int y = (top + bottom)/2;
1025 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1026 int oldX = aSize[0]/2;
1027 int oldY = aSize[1]/2;
1028 TranslateView(oldX, oldY, x, y);
1031 double dxf = right == left ? 1.0 : (double)(aSize[0]) / (double)(abs(right - left));
1032 double dyf = bottom == top ? 1.0 : (double)(aSize[1]) / (double)(abs(bottom - top));
1033 double zoomFactor = (dxf + dyf)/2 ;
1035 vtkCamera *aCam = GetCurrentRenderer()->GetActiveCamera();
1036 if(aCam->GetParallelProjection())
1037 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
1039 aCam->Dolly(zoomFactor);
1040 GetCurrentRenderer()->ResetCameraClippingRange();
1048 Starts viewer operation (!internal usage!)
1050 void SVTK_InteractorStyle::startOperation(int operation)
1054 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1055 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1056 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1057 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1058 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1059 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1060 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1061 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
1062 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1064 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
1065 setCursor(operation);
1068 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1070 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1071 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
1078 Sets proper cursor for window when viewer operation is activated
1080 void SVTK_InteractorStyle::setCursor(const int operation)
1082 if (!GetRenderWidget()) return;
1085 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1086 GetRenderWidget()->setCursor(myZoomCursor);
1087 myCursorState = true;
1089 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1090 GetRenderWidget()->setCursor(myPanCursor);
1091 myCursorState = true;
1093 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1094 GetRenderWidget()->setCursor(myRotateCursor);
1095 myCursorState = true;
1097 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1098 GetRenderWidget()->setCursor(mySpinCursor);
1099 myCursorState = true;
1101 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1102 GetRenderWidget()->setCursor(myGlobalPanCursor);
1103 myCursorState = true;
1105 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1106 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1107 GetRenderWidget()->setCursor(myHandCursor);
1108 myCursorState = true;
1110 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
1112 if ( myCurrRotationPointType == SVTK::StartPointSelection ||
1113 myCurrFocalPointType == SVTK::StartFocalPointSelection )
1114 GetRenderWidget()->setCursor(myHandCursor);
1116 GetRenderWidget()->setCursor(myDefCursor);
1117 myCursorState = false;
1124 Called when viewer operation started (!put necessary initialization here!)
1126 void SVTK_InteractorStyle::onStartOperation()
1128 if (!GetRenderWidget())
1131 vtkRenderWindowInteractor *aRWI = this->Interactor;
1132 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1133 aRenWin->SetDesiredUpdateRate(aRWI->GetDesiredUpdateRate());
1136 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1137 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1139 if ( myPoligonState == InProcess )
1145 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1146 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1147 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1148 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1149 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1156 Called when viewer operation finished (!put necessary post-processing here!)
1158 void SVTK_InteractorStyle::onFinishOperation()
1160 if (!GetRenderWidget())
1163 vtkRenderWindowInteractor *aRWI = this->Interactor;
1164 vtkRenderWindow *aRenWin = aRWI->GetRenderWindow();
1165 aRenWin->SetDesiredUpdateRate(aRWI->GetStillUpdateRate());
1167 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1170 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1171 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1174 QRect aRect(myPoint, myOtherPoint);
1175 aRect = aRect.normalized();
1177 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
1178 // making fit rect opeation
1180 Interactor->GetSize(w, h);
1181 int x1 = aRect.left();
1182 int y1 = h - aRect.top() - 1;
1183 int x2 = aRect.right();
1184 int y2 = h - aRect.bottom() - 1;
1185 fitRect(x1, y1, x2, y2);
1188 if (myPoint == myOtherPoint)
1190 // process point selection
1191 this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
1192 Interactor->StartPickCallback();
1194 SALOME_Actor* aHighlightedActor = NULL;
1195 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1197 aSelectionEvent->myIsRectangle = false;
1198 aSelectionEvent->myIsPolygon = false;
1200 GetSelector()->ClearIObjects();
1202 if( anActorCollection )
1204 if( !myShiftState &&
1205 anActorCollection->GetNumberOfItems () > 1 &&
1206 myLastHighlitedActor.GetPointer() ) {
1207 anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
1209 anActorCollection->InitTraversal();
1210 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1212 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1214 if( anActor->Highlight( this, aSelectionEvent, true ) )
1216 aHighlightedActor = anActor;
1223 if( !aHighlightedActor )
1225 if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
1226 myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
1228 myLastHighlitedActor = aHighlightedActor;
1232 if ( myPoligonState == InProcess || myPoligonState == Closed )
1233 aSelectionEvent->myIsPolygon = true;
1235 aSelectionEvent->myIsRectangle = true;
1237 //processing polygonal selection
1238 Interactor->StartPickCallback();
1239 GetSelector()->StartPickCallback();
1242 GetSelector()->ClearIObjects();
1244 VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
1245 vtkActorCollection* aListActors = aCopy.GetActors();
1246 aListActors->InitTraversal();
1247 while(vtkActor* aActor = aListActors->GetNextActor())
1249 if(aActor->GetVisibility())
1251 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
1253 if(aSActor->hasIO())
1254 aSActor->Highlight( this, aSelectionEvent, true );
1259 aSelectionEvent->myIsRectangle = false;
1260 aSelectionEvent->myIsPolygon = false;
1261 aSelectionEvent->myPolygonPoints.clear();
1263 Interactor->EndPickCallback();
1264 GetSelector()->EndPickCallback();
1268 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1269 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1270 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1271 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1273 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1276 Interactor->GetSize(w, h);
1278 y = h - myPoint.y() - 1;
1289 Called during viewer operation when user moves mouse (!put necessary processing here!)
1291 void SVTK_InteractorStyle::onOperation(QPoint mousePos)
1293 if (!GetRenderWidget())
1297 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1299 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1303 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1305 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1309 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1311 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1315 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1317 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1321 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1325 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1328 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1330 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1332 myOtherPoint = mousePos;
1333 if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
1335 else if ( myPoligonState != Finished )
1343 Called when user moves mouse inside viewer window and there is no active viewer operation
1344 (!put necessary processing here!)
1346 void SVTK_InteractorStyle::onCursorMove(QPoint /*mousePos*/)
1348 if ( !GetSelector()->IsPreSelectionEnabled() )
1351 // processing highlighting
1352 SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
1353 this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
1355 bool anIsChanged = false;
1357 SALOME_Actor* aPreHighlightedActor = NULL;
1358 vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
1360 if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
1362 myHighlightSelectionPointActor->SetVisibility( false );
1364 if( anActorCollection )
1366 anActorCollection->InitTraversal();
1367 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1369 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1371 SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
1372 myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
1373 vtkIdType aVtkId = myPointPicker->GetPointId();
1374 if ( aVtkId >= 0 ) {
1375 vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
1377 SVTK_TIndexedMapOfVtkId aMapIndex;
1378 aMapIndex.Add( anObjId );
1379 myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
1381 myHighlightSelectionPointActor->SetVisibility( true );
1390 if( anActorCollection )
1392 anActorCollection->InitTraversal();
1393 while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
1395 if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
1397 anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true );
1398 if( anActor->isPreselected() )
1400 aPreHighlightedActor = anActor;
1407 if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor)
1408 anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false );
1412 myLastPreHighlitedActor = aPreHighlightedActor;
1419 Called on finsh GlobalPan operation
1421 void SVTK_InteractorStyle::Place(const int theX, const int theY)
1423 if (GetCurrentRenderer() == NULL)
1427 int *aSize = GetCurrentRenderer()->GetRenderWindow()->GetSize();
1428 int centerX = aSize[0]/2;
1429 int centerY = aSize[1]/2;
1431 TranslateView(centerX, centerY, theX, theY);
1433 // restore zoom scale
1434 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1435 cam->SetParallelScale(myScale);
1436 GetCurrentRenderer()->ResetCameraClippingRange();
1444 Translates view from Point to Point
1446 void SVTK_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY)
1448 if (GetCurrentRenderer() == NULL)
1451 vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera();
1452 double viewFocus[4], focalDepth, viewPoint[3];
1453 double newPickPoint[4], oldPickPoint[4], motionVector[3];
1454 cam->GetFocalPoint(viewFocus);
1456 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1457 viewFocus[2], viewFocus);
1458 focalDepth = viewFocus[2];
1460 this->ComputeDisplayToWorld(double(toX), double(toY),
1461 focalDepth, newPickPoint);
1462 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1463 focalDepth, oldPickPoint);
1465 // camera motion is reversed
1466 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1467 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1468 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1470 cam->GetFocalPoint(viewFocus);
1471 cam->GetPosition(viewPoint);
1472 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1473 motionVector[1] + viewFocus[1],
1474 motionVector[2] + viewFocus[2]);
1475 cam->SetPosition(motionVector[0] + viewPoint[0],
1476 motionVector[1] + viewPoint[1],
1477 motionVector[2] + viewPoint[2]);
1480 void SVTK_InteractorStyle::IncrementalPan( const int incrX, const int incrY )
1482 this->PanXY( incrX, incrY, 0, 0 );
1485 void SVTK_InteractorStyle::IncrementalZoom( const int incr )
1487 this->DollyXY( incr, incr );
1490 void SVTK_InteractorStyle::IncrementalRotate( const int incrX, const int incrY )
1492 this->RotateXY( incrX, -incrY );
1496 Redefined in order to add an observer (callback) for custorm event (space mouse event)
1498 void SVTK_InteractorStyle::SetInteractor( vtkRenderWindowInteractor* theInteractor )
1500 // register EventCallbackCommand as observer of standard events (keypress, mousemove, etc)
1501 Superclass::SetInteractor( theInteractor );
1503 myInteractor = dynamic_cast<SVTK_GenericRenderWindowInteractor*>(theInteractor);
1506 // register EventCallbackCommand as observer of custorm event (3d space mouse event)
1507 theInteractor->AddObserver( SVTK::SpaceMouseMoveEvent, EventCallbackCommand, Priority );
1508 theInteractor->AddObserver( SVTK::SpaceMouseButtonEvent, EventCallbackCommand, Priority );
1509 theInteractor->AddObserver( SVTK::PanLeftEvent, EventCallbackCommand, Priority );
1510 theInteractor->AddObserver( SVTK::PanRightEvent, EventCallbackCommand, Priority );
1511 theInteractor->AddObserver( SVTK::PanUpEvent, EventCallbackCommand, Priority );
1512 theInteractor->AddObserver( SVTK::PanDownEvent, EventCallbackCommand, Priority );
1513 theInteractor->AddObserver( SVTK::ZoomInEvent, EventCallbackCommand, Priority );
1514 theInteractor->AddObserver( SVTK::ZoomOutEvent, EventCallbackCommand, Priority );
1515 theInteractor->AddObserver( SVTK::RotateLeftEvent, EventCallbackCommand, Priority );
1516 theInteractor->AddObserver( SVTK::RotateRightEvent, EventCallbackCommand, Priority );
1517 theInteractor->AddObserver( SVTK::RotateUpEvent, EventCallbackCommand, Priority );
1518 theInteractor->AddObserver( SVTK::RotateDownEvent, EventCallbackCommand, Priority );
1519 theInteractor->AddObserver( SVTK::PlusSpeedIncrementEvent, EventCallbackCommand, Priority );
1520 theInteractor->AddObserver( SVTK::MinusSpeedIncrementEvent, EventCallbackCommand, Priority );
1521 theInteractor->AddObserver( SVTK::SetSpeedIncrementEvent, EventCallbackCommand, Priority );
1523 theInteractor->AddObserver( SVTK::SetSMDecreaseSpeedEvent, EventCallbackCommand, Priority );
1524 theInteractor->AddObserver( SVTK::SetSMIncreaseSpeedEvent, EventCallbackCommand, Priority );
1525 theInteractor->AddObserver( SVTK::SetSMDominantCombinedSwitchEvent, EventCallbackCommand, Priority );
1527 theInteractor->AddObserver( SVTK::StartZoom, EventCallbackCommand, Priority );
1528 theInteractor->AddObserver( SVTK::StartPan, EventCallbackCommand, Priority );
1529 theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority );
1530 theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority );
1531 theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority );
1533 theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority );
1534 theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority );
1536 theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority );
1538 theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
1539 theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
1540 theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
1545 To implement cached rendering
1547 void SVTK_InteractorStyle::OnTimer()
1549 //vtkInteractorStyle::OnTimer();
1550 this->Interactor->Render();
1551 // check if bounding box was changed
1552 if ( GetCurrentRenderer() )
1554 #ifdef VGL_WORKAROUND
1555 GetCurrentRenderer()->Render();
1557 double aCurrBBCenter[3];
1558 if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
1560 if ( !myBBFirstCheck )
1562 if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 ||
1563 fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 ||
1564 fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) {
1565 // bounding box was changed => send SVTK::RotationPointChanged event
1566 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1567 InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter);
1568 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1573 for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i];
1574 myBBFirstCheck = false;
1581 To invoke #vtkRenderWindowInteractor::CreateTimer
1583 void SVTK_InteractorStyle::Render()
1585 this->Interactor->CreateTimer(VTKI_TIMER_FIRST);
1588 void SVTK_InteractorStyle::onSpaceMouseMove( double* data )
1590 // general things, do SetCurrentRenderer() within FindPokedRenderer()
1592 GetEventPosition( this->Interactor, x, y ); // current mouse position (from last mouse move event or any other event)
1593 FindPokedRenderer( x, y ); // calls SetCurrentRenderer
1595 IncrementalZoom( (int)data[2] ); // 1. push toward / pull backward = zoom out / zoom in
1596 IncrementalPan( (int)data[0], (int)data[1] );// 2. pull up / push down = pan up / down, 3. move left / right = pan left / right
1597 IncrementalRotate( 0, (int)data[4] ); // 4. twist the control = rotate around Y axis
1598 IncrementalRotate( (int)data[3], 0 ); // 5. tilt the control forward/backward = rotate around X axis (Z axis of local coordinate system of space mouse)
1601 void SVTK_InteractorStyle::onSpaceMouseButton( int button )
1603 if( mySMDecreaseSpeedBtn == button ) {
1604 ControllerIncrement()->Decrease();
1606 if( mySMIncreaseSpeedBtn == button ) {
1607 ControllerIncrement()->Increase();
1609 if( mySMDominantCombinedSwitchBtn == button )
1610 DominantCombinedSwitch();
1613 void SVTK_InteractorStyle::DominantCombinedSwitch()
1615 printf( "\n--DominantCombinedSwitch() NOT IMPLEMENTED--\n" );
1619 Draws rectangle by starting and current points
1621 void SVTK_InteractorStyle::drawRect()
1624 myRectBand = new QtxRectRubberBand( GetRenderWidget() );
1626 myRectBand->setUpdatesEnabled ( false );
1627 QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
1628 myRectBand->initGeometry( aRect );
1630 if ( !myRectBand->isVisible() )
1633 myRectBand->setUpdatesEnabled ( true );
1637 \brief Delete rubber band on the end on the dragging operation.
1639 void SVTK_InteractorStyle::endDrawRect()
1642 myRectBand->clearGeometry();
1647 bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
1648 const QPoint& theStart2, const QPoint& theEnd2 )
1650 if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
1651 ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
1654 if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
1655 theStart1 == theEnd2 || theEnd1 == theEnd2 )
1658 double x11 = theStart1.x() * 1.0;
1659 double x12 = theEnd1.x() * 1.0;
1660 double y11 = theStart1.y() * 1.0;
1661 double y12 = theEnd1.y() * 1.0;
1663 double x21 = theStart2.x() * 1.0;
1664 double x22 = theEnd2.x() * 1.0;
1665 double y21 = theStart2.y() * 1.0;
1666 double y22 = theEnd2.y() * 1.0;
1668 double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
1669 double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
1671 double b1 = y11 - k1 * x11;
1672 double b2 = y21 - k2 * x21;
1679 return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
1680 qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
1681 ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
1682 qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
1686 double x0 = ( b2 - b1 ) / ( k1 - k2 );
1687 double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
1689 if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
1690 qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
1691 qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
1692 qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
1698 bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
1700 if ( !thePoints->count() )
1703 if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
1706 const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
1708 if ( aLast == theCurrent )
1712 for ( int i = 0; i < thePoints->count() - 1 && res; i++ )
1714 const QPoint& aStart = thePoints->point( i );
1715 const QPoint& anEnd = thePoints->point( i + 1 );
1716 res = !isIntersect( aStart, anEnd, theCurrent, aLast );
1724 void SVTK_InteractorStyle::drawPolygon()
1726 QSize aToler( 5, 5 );
1727 if ( !myPolygonBand ) {
1728 myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
1730 palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
1731 myPolygonBand->setPalette( palette );
1732 myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) );
1734 myPolygonBand->hide();
1736 bool closed = false;
1737 bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1738 if ( !myPolygonPoints.at(0).isNull() )
1740 QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
1741 2 * aToler.width(), 2 * aToler.height() );
1742 closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1745 QPolygon* points = new QPolygon( myPolygonPoints );
1746 valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1747 myPoligonState = valid ? InProcess : NotValid;
1749 if ( closed && !valid )
1752 if ( closed && myPolygonPoints.size() > 2 ) {
1753 GetRenderWidget()->setCursor( Qt::CrossCursor );
1754 myPoligonState = Closed;
1757 GetRenderWidget()->setCursor( Qt::PointingHandCursor );
1759 GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
1761 myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) );
1763 QPolygon aPolygon( myPolygonPoints );
1764 myPolygonBand->initGeometry( aPolygon );
1765 myPolygonBand->setVisible( true );
1767 if ( myPolygonPoints.size() > 1 ) {
1768 myPolygonPoints.remove( myPolygonPoints.size() - 1 );
1773 \brief Delete rubber band on the end on the dragging operation.
1775 void SVTK_InteractorStyle::endDrawPolygon()
1777 if ( myPolygonBand ) myPolygonBand->hide();
1779 // RNV fix for : #19204 [CEA][Windows] VTK Viewer - Access violation while right clicking
1780 //delete myPolygonBand;
1781 myPolygonBand->deleteLater();
1784 myPolygonPoints.clear();
1788 Main process event method (reimplemented from #vtkInteractorStyle)
1790 void SVTK_InteractorStyle::ProcessEvents( vtkObject* object,
1791 unsigned long event,
1796 vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
1797 SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
1798 int aSpeedIncrement=self->ControllerIncrement()->Current();
1800 double* aSelectedPoint;
1803 case SVTK::SpaceMouseMoveEvent :
1804 self->onSpaceMouseMove( (double*)callData );
1806 case SVTK::SpaceMouseButtonEvent :
1807 self->onSpaceMouseButton( *((int*)callData) );
1809 case SVTK::PanLeftEvent:
1810 self->IncrementalPan(-aSpeedIncrement, 0);
1812 case SVTK::PanRightEvent:
1813 self->IncrementalPan(aSpeedIncrement, 0);
1815 case SVTK::PanUpEvent:
1816 self->IncrementalPan(0, aSpeedIncrement);
1818 case SVTK::PanDownEvent:
1819 self->IncrementalPan(0, -aSpeedIncrement);
1821 case SVTK::ZoomInEvent:
1822 self->IncrementalZoom(aSpeedIncrement);
1824 case SVTK::ZoomOutEvent:
1825 self->IncrementalZoom(-aSpeedIncrement);
1827 case SVTK::RotateLeftEvent:
1828 self->IncrementalRotate(-aSpeedIncrement, 0);
1830 case SVTK::RotateRightEvent:
1831 self->IncrementalRotate(aSpeedIncrement, 0);
1833 case SVTK::RotateUpEvent:
1834 self->IncrementalRotate(0, -aSpeedIncrement);
1836 case SVTK::RotateDownEvent:
1837 self->IncrementalRotate(0, aSpeedIncrement);
1839 case SVTK::PlusSpeedIncrementEvent:
1840 self->ControllerIncrement()->Increase();
1842 case SVTK::MinusSpeedIncrementEvent:
1843 self->ControllerIncrement()->Decrease();
1845 case SVTK::SetSpeedIncrementEvent:
1846 self->ControllerIncrement()->SetStartValue(*((int*)callData));
1849 case SVTK::SetSMDecreaseSpeedEvent:
1850 self->mySMDecreaseSpeedBtn = *((int*)callData);
1852 case SVTK::SetSMIncreaseSpeedEvent:
1853 self->mySMIncreaseSpeedBtn = *((int*)callData);
1855 case SVTK::SetSMDominantCombinedSwitchEvent:
1856 self->mySMDominantCombinedSwitchBtn = *((int*)callData);
1859 case SVTK::StartZoom:
1862 case SVTK::StartPan:
1865 case SVTK::StartRotate:
1866 self->startRotate();
1868 case SVTK::StartGlobalPan:
1869 self->startGlobalPan();
1871 case SVTK::StartFitArea:
1872 self->startFitArea();
1875 case SVTK::SetRotateGravity:
1876 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1878 self->myHighlightSelectionPointActor->SetVisibility( false );
1879 if( self->GetCurrentRenderer() != NULL )
1880 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1881 self->GetRenderWidget()->setCursor(self->myDefCursor);
1883 self->myPrevRotationPointType = self->myCurrRotationPointType;
1884 self->myCurrRotationPointType = SVTK::SetRotateGravity;
1885 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) )
1886 // invoke event for update coordinates in SVTK_SetRotationPointDlg
1887 self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter);
1889 case SVTK::StartPointSelection:
1890 self->startPointSelection();
1893 case SVTK::ChangeRotationPoint:
1894 if ( self->myCurrRotationPointType == SVTK::StartPointSelection )
1896 self->myHighlightSelectionPointActor->SetVisibility( false );
1897 if( self->GetCurrentRenderer() != NULL )
1898 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1899 self->GetRenderWidget()->setCursor(self->myDefCursor);
1901 self->myPrevRotationPointType = self->myCurrRotationPointType;
1902 self->myCurrRotationPointType = SVTK::SetRotateSelected;
1903 aSelectedPoint = (double*)callData;
1904 self->myRotationPointX = aSelectedPoint[0];
1905 self->myRotationPointY = aSelectedPoint[1];
1906 self->myRotationPointZ = aSelectedPoint[2];
1909 case SVTK::SetFocalPointGravity:
1910 if ( self->myCurrFocalPointType == SVTK::StartPointSelection )
1912 self->myHighlightSelectionPointActor->SetVisibility( false );
1913 if( self->GetCurrentRenderer() != NULL )
1914 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1915 self->GetRenderWidget()->setCursor(self->myDefCursor);
1917 self->myCurrFocalPointType = SVTK::SetFocalPointGravity;
1918 if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) {
1919 // invoke event for update coordinates in SVTK_ViewParameterDlg
1920 self->InvokeEvent(SVTK::FocalPointChanged,(void*)aCenter);
1923 case SVTK::StartFocalPointSelection:
1924 self->startFocalPointSelection();
1927 case SVTK::SetFocalPointSelected:
1928 if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
1930 self->myHighlightSelectionPointActor->SetVisibility( false );
1931 if( self->GetCurrentRenderer() != NULL )
1932 self->GetCurrentRenderer()->RemoveActor( self->myHighlightSelectionPointActor.GetPointer() );
1933 self->GetRenderWidget()->setCursor(self->myDefCursor);
1935 self->myPrevFocalPointType = self->myCurrFocalPointType;
1936 self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
1942 Superclass::ProcessEvents( object, event, clientData, callData );
1946 To handle keyboard event (reimplemented from #vtkInteractorStyle)
1948 void SVTK_InteractorStyle::OnChar()
1950 char key = GetInteractor()->GetKeyCode();
1952 case '+': ControllerIncrement()->Increase(); break;
1953 case '-': ControllerIncrement()->Decrease(); break;
1958 Redefined vtkInteractorStyle::OnKeyDown
1960 void SVTK_InteractorStyle::OnKeyDown()
1962 bool bInvokeSuperclass=myControllerOnKeyDown->OnKeyDown(this);
1963 if (bInvokeSuperclass){
1964 Superclass::OnKeyDown();
1969 Provide instructions for Picking
1971 void SVTK_InteractorStyle::ActionPicking()
1974 Interactor->GetEventPosition( x, y );
1975 FindPokedRenderer( x, y );
1977 myOtherPoint = myPoint = QPoint(x, y);
1979 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1980 onFinishOperation();
1981 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
1985 To set current increment controller
1987 void SVTK_InteractorStyle::SetControllerOnKeyDown(SVTK_ControllerOnKeyDown* theController)
1989 myControllerOnKeyDown=theController;
1993 To get current OnKeyDown controller
1995 SVTK_ControllerOnKeyDown* SVTK_InteractorStyle::ControllerOnKeyDown()
1997 return myControllerOnKeyDown.GetPointer();
2001 To set current increment controller
2003 void SVTK_InteractorStyle::SetControllerIncrement(SVTK_ControllerIncrement* theController)
2005 myControllerIncrement=theController;
2009 To modify current increment controller
2011 void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMode)
2013 SVTK_ControllerIncrement* c = 0;
2015 case 0: c = SVTK_ControllerIncrement::New(); break;
2016 case 1: c = SVTK_GeomControllerIncrement::New(); break;
2018 c->SetStartValue(theValue);
2020 SetControllerIncrement(c);
2025 To get current increment controller
2027 SVTK_ControllerIncrement* SVTK_InteractorStyle::ControllerIncrement()
2029 return myControllerIncrement.GetPointer();
2032 vtkStandardNewMacro(SVTK_ControllerIncrement)
2033 SVTK_ControllerIncrement::SVTK_ControllerIncrement()
2037 SVTK_ControllerIncrement::~SVTK_ControllerIncrement()
2040 void SVTK_ControllerIncrement::SetStartValue(const int theValue)
2042 myIncrement=theValue;
2044 int SVTK_ControllerIncrement::Current()const
2048 int SVTK_ControllerIncrement::Increase()
2053 int SVTK_ControllerIncrement::Decrease()
2061 vtkStandardNewMacro(SVTK_GeomControllerIncrement)
2062 SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
2065 SVTK_GeomControllerIncrement::~SVTK_GeomControllerIncrement()
2068 int SVTK_GeomControllerIncrement::Increase()
2073 int SVTK_GeomControllerIncrement::Decrease()
2082 vtkStandardNewMacro(SVTK_ControllerOnKeyDown)
2087 SVTK_ControllerOnKeyDown::SVTK_ControllerOnKeyDown()
2094 SVTK_ControllerOnKeyDown::~SVTK_ControllerOnKeyDown()
2098 bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* /*theIS*/)