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();
122 Print interactor to stream
126 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
128 vtkRenderWindowInteractor::PrintSelf(os, indent) ;
130 // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
131 // QGL specific stuff goes here. One should add output
132 // lines here if any protected members are added to
138 * Initializes the event handlers without an XtAppContext. This is \n
139 * good for when you don`t have a user interface, but you still \n
140 * want to have mouse interaction.\n
141 * We never allow the VTKViewer_RenderWindowInteractor to control \n
142 * the event loop. The application always has the control.
144 void VTKViewer_RenderWindowInteractor::Initialize()
147 // We cannot do much unless there is a render window
148 // associated with this interactor.
150 if( ! RenderWindow ) {
151 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
156 // We cannot hand a render window which is not a VTKViewer_RenderWindow.
157 // One way to force this is to use dynamic_cast and hope that
158 // it works. If the dynamic_cast does not work, we flag an error
159 // and get the hell out.
161 vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
162 if( !my_render_win ) {
163 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
168 // If the render window has zero size, then set it to a default
171 int* aSize = my_render_win->GetSize();
172 this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
173 this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
175 this->SetPicker(myBasicPicker);
177 SetSelectionTolerance();
180 // Enable the interactor.
185 // Start the rendering of the window.
187 my_render_win->Start() ;
190 // The interactor has been initialized.
192 this->Initialized = 1 ;
197 /*!Sets view window and add to it selection actors.*/
198 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
199 myViewWnd = theViewWnd;
202 myViewWnd->InsertActor(myCellActor);
203 myViewWnd->InsertActor(myEdgeActor);
204 myViewWnd->InsertActor(myPointActor);
208 /*!Move selection actors to view window.*/
209 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
211 myViewWnd->MoveActor(myCellActor);
212 myViewWnd->MoveActor(myEdgeActor);
213 myViewWnd->MoveActor(myPointActor);
216 /*!Sets interactor style.*/
217 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
218 myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
219 vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
222 /*!Sets selection properties.
223 *\param theRed - red component of color
224 *\param theGreen - green component of color
225 *\param theBlue - blue component of color
226 *\param theWidth - point size and line width
228 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen,
229 const double& theBlue, const int& theWidth)
231 myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
232 myCellActor->GetProperty()->SetLineWidth(theWidth);
234 myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
235 myPointActor->GetProperty()->SetPointSize(theWidth);
238 /*!Sets selection tolerance
239 *\param theTolNodes - nodes selection tolerance
240 *\param theTolItems - selection tolerance for basic and cell pickers.
242 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
244 myTolNodes = theTolNodes;
245 myTolItems = theTolItems;
247 myBasicPicker->SetTolerance(myTolItems);
248 myCellPicker->SetTolerance(myTolItems);
249 myPointPicker->SetTolerance(myTolNodes);
254 * Enable/Disable interactions. By default interactors are enabled when \n
255 * initialized. Initialize() must be called prior to enabling/disabling \n
256 * interaction. These methods are used when a window/widget is being \n
257 * shared by multiple renderers and interactors. This allows a "modal" \n
258 * display where one interactor is active when its data is to be displayed \n
259 * and all other interactors associated with the widget are disabled \n
260 * when their data is not displayed.
262 void VTKViewer_RenderWindowInteractor::Enable()
265 // Do not need to do anything if already enabled.
267 if( this->Enabled ) {
276 void VTKViewer_RenderWindowInteractor::Disable()
278 if( ! this->Enabled ) {
287 * This will start up the X event loop and never return. If you \n
288 * call this method it will loop processing X events until the \n
289 * application is exited.
291 void VTKViewer_RenderWindowInteractor::Start()
294 // We do not allow this interactor to control the
295 // event loop. Only the QtApplication objects are
296 // allowed to do that.
298 vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
302 * Event loop notification member for Window size change
304 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
306 // if the size changed send this on to the RenderWindow
307 if ((w != this->Size[0])||(h != this->Size[1])) {
310 this->RenderWindow->SetSize(w,h);
315 * Timer methods must be overridden by platform dependent subclasses.
316 * flag is passed to indicate if this is first timer set or an update
317 * as Win32 uses repeating timers, whereas X uses One shot more timer
318 * if flag == VTKXI_TIMER_FIRST Win32 and X should createtimer
319 * otherwise Win32 should exit and X should perform AddTimeOut
322 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
325 /// Start a one-shot timer for 10ms.
327 mTimer->start(10, TRUE) ;
332 \sa CreateTimer(int )
335 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
338 // :TRICKY: Tue May 2 00:17:32 2000 Pagey
340 /*! QTimer will automatically expire after 10ms. So
341 * we do not need to do anything here. In fact, we
342 * should not even Stop() the QTimer here because doing
343 * this will skip some of the processing that the TimerFunc()
344 * does and will result in undesirable effects. For
345 * example, this will result in vtkLODActor to leave
346 * the models in low-res mode after the mouse stops
352 /*! Not all of these slots are needed in VTK_MAJOR_VERSION=3,\n
353 * but moc does not understand "#if VTK_MAJOR_VERSION". Hence, \n
354 * we have to include all of these for the time being. Once,\n
355 * this bug in MOC is fixed, we can separate these.
357 void VTKViewer_RenderWindowInteractor::TimerFunc()
359 if( ! this->Enabled ) {
363 ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
364 emit RenderWindowModified() ;
367 /*!Emit render window modified on mouse move,\n
368 *if interactor style needs redrawing and render window enabled.*/
369 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
370 if( ! this->Enabled ) {
373 myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
374 if (myInteractorStyle->needsRedrawing() )
375 emit RenderWindowModified() ;
378 /*!Reaction on left button pressed.\n
379 *Same as left button down for interactor style.\n
380 *If render window enabled.
382 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
383 if( ! this->Enabled ) {
386 myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton),
387 (event->state() & ShiftButton),
388 event->x(), event->y());
391 /*!Reaction on left button releases.\n
392 *Same as left button up for interactor style.\n
393 *If render window enabled.
395 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
396 if( ! this->Enabled ) {
399 myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton),
400 (event->state() & ShiftButton),
401 event->x(), event->y() ) ;
404 /*!Reaction on middle button pressed.\n
405 *Same as middle button down for interactor style.\n
406 *If render window enabled.
408 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
409 if( ! this->Enabled ) {
412 myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton),
413 (event->state() & ShiftButton),
414 event->x(), event->y() ) ;
417 /*!Reaction on middle button released.\n
418 *Same as middle button up for interactor style.\n
419 *If render window enabled.
421 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
422 if( ! this->Enabled ) {
425 myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton),
426 (event->state() & ShiftButton),
427 event->x(), event->y() ) ;
430 /*!Reaction on right button pressed.\n
431 *Same as right button down for interactor style.\n
432 *If render window enabled.
434 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
435 if( ! this->Enabled ) {
438 myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton),
439 (event->state() & ShiftButton),
440 event->x(), event->y() ) ;
443 /*!Reaction on right button released.\n
444 *Same as right button up for interactor style.If render window enabled.\n
445 *Emit context menu requested, if interactor style state equal VTK_INTERACTOR_STYLE_CAMERA_NONE.
447 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
448 if( ! this->Enabled ) {
451 bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
452 myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton),
453 (event->state() & ShiftButton),
454 event->x(), event->y() );
457 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
458 event->pos(), event->globalPos(),
460 emit contextMenuRequested( &aEvent );
464 /*!Reaction on button pressed.
465 *\warning Do nothing.
467 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
471 /*!Reaction on button released..
472 *\warning Do nothing.
474 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
478 /*!Gets display mode.*/
479 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
480 return myDisplayMode;
483 /*!Sets display mode.*/
484 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
486 ChangeRepresentationToWireframe();
488 ChangeRepresentationToSurface();
489 myDisplayMode = theMode;
492 /*!Change all actors to wireframe*/
493 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
495 ChangeRepresentationToWireframe(GetRenderer()->GetActors());
498 /*!Change all actors to surface*/
499 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
501 ChangeRepresentationToSurface(GetRenderer()->GetActors());
504 /*!Change all actors from \a theCollection to wireframe and
505 * emit render window modified.
507 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
510 ForEach<VTKViewer_Actor>(theCollection,
511 TSetFunction<VTKViewer_Actor,int>
512 (&VTKViewer_Actor::setDisplayMode,0));
513 emit RenderWindowModified();
516 /*!Change all actors from \a theCollection to surface and
517 * emit render window modified.
519 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
522 ForEach<VTKViewer_Actor>(theCollection,
523 TSetFunction<VTKViewer_Actor,int>
524 (&VTKViewer_Actor::setDisplayMode,1));
525 emit RenderWindowModified();
529 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
531 vtkRendererCollection * theRenderers = this->RenderWindow->GetRenderers();
532 theRenderers->InitTraversal();
533 return theRenderers->GetNextItem();
537 void VTKViewer_RenderWindowInteractor::EraseAll()
541 /*!Display all actors.
542 *Sets visible for all actors from renderer collection and emit render window modified.
544 void VTKViewer_RenderWindowInteractor::DisplayAll()
547 vtkActorCollection* aCollection = GetRenderer()->GetActors();
548 ForEach<VTKViewer_Actor>(aCollection,TSetVisibility<VTKViewer_Actor>(true));
550 emit RenderWindowModified() ;
554 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
558 /*!Remove \a SActor from renderer and emit update window, if \a updateViewer - true*/
559 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
563 GetRenderer()->RemoveProp( SActor );
565 emit RenderWindowModified();
569 /*!Remove actors from render window collection(not implemented).
570 *Emit render window modified, if \a updateViewer - true.
572 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
574 vtkRenderer* aRenderer = GetRenderer();
575 vtkActorCollection* anActors = aRenderer->GetActors();
578 anActors->InitTraversal();
579 while ( vtkActor *anAct = anActors->GetNextActor() )
581 if ( anAct->IsA( "VTKViewer_Actor" ) )
587 emit RenderWindowModified();
591 /*!\brief Display the \a theActor.*/
592 /*! Add actor to renderer and set visibility to true.
593 * Emit render window modified, if \a update - true.
595 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
597 GetRenderer()->AddActor(theActor);
598 theActor->SetVisibility(true);
601 emit RenderWindowModified();
605 default key press event (empty implementation)
607 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
612 /*!Structure with one function "operator()", which call apply properties for actor.*/
613 struct TUpdateAction{
614 /*!Apply properties for \a theActor.*/
615 void operator()(vtkActor* theActor){
616 theActor->ApplyProperties();
620 /*!Update all actors from renderer and emit render window modified.*/
621 void VTKViewer_RenderWindowInteractor::Update() {
623 vtkRenderer* aRen = GetRenderer();
624 ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
628 emit RenderWindowModified();
631 /*!Unhighlight all selection actors.*/
632 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
633 myPointActor->SetVisibility(false);
634 myEdgeActor->SetVisibility(false);
635 myCellActor->SetVisibility(false);
638 /*!@see unHighlightSubSelection()
639 * Also emit render window modified.
641 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
642 unHighlightSubSelection();
644 emit RenderWindowModified() ;
649 /*! \li Sets actors data and sets visibility to true, if flag \a hilight - true,
650 * else sets visibility to false.
651 * \li Emit render window modified, if flag \a update - true.
653 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
654 VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
655 TUpdateActor theFun, bool hilight, bool update)
657 if(theMapIndex.Extent() == 0) return false;
660 setActorData(theMapIndex,theMapActor,theActor,theFun);
661 theActor->SetVisibility(true);
664 theActor->SetVisibility(false);
668 this->RenderWindow->Render();
669 emit RenderWindowModified() ;
675 /*!Sets actors data.*/
676 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
677 VTKViewer_Actor * theMapActor,
678 VTKViewer_Actor * theActor,
681 (*theFun)(theMapIndex,theMapActor,theActor);
682 vtkFloatingPointType aPos[3];
683 theMapActor->GetPosition(aPos);
684 theActor->SetPosition(aPos);