Salome HOME
6c3ef1b6e48416a8712470a2c936dbb46844247a
[modules/gui.git] / src / VTKViewer / VTKViewer_ViewWindow.cxx
1 #include "VTKViewer_ViewWindow.h"
2 #include "VTKViewer_ViewModel.h"
3 #include "VTKViewer_RenderWindow.h"
4 #include "VTKViewer_RenderWindowInteractor.h"
5 #include "VTKViewer_InteractorStyle.h"
6 #include "VTKViewer_Trihedron.h"
7 #include "VTKViewer_Transform.h"
8 #include "VTKViewer_Utilities.h"
9
10 #include "SUIT_Session.h"
11 #include "SUIT_ToolButton.h"
12 #include "SUIT_MessageBox.h"
13
14 #include "SUIT_Tools.h"
15 #include "SUIT_ResourceMgr.h"
16
17 #include <qapplication.h>
18
19 #include <vtkRenderer.h>
20 #include <vtkCamera.h>
21
22 /*! Construction*/
23 VTKViewer_ViewWindow::VTKViewer_ViewWindow( SUIT_Desktop* theDesktop, 
24                                             VTKViewer_Viewer* theModel,
25                                             VTKViewer_InteractorStyle* iStyle,
26                                             VTKViewer_RenderWindowInteractor* rw )
27 : SUIT_ViewWindow( theDesktop )
28 {
29   myModel = theModel;
30
31   myTrihedron = VTKViewer_Trihedron::New();
32   myTransform = VTKViewer_Transform::New();
33   myRenderer  = vtkRenderer::New() ;
34
35   myTrihedron->AddToRender( myRenderer );
36
37   myRenderWindow = new VTKViewer_RenderWindow( this, "RenderWindow" );
38   setCentralWidget(myRenderWindow);
39   myRenderWindow->setFocusPolicy( StrongFocus );
40   myRenderWindow->setFocus();
41
42   myRenderWindow->getRenderWindow()->AddRenderer( myRenderer );
43
44   myRenderer->GetActiveCamera()->ParallelProjectionOn();
45   myRenderer->LightFollowCameraOn();
46   myRenderer->TwoSidedLightingOn();
47
48   // Set BackgroundColor
49   QString BgrColorRed   = "0";//SUIT_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
50   QString BgrColorGreen = "0";//SUIT_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
51   QString BgrColorBlue  = "0";//SUIT_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
52
53   if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() ) 
54     myRenderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
55   else
56     myRenderer->SetBackground( 0, 0, 0 );
57   
58   // Create an interactor.
59   myRWInteractor = rw ? rw : VTKViewer_RenderWindowInteractor::New();
60   myRWInteractor->SetRenderWindow( myRenderWindow->getRenderWindow() );
61
62   VTKViewer_InteractorStyle* RWS = iStyle ? iStyle : VTKViewer_InteractorStyle::New();
63   RWS->setGUIWindow( myRenderWindow );
64   myRWInteractor->SetInteractorStyle( RWS ); 
65
66   myRWInteractor->Initialize();
67   RWS->setTriedron( myTrihedron );
68   RWS->FindPokedRenderer( 0, 0 );
69
70   setCentralWidget( myRenderWindow );
71
72   myToolBar = new QToolBar(this);
73   myToolBar->setCloseMode(QDockWindow::Undocked);
74   myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
75
76   createActions();
77   createToolBar();
78
79   connect( myRenderWindow, SIGNAL(KeyPressed( QKeyEvent* )),
80            this,           SLOT(onKeyPressed( QKeyEvent* )) );
81   connect( myRenderWindow, SIGNAL(KeyReleased( QKeyEvent* )),
82            this,           SLOT(onKeyReleased( QKeyEvent* )) );
83   connect( myRenderWindow, SIGNAL(MouseButtonPressed( QMouseEvent* )),
84            this,           SLOT(onMousePressed( QMouseEvent* )) );
85   connect( myRenderWindow, SIGNAL(MouseButtonReleased( QMouseEvent* )),
86            this,           SLOT(onMouseReleased( QMouseEvent* )) );
87   connect( myRenderWindow, SIGNAL(MouseDoubleClicked( QMouseEvent* )),
88            this,           SLOT(onMouseDoubleClicked( QMouseEvent* )) );
89   connect( myRenderWindow, SIGNAL(MouseMove( QMouseEvent* )),
90            this,           SLOT(onMouseMoving( QMouseEvent* )) );
91   connect( myRWInteractor, SIGNAL(RenderWindowModified()),
92            myRenderWindow, SLOT(update()) );
93
94   connect( myRenderWindow, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
95            this,           SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
96
97   connect( myRWInteractor, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
98            this,           SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
99
100
101   onResetView();
102 }
103
104 /*!Destructor.*/
105 VTKViewer_ViewWindow::~VTKViewer_ViewWindow()
106 {
107   myTransform->Delete();
108   // In order to ensure that the interactor unregisters
109   // this RenderWindow, we assign a NULL RenderWindow to 
110   // it before deleting it.
111   myRWInteractor->SetRenderWindow( NULL );
112   myRWInteractor->Delete();
113   
114   //m_RW->Delete() ;
115   myRenderer->RemoveAllProps();
116   //m_Renderer->Delete() ;
117   myTrihedron->Delete();
118 }
119
120 bool VTKViewer_ViewWindow::isTrihedronDisplayed(){
121   return myTrihedron->GetVisibility() == VTKViewer_Trihedron::eOn;
122 }
123
124 /*!
125     Activates 'zooming' transformation
126 */
127 void VTKViewer_ViewWindow::activateZoom()
128 {
129   myRWInteractor->GetInteractorStyle()->startZoom();
130 }
131
132 /*!
133     Activates 'panning' transformation
134 */
135 void VTKViewer_ViewWindow::activatePanning()
136 {
137   myRWInteractor->GetInteractorStyle()->startPan();
138 }
139
140 /*!
141     Activates 'rotation' transformation
142 */
143 void VTKViewer_ViewWindow::activateRotation()
144 {
145   myRWInteractor->GetInteractorStyle()->startRotate();
146 }
147
148 void VTKViewer_ViewWindow::activateGlobalPanning()
149 {
150   //if(myTrihedron->GetVisibleActorCount(myRenderer))
151   myRWInteractor->GetInteractorStyle()->startGlobalPan();
152 }
153
154 /*!
155     Activates 'fit area' transformation
156 */
157 void VTKViewer_ViewWindow::activateWindowFit()
158 {
159   myRWInteractor->GetInteractorStyle()->startFitArea();
160 }
161
162 void VTKViewer_ViewWindow::createActions()
163 {
164   if (!myActionsMap.isEmpty()) return;
165   
166   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
167   
168   QtxAction* aAction;
169
170   // Dump view
171   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_DUMP" ) ),
172                            tr( "MNU_DUMP_VIEW" ), 0, this);
173   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
174   connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
175   myActionsMap[ DumpId ] = aAction;
176
177   // FitAll
178   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FITALL" ) ),
179                            tr( "MNU_FITALL" ), 0, this);
180   aAction->setStatusTip(tr("DSC_FITALL"));
181   connect(aAction, SIGNAL(activated()), this, SLOT(onFitAll()));
182   myActionsMap[ FitAllId ] = aAction;
183
184   // FitRect
185   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FITAREA" ) ),
186                            tr( "MNU_FITRECT" ), 0, this);
187   aAction->setStatusTip(tr("DSC_FITRECT"));
188   connect(aAction, SIGNAL(activated()), this, SLOT(activateWindowFit()));
189   myActionsMap[ FitRectId ] = aAction;
190
191   // Zoom
192   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ZOOM" ) ),
193                            tr( "MNU_ZOOM_VIEW" ), 0, this);
194   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
195   connect(aAction, SIGNAL(activated()), this, SLOT(activateZoom()));
196   myActionsMap[ ZoomId ] = aAction;
197
198   // Panning
199   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_PAN" ) ),
200                            tr( "MNU_PAN_VIEW" ), 0, this);
201   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
202   connect(aAction, SIGNAL(activated()), this, SLOT(activatePanning()));
203   myActionsMap[ PanId ] = aAction;
204
205   // Global Panning
206   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_GLOBALPAN" ) ),
207                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
208   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
209   connect(aAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning()));
210   myActionsMap[ GlobalPanId ] = aAction;
211
212   // Rotation
213   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ROTATE" ) ),
214                            tr( "MNU_ROTATE_VIEW" ), 0, this);
215   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
216   connect(aAction, SIGNAL(activated()), this, SLOT(activateRotation()));
217   myActionsMap[ RotationId ] = aAction;
218
219   // Projections
220   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FRONT" ) ),
221                            tr( "MNU_FRONT_VIEW" ), 0, this);
222   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
223   connect(aAction, SIGNAL(activated()), this, SLOT(onFrontView()));
224   myActionsMap[ FrontId ] = aAction;
225
226   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BACK" ) ),
227                            tr( "MNU_BACK_VIEW" ), 0, this);
228   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
229   connect(aAction, SIGNAL(activated()), this, SLOT(onBackView()));
230   myActionsMap[ BackId ] = aAction;
231
232   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TOP" ) ),
233                            tr( "MNU_TOP_VIEW" ), 0, this);
234   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
235   connect(aAction, SIGNAL(activated()), this, SLOT(onTopView()));
236   myActionsMap[ TopId ] = aAction;
237
238   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BOTTOM" ) ),
239                            tr( "MNU_BOTTOM_VIEW" ), 0, this);
240   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
241   connect(aAction, SIGNAL(activated()), this, SLOT(onBottomView()));
242   myActionsMap[ BottomId ] = aAction;
243
244   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_LEFT" ) ),
245                            tr( "MNU_LEFT_VIEW" ), 0, this);
246   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
247   connect(aAction, SIGNAL(activated()), this, SLOT(onLeftView()));
248   myActionsMap[ LeftId ] = aAction;
249
250   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RIGHT" ) ),
251                            tr( "MNU_RIGHT_VIEW" ), 0, this);
252   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
253   connect(aAction, SIGNAL(activated()), this, SLOT(onRightView()));
254   myActionsMap[ RightId ] = aAction;
255
256   // Reset
257   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RESET" ) ),
258                            tr( "MNU_RESET_VIEW" ), 0, this);
259   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
260   connect(aAction, SIGNAL(activated()), this, SLOT(onResetView()));
261   myActionsMap[ ResetId ] = aAction;
262
263   aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRON"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TRIHEDRON" ) ),
264                            tr( "MNU_SHOW_TRIHEDRON" ), 0, this);
265   aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRON"));
266   connect(aAction, SIGNAL(activated()), this, SLOT(onTrihedronShow()));
267   myActionsMap[ TrihedronShowId ] = aAction;
268 }
269
270 void VTKViewer_ViewWindow::createToolBar()
271 {
272   myActionsMap[DumpId]->addTo(myToolBar);
273   myActionsMap[TrihedronShowId]->addTo(myToolBar);
274
275   SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar);
276   aScaleBtn->AddAction(myActionsMap[FitAllId]);
277   aScaleBtn->AddAction(myActionsMap[FitRectId]);
278   aScaleBtn->AddAction(myActionsMap[ZoomId]);
279
280   SUIT_ToolButton* aPanningBtn = new SUIT_ToolButton(myToolBar);
281   aPanningBtn->AddAction(myActionsMap[PanId]);
282   aPanningBtn->AddAction(myActionsMap[GlobalPanId]);
283
284   myActionsMap[RotationId]->addTo(myToolBar);
285
286   SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar);
287   aViewsBtn->AddAction(myActionsMap[FrontId]);
288   aViewsBtn->AddAction(myActionsMap[BackId]);
289   aViewsBtn->AddAction(myActionsMap[TopId]);
290   aViewsBtn->AddAction(myActionsMap[BottomId]);
291   aViewsBtn->AddAction(myActionsMap[LeftId]);
292   aViewsBtn->AddAction(myActionsMap[RightId]);
293
294   myActionsMap[ResetId]->addTo(myToolBar);
295 }
296
297 void VTKViewer_ViewWindow::onFrontView()
298 {
299   vtkCamera* camera = myRenderer->GetActiveCamera();
300   camera->SetPosition(1,0,0);
301   camera->SetViewUp(0,0,1);
302   camera->SetFocalPoint(0,0,0);
303   onFitAll();
304 }
305
306 void VTKViewer_ViewWindow::onBackView()
307 {
308   vtkCamera* camera = myRenderer->GetActiveCamera();
309   camera->SetPosition(-1,0,0);
310   camera->SetViewUp(0,0,1);
311   camera->SetFocalPoint(0,0,0);
312   onFitAll();
313 }
314
315 void VTKViewer_ViewWindow::onTopView()
316 {
317   vtkCamera* camera = myRenderer->GetActiveCamera();
318   camera->SetPosition(0,0,1);
319   camera->SetViewUp(0,1,0);
320   camera->SetFocalPoint(0,0,0);
321   onFitAll();
322 }
323
324 void VTKViewer_ViewWindow::onBottomView()
325 {
326   vtkCamera* camera = myRenderer->GetActiveCamera();
327   camera->SetPosition(0,0,-1);
328   camera->SetViewUp(0,1,0);
329   camera->SetFocalPoint(0,0,0);
330   onFitAll();
331 }
332
333 void VTKViewer_ViewWindow::onLeftView()
334 {
335   vtkCamera* camera = myRenderer->GetActiveCamera(); 
336   camera->SetPosition(0,-1,0);
337   camera->SetViewUp(0,0,1);
338   camera->SetFocalPoint(0,0,0);
339   onFitAll();
340 }
341
342 void VTKViewer_ViewWindow::onRightView()
343 {
344   vtkCamera* camera = myRenderer->GetActiveCamera();
345   camera->SetPosition(0,1,0);
346   camera->SetViewUp(0,0,1);
347   camera->SetFocalPoint(0,0,0);
348   onFitAll();
349 }
350
351 void VTKViewer_ViewWindow::onResetView()
352 {
353   int aTriedronIsVisible = isTrihedronDisplayed();
354   myTrihedron->SetVisibility( VTKViewer_Trihedron::eOnlyLineOn );
355   ::ResetCamera(myRenderer,true);  
356   vtkCamera* aCamera = myRenderer->GetActiveCamera();
357   aCamera->SetPosition(1,-1,1);
358   aCamera->SetViewUp(0,0,1);
359   ::ResetCamera(myRenderer,true);  
360   if(aTriedronIsVisible) myTrihedron->VisibilityOn();
361   else myTrihedron->VisibilityOff();
362   static float aCoeff = 3.0;
363   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
364   Repaint();
365 }
366
367 void VTKViewer_ViewWindow::onFitAll()
368 {
369   myRWInteractor->GetInteractorStyle()->ViewFitAll();
370   Repaint();
371 }
372
373 /*!
374     Set background of the viewport
375 */
376 void VTKViewer_ViewWindow::setBackgroundColor( const QColor& color )
377 {
378   if ( myRenderer )
379     myRenderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
380 }
381
382 /*!
383     Returns background of the viewport
384 */
385 QColor VTKViewer_ViewWindow::backgroundColor() const
386 {
387   float backint[3];
388   if ( myRenderer ) {
389     myRenderer->GetBackground( backint );
390     return QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255));
391   }
392   return SUIT_ViewWindow::backgroundColor();
393 }
394
395 void VTKViewer_ViewWindow::Repaint(bool theUpdateTrihedron)
396 {
397   if (theUpdateTrihedron) onAdjustTrihedron();
398   myRenderWindow->update();
399 }
400
401 void VTKViewer_ViewWindow::GetScale( double theScale[3] ) {
402   myTransform->GetScale( theScale );
403 }
404
405 void VTKViewer_ViewWindow::SetScale( double theScale[3] ) {
406   myTransform->SetMatrixScale( theScale[0], theScale[1], theScale[2] );
407   myRWInteractor->Render();
408   Repaint();
409 }
410
411 void VTKViewer_ViewWindow::onAdjustTrihedron(){   
412   if( !isTrihedronDisplayed() ) 
413     return;
414   int aVisibleNum = myTrihedron->GetVisibleActorCount(myRenderer);
415   if(aVisibleNum){
416     // calculating diagonal of visible props of the renderer
417     float bnd[6];
418     myTrihedron->VisibilityOff();
419     ::ComputeVisiblePropBounds(myRenderer,bnd);
420     myTrihedron->VisibilityOn();
421     float aLength = 0;
422     static bool CalcByDiag = false;
423     if(CalcByDiag){
424       aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
425                      (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
426                      (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
427     }else{
428       aLength = bnd[1]-bnd[0];
429       aLength = max((bnd[3]-bnd[2]),aLength);
430       aLength = max((bnd[5]-bnd[4]),aLength);
431     }
432    
433     static float aSizeInPercents = 105;
434     QString aSetting;// = SUIT_CONFIG->getSetting("Viewer:TrihedronSize");
435     if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
436
437     static float EPS_SIZE = 5.0E-3;
438     float aSize = myTrihedron->GetSize();
439     float aNewSize = aLength*aSizeInPercents/100.0;
440     // if the new trihedron size have sufficient difference, then apply the value
441     if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE){
442       myTrihedron->SetSize(aNewSize);
443     }
444   }
445   ::ResetCameraClippingRange(myRenderer);
446 }
447
448 void VTKViewer_ViewWindow::onKeyPressed(QKeyEvent* event)
449 {
450   emit keyPressed( this, event );
451 }
452
453 void VTKViewer_ViewWindow::onKeyReleased(QKeyEvent* event)
454 {
455   emit keyReleased( this, event );
456 }
457
458 void VTKViewer_ViewWindow::onMousePressed(QMouseEvent* event)
459 {
460   emit mousePressed(this, event);
461 }
462
463 void VTKViewer_ViewWindow::onMouseReleased(QMouseEvent* event)
464 {
465   emit mouseReleased( this, event );
466 }
467
468 void VTKViewer_ViewWindow::onMouseMoving(QMouseEvent* event)
469 {
470   emit mouseMoving( this, event );
471 }
472
473 void VTKViewer_ViewWindow::onMouseDoubleClicked( QMouseEvent* event )
474 {
475   emit mouseDoubleClicked( this, event );
476 }
477
478 void VTKViewer_ViewWindow::InsertActor( VTKViewer_Actor* theActor, bool theMoveInternalActors ){
479   theActor->AddToRender(myRenderer);
480   theActor->SetTransform(myTransform);
481   if(theMoveInternalActors) 
482     myRWInteractor->MoveInternalActors();
483 }
484
485 void VTKViewer_ViewWindow::AddActor( VTKViewer_Actor* theActor, bool theUpdate /*=false*/ ){
486   InsertActor(theActor);
487   if(theUpdate) 
488     Repaint();
489 }
490
491 void VTKViewer_ViewWindow::RemoveActor( VTKViewer_Actor* theActor, bool theUpdate /*=false*/ ){
492   theActor->RemoveFromRender(myRenderer);
493   if(theUpdate) 
494     Repaint();
495 }
496
497 void VTKViewer_ViewWindow::MoveActor( VTKViewer_Actor* theActor)
498 {
499   RemoveActor(theActor);
500   InsertActor(theActor,true);
501 }
502
503 void VTKViewer_ViewWindow::onTrihedronShow()
504 {
505   if (isTrihedronDisplayed())
506     myTrihedron->VisibilityOff();
507   else
508     myTrihedron->VisibilityOn();
509   myRenderWindow->update();
510 }
511
512 QImage VTKViewer_ViewWindow::dumpView()
513 {
514   QPixmap px = QPixmap::grabWindow( myRenderWindow->winId() );
515   return px.convertToImage();
516 }