Back to index

salome-gui  6.5.0
SVTK_RenderWindowInteractor.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SALOME VTKViewer : build VTK viewer into Salome desktop
00024 //  File   : 
00025 //  Author : 
00026 
00027 #include "SVTK_RenderWindowInteractor.h"
00028 
00029 #include "SVTK_InteractorStyle.h"
00030 #include "SVTK_Renderer.h"
00031 #include "SVTK_Functor.h"
00032 #include "SALOME_Actor.h"
00033 
00034 // QT Includes
00035 // Put Qt includes before the X11 includes which #define the symbol None
00036 // (see SVTK_SpaceMouse.h) to avoid the compilation error.
00037 #ifndef WIN32
00038 # include <QX11Info>
00039 #endif
00040 #include <QMouseEvent>
00041 
00042 #include "SVTK_SpaceMouse.h" 
00043 #include "SVTK_Event.h" 
00044 
00045 #include "VTKViewer_Algorithm.h"
00046 
00047 // VTK Includes
00048 #include <vtkObjectFactory.h>
00049 #include <vtkRendererCollection.h>
00050 #include <vtkRenderWindow.h>
00051 #include <vtkGenericRenderWindowInteractor.h>
00052 #include <vtkCallbackCommand.h>
00053 #include <vtkCommand.h>
00054 #include <vtkPicker.h>
00055 #include <vtkCamera.h>
00056 
00057 static bool GENERATE_SUIT_EVENTS = true;
00058 static bool FOCUS_UNDER_MOUSE = false;
00059 
00060 
00064 QVTK_RenderWindowInteractor
00065 ::QVTK_RenderWindowInteractor(QWidget* theParent, 
00066                               const char* theName):
00067   QWidget(theParent),
00068   myRenderWindow(vtkRenderWindow::New())
00069 {
00070   setAttribute( Qt::WA_PaintOnScreen );
00071   setAttribute( Qt::WA_NoSystemBackground );
00072 
00073   setObjectName(theName);
00074 
00075   setMouseTracking(true);
00076 
00077   myRenderWindow->Delete();
00078   myRenderWindow->DoubleBufferOn();
00079 
00080 #ifndef WIN32
00081   myRenderWindow->SetDisplayId((void*)QX11Info::display());
00082 #endif
00083   myRenderWindow->SetWindowId((void*)winId());
00084 }
00085 
00089 void 
00090 QVTK_RenderWindowInteractor
00091 ::Initialize(vtkGenericRenderWindowInteractor* theDevice)
00092 {
00093   if ( GetDevice() )
00094     myDevice->SetRenderWindow( NULL );
00095 
00096   myDevice = theDevice;
00097 
00098   if ( theDevice )
00099     theDevice->SetRenderWindow( getRenderWindow() );
00100 }
00101 
00105 QVTK_RenderWindowInteractor
00106 ::~QVTK_RenderWindowInteractor() 
00107 {
00108 #ifndef WIN32
00109   SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
00110   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
00111     aSpaceMouse->close( QX11Info::display() );
00112 #endif
00113 }
00114 
00115 
00119 vtkGenericRenderWindowInteractor* 
00120 QVTK_RenderWindowInteractor
00121 ::GetDevice()
00122 {
00123   return myDevice.GetPointer();
00124 }
00125 
00129 vtkRenderWindow*
00130 QVTK_RenderWindowInteractor
00131 ::getRenderWindow()
00132 {
00133   return myRenderWindow.GetPointer();
00134 }
00135 
00139 void
00140 QVTK_RenderWindowInteractor
00141 ::InvokeEvent(unsigned long theEvent, void* theCallData)
00142 {
00143   GetDevice()->InvokeEvent(theEvent,theCallData);
00144 }
00145 
00149 QPaintEngine* QVTK_RenderWindowInteractor::paintEngine() const
00150 {
00151   return 0;
00152 }
00153 
00157 void
00158 QVTK_RenderWindowInteractor
00159 ::show()
00160 {
00161   QWidget::show();
00162   update(); // needed for initial contents display on Win32
00163 }
00164 
00168 void
00169 QVTK_RenderWindowInteractor
00170 ::polish()
00171 {
00172   // Final initialization just before the widget is displayed
00173   GetDevice()->SetSize(width(),height());
00174   if(!GetDevice()->GetInitialized() && GetDevice()->GetRenderWindow()){
00175     GetDevice()->Initialize();
00176     GetDevice()->ConfigureEvent();
00177   }
00178 }
00179 
00183 void
00184 QVTK_RenderWindowInteractor
00185 ::resize(int w, int h) 
00186 {
00187   GetDevice()->UpdateSize(w,h);
00188 }
00189 
00193 void
00194 QVTK_RenderWindowInteractor
00195 ::paintEvent( QPaintEvent* theEvent ) 
00196 {
00197   GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
00198 }
00199 
00200 
00204 void
00205 QVTK_RenderWindowInteractor
00206 ::resizeEvent( QResizeEvent* theEvent )
00207 {
00208   int* aSize = getRenderWindow()->GetSize();
00209   int aWidth = aSize[0];
00210   int aHeight = aSize[1];
00211 
00212   GetDevice()->UpdateSize(width(),height());
00213 
00214   if(isVisible() && aWidth && aHeight){
00215     if( aWidth != width() || aHeight != height() ) {
00216       vtkRendererCollection * aRenderers = getRenderWindow()->GetRenderers();
00217       aRenderers->InitTraversal();
00218       double aCoeff = 1.0;
00219       if(vtkRenderer *aRenderer = aRenderers->GetNextItem()) {
00220         vtkCamera *aCamera = aRenderer->GetActiveCamera();
00221         double aScale = aCamera->GetParallelScale();
00222         if((aWidth - width())*(aHeight - height()) > 0)
00223           aCoeff = sqrt(double(aWidth)/double(width())*double(height())/double(aHeight));
00224         else
00225           aCoeff = double(aWidth)/double(width());
00226         aCamera->SetParallelScale(aScale*aCoeff);
00227       }
00228     }
00229   }
00230 
00231   update(); 
00232 }
00233 
00234 
00235 
00239 void
00240 QVTK_RenderWindowInteractor
00241 ::contextMenuEvent( QContextMenuEvent* event )
00242 {}
00243 
00247 void
00248 QVTK_RenderWindowInteractor
00249 ::mouseMoveEvent( QMouseEvent* event ) 
00250 {
00251   GetDevice()->SetEventInformationFlipY(event->x(), 
00252                                         event->y(),
00253                                         event->modifiers() & Qt::ControlModifier,
00254                                         event->modifiers() & Qt::ShiftModifier);
00255   GetDevice()->MouseMoveEvent();
00256 }
00257 
00258 
00262 void
00263 QVTK_RenderWindowInteractor
00264 ::mousePressEvent( QMouseEvent* event ) 
00265 {
00266   GetDevice()->SetEventInformationFlipY(event->x(), 
00267                                         event->y(),
00268                                         event->modifiers() & Qt::ControlModifier,
00269                                         event->modifiers() & Qt::ShiftModifier);
00270   if( event->button() & Qt::LeftButton )
00271     GetDevice()->LeftButtonPressEvent();
00272   else if( event->button() & Qt::MidButton )
00273     GetDevice()->MiddleButtonPressEvent();
00274   else if( event->button() & Qt::RightButton )
00275     GetDevice()->RightButtonPressEvent();
00276 }
00277 
00278 
00282 void
00283 QVTK_RenderWindowInteractor
00284 ::mouseReleaseEvent( QMouseEvent *event )
00285 {
00286   GetDevice()->SetEventInformationFlipY(event->x(), 
00287                                         event->y(),
00288                                         event->modifiers() & Qt::ControlModifier,
00289                                         event->modifiers() & Qt::ShiftModifier);
00290 
00291   if( event->button() & Qt::LeftButton )
00292     GetDevice()->LeftButtonReleaseEvent();
00293   else if( event->button() & Qt::MidButton )
00294     GetDevice()->MiddleButtonReleaseEvent();
00295   else if( event->button() & Qt::RightButton )
00296     GetDevice()->RightButtonReleaseEvent();
00297 }
00298 
00299 
00303 void
00304 QVTK_RenderWindowInteractor
00305 ::mouseDoubleClickEvent( QMouseEvent* event )
00306 {}
00307 
00308 
00312 void
00313 QVTK_RenderWindowInteractor
00314 ::wheelEvent( QWheelEvent* event )
00315 {
00316   activateWindow();
00317   setFocus();
00318   GetDevice()->SetEventInformationFlipY(event->x(), 
00319                                         event->y(),
00320                                         event->modifiers() & Qt::ControlModifier,
00321                                         event->modifiers() & Qt::ShiftModifier);
00322   if ( event->delta()>0)
00323     GetDevice()->MouseWheelForwardEvent();
00324   else
00325     GetDevice()->MouseWheelBackwardEvent();
00326 }
00327 
00328 
00332 void
00333 QVTK_RenderWindowInteractor
00334 ::keyPressEvent( QKeyEvent* event ) 
00335 {
00336   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
00337                                       event->modifiers() & Qt::ShiftModifier,
00338                                       event->key());
00339   GetDevice()->KeyPressEvent();
00340   GetDevice()->CharEvent();
00341 }
00342 
00346 void
00347 QVTK_RenderWindowInteractor
00348 ::keyReleaseEvent( QKeyEvent * event ) 
00349 {
00350   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
00351                                       event->modifiers() & Qt::ShiftModifier,
00352                                       event->key());
00353   GetDevice()->KeyReleaseEvent();
00354 }
00355 
00356 
00360 void  
00361 QVTK_RenderWindowInteractor
00362 ::enterEvent( QEvent* event )
00363 {
00364   if(FOCUS_UNDER_MOUSE){
00365     activateWindow();
00366     setFocus();
00367   }
00368   GetDevice()->EnterEvent();
00369 }
00370 
00374 void  
00375 QVTK_RenderWindowInteractor
00376 ::leaveEvent( QEvent * )
00377 {
00378   GetDevice()->LeaveEvent();
00379 }
00380 
00385 void  
00386 QVTK_RenderWindowInteractor
00387 ::focusInEvent( QFocusEvent* event )
00388 {
00389   QWidget::focusInEvent( event );
00390 
00391 #ifndef WIN32
00392   // register set space mouse events receiver
00393   SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
00394 
00395   if ( aSpaceMouse )
00396   {
00397     if ( !aSpaceMouse->isSpaceMouseOn() )
00398       // initialize 3D space mouse driver 
00399       aSpaceMouse->initialize( QX11Info::display(), winId() );
00400     else
00401       aSpaceMouse->setWindow( QX11Info::display(), winId() );
00402   }
00403 #endif
00404 }
00405 
00410 void  
00411 QVTK_RenderWindowInteractor
00412 ::focusOutEvent ( QFocusEvent* event )
00413 {
00414   QWidget::focusOutEvent( event );
00415 
00416 #ifndef WIN32
00417   // unregister set space mouse events receiver
00418   SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
00419   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
00420     aSpaceMouse->setWindow( QX11Info::display(), 0 );
00421 #endif
00422 }
00423 
00424 
00425 #ifdef WIN32
00426 
00430 bool QVTK_RenderWindowInteractor::winEvent( MSG* msg, long* result )
00431 {
00432   // TODO: Implement event handling for SpaceMouse
00433   return QWidget::winEvent( msg, result);
00434 }
00435 
00436 #else
00437 
00441 bool 
00442 QVTK_RenderWindowInteractor
00443 ::x11Event( XEvent *xEvent )
00444 {
00445   // handle 3d space mouse events
00446   if ( SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance() )
00447   {
00448     if ( aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage )
00449     {
00450       SVTK_SpaceMouse::MoveEvent anEvent;
00451       int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
00452       switch ( type )
00453       {
00454       case SVTK_SpaceMouse::SpaceMouseMove:
00455               GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
00456               break;
00457       case SVTK_SpaceMouse::SpaceButtonPress:
00458               GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
00459               break;
00460       case SVTK_SpaceMouse::SpaceButtonRelease:
00461               break;
00462       }
00463       return true; // stop handling the event
00464     }
00465   }
00466 
00467   return QWidget::x11Event( xEvent );
00468 }
00469 
00470 #endif
00471 
00475 SVTK_RenderWindowInteractor
00476 ::SVTK_RenderWindowInteractor(QWidget* theParent, 
00477                                const char* theName):
00478   QVTK_RenderWindowInteractor(theParent,theName),
00479   myEventCallbackCommand(vtkCallbackCommand::New())
00480 {
00481   myEventCallbackCommand->Delete();
00482 
00483   myEventCallbackCommand->SetClientData(this); 
00484   myPriority = 0.0;
00485 
00486   myEventCallbackCommand->SetCallback(SVTK_RenderWindowInteractor::ProcessEvents);
00487 }
00488 
00492 void
00493 SVTK_RenderWindowInteractor
00494 ::Initialize(vtkGenericRenderWindowInteractor* theDevice,
00495              SVTK_Renderer* theRenderer,
00496              SVTK_Selector* theSelector)
00497 {
00498   QVTK_RenderWindowInteractor::Initialize(theDevice);
00499   SetRenderer(theRenderer);
00500   SetSelector(theSelector);
00501 }
00502 
00506 SVTK_RenderWindowInteractor
00507 ::~SVTK_RenderWindowInteractor() 
00508 {
00509   // Sequence of the destruction call are fixed and should be changed.
00510   // vtkRenderWindow instance should be destroyed after all vtkRenderer's
00511   GetDevice()->SetInteractorStyle(NULL); 
00512   while(!myInteractorStyles.empty()){
00513     const PInteractorStyle& aStyle = myInteractorStyles.top();
00514     aStyle->SetInteractor(NULL);
00515     myInteractorStyles.pop();
00516   }
00517 
00518   SetRenderer(NULL);
00519 
00520   GetDevice()->SetRenderWindow(NULL);
00521 }
00522 
00526 SVTK_Renderer* 
00527 SVTK_RenderWindowInteractor
00528 ::GetRenderer()
00529 {
00530   return myRenderer.GetPointer();
00531 }
00532 
00536 vtkRenderer* 
00537 SVTK_RenderWindowInteractor
00538 ::getRenderer()
00539 {
00540   return GetRenderer()->GetDevice();
00541 }
00542 
00547 void
00548 SVTK_RenderWindowInteractor
00549 ::SetRenderer(SVTK_Renderer* theRenderer)
00550 {
00551   if(theRenderer == myRenderer.GetPointer())
00552     return;
00553 
00554   if(GetRenderer())
00555     myRenderWindow->RemoveRenderer(getRenderer());
00556 
00557   myRenderer = theRenderer;
00558 
00559   if(GetRenderer())
00560     myRenderWindow->AddRenderer(getRenderer());
00561 }
00562 
00563 
00568 void
00569 SVTK_RenderWindowInteractor
00570 ::InitInteractorStyle(vtkInteractorStyle* theStyle)
00571 {
00572   GetDevice()->SetInteractorStyle(theStyle); 
00573 }
00574 
00578 void
00579 SVTK_RenderWindowInteractor
00580 ::PushInteractorStyle(vtkInteractorStyle* theStyle)
00581 {
00582   myInteractorStyles.push(PInteractorStyle(theStyle));
00583   InitInteractorStyle(theStyle);
00584 }
00585 
00589 void
00590 SVTK_RenderWindowInteractor
00591 ::PopInteractorStyle()
00592 {
00593   if(GetInteractorStyle())
00594     myInteractorStyles.pop();
00595   
00596   if(GetInteractorStyle()) 
00597     InitInteractorStyle(GetInteractorStyle());
00598 }
00599 
00603 vtkInteractorStyle* 
00604 SVTK_RenderWindowInteractor
00605 ::GetInteractorStyle()
00606 {
00607   return myInteractorStyles.empty() ? 0 : myInteractorStyles.top().GetPointer();
00608 }
00609 
00610 
00614 SVTK_Selector* 
00615 SVTK_RenderWindowInteractor
00616 ::GetSelector() 
00617 { 
00618   return mySelector.GetPointer(); 
00619 }
00620 
00621 
00626 void
00627 SVTK_RenderWindowInteractor
00628 ::SetSelector(SVTK_Selector* theSelector)
00629 { 
00630   if(mySelector.GetPointer())
00631     mySelector->RemoveObserver(myEventCallbackCommand.GetPointer());
00632 
00633   mySelector = theSelector; 
00634 
00635   if(mySelector.GetPointer())
00636     mySelector->AddObserver(vtkCommand::EndPickEvent, 
00637                             myEventCallbackCommand.GetPointer(), 
00638                             myPriority);
00639 }
00640 
00644 void 
00645 SVTK_RenderWindowInteractor
00646 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
00647                 unsigned long theEvent,
00648                 void* theClientData, 
00649                 void* vtkNotUsed(theCallData))
00650 {
00651   SVTK_RenderWindowInteractor* self = reinterpret_cast<SVTK_RenderWindowInteractor*>(theClientData);
00652 
00653   switch(theEvent){
00654   case vtkCommand::EndPickEvent:
00655     self->onEmitSelectionChanged();
00656     break;
00657   }
00658 }
00659 
00663 void
00664 SVTK_RenderWindowInteractor
00665 ::SetSelectionMode(Selection_Mode theMode)
00666 {
00667   mySelector->SetSelectionMode(theMode);
00668 }
00669 
00673 Selection_Mode
00674 SVTK_RenderWindowInteractor
00675 ::SelectionMode() const
00676 {
00677   return mySelector->SelectionMode();
00678 }
00679 
00680 
00684 void
00685 SVTK_RenderWindowInteractor
00686 ::onEmitSelectionChanged()
00687 {
00688   return emit selectionChanged();
00689 }
00690 
00691 
00695 void
00696 SVTK_RenderWindowInteractor
00697 ::mouseMoveEvent( QMouseEvent* event ) 
00698 {
00699   QVTK_RenderWindowInteractor::mouseMoveEvent(event);
00700 
00701   if(GENERATE_SUIT_EVENTS)
00702     emit MouseMove( event );
00703 }
00704 
00705 
00709 void
00710 SVTK_RenderWindowInteractor
00711 ::mousePressEvent( QMouseEvent* event ) 
00712 {
00713   QVTK_RenderWindowInteractor::mousePressEvent(event);
00714 
00715   if(GENERATE_SUIT_EVENTS)
00716     emit MouseButtonPressed( event );
00717 }
00718 
00719 
00723 void
00724 SVTK_RenderWindowInteractor
00725 ::mouseReleaseEvent( QMouseEvent *event )
00726 {
00727   bool aRightBtn = event->button() == Qt::RightButton;
00728   bool isOperation = false;
00729   if( aRightBtn && GetInteractorStyle()) {
00730     SVTK_InteractorStyle* style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
00731     if ( style )
00732       isOperation = style->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
00733   }
00734 
00735   QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
00736 
00737   if ( aRightBtn && !isOperation && !( event->modifiers() & Qt::ControlModifier ) &&
00738        !( event->modifiers() & Qt::ShiftModifier ) ) {
00739     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
00740                               event->pos(), event->globalPos() );
00741     emit contextMenuRequested( &aEvent );
00742   }
00743   if(GENERATE_SUIT_EVENTS)
00744     emit MouseButtonReleased( event );
00745 }
00746 
00747 
00751 void
00752 SVTK_RenderWindowInteractor
00753 ::mouseDoubleClickEvent( QMouseEvent* event )
00754 {
00755   QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event);
00756 
00757   if(GENERATE_SUIT_EVENTS)
00758     emit MouseDoubleClicked( event );
00759 }
00760 
00761 
00765 void
00766 SVTK_RenderWindowInteractor
00767 ::wheelEvent( QWheelEvent* event )
00768 {
00769   QVTK_RenderWindowInteractor::wheelEvent(event);
00770 
00771   if(event->delta() > 0)
00772     GetDevice()->InvokeEvent(SVTK::ZoomInEvent,NULL);
00773   else
00774     GetDevice()->InvokeEvent(SVTK::ZoomOutEvent,NULL);
00775 
00776   if(GENERATE_SUIT_EVENTS)
00777     emit WheelMoved( event );
00778 }
00779 
00783 void
00784 SVTK_RenderWindowInteractor
00785 ::keyPressEvent( QKeyEvent* event ) 
00786 {
00787   QVTK_RenderWindowInteractor::keyPressEvent(event);
00788 
00789   if(GENERATE_SUIT_EVENTS)
00790     emit KeyPressed( event );
00791 }
00792 
00796 void
00797 SVTK_RenderWindowInteractor
00798 ::keyReleaseEvent( QKeyEvent * event ) 
00799 {
00800   QVTK_RenderWindowInteractor::keyReleaseEvent(event);
00801 
00802   if(GENERATE_SUIT_EVENTS)
00803     emit KeyReleased( event );
00804 }
00805