Salome HOME
updated copyright message
[modules/gui.git] / src / VTKViewer / VTKViewer_ViewWindow.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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, or (at your option) any later version.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "VTKViewer_ViewWindow.h"
24 #include "VTKViewer_ViewModel.h"
25 #include "VTKViewer_RenderWindow.h"
26 #include "VTKViewer_RenderWindowInteractor.h"
27 #include "VTKViewer_InteractorStyle.h"
28 #include "VTKViewer_Trihedron.h"
29 #include "VTKViewer_Transform.h"
30 #include "VTKViewer_Utilities.h"
31 #include "VTKViewer_Texture.h"
32 #include "VTKViewer_OpenGLRenderer.h"
33
34 #include <SUIT_Session.h>
35 #include <SUIT_MessageBox.h>
36 #include <SUIT_Tools.h>
37 #include <SUIT_ResourceMgr.h>
38
39 #include <QFileInfo>
40 #include <QImage>
41
42 #include <vtkCamera.h>
43 #include <vtkJPEGReader.h>
44 #include <vtkBMPReader.h>
45 #include <vtkTIFFReader.h>
46 #include <vtkPNGReader.h>
47 #include <vtkMetaImageReader.h>
48 #include <vtkImageMapToColors.h>
49 #include <vtkTexture.h>
50
51 #include <QtxToolBar.h>
52 #include <QtxMultiAction.h>
53
54 /*! Construction*/
55 VTKViewer_ViewWindow::VTKViewer_ViewWindow( SUIT_Desktop* theDesktop, 
56                                             VTKViewer_Viewer* theModel,
57                                             VTKViewer_InteractorStyle* iStyle,
58                                             VTKViewer_RenderWindowInteractor* rw )
59 : SUIT_ViewWindow( theDesktop )
60 {
61   myModel = theModel;
62
63   myTrihedron = VTKViewer_Trihedron::New();
64   myTransform = VTKViewer_Transform::New();
65   myRenderer  = VTKViewer_OpenGLRenderer::New() ;
66
67   myTrihedron->AddToRender( myRenderer );
68
69   myRenderWindow = new VTKViewer_RenderWindow( this, "RenderWindow" );
70   setCentralWidget(myRenderWindow);
71   myRenderWindow->setFocusPolicy( Qt::StrongFocus );
72   myRenderWindow->setFocus();
73
74   myRenderWindow->getRenderWindow()->AddRenderer( myRenderer );
75
76   myRenderer->GetActiveCamera()->ParallelProjectionOn();
77   myRenderer->LightFollowCameraOn();
78   myRenderer->TwoSidedLightingOn();
79
80   // Create an interactor.
81   myRWInteractor = rw ? rw : VTKViewer_RenderWindowInteractor::New();
82   myRWInteractor->SetRenderWindow( myRenderWindow->getRenderWindow() );
83
84   VTKViewer_InteractorStyle* RWS = iStyle ? iStyle : VTKViewer_InteractorStyle::New();
85   RWS->setGUIWindow( myRenderWindow );
86   myRWInteractor->SetInteractorStyle( RWS ); 
87
88   myRWInteractor->Initialize();
89   RWS->setTriedron( myTrihedron );
90   RWS->FindPokedRenderer( 0, 0 );
91
92   setCentralWidget( myRenderWindow );
93
94   myToolBar = new QtxToolBar( true, tr("LBL_TOOLBAR_LABEL"), this );
95   myToolBar->setObjectName( "VTKViewerViewOperations" );
96   myToolBar->setFloatable( false );
97
98   createActions();
99   createToolBar();
100
101   connect( myRenderWindow, SIGNAL(KeyPressed( QKeyEvent* )),
102            this,           SLOT(onKeyPressed( QKeyEvent* )) );
103   connect( myRenderWindow, SIGNAL(KeyReleased( QKeyEvent* )),
104            this,           SLOT(onKeyReleased( QKeyEvent* )) );
105   connect( myRenderWindow, SIGNAL(MouseButtonPressed( QMouseEvent* )),
106            this,           SLOT(onMousePressed( QMouseEvent* )) );
107   connect( myRenderWindow, SIGNAL(MouseButtonReleased( QMouseEvent* )),
108            this,           SLOT(onMouseReleased( QMouseEvent* )) );
109   connect( myRenderWindow, SIGNAL(MouseDoubleClicked( QMouseEvent* )),
110            this,           SLOT(onMouseDoubleClicked( QMouseEvent* )) );
111   connect( myRenderWindow, SIGNAL(MouseMove( QMouseEvent* )),
112            this,           SLOT(onMouseMoving( QMouseEvent* )) );
113   connect( myRWInteractor, SIGNAL(RenderWindowModified()),
114            myRenderWindow, SLOT(update()) );
115
116   connect( myRenderWindow, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
117            this,           SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
118
119   connect( myRWInteractor, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
120            this,           SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
121
122
123   // set default background
124   setBackground( Qtx::BackgroundData( Qt::black ) );
125   // reset view
126   onResetView();
127 }
128
129 /*!Destructor.*/
130 VTKViewer_ViewWindow::~VTKViewer_ViewWindow()
131 {
132   myTransform->Delete();
133   // In order to ensure that the interactor unregisters
134   // this RenderWindow, we assign a NULL RenderWindow to 
135   // it before deleting it.
136   myRWInteractor->SetRenderWindow( NULL );
137   myRWInteractor->Delete();
138   
139   //m_RW->Delete() ;
140   myRenderer->RemoveAllViewProps();
141   //m_Renderer->Delete() ;
142   myTrihedron->Delete();
143 }
144
145 /*!Checks: is trihedron displayed.*/
146 bool VTKViewer_ViewWindow::isTrihedronDisplayed(){
147   return myTrihedron->GetVisibility() == VTKViewer_Trihedron::eOn;
148 }
149
150 /*!Activates 'zooming' transformation*/
151 void VTKViewer_ViewWindow::activateZoom()
152 {
153   myRWInteractor->GetInteractorStyle()->startZoom();
154 }
155
156 /*!Activates 'panning' transformation*/
157 void VTKViewer_ViewWindow::activatePanning()
158 {
159   myRWInteractor->GetInteractorStyle()->startPan();
160 }
161
162 /*!Activates 'rotation' transformation*/
163 void VTKViewer_ViewWindow::activateRotation()
164 {
165   myRWInteractor->GetInteractorStyle()->startRotate();
166 }
167
168 /*!Activate global panning.*/
169 void VTKViewer_ViewWindow::activateGlobalPanning()
170 {
171   //if(myTrihedron->GetVisibleActorCount(myRenderer))
172   myRWInteractor->GetInteractorStyle()->startGlobalPan();
173 }
174
175 /*!Activates 'fit area' transformation*/
176 void VTKViewer_ViewWindow::activateWindowFit()
177 {
178   myRWInteractor->GetInteractorStyle()->startFitArea();
179 }
180
181 /*!Create actions:*/
182 void VTKViewer_ViewWindow::createActions()
183 {
184   if (!myActionsMap.isEmpty()) return;
185   
186   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
187   
188   QtxAction* aAction;
189
190   //! \li Dump view
191   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_DUMP" ) ),
192                            tr( "MNU_DUMP_VIEW" ), 0, this);
193   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
194   connect(aAction, SIGNAL(triggered()), this, SLOT(onDumpView()));
195   myActionsMap[ DumpId ] = aAction;
196
197   //! \li FitAll
198   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FITALL" ) ),
199                            tr( "MNU_FITALL" ), 0, this);
200   aAction->setStatusTip(tr("DSC_FITALL"));
201   connect(aAction, SIGNAL(triggered()), this, SLOT(onFitAll()));
202   myActionsMap[ FitAllId ] = aAction;
203
204   //! \li FitRect
205   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FITAREA" ) ),
206                            tr( "MNU_FITRECT" ), 0, this);
207   aAction->setStatusTip(tr("DSC_FITRECT"));
208   connect(aAction, SIGNAL(triggered()), this, SLOT(activateWindowFit()));
209   myActionsMap[ FitRectId ] = aAction;
210
211   //! \li FitSelection
212   aAction = new QtxAction(tr("MNU_FITSELECTION"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FITSELECTION" ) ),
213                            tr( "MNU_FITSELECTION" ), 0, this);
214   aAction->setStatusTip(tr("DSC_FITSELECTION"));
215   connect(aAction, SIGNAL(triggered()), this, SLOT(onFitSelection()));
216   myActionsMap[ FitSelectionId ] = aAction;
217
218   //! \li Zoom
219   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ZOOM" ) ),
220                            tr( "MNU_ZOOM_VIEW" ), 0, this);
221   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
222   connect(aAction, SIGNAL(triggered()), this, SLOT(activateZoom()));
223   myActionsMap[ ZoomId ] = aAction;
224
225   //! \li Panning
226   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_PAN" ) ),
227                            tr( "MNU_PAN_VIEW" ), 0, this);
228   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
229   connect(aAction, SIGNAL(triggered()), this, SLOT(activatePanning()));
230   myActionsMap[ PanId ] = aAction;
231
232   //! \li Global Panning
233   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_GLOBALPAN" ) ),
234                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
235   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
236   connect(aAction, SIGNAL(triggered()), this, SLOT(activateGlobalPanning()));
237   myActionsMap[ GlobalPanId ] = aAction;
238
239   //! \li Rotation
240   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ROTATE" ) ),
241                            tr( "MNU_ROTATE_VIEW" ), 0, this);
242   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
243   connect(aAction, SIGNAL(triggered()), this, SLOT(activateRotation()));
244   myActionsMap[ RotationId ] = aAction;
245
246   //! \li Projections
247   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FRONT" ) ),
248                            tr( "MNU_FRONT_VIEW" ), 0, this);
249   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
250   connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView()));
251   myActionsMap[ FrontId ] = aAction;
252
253   //! \li Back view
254   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BACK" ) ),
255                            tr( "MNU_BACK_VIEW" ), 0, this);
256   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
257   connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView()));
258   myActionsMap[ BackId ] = aAction;
259
260   //! \li Top view
261   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TOP" ) ),
262                            tr( "MNU_TOP_VIEW" ), 0, this);
263   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
264   connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView()));
265   myActionsMap[ TopId ] = aAction;
266
267   //! \li Bottom view
268   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BOTTOM" ) ),
269                            tr( "MNU_BOTTOM_VIEW" ), 0, this);
270   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
271   connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView()));
272   myActionsMap[ BottomId ] = aAction;
273
274   //! \li Left view
275   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_LEFT" ) ),
276                            tr( "MNU_LEFT_VIEW" ), 0, this);
277   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
278   connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView()));
279   myActionsMap[ LeftId ] = aAction;
280
281   //! \li Right view
282   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RIGHT" ) ),
283                            tr( "MNU_RIGHT_VIEW" ), 0, this);
284   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
285   connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView()));
286   myActionsMap[ RightId ] = aAction;
287
288   // \li Rotate anticlockwise
289   aAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ANTICLOCKWISE" ) ),
290                           tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this);
291   aAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW"));
292   connect(aAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView()));
293   myActionsMap[ AntiClockWiseId ] = aAction;
294
295   // \li Rotate clockwise
296   aAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_CLOCKWISE" ) ),
297                           tr( "MNU_CLOCKWISE_VIEW" ), 0, this);
298   aAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW"));
299   connect(aAction, SIGNAL(triggered()), this, SLOT(onClockWiseView()));
300   myActionsMap[ ClockWiseId ] = aAction;
301
302   //! \li Reset
303   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RESET" ) ),
304                            tr( "MNU_RESET_VIEW" ), 0, this);
305   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
306   connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView()));
307   myActionsMap[ ResetId ] = aAction;
308
309   //! \li Trihedron shown
310   aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRON"), aResMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TRIHEDRON" ) ),
311                            tr( "MNU_SHOW_TRIHEDRON" ), 0, this);
312   aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRON"));
313   connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow()));
314   myActionsMap[ TrihedronShowId ] = aAction;
315 }
316
317 /*!Create tool bar.*/
318 void VTKViewer_ViewWindow::createToolBar()
319 {
320   myToolBar->addAction( myActionsMap[DumpId] );
321   myToolBar->addAction( myActionsMap[TrihedronShowId] );
322
323   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
324   aScaleAction->insertAction( myActionsMap[FitAllId] );
325   aScaleAction->insertAction( myActionsMap[FitRectId] );
326   aScaleAction->insertAction( myActionsMap[FitSelectionId] );
327   aScaleAction->insertAction( myActionsMap[ZoomId] );
328   myToolBar->addAction( aScaleAction );
329
330   QtxMultiAction* aPanningAction = new QtxMultiAction( this );
331   aPanningAction->insertAction( myActionsMap[PanId] );
332   aPanningAction->insertAction( myActionsMap[GlobalPanId] );
333   myToolBar->addAction( aPanningAction );
334
335   myToolBar->addAction( myActionsMap[RotationId] );
336
337   QtxMultiAction* aViewsAction = new QtxMultiAction(myToolBar);
338   aViewsAction->insertAction( myActionsMap[FrontId] );
339   aViewsAction->insertAction( myActionsMap[BackId] );
340   aViewsAction->insertAction( myActionsMap[TopId] );
341   aViewsAction->insertAction( myActionsMap[BottomId] );
342   aViewsAction->insertAction( myActionsMap[LeftId] );
343   aViewsAction->insertAction( myActionsMap[RightId] );
344   myToolBar->addAction( aViewsAction );
345
346   myToolBar->addAction( myActionsMap[AntiClockWiseId] );
347   myToolBar->addAction( myActionsMap[ClockWiseId] );
348
349   myToolBar->addAction( myActionsMap[ResetId] );
350 }
351
352 /*!On front view event.*/
353 void VTKViewer_ViewWindow::onFrontView()
354 {
355   vtkCamera* camera = myRenderer->GetActiveCamera();
356   camera->SetPosition(1,0,0);
357   camera->SetViewUp(0,0,1);
358   camera->SetFocalPoint(0,0,0);
359   onFitAll();
360 }
361
362 /*!On back view slot.*/
363 void VTKViewer_ViewWindow::onBackView()
364 {
365   vtkCamera* camera = myRenderer->GetActiveCamera();
366   camera->SetPosition(-1,0,0);
367   camera->SetViewUp(0,0,1);
368   camera->SetFocalPoint(0,0,0);
369   onFitAll();
370 }
371
372 /*!On back view slot.*/
373 void VTKViewer_ViewWindow::onTopView()
374 {
375   vtkCamera* camera = myRenderer->GetActiveCamera();
376   camera->SetPosition(0,0,1);
377   camera->SetViewUp(0,1,0);
378   camera->SetFocalPoint(0,0,0);
379   onFitAll();
380 }
381
382 /*!On bottom view slot.*/
383 void VTKViewer_ViewWindow::onBottomView()
384 {
385   vtkCamera* camera = myRenderer->GetActiveCamera();
386   camera->SetPosition(0,0,-1);
387   camera->SetViewUp(0,1,0);
388   camera->SetFocalPoint(0,0,0);
389   onFitAll();
390 }
391
392 /*!On left view slot.*/
393 void VTKViewer_ViewWindow::onLeftView()
394 {
395   vtkCamera* camera = myRenderer->GetActiveCamera(); 
396   camera->SetPosition(0,-1,0);
397   camera->SetViewUp(0,0,1);
398   camera->SetFocalPoint(0,0,0);
399   onFitAll();
400 }
401
402 /*!On right view slot.*/
403 void VTKViewer_ViewWindow::onRightView()
404 {
405   vtkCamera* camera = myRenderer->GetActiveCamera();
406   camera->SetPosition(0,1,0);
407   camera->SetViewUp(0,0,1);
408   camera->SetFocalPoint(0,0,0);
409   onFitAll();
410 }
411
412 /*!
413   \brief Rotate view 90 degrees clockwise
414 */
415 void VTKViewer_ViewWindow::onClockWiseView()
416 {
417   vtkCamera* aCamera = myRenderer->GetActiveCamera(); 
418   aCamera->Roll(-90);
419   aCamera->OrthogonalizeViewUp();
420   Repaint();
421 }
422
423 /*!
424   \brief Rotate view 90 degrees conterclockwise
425 */
426 void VTKViewer_ViewWindow::onAntiClockWiseView()
427 {
428   vtkCamera* aCamera = myRenderer->GetActiveCamera(); 
429   aCamera->Roll(90);
430   aCamera->OrthogonalizeViewUp();
431   Repaint();
432 }
433
434 /*!On reset view slot.*/
435 void VTKViewer_ViewWindow::onResetView()
436 {
437   int aTriedronIsVisible = isTrihedronDisplayed();
438   myTrihedron->SetVisibility( VTKViewer_Trihedron::eOnlyLineOn );
439   ::ResetCamera(myRenderer,true);  
440   vtkCamera* aCamera = myRenderer->GetActiveCamera();
441   aCamera->SetPosition(1,-1,1);
442   aCamera->SetViewUp(0,0,1);
443   ::ResetCamera(myRenderer,true);  
444   if(aTriedronIsVisible) myTrihedron->VisibilityOn();
445   else myTrihedron->VisibilityOff();
446   static double aCoeff = 3.0;
447   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
448   Repaint();
449 }
450
451 /*!On fit all slot.*/
452 void VTKViewer_ViewWindow::onFitAll()
453 {
454   myRWInteractor->GetInteractorStyle()->ViewFitAll();
455   Repaint();
456 }
457
458 /*!On fit selection slot.*/
459 void VTKViewer_ViewWindow::onFitSelection()
460 {
461   myRWInteractor->GetInteractorStyle()->ViewFitSelection();
462   Repaint();
463 }
464
465 /*!Set background color of the viewport [obsolete]*/
466 void VTKViewer_ViewWindow::setBackgroundColor( const QColor& c )
467 {
468   Qtx::BackgroundData bg = background();
469   bg.setColor( c );
470   setBackground( bg );
471 }
472
473 /*!Returns background color of the viewport [obsolete]*/
474 QColor VTKViewer_ViewWindow::backgroundColor() const
475 {
476   return background().color();
477 }
478
479 /*!Set background of the viewport*/
480 void VTKViewer_ViewWindow::setBackground( const Qtx::BackgroundData& bgData )
481 {
482   bool ok = false;
483  
484   if ( bgData.isValid() ) {
485     switch ( bgData.mode() ) {
486     case Qtx::ColorBackground:
487       {
488         QColor c = bgData.color();
489         if ( c.isValid() ) {
490           // show solid-colored background
491           getRenderer()->SetTexturedBackground( false );  // cancel texture mode
492           getRenderer()->SetGradientBackground( false );  // cancel gradient mode
493           getRenderer()->SetBackground( c.red()/255.0,
494                                         c.green()/255.0,
495                                         c.blue()/255.0 ); // set background color
496           ok = true;
497         }
498         break;
499       }
500     case Qtx::SimpleGradientBackground:
501       {
502         QColor c1, c2;
503         int type = bgData.gradient( c1, c2 );
504         if ( c1.isValid() )
505         {
506           if ( !c2.isValid() )
507             c2 = c1;
508
509           // show two-color gradient background
510           getRenderer()->SetTexturedBackground( false );    // cancel texture mode
511           getRenderer()->SetGradientBackground( true );     // switch to gradient mode
512
513           VTKViewer_OpenGLRenderer* aRenderer =
514             VTKViewer_OpenGLRenderer::SafeDownCast( getRenderer() );
515           if( aRenderer )
516           {
517             aRenderer->SetGradientType( type );
518             aRenderer->SetBackground( c1.redF(), c1.greenF(), c1.blueF() );
519             aRenderer->SetBackground2( c2.redF(), c2.greenF(), c2.blueF() );
520             ok = true;
521           }
522         }
523         break;
524       }
525     case Qtx::CustomGradientBackground:
526       {
527         // NOT IMPLEMENTED YET
528         getRenderer()->SetTexturedBackground( false );  // cancel texture mode
529         getRenderer()->SetGradientBackground( false );  // cancel gradient mode
530         // .........
531         break;
532       }
533     default:
534       break;
535     }
536     if ( bgData.isTextureShown() ) {
537       QString fileName;
538       int textureMode = bgData.texture( fileName );
539       QFileInfo fi( fileName );
540       if ( !fileName.isEmpty() && fi.exists() ) {
541         // read texture from file
542         QString extension = fi.suffix().toLower();
543         vtkImageReader2* aReader = 0;
544         if ( extension == "jpg" || extension == "jpeg" )
545           aReader = vtkJPEGReader::New();
546         else if ( extension == "bmp" )
547           aReader = vtkBMPReader::New();
548         else if ( extension == "tif" || extension == "tiff" )
549           aReader = vtkTIFFReader::New();
550         else if ( extension == "png" )
551           aReader = vtkPNGReader::New();
552         else if ( extension == "mhd" || extension == "mha" )
553           aReader = vtkMetaImageReader::New();           
554         if ( aReader ) {
555           // create texture
556           aReader->SetFileName( fi.absoluteFilePath().toUtf8().constData() );
557           aReader->Update();
558           
559           VTKViewer_Texture* aTexture = VTKViewer_Texture::New();
560           vtkImageMapToColors* aMap = 0;
561           vtkAlgorithmOutput* anOutput;
562           /*
563           // special processing for BMP reader
564           vtkBMPReader* aBMPReader = (vtkBMPReader*)aReader;
565           if ( aBMPReader ) {
566             // Special processing for BMP file
567             aBMPReader->SetAllow8BitBMP(1);
568             
569             aMap = vtkImageMapToColors::New();
570             aMap->SetInputConnection( aBMPReader->GetOutputPort() );
571             aMap->SetLookupTable( (vtkScalarsToColors*)aBMPReader->GetLookupTable() );
572             aMap->SetOutputFormatToRGB();
573             
574             anOutput = aMap->GetOutputPort();
575           }
576           else {
577           }
578           */
579           anOutput = aReader->GetOutputPort( 0 );
580           aTexture->SetInputConnection( anOutput );
581           // set texture mode
582           // VSR: Currently, VTK only supports Stretch mode, so below code will give
583           // the same results for all modes
584           switch ( textureMode ) {
585           case Qtx::TileTexture:
586             aTexture->RepeatOn();
587             aTexture->EdgeClampOff();
588             aTexture->InterpolateOff();
589             break;
590           case Qtx::StretchTexture:
591             aTexture->RepeatOff();
592             aTexture->EdgeClampOff();
593             aTexture->InterpolateOn();
594             break;
595           case Qtx::CenterTexture:
596           default:
597             aTexture->RepeatOff();
598             aTexture->EdgeClampOn();
599             aTexture->InterpolateOff();
600             break;
601           }
602           // show textured background
603           getRenderer()->SetTexturedBackground( true );     // switch to texture mode
604           getRenderer()->SetBackgroundTexture( aTexture );  // set texture image
605           
606           // clean-up resources
607           if ( aMap )
608             aMap->Delete();
609           aReader->Delete();
610           aTexture->Delete();
611           ok = true;
612         }
613       }
614     }
615   }
616
617   if ( ok )
618     myBackground = bgData;
619 }
620
621 /*!Returns background of the viewport*/
622 Qtx::BackgroundData VTKViewer_ViewWindow::background() const
623 {
624   return myBackground;
625 }
626
627 /*!Repaint window. If \a theUpdateTrihedron is true - recalculate trihedron.*/
628 void VTKViewer_ViewWindow::Repaint(bool theUpdateTrihedron)
629 {
630   if (theUpdateTrihedron) onAdjustTrihedron();
631   myRenderWindow->update();
632 }
633
634 /*!Get scale of transformation filter.*/
635 void VTKViewer_ViewWindow::GetScale( double theScale[3] ) {
636   myTransform->GetScale( theScale );
637 }
638
639 /*!Set scale of transformation filter and repaint window.*/
640 void VTKViewer_ViewWindow::SetScale( double theScale[3] ) {
641   myTransform->SetMatrixScale( theScale[0], theScale[1], theScale[2] );
642   myRWInteractor->Render();
643   Repaint();
644 }
645
646 /*!Calculation trihedron size.*/
647 void VTKViewer_ViewWindow::onAdjustTrihedron(){   
648   if( !isTrihedronDisplayed() ) 
649     return;
650   int aVisibleNum = myTrihedron->GetVisibleActorCount(myRenderer);
651   if(aVisibleNum){
652     // calculating diagonal of visible props of the renderer
653     double bnd[6];
654     myTrihedron->VisibilityOff();
655     ::ComputeVisiblePropBounds(myRenderer,bnd);
656     myTrihedron->VisibilityOn();
657     double aLength = 0;
658     static bool CalcByDiag = false;
659     if(CalcByDiag){
660       aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
661                      (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
662                      (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
663     }else{
664       aLength = bnd[1]-bnd[0];
665       aLength = qMax((bnd[3]-bnd[2]),aLength);
666       aLength = qMax((bnd[5]-bnd[4]),aLength);
667     }
668    
669     static double aSizeInPercents = 105;
670     QString aSetting;// = SUIT_CONFIG->getSetting("Viewer:TrihedronSize");
671     if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
672
673     static double EPS_SIZE = 5.0E-3;
674     double aSize = myTrihedron->GetSize();
675     double aNewSize = aLength*aSizeInPercents/100.0;
676     // if the new trihedron size have sufficient difference, then apply the value
677     if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE){
678       myTrihedron->SetSize(aNewSize);
679     }
680   }
681   ::ResetCameraClippingRange(myRenderer);
682 }
683
684 /*!Emit key pressed.*/
685 void VTKViewer_ViewWindow::onKeyPressed(QKeyEvent* event)
686 {
687   emit keyPressed( this, event );
688 }
689
690 /*!Emit key released.*/
691 void VTKViewer_ViewWindow::onKeyReleased(QKeyEvent* event)
692 {
693   emit keyReleased( this, event );
694 }
695
696 /*!Emit key pressed.*/
697 void VTKViewer_ViewWindow::onMousePressed(QMouseEvent* event)
698 {
699   emit mousePressed(this, event);
700 }
701
702 /*!Emit mouse released.*/
703 void VTKViewer_ViewWindow::onMouseReleased(QMouseEvent* event)
704 {
705   emit mouseReleased( this, event );
706 }
707
708 /*!Emit mouse moving.*/
709 void VTKViewer_ViewWindow::onMouseMoving(QMouseEvent* event)
710 {
711   emit mouseMoving( this, event );
712 }
713
714 /*!Emit mouse double clicked.*/
715 void VTKViewer_ViewWindow::onMouseDoubleClicked( QMouseEvent* event )
716 {
717   emit mouseDoubleClicked( this, event );
718 }
719
720 /*!Insert actor to renderer and transformation filter.
721  *Move Internal actors, if \a theMoveInternalActors is true.
722  */
723 void VTKViewer_ViewWindow::InsertActor( VTKViewer_Actor* theActor, bool theMoveInternalActors ){
724   theActor->AddToRender(myRenderer);
725   theActor->SetTransform(myTransform);
726   if(theMoveInternalActors) 
727     myRWInteractor->MoveInternalActors();
728 }
729
730 /*!Add actor.Repaint window if \a theUpdate is true.
731  *@see InsertActor( VTKViewer_Actor* theActor, bool theMoveInternalActors )
732  */
733 void VTKViewer_ViewWindow::AddActor( VTKViewer_Actor* theActor, bool theUpdate /*=false*/ ){
734   InsertActor(theActor);
735   if(theUpdate) 
736     Repaint();
737 }
738
739 /*!Remove \a theActor from renderer and pepaint, if \a theUpdate is true.*/
740 void VTKViewer_ViewWindow::RemoveActor( VTKViewer_Actor* theActor, bool theUpdate /*=false*/ ){
741   theActor->RemoveFromRender(myRenderer);
742   if(theUpdate) 
743     Repaint();
744 }
745
746 /*!@see RemoveActor() and InsertActor().*/
747 void VTKViewer_ViewWindow::MoveActor( VTKViewer_Actor* theActor)
748 {
749   RemoveActor(theActor);
750   InsertActor(theActor,true);
751 }
752
753 /*!On trihedron show slot.*/
754 void VTKViewer_ViewWindow::onTrihedronShow()
755 {
756   if (isTrihedronDisplayed())
757     myTrihedron->VisibilityOff();
758   else
759     myTrihedron->VisibilityOn();
760   myRenderWindow->update();
761 }
762
763 /*!Dump view.*/
764 QImage VTKViewer_ViewWindow::dumpView()
765 {
766   QPixmap px = QPixmap::grabWindow( myRenderWindow->winId() );
767   return px.toImage();
768 }
769
770 /*! The method returns the visual parameters of this view as a formated string
771  */
772 QString VTKViewer_ViewWindow::getVisualParameters()
773 {
774   double pos[3], focalPnt[3], viewUp[3], parScale, scale[3];
775
776   vtkCamera* camera = myRenderer->GetActiveCamera();
777   camera->GetPosition( pos );
778   camera->GetFocalPoint( focalPnt );
779   camera->GetViewUp( viewUp );
780   parScale = camera->GetParallelScale();
781   GetScale( scale );
782
783   QString retStr;
784   retStr.sprintf( "%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", 
785                   pos[0], pos[1], pos[2], focalPnt[0], focalPnt[1], focalPnt[2], viewUp[0], viewUp[1], 
786                   viewUp[2], parScale, scale[0], scale[1], scale[2] );
787   return retStr;
788 }
789
790 /*! The method restors visual parameters of this view from a formated string
791  */
792 void VTKViewer_ViewWindow::setVisualParameters( const QString& parameters )
793 {
794   QStringList paramsLst = parameters.split( '*' );
795   if ( paramsLst.size() == 13 ) {
796     double pos[3], focalPnt[3], viewUp[3], parScale, scale[3];
797     pos[0] = paramsLst[0].toDouble();
798     pos[1] = paramsLst[1].toDouble();
799     pos[2] = paramsLst[2].toDouble();
800     focalPnt[0] = paramsLst[3].toDouble();
801     focalPnt[1] = paramsLst[4].toDouble();
802     focalPnt[2] = paramsLst[5].toDouble();
803     viewUp[0] = paramsLst[6].toDouble();
804     viewUp[1] = paramsLst[7].toDouble();
805     viewUp[2] = paramsLst[8].toDouble();
806     parScale = paramsLst[9].toDouble();
807     scale[0] = paramsLst[10].toDouble();
808     scale[1] = paramsLst[11].toDouble();
809     scale[2] = paramsLst[12].toDouble();
810
811     vtkCamera* camera = myRenderer->GetActiveCamera();
812     camera->SetPosition( pos );
813     camera->SetFocalPoint( focalPnt );
814     camera->SetViewUp( viewUp );
815     camera->SetParallelScale( parScale );
816     myTransform->SetMatrixScale( scale[0], scale[1], scale[2] );
817     myRWInteractor->Render();
818   }
819 }