1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 #include "VTKViewer_RenderWindowInteractor.h"
20 #include "VTKViewer_RenderWindow.h"
21 #include "VTKViewer_InteractorStyle.h"
22 #include "SUIT_ViewModel.h"
23 #include "VTKViewer_ViewWindow.h"
25 //#include "SUIT_Application.h"
26 //#include "SUIT_Desktop.h"
28 //#include "SALOME_Selection.h"
29 #include "VTKViewer_Actor.h"
30 #include "VTKViewer_Algorithm.h"
31 #include "VTKViewer_Functor.h"
39 #include <vtkAssemblyNode.h>
41 #include <vtkInteractorStyle.h>
42 #include <vtkObjectFactory.h>
43 #include <vtkPicker.h>
44 #include <vtkCellPicker.h>
45 #include <vtkPointPicker.h>
46 #include <vtkUnstructuredGrid.h>
47 #include <vtkPolyDataMapper.h>
48 #include <vtkSphereSource.h>
49 #include <vtkDataSet.h>
50 #include <vtkMaskPoints.h>
51 #include <vtkVertex.h>
52 #include <vtkRendererCollection.h>
53 #include <vtkPolyDataWriter.h>
54 #include <vtkProperty.h>
59 /*! Create new instance of VTKViewer_RenderWindowInteractor*/
60 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New()
62 vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
64 return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
66 return new VTKViewer_RenderWindowInteractor;
70 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor()
73 this->mTimer = new QTimer( this ) ;
76 myBasicPicker = vtkPicker::New();
77 myCellPicker = vtkCellPicker::New();
78 myPointPicker = vtkPointPicker::New();
80 myCellActor = VTKViewer_Actor::New();
81 myCellActor->PickableOff();
82 myCellActor->GetProperty()->SetColor(1,1,0);
83 myCellActor->GetProperty()->SetLineWidth(5);
84 myCellActor->GetProperty()->SetRepresentationToSurface();
86 myEdgeActor = VTKViewer_Actor::New();
87 myEdgeActor->PickableOff();
88 myEdgeActor->GetProperty()->SetColor(1,0,0);
89 myEdgeActor->GetProperty()->SetLineWidth(5);
90 myEdgeActor->GetProperty()->SetRepresentationToWireframe();
92 myPointActor = VTKViewer_Actor::New();
93 myPointActor->PickableOff();
94 myPointActor->GetProperty()->SetColor(1,1,0);
95 myPointActor->GetProperty()->SetPointSize(5);
96 myPointActor->GetProperty()->SetRepresentationToPoints();
98 connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
102 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor()
106 if ( GetRenderWindow() ) {
107 myViewWnd->RemoveActor(myCellActor);
108 myViewWnd->RemoveActor(myEdgeActor);
109 myViewWnd->RemoveActor(myPointActor);
112 myCellActor->Delete();
113 myEdgeActor->Delete();
114 myPointActor->Delete();
116 myBasicPicker->Delete();
117 myCellPicker->Delete();
118 myPointPicker->Delete();
121 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
123 vtkRenderWindowInteractor::PrintSelf(os, indent) ;
125 // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
126 // QGL specific stuff goes here. One should add output
127 // lines here if any protected members are added to
133 * Initializes the event handlers without an XtAppContext. This is \n
134 * good for when you don`t have a user interface, but you still \n
135 * want to have mouse interaction.\n
136 * We never allow the VTKViewer_RenderWindowInteractor to control \n
137 * the event loop. The application always has the control.
139 void VTKViewer_RenderWindowInteractor::Initialize()
142 // We cannot do much unless there is a render window
143 // associated with this interactor.
145 if( ! RenderWindow ) {
146 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
151 // We cannot hand a render window which is not a VTKViewer_RenderWindow.
152 // One way to force this is to use dynamic_cast and hope that
153 // it works. If the dynamic_cast does not work, we flag an error
154 // and get the hell out.
156 vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
157 if( !my_render_win ) {
158 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
163 // If the render window has zero size, then set it to a default
166 int* aSize = my_render_win->GetSize();
167 this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
168 this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
170 this->SetPicker(myBasicPicker);
172 SetSelectionTolerance();
175 // Enable the interactor.
180 // Start the rendering of the window.
182 my_render_win->Start() ;
185 // The interactor has been initialized.
187 this->Initialized = 1 ;
192 /*!Sets view window and add to it selection actors.*/
193 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
194 myViewWnd = theViewWnd;
197 myViewWnd->InsertActor(myCellActor);
198 myViewWnd->InsertActor(myEdgeActor);
199 myViewWnd->InsertActor(myPointActor);
203 /*!Move selection actors to view window.*/
204 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
206 myViewWnd->MoveActor(myCellActor);
207 myViewWnd->MoveActor(myEdgeActor);
208 myViewWnd->MoveActor(myPointActor);
211 /*!Sets interactor style.*/
212 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
213 myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
214 vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
219 void VTKViewer_RenderWindowInteractor::SetSelectionMode(Selection_Mode theMode)
221 myCellActor->SetVisibility(false);
222 myEdgeActor->SetVisibility(false);
223 myPointActor->SetVisibility(false);
227 this->SetPicker(myBasicPicker);
230 this->SetPicker(myPointPicker);
235 case VolumeSelection:
236 case EdgeOfCellSelection:
237 this->SetPicker(myCellPicker);
241 myInteractorStyle->OnSelectionModeChanged();
245 /*!Sets selection properties.
246 *\param theRed - red component of color
247 *\param theGreen - green component of color
248 *\param theBlue - blue component of color
249 *\param theWidth - point size and line width
251 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen,
252 const double& theBlue, const int& theWidth)
254 myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
255 myCellActor->GetProperty()->SetLineWidth(theWidth);
257 myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
258 myPointActor->GetProperty()->SetPointSize(theWidth);
261 /*!Sets selection tolerance
262 *\param theTolNodes - nodes selection tolerance
263 *\param theTolItems - selection tolerance for basic and cell pickers.
265 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
267 myTolNodes = theTolNodes;
268 myTolItems = theTolItems;
270 myBasicPicker->SetTolerance(myTolItems);
271 myCellPicker->SetTolerance(myTolItems);
272 myPointPicker->SetTolerance(myTolNodes);
277 * Enable/Disable interactions. By default interactors are enabled when \n
278 * initialized. Initialize() must be called prior to enabling/disabling \n
279 * interaction. These methods are used when a window/widget is being \n
280 * shared by multiple renderers and interactors. This allows a "modal" \n
281 * display where one interactor is active when its data is to be displayed \n
282 * and all other interactors associated with the widget are disabled \n
283 * when their data is not displayed.
285 void VTKViewer_RenderWindowInteractor::Enable()
288 // Do not need to do anything if already enabled.
290 if( this->Enabled ) {
299 void VTKViewer_RenderWindowInteractor::Disable()
301 if( ! this->Enabled ) {
310 * This will start up the X event loop and never return. If you \n
311 * call this method it will loop processing X events until the \n
312 * application is exited.
314 void VTKViewer_RenderWindowInteractor::Start()
317 // We do not allow this interactor to control the
318 // event loop. Only the QtApplication objects are
319 // allowed to do that.
321 vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
325 * Event loop notification member for Window size change
327 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
329 // if the size changed send this on to the RenderWindow
330 if ((w != this->Size[0])||(h != this->Size[1])) {
333 this->RenderWindow->SetSize(w,h);
338 * Timer methods must be overridden by platform dependent subclasses.
339 * flag is passed to indicate if this is first timer set or an update
340 * as Win32 uses repeating timers, whereas X uses One shot more timer
341 * if flag == VTKXI_TIMER_FIRST Win32 and X should createtimer
342 * otherwise Win32 should exit and X should perform AddTimeOut
345 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
348 /// Start a one-shot timer for 10ms.
350 mTimer->start(10, TRUE) ;
354 /**@see CreateTimer(int )
357 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
360 // :TRICKY: Tue May 2 00:17:32 2000 Pagey
362 /*! QTimer will automatically expire after 10ms. So
363 * we do not need to do anything here. In fact, we
364 * should not even Stop() the QTimer here because doing
365 * this will skip some of the processing that the TimerFunc()
366 * does and will result in undesirable effects. For
367 * example, this will result in vtkLODActor to leave
368 * the models in low-res mode after the mouse stops
374 /*! Not all of these slots are needed in VTK_MAJOR_VERSION=3,\n
375 * but moc does not understand "#if VTK_MAJOR_VERSION". Hence, \n
376 * we have to include all of these for the time being. Once,\n
377 * this bug in MOC is fixed, we can separate these.
379 void VTKViewer_RenderWindowInteractor::TimerFunc()
381 if( ! this->Enabled ) {
385 ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
386 emit RenderWindowModified() ;
389 /*!Emit render window modified on mouse move,\n
390 *if interactor style needs redrawing and render window enabled.*/
391 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
392 if( ! this->Enabled ) {
395 myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
396 if (myInteractorStyle->needsRedrawing() )
397 emit RenderWindowModified() ;
400 /*!Reaction on left button pressed.\n
401 *Same as left button down for interactor style.\n
402 *If render window enabled.
404 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
405 if( ! this->Enabled ) {
408 myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton),
409 (event->state() & ShiftButton),
410 event->x(), event->y());
413 /*!Reaction on left button releases.\n
414 *Same as left button up for interactor style.\n
415 *If render window enabled.
417 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
418 if( ! this->Enabled ) {
421 myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton),
422 (event->state() & ShiftButton),
423 event->x(), event->y() ) ;
426 /*!Reaction on middle button pressed.\n
427 *Same as middle button down for interactor style.\n
428 *If render window enabled.
430 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
431 if( ! this->Enabled ) {
434 myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton),
435 (event->state() & ShiftButton),
436 event->x(), event->y() ) ;
439 /*!Reaction on middle button released.\n
440 *Same as middle button up for interactor style.\n
441 *If render window enabled.
443 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
444 if( ! this->Enabled ) {
447 myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton),
448 (event->state() & ShiftButton),
449 event->x(), event->y() ) ;
452 /*!Reaction on right button pressed.\n
453 *Same as right button down for interactor style.\n
454 *If render window enabled.
456 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
457 if( ! this->Enabled ) {
460 myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton),
461 (event->state() & ShiftButton),
462 event->x(), event->y() ) ;
465 /*!Reaction on right button released.\n
466 *Same as right button up for interactor style.If render window enabled.\n
467 *Emit context menu requested, if interactor style state equal VTK_INTERACTOR_STYLE_CAMERA_NONE.
469 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
470 if( ! this->Enabled ) {
473 bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
474 myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton),
475 (event->state() & ShiftButton),
476 event->x(), event->y() );
479 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
480 event->pos(), event->globalPos(),
482 emit contextMenuRequested( &aEvent );
486 /*!Reaction on button pressed.
487 *\warning Do nothing.
489 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
493 /*!Reaction on button released..
494 *\warning Do nothing.
496 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
500 /*!Gets display mode.*/
501 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
502 return myDisplayMode;
505 /*!Sets display mode.*/
506 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
508 ChangeRepresentationToWireframe();
510 ChangeRepresentationToSurface();
511 myDisplayMode = theMode;
514 /*!Change all actors to wireframe*/
515 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
517 ChangeRepresentationToWireframe(GetRenderer()->GetActors());
520 /*!Change all actors to surface*/
521 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
523 ChangeRepresentationToSurface(GetRenderer()->GetActors());
526 /*!Change all actors from \a theCollection to wireframe and
527 * emit render window modified.
529 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
532 ForEach<VTKViewer_Actor>(theCollection,
533 TSetFunction<VTKViewer_Actor,int>
534 (&VTKViewer_Actor::setDisplayMode,0));
535 emit RenderWindowModified();
538 /*!Change all actors from \a theCollection to surface and
539 * emit render window modified.
541 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
544 ForEach<VTKViewer_Actor>(theCollection,
545 TSetFunction<VTKViewer_Actor,int>
546 (&VTKViewer_Actor::setDisplayMode,1));
547 emit RenderWindowModified();
551 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
553 vtkRendererCollection * theRenderers = this->RenderWindow->GetRenderers();
554 theRenderers->InitTraversal();
555 return theRenderers->GetNextItem();
559 void VTKViewer_RenderWindowInteractor::EraseAll()
563 /*!Display all actors.
564 *Sets visible for all actors from renderer collection and emit render window modified.
566 void VTKViewer_RenderWindowInteractor::DisplayAll()
569 vtkActorCollection* aCollection = GetRenderer()->GetActors();
570 ForEach<VTKViewer_Actor>(aCollection,TSetVisibility<VTKViewer_Actor>(true));
572 emit RenderWindowModified() ;
576 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
580 /*!Remove \a SActor from renderer and emit update window, if \a updateViewer - true*/
581 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
585 GetRenderer()->RemoveProp( SActor );
587 emit RenderWindowModified();
591 /*!Remove actors from render window collection(not implemented).
592 *Emit render window modified, if \a updateViewer - true.
594 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
596 vtkRenderer* aRenderer = GetRenderer();
597 vtkActorCollection* anActors = aRenderer->GetActors();
600 anActors->InitTraversal();
601 while ( vtkActor *anAct = anActors->GetNextActor() )
603 if ( anAct->IsA( "VTKViewer_Actor" ) )
609 emit RenderWindowModified();
613 /*!\brief Display the \a theActor.*/
614 /*! Add actor to renderer and set visibility to true.
615 * Emit render window modified, if \a update - true.
617 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
619 GetRenderer()->AddActor(theActor);
620 theActor->SetVisibility(true);
623 emit RenderWindowModified();
626 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
631 /*!Structure with one function "operator()", which call apply properties for actor.*/
632 struct TUpdateAction{
633 /*!Apply properties for \a theActor.*/
634 void operator()(vtkActor* theActor){
635 theActor->ApplyProperties();
639 /*!Update all actors from renderer and emit render window modified.*/
640 void VTKViewer_RenderWindowInteractor::Update() {
642 vtkRenderer* aRen = GetRenderer();
643 ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
647 emit RenderWindowModified();
650 /*!Unhighlight all selection actors.*/
651 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
652 myPointActor->SetVisibility(false);
653 myEdgeActor->SetVisibility(false);
654 myCellActor->SetVisibility(false);
657 /*!@see unHighlightSubSelection()
658 * Also emit render window modified.
660 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
661 unHighlightSubSelection();
663 emit RenderWindowModified() ;
668 /*! \li Sets actors data and sets visibility to true, if flag \a hilight - true,
669 * else sets visibility to false.
670 * \li Emit render window modified, if flag \a update - true.
672 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
673 VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
674 TUpdateActor theFun, bool hilight, bool update)
676 if(theMapIndex.Extent() == 0) return false;
679 setActorData(theMapIndex,theMapActor,theActor,theFun);
680 theActor->SetVisibility(true);
683 theActor->SetVisibility(false);
687 this->RenderWindow->Render();
688 emit RenderWindowModified() ;
694 /*!Sets actors data.*/
695 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
696 VTKViewer_Actor * theMapActor,
697 VTKViewer_Actor * theActor,
700 (*theFun)(theMapIndex,theMapActor,theActor);
702 theMapActor->GetPosition(aPos);
703 theActor->SetPosition(aPos);