1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "VTKViewer_RenderWindowInteractor.h"
24 #include "VTKViewer_RenderWindow.h"
25 #include "VTKViewer_InteractorStyle.h"
26 #include "SUIT_ViewModel.h"
27 #include "VTKViewer_ViewWindow.h"
29 #include "VTKViewer_Actor.h"
30 #include "VTKViewer_Algorithm.h"
31 #include "VTKViewer_Functor.h"
34 #include <vtkAssemblyNode.h>
36 #include <vtkInteractorStyle.h>
37 #include <vtkObjectFactory.h>
38 #include <vtkPicker.h>
39 #include <vtkCellPicker.h>
40 #include <vtkPointPicker.h>
41 #include <vtkUnstructuredGrid.h>
42 #include <vtkPolyDataMapper.h>
43 #include <vtkSphereSource.h>
44 #include <vtkDataSet.h>
45 #include <vtkMaskPoints.h>
46 #include <vtkVertex.h>
47 #include <vtkRendererCollection.h>
48 #include <vtkPolyDataWriter.h>
49 #include <vtkProperty.h>
53 #include <QMouseEvent>
55 #include <QContextMenuEvent>
57 /*! Create new instance of VTKViewer_RenderWindowInteractor*/
58 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New()
60 vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
62 return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
64 return new VTKViewer_RenderWindowInteractor;
68 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor()
71 this->mTimer = new QTimer( this ) ;
74 myBasicPicker = vtkPicker::New();
75 myCellPicker = vtkCellPicker::New();
76 myPointPicker = vtkPointPicker::New();
78 myCellActor = VTKViewer_Actor::New();
79 myCellActor->PickableOff();
80 myCellActor->GetProperty()->SetColor(1,1,0);
81 myCellActor->GetProperty()->SetLineWidth(5);
82 myCellActor->GetProperty()->SetRepresentationToSurface();
84 myEdgeActor = VTKViewer_Actor::New();
85 myEdgeActor->PickableOff();
86 myEdgeActor->GetProperty()->SetColor(1,0,0);
87 myEdgeActor->GetProperty()->SetLineWidth(5);
88 myEdgeActor->GetProperty()->SetRepresentationToWireframe();
90 myPointActor = VTKViewer_Actor::New();
91 myPointActor->PickableOff();
92 myPointActor->GetProperty()->SetColor(1,1,0);
93 myPointActor->GetProperty()->SetPointSize(5);
94 myPointActor->GetProperty()->SetRepresentationToPoints();
96 connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
100 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor()
104 if ( GetRenderWindow() ) {
105 myViewWnd->RemoveActor(myCellActor);
106 myViewWnd->RemoveActor(myEdgeActor);
107 myViewWnd->RemoveActor(myPointActor);
110 myCellActor->Delete();
111 myEdgeActor->Delete();
112 myPointActor->Delete();
114 myBasicPicker->Delete();
115 myCellPicker->Delete();
116 myPointPicker->Delete();
120 Print interactor to stream
124 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
126 vtkRenderWindowInteractor::PrintSelf(os, indent) ;
128 // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
129 // QGL specific stuff goes here. One should add output
130 // lines here if any protected members are added to
136 * Initializes the event handlers without an XtAppContext. This is \n
137 * good for when you don`t have a user interface, but you still \n
138 * want to have mouse interaction.\n
139 * We never allow the VTKViewer_RenderWindowInteractor to control \n
140 * the event loop. The application always has the control.
142 void VTKViewer_RenderWindowInteractor::Initialize()
145 // We cannot do much unless there is a render window
146 // associated with this interactor.
148 if( ! RenderWindow ) {
149 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
154 // We cannot hand a render window which is not a VTKViewer_RenderWindow.
155 // One way to force this is to use dynamic_cast and hope that
156 // it works. If the dynamic_cast does not work, we flag an error
157 // and get the hell out.
159 vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
160 if( !my_render_win ) {
161 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
166 // If the render window has zero size, then set it to a default
169 int* aSize = my_render_win->GetSize();
170 this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
171 this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
173 this->SetPicker(myBasicPicker);
175 SetSelectionTolerance();
178 // Enable the interactor.
183 // Start the rendering of the window.
185 my_render_win->Start() ;
188 // The interactor has been initialized.
190 this->Initialized = 1 ;
195 /*!Sets view window and add to it selection actors.*/
196 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
197 myViewWnd = theViewWnd;
200 myViewWnd->InsertActor(myCellActor);
201 myViewWnd->InsertActor(myEdgeActor);
202 myViewWnd->InsertActor(myPointActor);
206 /*!Move selection actors to view window.*/
207 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
209 myViewWnd->MoveActor(myCellActor);
210 myViewWnd->MoveActor(myEdgeActor);
211 myViewWnd->MoveActor(myPointActor);
214 /*!Sets interactor style.*/
215 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
216 myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
217 vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
220 /*!Sets selection properties.
221 *\param theRed - red component of color
222 *\param theGreen - green component of color
223 *\param theBlue - blue component of color
224 *\param theWidth - point size and line width
226 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen,
227 const double& theBlue, const int& theWidth)
229 myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
230 myCellActor->GetProperty()->SetLineWidth(theWidth);
232 myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
233 myPointActor->GetProperty()->SetPointSize(theWidth);
236 /*!Sets selection tolerance
237 *\param theTolNodes - nodes selection tolerance
238 *\param theTolItems - selection tolerance for basic and cell pickers.
240 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
242 myTolNodes = theTolNodes;
243 myTolItems = theTolItems;
245 myBasicPicker->SetTolerance(myTolItems);
246 myCellPicker->SetTolerance(myTolItems);
247 myPointPicker->SetTolerance(myTolNodes);
252 * Enable/Disable interactions. By default interactors are enabled when \n
253 * initialized. Initialize() must be called prior to enabling/disabling \n
254 * interaction. These methods are used when a window/widget is being \n
255 * shared by multiple renderers and interactors. This allows a "modal" \n
256 * display where one interactor is active when its data is to be displayed \n
257 * and all other interactors associated with the widget are disabled \n
258 * when their data is not displayed.
260 void VTKViewer_RenderWindowInteractor::Enable()
263 // Do not need to do anything if already enabled.
265 if( this->Enabled ) {
274 void VTKViewer_RenderWindowInteractor::Disable()
276 if( ! this->Enabled ) {
285 * This will start up the X event loop and never return. If you \n
286 * call this method it will loop processing X events until the \n
287 * application is exited.
289 void VTKViewer_RenderWindowInteractor::Start()
292 // We do not allow this interactor to control the
293 // event loop. Only the QtApplication objects are
294 // allowed to do that.
296 vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
300 * Event loop notification member for Window size change
302 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
304 // if the size changed send this on to the RenderWindow
305 if ((w != this->Size[0])||(h != this->Size[1])) {
308 this->RenderWindow->SetSize(w,h);
313 * Timer methods must be overridden by platform dependent subclasses.
314 * flag is passed to indicate if this is first timer set or an update
315 * as Win32 uses repeating timers, whereas X uses One shot more timer
316 * if flag == VTKXI_TIMER_FIRST Win32 and X should createtimer
317 * otherwise Win32 should exit and X should perform AddTimeOut
320 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
323 /// Start a one-shot timer for 10ms.
325 mTimer->setSingleShot(TRUE) ;
331 \sa CreateTimer(int )
334 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
337 // :TRICKY: Tue May 2 00:17:32 2000 Pagey
339 /*! QTimer will automatically expire after 10ms. So
340 * we do not need to do anything here. In fact, we
341 * should not even Stop() the QTimer here because doing
342 * this will skip some of the processing that the TimerFunc()
343 * does and will result in undesirable effects. For
344 * example, this will result in vtkLODActor to leave
345 * the models in low-res mode after the mouse stops
351 /*! Not all of these slots are needed in VTK_MAJOR_VERSION=3,\n
352 * but moc does not understand "#if VTK_MAJOR_VERSION". Hence, \n
353 * we have to include all of these for the time being. Once,\n
354 * this bug in MOC is fixed, we can separate these.
356 void VTKViewer_RenderWindowInteractor::TimerFunc()
358 if( ! this->Enabled ) {
362 ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
363 emit RenderWindowModified() ;
366 /*!Emit render window modified on mouse move,\n
367 *if interactor style needs redrawing and render window enabled.*/
368 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
369 if( ! this->Enabled ) {
372 myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
373 if (myInteractorStyle->needsRedrawing() )
374 emit RenderWindowModified() ;
377 /*!Reaction on left button pressed.\n
378 *Same as left button down for interactor style.\n
379 *If render window enabled.
381 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
382 if( ! this->Enabled ) {
385 myInteractorStyle->OnLeftButtonDown((event->modifiers() & Qt::ControlModifier),
386 (event->modifiers() & Qt::ShiftModifier),
387 event->x(), event->y());
390 /*!Reaction on left button releases.\n
391 *Same as left button up for interactor style.\n
392 *If render window enabled.
394 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
395 if( ! this->Enabled ) {
398 myInteractorStyle->OnLeftButtonUp( (event->modifiers() & Qt::ControlModifier),
399 (event->modifiers() & Qt::ShiftModifier),
400 event->x(), event->y() ) ;
403 /*!Reaction on middle button pressed.\n
404 *Same as middle button down for interactor style.\n
405 *If render window enabled.
407 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
408 if( ! this->Enabled ) {
411 myInteractorStyle->OnMiddleButtonDown((event->modifiers() & Qt::ControlModifier),
412 (event->modifiers() & Qt::ShiftModifier),
413 event->x(), event->y() ) ;
416 /*!Reaction on middle button released.\n
417 *Same as middle button up for interactor style.\n
418 *If render window enabled.
420 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
421 if( ! this->Enabled ) {
424 myInteractorStyle->OnMiddleButtonUp( (event->modifiers() & Qt::ControlModifier),
425 (event->modifiers() & Qt::ShiftModifier),
426 event->x(), event->y() ) ;
429 /*!Reaction on right button pressed.\n
430 *Same as right button down for interactor style.\n
431 *If render window enabled.
433 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
434 if( ! this->Enabled ) {
437 myInteractorStyle->OnRightButtonDown( (event->modifiers() & Qt::ControlModifier),
438 (event->modifiers() & Qt::ShiftModifier),
439 event->x(), event->y() ) ;
442 /*!Reaction on right button released.\n
443 *Same as right button up for interactor style.If render window enabled.\n
444 *Emit context menu requested, if interactor style state equal VTK_INTERACTOR_STYLE_CAMERA_NONE.
446 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
447 if( ! this->Enabled ) {
450 bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
451 myInteractorStyle->OnRightButtonUp( (event->modifiers() & Qt::ControlModifier),
452 (event->modifiers() & Qt::ShiftModifier),
453 event->x(), event->y() );
456 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
457 event->pos(), event->globalPos() );
458 emit contextMenuRequested( &aEvent );
462 /*!Reaction on button pressed.
463 *\warning Do nothing.
465 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
469 /*!Reaction on button released..
470 *\warning Do nothing.
472 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
476 /*!Gets display mode.*/
477 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
478 return myDisplayMode;
481 /*!Sets display mode.*/
482 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
484 ChangeRepresentationToWireframe();
485 else if (theMode == 1)
486 ChangeRepresentationToSurface();
487 else if (theMode == 2) {
488 ChangeRepresentationToSurfaceWithEdges();
491 myDisplayMode = theMode;
494 /*!Change all actors to wireframe*/
495 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
498 ActorCollectionCopy aCopy(GetRenderer()->GetActors());
499 ChangeRepresentationToWireframe(aCopy.GetActors());
502 /*!Change all actors to surface*/
503 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
506 ActorCollectionCopy aCopy(GetRenderer()->GetActors());
507 ChangeRepresentationToSurface(aCopy.GetActors());
510 /*!Change all actors to surface with edges*/
511 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurfaceWithEdges()
514 ActorCollectionCopy aCopy(GetRenderer()->GetActors());
515 ChangeRepresentationToSurfaceWithEdges(aCopy.GetActors());
518 /*!Change all actors from \a theCollection to wireframe and
519 * emit render window modified.
521 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
524 ForEach<VTKViewer_Actor>(theCollection,
525 TSetFunction<VTKViewer_Actor,int>
526 (&VTKViewer_Actor::setDisplayMode,0));
527 emit RenderWindowModified();
530 /*!Change all actors from \a theCollection to surface and
531 * emit render window modified.
533 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
536 ForEach<VTKViewer_Actor>(theCollection,
537 TSetFunction<VTKViewer_Actor,int>
538 (&VTKViewer_Actor::setDisplayMode,1));
539 emit RenderWindowModified();
542 /*!Change all actors from \a theCollection to surface with edges and
543 * emit render window modified.
545 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurfaceWithEdges(vtkActorCollection* theCollection)
548 ForEach<VTKViewer_Actor>(theCollection,
549 TSetFunction<VTKViewer_Actor,int>
550 (&VTKViewer_Actor::setDisplayMode,3));
551 emit RenderWindowModified();
555 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
557 vtkRendererCollection * theRenderers = this->RenderWindow->GetRenderers();
558 theRenderers->InitTraversal();
559 return theRenderers->GetNextItem();
563 void VTKViewer_RenderWindowInteractor::EraseAll()
567 /*!Display all actors.
568 *Sets visible for all actors from renderer collection and emit render window modified.
570 void VTKViewer_RenderWindowInteractor::DisplayAll()
573 ActorCollectionCopy aCopy(GetRenderer()->GetActors());
574 ForEach<VTKViewer_Actor>(aCopy.GetActors(),TSetVisibility<VTKViewer_Actor>(true));
576 emit RenderWindowModified() ;
580 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
584 /*!Remove \a SActor from renderer and emit update window, if \a updateViewer - true*/
585 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
589 GetRenderer()->RemoveViewProp( SActor );
591 emit RenderWindowModified();
595 /*!Remove actors from render window collection(not implemented).
596 *Emit render window modified, if \a updateViewer - true.
598 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
601 vtkRenderer* aRenderer = GetRenderer();
602 ActorCollectionCopy aCopy(aRenderer->GetActors());
603 vtkActorCollection* anActors = aCopy.GetActors();
606 anActors->InitTraversal();
607 while ( vtkActor *anAct = anActors->GetNextActor() )
609 if ( anAct->IsA( "VTKViewer_Actor" ) )
615 emit RenderWindowModified();
619 /*!\brief Display the \a theActor.*/
620 /*! Add actor to renderer and set visibility to true.
621 * Emit render window modified, if \a update - true.
623 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
625 GetRenderer()->AddActor(theActor);
626 theActor->SetVisibility(true);
629 emit RenderWindowModified();
633 default key press event (empty implementation)
635 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
640 /*!Structure with one function "operator()", which call apply properties for actor.*/
641 struct TUpdateAction{
642 /*!Apply properties for \a theActor.*/
643 void operator()(vtkActor* theActor){
644 theActor->ApplyProperties();
648 /*!Update all actors from renderer and emit render window modified.*/
649 void VTKViewer_RenderWindowInteractor::Update() {
651 vtkRenderer* aRen = GetRenderer();
652 ActorCollectionCopy aCopy(aRen->GetActors());
653 ForEach<vtkActor>(aCopy.GetActors(),TUpdateAction());
657 emit RenderWindowModified();
660 /*!Unhighlight all selection actors.*/
661 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
662 myPointActor->SetVisibility(false);
663 myEdgeActor->SetVisibility(false);
664 myCellActor->SetVisibility(false);
667 /*!@see unHighlightSubSelection()
668 * Also emit render window modified.
670 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
671 unHighlightSubSelection();
673 emit RenderWindowModified() ;
678 /*! \li Sets actors data and sets visibility to true, if flag \a hilight - true,
679 * else sets visibility to false.
680 * \li Emit render window modified, if flag \a update - true.
682 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
683 VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
684 TUpdateActor theFun, bool hilight, bool update)
686 if(theMapIndex.Extent() == 0) return false;
689 setActorData(theMapIndex,theMapActor,theActor,theFun);
690 theActor->SetVisibility(true);
693 theActor->SetVisibility(false);
697 this->RenderWindow->Render();
698 emit RenderWindowModified() ;
704 /*!Sets actors data.*/
705 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
706 VTKViewer_Actor * theMapActor,
707 VTKViewer_Actor * theActor,
710 (*theFun)(theMapIndex,theMapActor,theActor);
712 theMapActor->GetPosition(aPos);
713 theActor->SetPosition(aPos);