Back to index

salome-gui  6.5.0
VTKViewer_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 #include "VTKViewer_RenderWindowInteractor.h"
00024 #include "VTKViewer_RenderWindow.h"
00025 #include "VTKViewer_InteractorStyle.h"
00026 #include "SUIT_ViewModel.h"
00027 #include "VTKViewer_ViewWindow.h"
00028 
00029 #include "VTKViewer_Actor.h"
00030 #include "VTKViewer_Algorithm.h"
00031 #include "VTKViewer_Functor.h"
00032 
00033 // VTK Includes
00034 #include <vtkAssemblyNode.h>
00035 #include <vtkActor.h>
00036 #include <vtkInteractorStyle.h>
00037 #include <vtkObjectFactory.h>
00038 #include <vtkPicker.h>
00039 #include <vtkCellPicker.h>
00040 #include <vtkPointPicker.h>
00041 #include <vtkUnstructuredGrid.h>
00042 #include <vtkPolyDataMapper.h>
00043 #include <vtkSphereSource.h>
00044 #include <vtkDataSet.h>
00045 #include <vtkMaskPoints.h>
00046 #include <vtkVertex.h>
00047 #include <vtkRendererCollection.h>
00048 #include <vtkPolyDataWriter.h>
00049 #include <vtkProperty.h>
00050 
00051 // QT Includes
00052 #include <QTimer>
00053 #include <QMouseEvent>
00054 #include <QKeyEvent>
00055 #include <QContextMenuEvent>
00056 
00058 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New() 
00059 {
00060   vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
00061   if( ret ) {
00062     return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
00063   }
00064   return new VTKViewer_RenderWindowInteractor;
00065 }
00066 
00068 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor() 
00069 {
00070   this->Enabled = 0 ;
00071   this->mTimer = new QTimer( this ) ;
00072   myDisplayMode = 0;
00073 
00074   myBasicPicker = vtkPicker::New();
00075   myCellPicker = vtkCellPicker::New();
00076   myPointPicker = vtkPointPicker::New();
00077 
00078   myCellActor = VTKViewer_Actor::New(); 
00079   myCellActor->PickableOff();
00080   myCellActor->GetProperty()->SetColor(1,1,0);
00081   myCellActor->GetProperty()->SetLineWidth(5);
00082   myCellActor->GetProperty()->SetRepresentationToSurface();
00083 
00084   myEdgeActor = VTKViewer_Actor::New(); 
00085   myEdgeActor->PickableOff();
00086   myEdgeActor->GetProperty()->SetColor(1,0,0);
00087   myEdgeActor->GetProperty()->SetLineWidth(5);
00088   myEdgeActor->GetProperty()->SetRepresentationToWireframe();
00089 
00090   myPointActor = VTKViewer_Actor::New(); 
00091   myPointActor->PickableOff();
00092   myPointActor->GetProperty()->SetColor(1,1,0);
00093   myPointActor->GetProperty()->SetPointSize(5);
00094   myPointActor->GetProperty()->SetRepresentationToPoints();
00095 
00096   connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
00097 }
00098 
00100 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor() 
00101 {
00102   delete mTimer ;
00103 
00104   if ( GetRenderWindow() ) {
00105     myViewWnd->RemoveActor(myCellActor);
00106     myViewWnd->RemoveActor(myEdgeActor);
00107     myViewWnd->RemoveActor(myPointActor);
00108   }
00109 
00110   myCellActor->Delete();
00111   myEdgeActor->Delete();
00112   myPointActor->Delete();
00113 
00114   myBasicPicker->Delete();
00115   myCellPicker->Delete();
00116   myPointPicker->Delete();
00117 }
00118 
00124 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent) 
00125 {
00126   vtkRenderWindowInteractor::PrintSelf(os, indent) ;
00127   //
00128   // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
00129   // QGL specific stuff goes here. One should add output 
00130   // lines here if any protected members are added to
00131   // the class. 
00132   //
00133 }
00134 
00142 void VTKViewer_RenderWindowInteractor::Initialize()
00143 {
00144   //
00145   // We cannot do much unless there is a render window 
00146   // associated with this interactor. 
00147   //
00148   if( ! RenderWindow ) {
00149     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
00150     return ;
00151   }
00152   
00153   //
00154   // We cannot hand a render window which is not a VTKViewer_RenderWindow. 
00155   // One way to force this is to use dynamic_cast and hope that 
00156   // it works. If the dynamic_cast does not work, we flag an error
00157   // and get the hell out.
00158   //
00159   vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
00160   if( !my_render_win ) {
00161     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
00162     return ;
00163   }
00164  
00165   //
00166   // If the render window has zero size, then set it to a default 
00167   // value of 300x300.
00168   // 
00169   int* aSize = my_render_win->GetSize();
00170   this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
00171   this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
00172 
00173   this->SetPicker(myBasicPicker);
00174 
00175   SetSelectionTolerance();
00176 
00177   //
00178   // Enable the interactor. 
00179   //
00180   this->Enable() ;
00181   
00182   //
00183   // Start the rendering of the window. 
00184   //
00185   my_render_win->Start() ;
00186   
00187   //
00188   // The interactor has been initialized.
00189   //
00190   this->Initialized = 1 ;
00191 
00192   return ;
00193 }
00194 
00196 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
00197   myViewWnd = theViewWnd;
00198 
00199   if ( myViewWnd ) {
00200     myViewWnd->InsertActor(myCellActor);
00201     myViewWnd->InsertActor(myEdgeActor);
00202     myViewWnd->InsertActor(myPointActor);
00203   }
00204 }
00205 
00207 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
00208 {
00209   myViewWnd->MoveActor(myCellActor);
00210   myViewWnd->MoveActor(myEdgeActor);
00211   myViewWnd->MoveActor(myPointActor);
00212 }
00213 
00215 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
00216   myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
00217   vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
00218 }
00219 
00226 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen, 
00227                                                         const double& theBlue, const int& theWidth) 
00228 {
00229   myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
00230   myCellActor->GetProperty()->SetLineWidth(theWidth);
00231 
00232   myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
00233   myPointActor->GetProperty()->SetPointSize(theWidth);
00234 }
00235 
00240 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
00241 {
00242   myTolNodes = theTolNodes;
00243   myTolItems = theTolItems;
00244 
00245   myBasicPicker->SetTolerance(myTolItems);
00246   myCellPicker->SetTolerance(myTolItems);
00247   myPointPicker->SetTolerance(myTolNodes);
00248 
00249 }
00250 
00260 void VTKViewer_RenderWindowInteractor::Enable()
00261 {
00262   //
00263   // Do not need to do anything if already enabled.
00264   //
00265   if( this->Enabled ) {
00266     return ;
00267   }
00268   
00269   this->Enabled = 1 ;
00270   this->Modified() ;
00271 }
00272 
00274 void VTKViewer_RenderWindowInteractor::Disable()
00275 {
00276   if( ! this->Enabled ) {
00277     return ;
00278   }
00279   
00280   this->Enabled = 0 ;
00281   this->Modified() ;
00282 }
00283 
00289 void VTKViewer_RenderWindowInteractor::Start()
00290 {
00291   //
00292   // We do not allow this interactor to control the 
00293   // event loop. Only the QtApplication objects are
00294   // allowed to do that. 
00295   //
00296   vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
00297 }
00298 
00302 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
00303 {
00304   // if the size changed send this on to the RenderWindow
00305   if ((w != this->Size[0])||(h != this->Size[1])) {
00306     this->Size[0] = w;
00307     this->Size[1] = h;
00308     this->RenderWindow->SetSize(w,h);
00309   }
00310 }
00311 
00320 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
00321 {
00325   mTimer->setSingleShot(TRUE) ;
00326   mTimer->start(10) ;
00327   return 1 ;
00328 }
00329 
00334 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
00335 {
00336   //
00337   // :TRICKY: Tue May  2 00:17:32 2000 Pagey
00338   //
00348   return 1 ;
00349 }
00350 
00356 void VTKViewer_RenderWindowInteractor::TimerFunc()
00357 {
00358   if( ! this->Enabled ) {
00359     return ;
00360   }
00361   
00362   ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
00363   emit RenderWindowModified() ;
00364 }
00365 
00368 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
00369   if( ! this->Enabled ) {
00370     return ;
00371   }
00372   myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
00373   if (myInteractorStyle->needsRedrawing() )
00374     emit RenderWindowModified() ; 
00375 }
00376 
00381 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
00382   if( ! this->Enabled ) {
00383     return ;
00384   }
00385   myInteractorStyle->OnLeftButtonDown((event->modifiers() & Qt::ControlModifier), 
00386                                       (event->modifiers() & Qt::ShiftModifier), 
00387                                       event->x(), event->y());
00388 }
00389 
00394 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
00395   if( ! this->Enabled ) {
00396     return ;
00397   }
00398   myInteractorStyle->OnLeftButtonUp( (event->modifiers() & Qt::ControlModifier), 
00399                                      (event->modifiers() & Qt::ShiftModifier), 
00400                                      event->x(), event->y() ) ;
00401 }
00402 
00407 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
00408   if( ! this->Enabled ) {
00409     return ;
00410   }
00411   myInteractorStyle->OnMiddleButtonDown((event->modifiers() & Qt::ControlModifier), 
00412                                         (event->modifiers() & Qt::ShiftModifier), 
00413                                         event->x(), event->y() ) ;
00414 }
00415 
00420 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
00421   if( ! this->Enabled ) {
00422     return ;
00423   }
00424   myInteractorStyle->OnMiddleButtonUp( (event->modifiers() & Qt::ControlModifier), 
00425                                        (event->modifiers() & Qt::ShiftModifier), 
00426                                        event->x(), event->y() ) ;
00427 }
00428 
00433 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
00434   if( ! this->Enabled ) {
00435     return ;
00436   }
00437   myInteractorStyle->OnRightButtonDown( (event->modifiers() & Qt::ControlModifier), 
00438                                         (event->modifiers() & Qt::ShiftModifier), 
00439                                         event->x(), event->y() ) ;
00440 }
00441 
00446 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
00447   if( ! this->Enabled ) {
00448     return ;
00449   }
00450   bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
00451   myInteractorStyle->OnRightButtonUp( (event->modifiers() & Qt::ControlModifier),
00452                                       (event->modifiers() & Qt::ShiftModifier),
00453                                       event->x(), event->y() );
00454   if ( !isOperation )
00455   {
00456     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
00457                               event->pos(), event->globalPos() );
00458     emit contextMenuRequested( &aEvent );
00459   }
00460 }
00461 
00465 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
00466   return ;
00467 }
00468 
00472 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
00473   return ;
00474 }
00475 
00477 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
00478   return myDisplayMode;
00479 }
00480 
00482 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
00483   if(theMode == 0)
00484     ChangeRepresentationToWireframe();
00485   else if (theMode == 1)
00486     ChangeRepresentationToSurface();
00487   else if (theMode == 2) {
00488     ChangeRepresentationToSurfaceWithEdges();
00489     theMode++;
00490   }
00491   myDisplayMode = theMode;
00492 }
00493 
00495 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
00496 {
00497   using namespace VTK;
00498   ActorCollectionCopy aCopy(GetRenderer()->GetActors());
00499   ChangeRepresentationToWireframe(aCopy.GetActors());
00500 }
00501 
00503 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
00504 {
00505   using namespace VTK;
00506   ActorCollectionCopy aCopy(GetRenderer()->GetActors());
00507   ChangeRepresentationToSurface(aCopy.GetActors());
00508 }
00509 
00511 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurfaceWithEdges()
00512 {
00513   using namespace VTK;
00514   ActorCollectionCopy aCopy(GetRenderer()->GetActors());
00515   ChangeRepresentationToSurfaceWithEdges(aCopy.GetActors());
00516 }
00517 
00521 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
00522 {
00523   using namespace VTK;
00524   ForEach<VTKViewer_Actor>(theCollection,
00525                         TSetFunction<VTKViewer_Actor,int>
00526                         (&VTKViewer_Actor::setDisplayMode,0));
00527   emit RenderWindowModified();
00528 }
00529 
00533 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
00534 {
00535   using namespace VTK;
00536   ForEach<VTKViewer_Actor>(theCollection,
00537                         TSetFunction<VTKViewer_Actor,int>
00538                         (&VTKViewer_Actor::setDisplayMode,1));
00539   emit RenderWindowModified();
00540 }
00541 
00545 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurfaceWithEdges(vtkActorCollection* theCollection)
00546 {
00547   using namespace VTK;
00548   ForEach<VTKViewer_Actor>(theCollection,
00549                         TSetFunction<VTKViewer_Actor,int>
00550                         (&VTKViewer_Actor::setDisplayMode,3));
00551   emit RenderWindowModified();
00552 }
00553 
00555 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
00556 {
00557   vtkRendererCollection * theRenderers =  this->RenderWindow->GetRenderers();
00558   theRenderers->InitTraversal();
00559   return theRenderers->GetNextItem();
00560 }
00561 
00563 void VTKViewer_RenderWindowInteractor::EraseAll()
00564 {
00565 }
00566 
00570 void VTKViewer_RenderWindowInteractor::DisplayAll()
00571 {
00572   using namespace VTK;
00573   ActorCollectionCopy aCopy(GetRenderer()->GetActors());
00574   ForEach<VTKViewer_Actor>(aCopy.GetActors(),TSetVisibility<VTKViewer_Actor>(true));
00575 
00576   emit RenderWindowModified() ;
00577 }
00578 
00580 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
00581 {
00582 }
00583 
00585 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
00586 {
00587   if ( SActor != 0 )
00588   {
00589     GetRenderer()->RemoveViewProp( SActor );
00590     if ( updateViewer )
00591       emit RenderWindowModified();
00592   }
00593 }
00594 
00598 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
00599 {
00600   using namespace VTK;
00601   vtkRenderer* aRenderer = GetRenderer();
00602   ActorCollectionCopy aCopy(aRenderer->GetActors());
00603   vtkActorCollection* anActors = aCopy.GetActors();
00604   if ( anActors )
00605   {
00606     anActors->InitTraversal();
00607     while ( vtkActor *anAct = anActors->GetNextActor() )
00608     {
00609       if ( anAct->IsA( "VTKViewer_Actor" ) )
00610       {
00611       }
00612     }
00613 
00614     if ( updateViewer )
00615       emit RenderWindowModified();
00616   }
00617 }
00618 
00623 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
00624 {
00625   GetRenderer()->AddActor(theActor);
00626   theActor->SetVisibility(true);
00627 
00628   if(update)
00629     emit RenderWindowModified();
00630 }
00631 
00635 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
00636 {
00638 }
00639 
00641 struct TUpdateAction{
00643   void operator()(vtkActor* theActor){
00644     theActor->ApplyProperties();
00645   }
00646 };
00647 
00649 void VTKViewer_RenderWindowInteractor::Update() {
00650   using namespace VTK;
00651   vtkRenderer* aRen = GetRenderer();
00652   ActorCollectionCopy aCopy(aRen->GetActors());
00653   ForEach<vtkActor>(aCopy.GetActors(),TUpdateAction());
00654 
00655   aRen->ResetCamera();
00656 
00657   emit RenderWindowModified();  
00658 }
00659 
00661 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
00662   myPointActor->SetVisibility(false);
00663   myEdgeActor->SetVisibility(false);
00664   myCellActor->SetVisibility(false);
00665 }
00666 
00670 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
00671   unHighlightSubSelection();
00672 
00673   emit RenderWindowModified() ;
00674   return false;
00675 }
00676 
00677 
00682 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
00683                                                  VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
00684                                                  TUpdateActor theFun, bool hilight, bool update)
00685 {
00686   if(theMapIndex.Extent() == 0) return false;
00687 
00688   if (hilight) {
00689     setActorData(theMapIndex,theMapActor,theActor,theFun);
00690     theActor->SetVisibility(true);
00691   }
00692   else {
00693     theActor->SetVisibility(false);
00694   }
00695 
00696   if(update){
00697     this->RenderWindow->Render();
00698     emit RenderWindowModified() ;
00699   }
00700 
00701   return false;
00702 }
00703 
00705 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
00706                                                     VTKViewer_Actor * theMapActor,
00707                                                     VTKViewer_Actor * theActor,
00708                                                     TUpdateActor theFun)
00709 {
00710   (*theFun)(theMapIndex,theMapActor,theActor);
00711   vtkFloatingPointType aPos[3];
00712   theMapActor->GetPosition(aPos);
00713   theActor->SetPosition(aPos);
00714 }