1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SVTK_InteractorStyle.cxx
25 // Author : Christophe ATTANASIO
30 #include "SVTK_InteractorStyle.h"
32 #include "VTKViewer_CellRectPicker.h"
33 #include "VTKViewer_Utilities.h"
34 #include "VTKViewer_RectPicker.h"
36 #include "SVTK_RenderWindowInteractor.h"
37 #include "SVTK_RenderWindow.h"
38 #include "SVTK_ViewWindow.h"
40 #include "SALOME_Actor.h"
41 #include "SVTK_Actor.h"
42 #include "SVTK_Selector.h"
44 #include "SALOME_ListIteratorOfListIO.hxx"
45 #include "SALOME_ListIO.hxx"
47 #include "SUIT_Session.h"
48 #include "CAM_Application.h"
50 #include <vtkObjectFactory.h>
52 #include <vtkCommand.h>
53 #include <vtkCamera.h>
54 #include <vtkRenderer.h>
55 #include <vtkPicker.h>
56 #include <vtkPointPicker.h>
57 #include <vtkCellPicker.h>
59 #include <vtkMapper.h>
60 #include <vtkDataSet.h>
61 #include <vtkSmartPointer.h>
62 #include <vtkRenderWindow.h>
64 #include <qapplication.h>
65 //VRV: porting on Qt 3.0.5
66 #if QT_VERSION >= 0x030005
69 //VRV: porting on Qt 3.0.5
78 GetEdgeId(vtkPicker *thePicker, SALOME_Actor *theActor, int theObjId)
81 if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
82 float aPickPosition[3];
83 thePicker->GetPickPosition(aPickPosition);
84 float aMinDist = 1000000.0, aDist = 0;
85 for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
86 if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
87 int subId; float pcoords[3], closestPoint[3], weights[3];
88 aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
89 if (aDist < aMinDist) {
101 bool CheckDimensionId(Selection_Mode theMode, SALOME_Actor *theActor, vtkIdType theObjId){
106 return ( theActor->GetObjDimension( theObjId ) == 1 );
108 return ( theActor->GetObjDimension( theObjId ) == 2 );
109 case VolumeSelection:
110 return ( theActor->GetObjDimension( theObjId ) == 3 );
116 //----------------------------------------------------------------------------
117 vtkStandardNewMacro(SVTK_InteractorStyle);
118 //----------------------------------------------------------------------------
121 ::SVTK_InteractorStyle()
123 myPreViewActor = NULL;
127 this->MotionFactor = 10.0;
128 this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE;
129 this->RadianToDegree = 180.0 / vtkMath::Pi();
130 this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
133 myPreSelectionActor = SVTK_Actor::New();
134 myPreSelectionActor->GetProperty()->SetColor(0,1,1);
135 myPreSelectionActor->GetProperty()->SetLineWidth(5);
136 myPreSelectionActor->GetProperty()->SetPointSize(5);
138 OnSelectionModeChanged();
141 //----------------------------------------------------------------------------
143 ::~SVTK_InteractorStyle()
145 myViewWindow->RemoveActor(myPreSelectionActor);
148 //----------------------------------------------------------------------------
153 return myViewWindow->GetSelector();
156 //----------------------------------------------------------------------------
159 ::setPreselectionProp(const double& theRed,
160 const double& theGreen,
161 const double& theBlue,
164 if ( myPreSelectionActor->GetProperty() == 0 )
166 myPreSelectionActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
167 myPreSelectionActor->GetProperty()->SetLineWidth(theWidth);
168 myPreSelectionActor->GetProperty()->SetPointSize(theWidth);
171 //----------------------------------------------------------------------------
174 ::SetInteractor(vtkRenderWindowInteractor *theInteractor)
176 myInteractor = dynamic_cast<SVTK_RenderWindowInteractor*>(theInteractor);
177 Superclass::SetInteractor(theInteractor);
180 //----------------------------------------------------------------------------
185 return State | ForcedState;
188 //----------------------------------------------------------------------------
191 ::setViewWindow(SVTK_ViewWindow* theViewWindow)
193 myViewWindow = theViewWindow;
194 myViewWindow->AddActor(myPreSelectionActor);
195 myPreSelectionActor->Delete();
198 //----------------------------------------------------------------------------
201 ::setGUIWindow(QWidget* theWindow)
203 myGUIWindow = theWindow;
206 //----------------------------------------------------------------------------
209 ::RotateXY(int dx, int dy)
215 if (this->CurrentRenderer == NULL)
220 int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
221 this->DeltaElevation = -20.0 / size[1];
222 this->DeltaAzimuth = -20.0 / size[0];
224 rxf = (double)dx * this->DeltaAzimuth * this->MotionFactor;
225 ryf = (double)dy * this->DeltaElevation * this->MotionFactor;
227 cam = this->CurrentRenderer->GetActiveCamera();
230 cam->OrthogonalizeViewUp();
231 ::ResetCameraClippingRange(this->CurrentRenderer);
232 //this->Interactor->Render();
233 myGUIWindow->update();
236 //----------------------------------------------------------------------------
239 ::PanXY(int x, int y, int oldX, int oldY)
241 TranslateView(x, y, oldX, oldY);
242 //this->Interactor->Render();
243 myGUIWindow->update();
247 //----------------------------------------------------------------------------
250 ::DollyXY(int dx, int dy)
252 if (this->CurrentRenderer == NULL) return;
254 double dxf = this->MotionFactor * (double)(dx) / (double)(this->CurrentRenderer->GetCenter()[1]);
255 double dyf = this->MotionFactor * (double)(dy) / (double)(this->CurrentRenderer->GetCenter()[1]);
257 double zoomFactor = pow((double)1.1, dxf + dyf);
259 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
260 if (aCam->GetParallelProjection())
261 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
263 aCam->Dolly(zoomFactor);
264 ::ResetCameraClippingRange(this->CurrentRenderer);
267 //this->Interactor->Render();
268 myGUIWindow->update();
271 //----------------------------------------------------------------------------
274 ::SpinXY(int x, int y, int oldX, int oldY)
278 if (this->CurrentRenderer == NULL)
283 double newAngle = atan2((double)(y - this->CurrentRenderer->GetCenter()[1]),
284 (double)(x - this->CurrentRenderer->GetCenter()[0]));
285 double oldAngle = atan2((double)(oldY -this->CurrentRenderer->GetCenter()[1]),
286 (double)(oldX - this->CurrentRenderer->GetCenter()[0]));
288 newAngle *= this->RadianToDegree;
289 oldAngle *= this->RadianToDegree;
291 cam = this->CurrentRenderer->GetActiveCamera();
292 cam->Roll(newAngle - oldAngle);
293 cam->OrthogonalizeViewUp();
295 //this->Interactor->Render();
296 myGUIWindow->update();
300 //----------------------------------------------------------------------------
303 ::OnMouseMove(int vtkNotUsed(ctrl),
307 myShiftState = shift;
308 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
309 onOperation(QPoint(x, y));
310 else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE)
311 onCursorMove(QPoint(x, y));
315 //----------------------------------------------------------------------------
318 ::OnLeftButtonDown(int ctrl, int shift,
321 if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) {
322 this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
325 this->FindPokedRenderer(x, y);
326 if (this->CurrentRenderer == NULL) {
329 myShiftState = shift;
330 // finishing current viewer operation
331 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
333 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
335 myOtherPoint = myPoint = QPoint(x, y);
336 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
337 startOperation(ForcedState);
340 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
342 startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
348 //----------------------------------------------------------------------------
351 ::OnLeftButtonUp(int vtkNotUsed(ctrl),
356 myShiftState = shift;
357 // finishing current viewer operation
358 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
360 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
365 //----------------------------------------------------------------------------
368 ::OnMiddleButtonDown(int ctrl,
372 if (this->HasObserver(vtkCommand::MiddleButtonPressEvent))
374 this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
377 this->FindPokedRenderer(x, y);
378 if (this->CurrentRenderer == NULL)
382 myShiftState = shift;
383 // finishing current viewer operation
384 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
386 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
388 myOtherPoint = myPoint = QPoint(x, y);
389 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
390 startOperation(ForcedState);
394 startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN);
399 //----------------------------------------------------------------------------
402 ::OnMiddleButtonUp(int vtkNotUsed(ctrl),
407 myShiftState = shift;
408 // finishing current viewer operation
409 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
411 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
416 //----------------------------------------------------------------------------
419 ::OnRightButtonDown(int ctrl,
423 if (this->HasObserver(vtkCommand::RightButtonPressEvent))
425 this->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
428 this->FindPokedRenderer(x, y);
429 if (this->CurrentRenderer == NULL)
433 myShiftState = shift;
434 // finishing current viewer operation
435 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
437 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
439 myOtherPoint = myPoint = QPoint(x, y);
440 if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
441 startOperation(ForcedState);
445 startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
449 //----------------------------------------------------------------------------
452 ::OnRightButtonUp(int vtkNotUsed(ctrl),
457 myShiftState = shift;
458 // finishing current viewer operation
459 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
461 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
465 //----------------------------------------------------------------------------
467 const char* imageZoomCursor[] = {
472 "................................",
473 "................................",
474 ".#######........................",
475 "..aaaaaaa.......................",
476 "................................",
477 ".............#####..............",
478 "...........##.aaaa##............",
479 "..........#.aa.....a#...........",
480 ".........#.a.........#..........",
481 ".........#a..........#a.........",
482 "........#.a...........#.........",
483 "........#a............#a........",
484 "........#a............#a........",
485 "........#a............#a........",
486 "........#a............#a........",
487 ".........#...........#.a........",
488 ".........#a..........#a.........",
489 ".........##.........#.a.........",
490 "........#####.....##.a..........",
491 ".......###aaa#####.aa...........",
492 "......###aa...aaaaa.......#.....",
493 ".....###aa................#a....",
494 "....###aa.................#a....",
495 "...###aa...............#######..",
496 "....#aa.................aa#aaaa.",
497 ".....a....................#a....",
498 "..........................#a....",
499 "...........................a....",
500 "................................",
501 "................................",
502 "................................",
503 "................................"};
505 const char* imageRotateCursor[] = {
510 "................................",
511 "................................",
512 "................................",
513 "................................",
514 "........#.......................",
515 ".......#.a......................",
516 "......#######...................",
517 ".......#aaaaa#####..............",
518 "........#..##.a#aa##........##..",
519 ".........a#.aa..#..a#.....##.aa.",
520 ".........#.a.....#...#..##.aa...",
521 ".........#a.......#..###.aa.....",
522 "........#.a.......#a..#aa.......",
523 "........#a.........#..#a........",
524 "........#a.........#a.#a........",
525 "........#a.........#a.#a........",
526 "........#a.........#a.#a........",
527 ".........#.........#a#.a........",
528 "........##a........#a#a.........",
529 "......##.a#.......#.#.a.........",
530 "....##.aa..##.....##.a..........",
531 "..##.aa.....a#####.aa...........",
532 "...aa.........aaa#a.............",
533 "................#.a.............",
534 "...............#.a..............",
535 "..............#.a...............",
536 "...............a................",
537 "................................",
538 "................................",
539 "................................",
540 "................................",
541 "................................"};
544 //----------------------------------------------------------------------------
545 // loads cursors for viewer operations - zoom, pan, etc...
550 myDefCursor = QCursor(ArrowCursor);
551 myHandCursor = QCursor(PointingHandCursor);
552 myPanCursor = QCursor(SizeAllCursor);
553 myZoomCursor = QCursor(QPixmap(imageZoomCursor));
554 myRotateCursor = QCursor(QPixmap(imageRotateCursor));
555 mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!!
556 myGlobalPanCursor = QCursor(CrossCursor);
557 myCursorState = false;
561 //----------------------------------------------------------------------------
562 // event filter - controls mouse and keyboard events during viewer operations
565 ::eventFilter(QObject* object, QEvent* event)
567 if (!myGUIWindow) return false;
568 if ( (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress) && object != myGUIWindow)
570 qApp->removeEventFilter(this);
571 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
573 return QObject::eventFilter(object, event);
577 //----------------------------------------------------------------------------
578 // starts Zoom operation (e.g. through menu command)
583 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
586 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
588 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM);
589 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM;
590 qApp->installEventFilter(this);
594 //----------------------------------------------------------------------------
595 // starts Pan operation (e.g. through menu command)
600 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
603 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
605 setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN);
606 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN;
607 qApp->installEventFilter(this);
610 //----------------------------------------------------------------------------
611 // starts Rotate operation (e.g. through menu command)
616 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
619 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
621 setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE);
622 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
623 qApp->installEventFilter(this);
627 //----------------------------------------------------------------------------
628 // starts Spin operation (e.g. through menu command)
633 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
636 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
638 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN);
639 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN;
640 qApp->installEventFilter(this);
645 //----------------------------------------------------------------------------
646 // starts Fit Area operation (e.g. through menu command)
651 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
654 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
656 setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT);
657 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT;
658 qApp->installEventFilter(this);
662 //----------------------------------------------------------------------------
663 // starts Global Panning operation (e.g. through menu command)
668 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
671 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
673 setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN);
674 ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN;
676 // store current zoom scale
677 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
678 myScale = cam->GetParallelScale();
680 if (myViewWindow) myViewWindow->onFitAll();
682 if (myGUIWindow) myGUIWindow->update();
684 qApp->installEventFilter(this);
688 //----------------------------------------------------------------------------
689 // returns TRUE if needs redrawing
694 return State == VTK_INTERACTOR_STYLE_CAMERA_ZOOM ||
695 State == VTK_INTERACTOR_STYLE_CAMERA_PAN ||
696 State == VTK_INTERACTOR_STYLE_CAMERA_ROTATE ||
697 State == VTK_INTERACTOR_STYLE_CAMERA_SPIN ||
698 State == VTK_INTERACTOR_STYLE_CAMERA_NONE;
702 //----------------------------------------------------------------------------
703 // fits viewer contents to rect
706 ::fitRect(const int left,
711 if (this->CurrentRenderer == NULL) return;
714 int x = (left + right)/2;
715 int y = (top + bottom)/2;
716 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
717 int oldX = aSize[0]/2;
718 int oldY = aSize[1]/2;
719 TranslateView(oldX, oldY, x, y);
722 double dxf = (double)(aSize[0]) / (double)(abs(right - left));
723 double dyf = (double)(aSize[1]) / (double)(abs(bottom - top));
724 double zoomFactor = (dxf + dyf)/2 ;
726 vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera();
727 if(aCam->GetParallelProjection())
728 aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor);
730 aCam->Dolly(zoomFactor);
731 ::ResetCameraClippingRange(this->CurrentRenderer);
734 myGUIWindow->update();
738 //----------------------------------------------------------------------------
739 // starts viewer operation (!internal usage!)
742 ::startOperation(int operation)
746 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
747 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
748 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
749 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
750 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
751 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
752 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
753 if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
754 startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
756 if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT)
757 setCursor(operation);
760 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
762 setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE);
763 State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE;
769 //----------------------------------------------------------------------------
770 // sets proper cursor for window when viewer operation is activated
773 ::setCursor(const int operation)
775 if (!myGUIWindow) return;
778 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
779 myGUIWindow->setCursor(myZoomCursor);
780 myCursorState = true;
782 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
783 myGUIWindow->setCursor(myPanCursor);
784 myCursorState = true;
786 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
787 myGUIWindow->setCursor(myRotateCursor);
788 myCursorState = true;
790 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
791 myGUIWindow->setCursor(mySpinCursor);
792 myCursorState = true;
794 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
795 myGUIWindow->setCursor(myGlobalPanCursor);
796 myCursorState = true;
798 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
799 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
800 myGUIWindow->setCursor(myHandCursor);
801 myCursorState = true;
803 case VTK_INTERACTOR_STYLE_CAMERA_NONE:
805 myGUIWindow->setCursor(myDefCursor);
806 myCursorState = false;
812 //----------------------------------------------------------------------------
813 // called when viewer operation started (!put necessary initialization here!)
818 if (!myGUIWindow) return;
819 // VSV: LOD actor activisation
820 // this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
822 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
823 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
825 QPainter p(myGUIWindow);
826 p.setPen(Qt::lightGray);
827 p.setRasterOp(Qt::XorROP);
828 p.drawRect(QRect(myPoint, myOtherPoint));
831 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
832 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
833 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
834 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
835 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
841 //----------------------------------------------------------------------------
842 // called when viewer operation finished (!put necessary post-processing here!)
845 ::onFinishOperation()
850 // VSV: LOD actor activisation
851 // rwi->GetRenderWindow()->SetDesiredUpdateRate(rwi->GetStillUpdateRate());
853 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
854 bool aSelActiveCompOnly = false;
856 QString aComponentDataType;
857 if(SUIT_Session* aSession = SUIT_Session::session())
858 if(SUIT_Application* aSUITApp = aSession->activeApplication())
859 if(CAM_Application* aCAMApp = dynamic_cast<CAM_Application*>(aSUITApp))
860 if(CAM_Module* aModule = aCAMApp->activeModule())
861 aComponentDataType = aModule->name();
864 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
865 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
867 QPainter p(myGUIWindow);
868 p.setPen(Qt::lightGray);
869 p.setRasterOp(Qt::XorROP);
870 QRect rect(myPoint, myOtherPoint);
872 rect = rect.normalize();
873 if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) {
874 // making fit rect opeation
876 myInteractor->GetSize(w, h);
879 y1 = h - rect.top() - 1;
881 y2 = h - rect.bottom() - 1;
882 fitRect(x1, y1, x2, y2);
885 if (myPoint == myOtherPoint) {
886 // process point selection
888 myInteractor->GetSize(w, h);
890 y = h - myPoint.y() - 1;
892 this->FindPokedRenderer(x, y);
893 myInteractor->StartPickCallback();
895 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
896 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
898 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
900 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
901 int aVtkId = picker->GetCellId();
902 if ( aVtkId >= 0 && aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
903 int anObjId = aSActor->GetElemObjId(aVtkId);
905 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
906 if(aSelectionMode != EdgeOfCellSelection) {
907 if(CheckDimensionId(aSelectionMode,aSActor,anObjId)){
908 if (GetSelector()->IsSelected(anIO)) {
909 // This IO is already in the selection
910 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
913 this->HighlightProp( NULL );
914 GetSelector()->ClearIObjects();
916 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
917 GetSelector()->AddIObject(aSActor);
922 this->HighlightProp( NULL );
923 GetSelector()->ClearIObjects();
925 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
927 GetSelector()->AddOrRemoveIndex(anIO,anObjId,false);
928 GetSelector()->AddOrRemoveIndex(anIO,-anEdgeId-1,true);
929 GetSelector()->AddIObject(aSActor);
934 this->HighlightProp( NULL );
935 GetSelector()->ClearIObjects();
937 } else if ( vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker) ) {
938 int aVtkId = picker->GetPointId();
939 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
940 if ( aSActor && aSActor->hasIO() ) {
941 int anObjId = aSActor->GetNodeObjId(aVtkId);
943 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
944 if(GetSelector()->IsSelected(anIO)) {
945 // This IO is already in the selection
946 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
949 this->HighlightProp( NULL );
950 GetSelector()->ClearIObjects();
952 GetSelector()->AddOrRemoveIndex(anIO,anObjId,myShiftState);
953 GetSelector()->AddIObject(aSActor);
958 this->HighlightProp( NULL );
959 GetSelector()->ClearIObjects();
962 if ( aSActor && aSActor->hasIO() ) {
964 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
965 if(GetSelector()->IsSelected(anIO)) {
966 // This IO is already in the selection
968 GetSelector()->RemoveIObject(aSActor);
973 this->HighlightProp( NULL );
974 GetSelector()->ClearIObjects();
976 GetSelector()->AddIObject(aSActor);
979 // No selection clear all
980 this->PropPicked = 0;
981 this->HighlightProp( NULL );
982 GetSelector()->ClearIObjects();
985 myInteractor->EndPickCallback();
987 //processing rectangle selection
988 if(aSelActiveCompOnly && aComponentDataType.isEmpty()) return;
989 myInteractor->StartPickCallback();
992 this->PropPicked = 0;
993 this->HighlightProp( NULL );
994 GetSelector()->ClearIObjects();
998 // vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
999 QRect rect(myPoint, myOtherPoint);
1000 rect = rect.normalize();
1002 myInteractor->GetSize(w, h);
1005 y1 = h - rect.top() - 1;
1007 y2 = h - rect.bottom() - 1;
1009 switch (aSelectionMode) {
1010 case NodeSelection: {
1011 if ( vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(myInteractor->GetPicker()) ) {
1012 vtkActorCollection* aListActors = this->CurrentRenderer->GetActors();
1013 aListActors->InitTraversal();
1014 while (vtkActor* aActor = aListActors->GetNextActor()) {
1015 if (!aActor->GetVisibility())
1017 if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1018 if (aSActor->hasIO()) {
1019 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1022 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1024 if (vtkDataSet* aDataSet = aSActor->GetInput()) {
1025 TColStd_MapOfInteger anIndices;
1026 for(int i = 0; i < aDataSet->GetNumberOfPoints(); i++) {
1028 aDataSet->GetPoint(i,aPoint);
1029 if (IsInRect(aPoint,x1,y1,x2,y2)){
1031 ComputeWorldToDisplay(aPoint[0],aPoint[1],aPoint[2],aDisp);
1032 if(aPointPicker->Pick(aDisp[0],aDisp[1],0.0,CurrentRenderer)){
1033 if(vtkActorCollection *anActorCollection = aPointPicker->GetActors()){
1034 if(anActorCollection->IsItemPresent(aSActor)){
1035 float aPickedPoint[3];
1036 aPointPicker->GetMapperPosition(aPickedPoint);
1037 vtkIdType aVtkId = aDataSet->FindPoint(aPickedPoint);
1038 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ){
1039 int anObjId = aSActor->GetNodeObjId(aVtkId);
1040 anIndices.Add(anObjId);
1047 if (!anIndices.IsEmpty()) {
1048 GetSelector()->AddOrRemoveIndex(anIO,anIndices,true); // ENK false to true
1049 GetSelector()->AddIObject(aSActor);
1052 GetSelector()->RemoveIObject(aSActor);
1062 case EdgeOfCellSelection:
1065 case VolumeSelection:
1067 vtkSmartPointer<VTKViewer_CellRectPicker> picker = VTKViewer_CellRectPicker::New();
1068 picker->SetTolerance(0.001);
1069 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1071 vtkActorCollection* aListActors = picker->GetActors();
1072 aListActors->InitTraversal();
1073 while(vtkActor* aActor = aListActors->GetNextActor()) {
1074 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1075 if (aSActor->hasIO()) {
1076 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1077 if (aSelActiveCompOnly && aComponentDataType != anIO->getComponentDataType())
1079 VTKViewer_CellDataSet cellList = picker->GetCellData(aActor);
1080 if ( !cellList.empty() ) {
1081 TColStd_MapOfInteger anIndexes;
1082 VTKViewer_CellDataSet::iterator it;
1083 for ( it = cellList.begin(); it != cellList.end(); ++it ) {
1084 int aCellId = (*it).cellId;
1086 if ( !IsValid( aSActor, aCellId ) )
1089 int anObjId = aSActor->GetElemObjId(aCellId);
1091 if ( CheckDimensionId(aSelectionMode,aSActor,anObjId) ) {
1092 anIndexes.Add(anObjId);
1096 GetSelector()->AddOrRemoveIndex(anIO,anIndexes,true);
1097 GetSelector()->AddIObject(aSActor);
1104 case ActorSelection: // objects selection
1106 vtkSmartPointer<VTKViewer_RectPicker> picker = VTKViewer_RectPicker::New();
1107 picker->SetTolerance(0.001);
1108 picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);
1110 vtkActorCollection* aListActors = picker->GetActors();
1111 aListActors->InitTraversal();
1112 while(vtkActor* aActor = aListActors->GetNextActor()) {
1113 if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) {
1114 if (aSActor->hasIO()) {
1115 Handle(SALOME_InteractiveObject) anIO = aSActor->getIO();
1116 GetSelector()->AddIObject(aSActor);
1123 myInteractor->EndPickCallback();
1125 myViewWindow->onSelectionChanged();
1129 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1130 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1131 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1132 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1134 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1137 myInteractor->GetSize(w, h);
1139 y = h - myPoint.y() - 1;
1144 if (myGUIWindow) myGUIWindow->update();
1149 // called during viewer operation when user moves mouse (!put necessary processing here!)
1151 SVTK_InteractorStyle
1152 ::onOperation(QPoint mousePos)
1154 if (!myGUIWindow) return;
1156 GetInteractor()->GetSize(w, h);
1158 case VTK_INTERACTOR_STYLE_CAMERA_PAN:
1160 // processing panning
1161 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1162 this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y());
1166 case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
1168 // processing zooming
1169 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1170 this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y());
1174 case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
1176 // processing rotation
1177 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1178 this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y());
1182 case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
1184 // processing spinning
1185 //this->FindPokedCamera(mousePos.x(), mousePos.y());
1186 this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y());
1190 case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
1194 case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
1197 setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
1199 case VTK_INTERACTOR_STYLE_CAMERA_FIT:
1201 QPainter p(myGUIWindow);
1202 p.setPen(Qt::lightGray);
1203 p.setRasterOp(Qt::XorROP);
1204 p.drawRect(QRect(myPoint, myOtherPoint));
1205 myOtherPoint = mousePos;
1206 p.drawRect(QRect(myPoint, myOtherPoint));
1210 this->LastPos[0] = mousePos.x();
1211 this->LastPos[1] = h - mousePos.y() - 1;
1214 // called when selection mode changed (!put necessary initialization here!)
1216 SVTK_InteractorStyle
1217 ::OnSelectionModeChanged()
1220 myPreSelectionActor->SetVisibility(false);
1221 myElemId = myEdgeId = myNodeId = -1;
1222 mySelectedActor = NULL;
1225 // called when user moves mouse inside viewer window and there is no active viewer operation
1226 // (!put necessary processing here!)
1228 SVTK_InteractorStyle
1229 ::onCursorMove(QPoint mousePos)
1231 // processing highlighting
1232 Selection_Mode aSelectionMode = myViewWindow->SelectionMode();
1235 myInteractor->GetSize(w, h);
1236 x = mousePos.x(); y = h - mousePos.y() - 1;
1238 this->FindPokedRenderer(x,y);
1239 myInteractor->StartPickCallback();
1240 myPreSelectionActor->SetVisibility(false);
1242 vtkPicker* aPicker = vtkPicker::SafeDownCast(myInteractor->GetPicker());
1243 aPicker->Pick(x, y, 0.0, this->CurrentRenderer);
1245 SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aPicker->GetActor());
1247 if (aSActor && myPreSelectionActor){
1249 aSActor->GetPosition(aPos);
1250 myPreSelectionActor->SetPosition(aPos);
1253 if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) {
1254 int aVtkId = picker->GetCellId();
1255 if ( aVtkId >= 0 ) {
1256 int anObjId = aSActor->GetElemObjId(aVtkId);
1257 if ( aSActor && aSActor->hasIO() && IsValid( aSActor, aVtkId ) ) {
1258 bool anIsSameObjId = (mySelectedActor == aSActor && myElemId == anObjId);
1259 bool aResult = anIsSameObjId;
1260 if(!anIsSameObjId) {
1261 if(aSelectionMode != EdgeOfCellSelection) {
1262 aResult = CheckDimensionId(aSelectionMode,aSActor,anObjId);
1264 mySelectedActor = aSActor;
1266 myInteractor->setCellData(anObjId,aSActor,myPreSelectionActor);
1270 if(aSelectionMode == EdgeOfCellSelection){
1271 int anEdgeId = GetEdgeId(picker,aSActor,anObjId);
1272 bool anIsSameEdgeId = (myEdgeId != anEdgeId) && anIsSameObjId;
1273 aResult = anIsSameEdgeId;
1274 if(!anIsSameEdgeId) {
1275 aResult = (anEdgeId >= 0);
1277 mySelectedActor = aSActor;
1278 myEdgeId = anEdgeId;
1280 myInteractor->setEdgeData(anObjId,aSActor,-anEdgeId-1,myPreSelectionActor);
1285 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1286 myPreSelectionActor->SetVisibility(true);
1291 else if (vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker)) {
1292 int aVtkId = picker->GetPointId();
1293 if ( aVtkId >= 0 && IsValid( aSActor, aVtkId, true ) ) {
1294 if ( aSActor && aSActor->hasIO() ) {
1295 int anObjId = aSActor->GetNodeObjId(aVtkId);
1296 bool anIsSameObjId = (mySelectedActor == aSActor && myNodeId == anObjId);
1297 if(!anIsSameObjId) {
1298 mySelectedActor = aSActor;
1300 myInteractor->setPointData(anObjId,aSActor,myPreSelectionActor);
1302 myPreSelectionActor->GetProperty()->SetRepresentationToSurface();
1303 myPreSelectionActor->SetVisibility(true);
1307 else if ( vtkPicker::SafeDownCast(aPicker) ) {
1309 if ( myPreViewActor != aSActor ) {
1310 if ( myPreViewActor != NULL ) {
1311 myPreViewActor->SetPreSelected( false );
1313 myPreViewActor = aSActor;
1315 if ( aSActor->hasIO() ) {
1316 Handle( SALOME_InteractiveObject) IO = aSActor->getIO();
1317 if ( !GetSelector()->IsSelected(IO) ) {
1318 // Find All actors with same IO
1319 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1320 theActors->InitTraversal();
1321 while( vtkActor *ac = theActors->GetNextActor() ) {
1322 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1323 if ( anActor->hasIO() ) {
1324 Handle(SALOME_InteractiveObject) IOS = anActor->getIO();
1325 if(IO->isSame(IOS)) {
1326 anActor->SetPreSelected( true );
1335 myPreViewActor = NULL;
1336 vtkActorCollection* theActors = this->CurrentRenderer->GetActors();
1337 theActors->InitTraversal();
1338 while( vtkActor *ac = theActors->GetNextActor() ) {
1339 if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) {
1340 anActor->SetPreSelected( false );
1345 myInteractor->EndPickCallback();
1346 //myInteractor->Render();
1347 myGUIWindow->update();
1349 this->LastPos[0] = x;
1350 this->LastPos[1] = y;
1353 // called on finsh GlobalPan operation
1355 SVTK_InteractorStyle
1356 ::Place(const int theX, const int theY)
1358 if (this->CurrentRenderer == NULL) {
1363 int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize();
1364 int centerX = aSize[0]/2;
1365 int centerY = aSize[1]/2;
1367 TranslateView(centerX, centerY, theX, theY);
1369 // restore zoom scale
1370 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1371 cam->SetParallelScale(myScale);
1372 ::ResetCameraClippingRange(this->CurrentRenderer);
1374 if (myGUIWindow) myGUIWindow->update();
1380 // Translates view from Point to Point
1382 SVTK_InteractorStyle
1383 ::TranslateView(int toX, int toY, int fromX, int fromY)
1385 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
1386 double viewFocus[4], focalDepth, viewPoint[3];
1387 float newPickPoint[4], oldPickPoint[4], motionVector[3];
1388 cam->GetFocalPoint(viewFocus);
1390 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1],
1391 viewFocus[2], viewFocus);
1392 focalDepth = viewFocus[2];
1394 this->ComputeDisplayToWorld(double(toX), double(toY),
1395 focalDepth, newPickPoint);
1396 this->ComputeDisplayToWorld(double(fromX),double(fromY),
1397 focalDepth, oldPickPoint);
1399 // camera motion is reversed
1400 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1401 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1402 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1404 cam->GetFocalPoint(viewFocus);
1405 cam->GetPosition(viewPoint);
1406 cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1407 motionVector[1] + viewFocus[1],
1408 motionVector[2] + viewFocus[2]);
1409 cam->SetPosition(motionVector[0] + viewPoint[0],
1410 motionVector[1] + viewPoint[1],
1411 motionVector[2] + viewPoint[2]);
1415 /// Checks: is the given Actor within display coordinates?
1417 SVTK_InteractorStyle
1418 ::IsInRect(vtkActor* theActor,
1419 const int left, const int top,
1420 const int right, const int bottom)
1422 float* aBounds = theActor->GetBounds();
1423 float aMin[3], aMax[3];
1424 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1425 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1426 if (aMin[0] > aMax[0]) {
1427 float aBuf = aMin[0];
1431 if (aMin[1] > aMax[1]) {
1432 float aBuf = aMin[1];
1437 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1441 /// Checks: is the given Cell within display coordinates?
1443 SVTK_InteractorStyle
1444 ::IsInRect(vtkCell* theCell,
1445 const int left, const int top,
1446 const int right, const int bottom)
1448 float* aBounds = theCell->GetBounds();
1449 float aMin[3], aMax[3];
1450 ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin);
1451 ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax);
1452 if (aMin[0] > aMax[0]) {
1453 float aBuf = aMin[0];
1457 if (aMin[1] > aMax[1]) {
1458 float aBuf = aMin[1];
1463 return ((aMin[0]>left) && (aMax[0]<right) && (aMin[1]>bottom) && (aMax[1]<top));
1468 SVTK_InteractorStyle
1469 ::IsInRect(float* thePoint,
1470 const int left, const int top,
1471 const int right, const int bottom)
1474 ComputeWorldToDisplay(thePoint[0], thePoint[1], thePoint[2], aPnt);
1476 return ((aPnt[0]>left) && (aPnt[0]<right) && (aPnt[1]>bottom) && (aPnt[1]<top));
1480 SVTK_InteractorStyle
1481 ::SetFilter( const Handle(VTKViewer_Filter)& theFilter )
1483 myFilters[ theFilter->GetId() ] = theFilter;
1487 SVTK_InteractorStyle
1488 ::IsFilterPresent( const int theId )
1490 return myFilters.find( theId ) != myFilters.end();
1494 SVTK_InteractorStyle
1495 ::RemoveFilter( const int theId )
1497 if ( IsFilterPresent( theId ) )
1498 myFilters.erase( theId );
1503 SVTK_InteractorStyle
1504 ::IsValid( SALOME_Actor* theActor,
1506 const bool theIsNode )
1508 std::map<int, Handle(VTKViewer_Filter)>::const_iterator anIter;
1509 for ( anIter = myFilters.begin(); anIter != myFilters.end(); ++anIter )
1511 const Handle(VTKViewer_Filter)& aFilter = anIter->second;
1512 if ( theIsNode == aFilter->IsNodeFilter() &&
1513 !aFilter->IsValid( theActor, theId ) )
1519 Handle(VTKViewer_Filter)
1520 SVTK_InteractorStyle
1521 ::GetFilter( const int theId )
1523 return IsFilterPresent( theId ) ? myFilters[ theId ] : Handle(VTKViewer_Filter)();
1527 SVTK_InteractorStyle
1528 ::IncrementalPan( const int incrX, const int incrY )
1530 this->PanXY( incrX, incrY, 0, 0 );
1534 SVTK_InteractorStyle
1535 ::IncrementalZoom( const int incr )
1537 this->DollyXY( incr, incr );
1541 SVTK_InteractorStyle
1542 ::IncrementalRotate( const int incrX, const int incrY )
1544 this->RotateXY( incrX, -incrY );