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>
58 /*! Create new instance of VTKViewer_RenderWindowInteractor*/
59 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New()
61 vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
63 return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
65 return new VTKViewer_RenderWindowInteractor;
69 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor()
72 this->mTimer = new QTimer( this ) ;
75 myBasicPicker = vtkPicker::New();
76 myCellPicker = vtkCellPicker::New();
77 myPointPicker = vtkPointPicker::New();
79 myCellActor = VTKViewer_Actor::New();
80 myCellActor->PickableOff();
81 myCellActor->GetProperty()->SetColor(1,1,0);
82 myCellActor->GetProperty()->SetLineWidth(5);
83 myCellActor->GetProperty()->SetRepresentationToSurface();
85 myEdgeActor = VTKViewer_Actor::New();
86 myEdgeActor->PickableOff();
87 myEdgeActor->GetProperty()->SetColor(1,0,0);
88 myEdgeActor->GetProperty()->SetLineWidth(5);
89 myEdgeActor->GetProperty()->SetRepresentationToWireframe();
91 myPointActor = VTKViewer_Actor::New();
92 myPointActor->PickableOff();
93 myPointActor->GetProperty()->SetColor(1,1,0);
94 myPointActor->GetProperty()->SetPointSize(5);
95 myPointActor->GetProperty()->SetRepresentationToPoints();
97 connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
101 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor()
105 if ( GetRenderWindow() ) {
106 myViewWnd->RemoveActor(myCellActor);
107 myViewWnd->RemoveActor(myEdgeActor);
108 myViewWnd->RemoveActor(myPointActor);
111 myCellActor->Delete();
112 myEdgeActor->Delete();
113 myPointActor->Delete();
115 myBasicPicker->Delete();
116 myCellPicker->Delete();
117 myPointPicker->Delete();
120 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
122 vtkRenderWindowInteractor::PrintSelf(os, indent) ;
124 // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
125 // QGL specific stuff goes here. One should add output
126 // lines here if any protected members are added to
132 * Initializes the event handlers without an XtAppContext. This is \n
133 * good for when you don`t have a user interface, but you still \n
134 * want to have mouse interaction.\n
135 * We never allow the VTKViewer_RenderWindowInteractor to control \n
136 * the event loop. The application always has the control.
138 void VTKViewer_RenderWindowInteractor::Initialize()
141 // We cannot do much unless there is a render window
142 // associated with this interactor.
144 if( ! RenderWindow ) {
145 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
150 // We cannot hand a render window which is not a VTKViewer_RenderWindow.
151 // One way to force this is to use dynamic_cast and hope that
152 // it works. If the dynamic_cast does not work, we flag an error
153 // and get the hell out.
155 vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
156 if( !my_render_win ) {
157 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
162 // If the render window has zero size, then set it to a default
165 int* aSize = my_render_win->GetSize();
166 this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
167 this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
169 this->SetPicker(myBasicPicker);
171 SetSelectionTolerance();
174 // Enable the interactor.
179 // Start the rendering of the window.
181 my_render_win->Start() ;
184 // The interactor has been initialized.
186 this->Initialized = 1 ;
191 /*!Sets view window and add to it selection actors.*/
192 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
193 myViewWnd = theViewWnd;
196 myViewWnd->InsertActor(myCellActor);
197 myViewWnd->InsertActor(myEdgeActor);
198 myViewWnd->InsertActor(myPointActor);
202 /*!Move selection actors to view window.*/
203 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
205 myViewWnd->MoveActor(myCellActor);
206 myViewWnd->MoveActor(myEdgeActor);
207 myViewWnd->MoveActor(myPointActor);
210 /*!Sets interactor style.*/
211 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
212 myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
213 vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
218 void VTKViewer_RenderWindowInteractor::SetSelectionMode(Selection_Mode theMode)
220 myCellActor->SetVisibility(false);
221 myEdgeActor->SetVisibility(false);
222 myPointActor->SetVisibility(false);
226 this->SetPicker(myBasicPicker);
229 this->SetPicker(myPointPicker);
234 case VolumeSelection:
235 case EdgeOfCellSelection:
236 this->SetPicker(myCellPicker);
240 myInteractorStyle->OnSelectionModeChanged();
244 /*!Sets selection properties.
245 *\param theRed - red component of color
246 *\param theGreen - green component of color
247 *\param theBlue - blue component of color
248 *\param theWidth - point size and line width
250 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen,
251 const double& theBlue, const int& theWidth)
253 myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
254 myCellActor->GetProperty()->SetLineWidth(theWidth);
256 myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
257 myPointActor->GetProperty()->SetPointSize(theWidth);
260 /*!Sets selection tolerance
261 *\param theTolNodes - nodes selection tolerance
262 *\param theTolItems - selection tolerance for basic and cell pickers.
264 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
266 myTolNodes = theTolNodes;
267 myTolItems = theTolItems;
269 myBasicPicker->SetTolerance(myTolItems);
270 myCellPicker->SetTolerance(myTolItems);
271 myPointPicker->SetTolerance(myTolNodes);
276 * Enable/Disable interactions. By default interactors are enabled when \n
277 * initialized. Initialize() must be called prior to enabling/disabling \n
278 * interaction. These methods are used when a window/widget is being \n
279 * shared by multiple renderers and interactors. This allows a "modal" \n
280 * display where one interactor is active when its data is to be displayed \n
281 * and all other interactors associated with the widget are disabled \n
282 * when their data is not displayed.
284 void VTKViewer_RenderWindowInteractor::Enable()
287 // Do not need to do anything if already enabled.
289 if( this->Enabled ) {
298 void VTKViewer_RenderWindowInteractor::Disable()
300 if( ! this->Enabled ) {
309 * This will start up the X event loop and never return. If you \n
310 * call this method it will loop processing X events until the \n
311 * application is exited.
313 void VTKViewer_RenderWindowInteractor::Start()
316 // We do not allow this interactor to control the
317 // event loop. Only the QtApplication objects are
318 // allowed to do that.
320 vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
324 * Event loop notification member for Window size change
326 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
328 // if the size changed send this on to the RenderWindow
329 if ((w != this->Size[0])||(h != this->Size[1])) {
332 this->RenderWindow->SetSize(w,h);
337 * Timer methods must be overridden by platform dependent subclasses.
338 * flag is passed to indicate if this is first timer set or an update
339 * as Win32 uses repeating timers, whereas X uses One shot more timer
340 * if flag == VTKXI_TIMER_FIRST Win32 and X should createtimer
341 * otherwise Win32 should exit and X should perform AddTimeOut
344 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
347 /// Start a one-shot timer for 10ms.
349 mTimer->start(10, TRUE) ;
353 /**@see CreateTimer(int )
356 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
359 // :TRICKY: Tue May 2 00:17:32 2000 Pagey
361 /*! QTimer will automatically expire after 10ms. So
362 * we do not need to do anything here. In fact, we
363 * should not even Stop() the QTimer here because doing
364 * this will skip some of the processing that the TimerFunc()
365 * does and will result in undesirable effects. For
366 * example, this will result in vtkLODActor to leave
367 * the models in low-res mode after the mouse stops
373 /*! Not all of these slots are needed in VTK_MAJOR_VERSION=3,\n
374 * but moc does not understand "#if VTK_MAJOR_VERSION". Hence, \n
375 * we have to include all of these for the time being. Once,\n
376 * this bug in MOC is fixed, we can separate these.
378 void VTKViewer_RenderWindowInteractor::TimerFunc()
380 if( ! this->Enabled ) {
384 ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
385 emit RenderWindowModified() ;
388 /*!Emit render window modified on mouse move,\n
389 *if interactor style needs redrawing and render window enabled.*/
390 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
391 if( ! this->Enabled ) {
394 myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
395 if (myInteractorStyle->needsRedrawing() )
396 emit RenderWindowModified() ;
399 /*!Reaction on left button pressed.\n
400 *Same as left button down for interactor style.\n
401 *If render window enabled.
403 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
404 if( ! this->Enabled ) {
407 myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton),
408 (event->state() & ShiftButton),
409 event->x(), event->y());
412 /*!Reaction on left button releases.\n
413 *Same as left button up for interactor style.\n
414 *If render window enabled.
416 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
417 if( ! this->Enabled ) {
420 myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton),
421 (event->state() & ShiftButton),
422 event->x(), event->y() ) ;
425 /*!Reaction on middle button pressed.\n
426 *Same as middle button down for interactor style.\n
427 *If render window enabled.
429 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
430 if( ! this->Enabled ) {
433 myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton),
434 (event->state() & ShiftButton),
435 event->x(), event->y() ) ;
438 /*!Reaction on middle button released.\n
439 *Same as middle button up for interactor style.\n
440 *If render window enabled.
442 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
443 if( ! this->Enabled ) {
446 myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton),
447 (event->state() & ShiftButton),
448 event->x(), event->y() ) ;
451 /*!Reaction on right button pressed.\n
452 *Same as right button down for interactor style.\n
453 *If render window enabled.
455 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
456 if( ! this->Enabled ) {
459 myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton),
460 (event->state() & ShiftButton),
461 event->x(), event->y() ) ;
464 /*!Reaction on right button released.\n
465 *Same as right button up for interactor style.If render window enabled.\n
466 *Emit context menu requested, if interactor style state equal VTK_INTERACTOR_STYLE_CAMERA_NONE.
468 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
469 if( ! this->Enabled ) {
472 bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
473 myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton),
474 (event->state() & ShiftButton),
475 event->x(), event->y() );
478 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
479 event->pos(), event->globalPos(),
481 emit contextMenuRequested( &aEvent );
485 /*!Reaction on button pressed.
486 *\warning Do nothing.
488 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
492 /*!Reaction on button released..
493 *\warning Do nothing.
495 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
499 /*!Gets display mode.*/
500 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
501 return myDisplayMode;
504 /*!Sets display mode.*/
505 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
507 ChangeRepresentationToWireframe();
509 ChangeRepresentationToSurface();
510 myDisplayMode = theMode;
513 /*!Change all actors to wireframe*/
514 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
516 ChangeRepresentationToWireframe(GetRenderer()->GetActors());
519 /*!Change all actors to surface*/
520 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
522 ChangeRepresentationToSurface(GetRenderer()->GetActors());
525 /*!Change all actors from \a theCollection to wireframe and
526 * emit render window modified.
528 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
531 ForEach<VTKViewer_Actor>(theCollection,
532 TSetFunction<VTKViewer_Actor,int>
533 (&VTKViewer_Actor::setDisplayMode,0));
534 emit RenderWindowModified();
537 /*!Change all actors from \a theCollection to surface and
538 * emit render window modified.
540 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
543 ForEach<VTKViewer_Actor>(theCollection,
544 TSetFunction<VTKViewer_Actor,int>
545 (&VTKViewer_Actor::setDisplayMode,1));
546 emit RenderWindowModified();
550 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
552 vtkRendererCollection * theRenderers = this->RenderWindow->GetRenderers();
553 theRenderers->InitTraversal();
554 return theRenderers->GetNextItem();
558 void VTKViewer_RenderWindowInteractor::EraseAll()
562 /*!Display all actors.
563 *Sets visible for all actors from renderer collection and emit render window modified.
565 void VTKViewer_RenderWindowInteractor::DisplayAll()
568 vtkActorCollection* aCollection = GetRenderer()->GetActors();
569 ForEach<VTKViewer_Actor>(aCollection,TSetVisibility<VTKViewer_Actor>(true));
571 emit RenderWindowModified() ;
575 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
579 /*!Remove \a SActor from renderer and emit update window, if \a updateViewer - true*/
580 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
584 GetRenderer()->RemoveProp( SActor );
586 emit RenderWindowModified();
590 /*!Remove actors from render window collection(not implemented).
591 *Emit render window modified, if \a updateViewer - true.
593 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
595 vtkRenderer* aRenderer = GetRenderer();
596 vtkActorCollection* anActors = aRenderer->GetActors();
599 anActors->InitTraversal();
600 while ( vtkActor *anAct = anActors->GetNextActor() )
602 if ( anAct->IsA( "VTKViewer_Actor" ) )
608 emit RenderWindowModified();
612 /*!\brief Display the \a theActor.*/
613 /*! Add actor to renderer and set visibility to true.
614 * Emit render window modified, if \a update - true.
616 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
618 GetRenderer()->AddActor(theActor);
619 theActor->SetVisibility(true);
622 emit RenderWindowModified();
625 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
630 /*!Structure with one function "operator()", which call apply properties for actor.*/
631 struct TUpdateAction{
632 /*!Apply properties for \a theActor.*/
633 void operator()(vtkActor* theActor){
634 theActor->ApplyProperties();
638 /*!Update all actors from renderer and emit render window modified.*/
639 void VTKViewer_RenderWindowInteractor::Update() {
641 vtkRenderer* aRen = GetRenderer();
642 ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
646 emit RenderWindowModified();
649 /*!Unhighlight all selection actors.*/
650 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
651 myPointActor->SetVisibility(false);
652 myEdgeActor->SetVisibility(false);
653 myCellActor->SetVisibility(false);
656 /*!@see unHighlightSubSelection()
657 * Also emit render window modified.
659 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
660 unHighlightSubSelection();
662 emit RenderWindowModified() ;
667 /*! \li Sets actors data and sets visibility to true, if flag \a hilight - true,
668 * else sets visibility to false.
669 * \li Emit render window modified, if flag \a update - true.
671 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
672 VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
673 TUpdateActor theFun, bool hilight, bool update)
675 if(theMapIndex.Extent() == 0) return false;
678 setActorData(theMapIndex,theMapActor,theActor,theFun);
679 theActor->SetVisibility(true);
682 theActor->SetVisibility(false);
686 this->RenderWindow->Render();
687 emit RenderWindowModified() ;
693 /*!Sets actors data.*/
694 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
695 VTKViewer_Actor * theMapActor,
696 VTKViewer_Actor * theActor,
699 (*theFun)(theMapIndex,theMapActor,theActor);
701 theMapActor->GetPosition(aPos);
702 theActor->SetPosition(aPos);