]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
Plugin system is now instalable. Dependency to boost eliminated.
[cpPlugins.git] / appli / ImageMPR / ImageMPR.cxx
1 #include "ImageMPR.h"
2 #include "ui_ImageMPR.h"
3
4 #include <vtkProperty.h>
5 #include <vtkRenderWindow.h>
6
7 #include <QFileDialog>
8 #include <QMessageBox>
9
10 #ifdef _WIN32
11 #  define PLUGIN_PREFIX ""
12 #  define PLUGIN_EXT "dll"
13 #  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
14 #else
15 #  define PLUGIN_PREFIX "lib"
16 #  define PLUGIN_EXT "so"
17 #  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
18 #endif // _WIN32
19
20 // -------------------------------------------------------------------------
21 ImageMPR::ImageMPR( QWidget* parent )
22   : QMainWindow( parent ),
23     m_UI( new Ui::ImageMPR ),
24     m_ImageReaderClass( "" ),
25     m_ImageWriterClass( "" ),
26     m_InputImage( NULL )
27 {
28   this->m_UI->setupUi( this );
29
30   // Create and associate renderers
31   this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
32   this->m_MPRObjects->SetRenderWindows(
33     this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
34     this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
35     this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
36     this->m_UI->m_3DVTK->GetRenderWindow( )
37     );
38
39   // signals <-> slots
40   QObject::connect(
41     this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
42     this, SLOT( _triggered_actionOpenPlugins( ) )
43     );
44   QObject::connect(
45     this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
46     this, SLOT( _triggered_actionOpenInputImage( ) )
47     );
48   QObject::connect(
49     this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
50     this, SLOT( _triggered_actionOpenSegmentation( ) )
51     );
52   QObject::connect(
53     this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
54     this, SLOT( _triggered_actionOpenInputPolyData( ) )
55     );
56
57   // Start: load all disponible plugins
58   this->_LoadPlugins(
59     std::string( PLUGIN_PREFIX ) +
60     std::string( "cpPluginsIO." ) +
61     std::string( PLUGIN_EXT )
62     );
63 }
64
65 // -------------------------------------------------------------------------
66 ImageMPR::
67 ~ImageMPR( )
68 {
69   // Close all connections
70   this->m_Plugins.UnloadAll( );
71
72   // Delete objects
73   delete this->m_UI;
74 }
75
76 // -------------------------------------------------------------------------
77 bool ImageMPR::
78 _LoadPlugins( const std::string& filename )
79 {
80   QApplication::setOverrideCursor( Qt::WaitCursor );
81   this->setEnabled( false );
82
83   this->m_ImageReaderClass = "";
84   this->m_ImageWriterClass = "";
85   this->m_MeshReaderClass = "";
86   this->m_MeshWriterClass = "";
87   this->m_UI->MenuImageToImage->clear( );
88   this->m_UI->MenuImageToMesh->clear( );
89
90   if( !( this->m_Plugins.Load( filename ) ) )
91     return( false );
92
93   typedef TPluginsInterface::TClasses _TClasses;
94   _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
95   for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
96   {
97     TPluginFilter::Pointer o =
98       this->m_Plugins.CreateProcessObject( cIt->first );
99     std::string name = o->GetClassName( );
100     std::string category = o->GetClassCategory( );
101     if( category == "ImageReader" )
102       this->m_ImageReaderClass = name;
103     else if( category == "ImageWriter" )
104       this->m_ImageWriterClass = name;
105     else if( category == "MeshReader" )
106       this->m_MeshReaderClass = name;
107     else if( category == "MeshWriter" )
108       this->m_MeshWriterClass = name;
109     else if( category == "ImageToImageFilter" )
110     {
111       QAction* action =
112         this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
113       QObject::connect(
114         action, SIGNAL( triggered( ) ),
115         this, SLOT( _triggered_actionImageToImage( ) )
116         );
117     }
118     else if( category == "ImageToMeshFilter" )
119     {
120       QAction* action =
121         this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
122       QObject::connect(
123         action, SIGNAL( triggered( ) ),
124         this, SLOT( _triggered_actionImageToMesh( ) )
125         );
126
127     } // fi
128
129   } // rof
130   QApplication::restoreOverrideCursor( );
131   this->setEnabled( true );
132
133   return( true );
134 }
135
136 // -------------------------------------------------------------------------
137 std::string ImageMPR::
138 _LoadImage( TPluginImage::Pointer& image, const QStringList& names )
139 {
140   // Block application
141   QApplication::setOverrideCursor( Qt::WaitCursor );
142   this->setEnabled( false );
143
144   std::string ret = "";
145   image = NULL;
146
147   // Get a reader from loaded plugins
148   TPluginFilter::Pointer reader =
149     this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
150   if( reader.IsNotNull( ) )
151   {
152     // Configure reader
153     TParameters params = reader->GetDefaultParameters( );
154     QStringList::const_iterator qIt = names.begin( );
155     for( ; qIt != names.end( ); ++qIt )
156       params.AddValueToStringList( "FileNames", qIt->toStdString( ) );
157     params.SetValueAsBool( "VectorType", false );
158     reader->SetParameters( params );
159
160     // Execute and get error message, if any
161     ret = reader->Update( );
162
163     // Assign fresh image, if any
164     if( ret == "" )
165     {
166       image = reader->GetOutput< TPluginImage >( 0 );
167       reader->DisconnectOutputs( );
168
169     } // fi
170   }
171   else
172     ret = "No suitable reader object found in loaded plugins.";
173   
174   // Finish reading
175   QApplication::restoreOverrideCursor( );
176   this->setEnabled( true );
177   return( ret );
178 }
179
180 // -------------------------------------------------------------------------
181 void ImageMPR::
182 _triggered_actionOpenPlugins( )
183 {
184   // Show dialog and check if it was accepted
185   QFileDialog dialog( this );
186   dialog.setFileMode( QFileDialog::ExistingFile );
187   dialog.setDirectory( "." );
188   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
189   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
190   if( !( dialog.exec( ) ) )
191     return;
192   
193   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
194   if( !( _LoadPlugins( fname ) ) )
195     QMessageBox::critical(
196       this,
197       tr( "Ignoring plugin" ),
198       tr( fname.c_str( ) )
199       );
200 }
201
202 // -------------------------------------------------------------------------
203 void ImageMPR::
204 _triggered_actionOpenInputImage( )
205 {
206   // Show dialog and check if it was accepted
207   QFileDialog dialog( this );
208   dialog.setFileMode( QFileDialog::ExistingFiles );
209   dialog.setDirectory( tr( "." ) );
210   dialog.setNameFilter(
211     tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
212     );
213   dialog.setDefaultSuffix( tr( "mhd" ) );
214   if( !( dialog.exec( ) ) )
215     return;
216   
217   // Read image
218   std::string err =
219     this->_LoadImage( this->m_InputImage, dialog.selectedFiles( ) );
220   if( err == "" )
221   {
222     vtkImageData* vtk_id = this->m_InputImage->GetVTKImageData( );
223     if( vtk_id != NULL )
224     {
225       this->m_MPRObjects->SetImage( vtk_id );
226       this->m_MPRObjects->ActivateInteractors( );
227       this->m_MPRObjects->ResetCameras( );
228       this->m_MPRObjects->RenderAll( );
229     }
230     else
231       QMessageBox::critical(
232         this,
233         tr( "Error message" ),
234         tr( "Read image does not have a valid VTK converter." )
235         );
236   }
237   else
238     QMessageBox::critical(
239       this,
240       tr( "Error reading single image" ),
241       tr( err.c_str( ) )
242       );
243 }
244
245 // -------------------------------------------------------------------------
246 void ImageMPR::
247 _triggered_actionOpenSegmentation( )
248 {
249   if( this->m_InputImage.IsNull( ) )
250   {
251     QMessageBox::critical(
252       this,
253       tr( "Error message" ),
254       tr( "Before reading a segmentation, first load a raw image." )
255       );
256     return;
257
258   } // fi
259
260   // Show dialog and check if it was accepted
261   QFileDialog dialog( this );
262   dialog.setFileMode( QFileDialog::ExistingFiles );
263   dialog.setDirectory( tr( "." ) );
264   dialog.setNameFilter(
265     tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
266     );
267   dialog.setDefaultSuffix( tr( "mhd" ) );
268   if( !( dialog.exec( ) ) )
269     return;
270   
271   // Read image
272   std::string err =
273     this->_LoadImage( this->m_InputSegmentation, dialog.selectedFiles( ) );
274   if( err == "" )
275   {
276     vtkImageData* vtk_id = this->m_InputSegmentation->GetVTKImageData( );
277     if( vtk_id != NULL )
278     {
279       this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
280       this->m_MPRObjects->RenderAll( );
281     }
282     else
283       QMessageBox::critical(
284         this,
285         tr( "Error message" ),
286         tr( "Read image does not have a valid VTK converter." )
287         );
288   }
289   else
290     QMessageBox::critical(
291       this,
292       tr( "Error reading single image" ),
293       tr( err.c_str( ) )
294       );
295 }
296
297 // -------------------------------------------------------------------------
298 void ImageMPR::
299 _triggered_actionOpenInputPolyData( )
300 {
301   // Show dialog and check if it was accepted
302   QFileDialog dialog( this );
303   dialog.setFileMode( QFileDialog::ExistingFile );
304   dialog.setDirectory( tr( "." ) );
305   dialog.setNameFilter(
306     tr( "Mesh files (*.vtk *.obj);;All files (*)" )
307     );
308   dialog.setDefaultSuffix( tr( "vtk" ) );
309   if( !( dialog.exec( ) ) )
310     return;
311   
312   this->m_InputMesh = NULL;
313
314   // Get a reader from plugins
315   TPluginFilter::Pointer reader =
316     this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
317
318   // Configure reader
319   TParameters reader_params = reader->GetDefaultParameters( );
320   QStringList q_fnames = dialog.selectedFiles( );
321   QStringList::const_iterator qIt = q_fnames.begin( );
322   for( ; qIt != q_fnames.end( ); ++qIt )
323     reader_params.SetValueAsString( "FileName", qIt->toStdString( ) );
324   reader->SetParameters( reader_params );
325
326   // Execute and get error message, if any
327   QApplication::setOverrideCursor( Qt::WaitCursor );
328   this->setEnabled( false );
329   std::string err = reader->Update( );
330   QApplication::restoreOverrideCursor( );
331   this->setEnabled( true );
332
333
334   // Assign fresh image, if any
335   if( err == "" )
336   {
337     this->m_InputMesh = reader->GetOutput< TPluginMesh >( 0 );
338     reader->DisconnectOutputs( );
339     if( this->m_InputMesh.IsNotNull( ) )
340     {
341       vtkActor* vtk_actor = this->m_InputMesh->GetVTKActor( );
342       if( vtk_actor != NULL )
343       {
344         this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
345         this->m_MPRObjects->Render( 4 );
346       }
347       else
348         QMessageBox::critical(
349           this,
350           tr( "Error message" ),
351           tr( "Read mesh does not have a valid vtkActor." )
352           );
353
354     } // fi
355   }
356   else
357     QMessageBox::critical(
358       this,
359       tr( "Error reading mesh" ),
360       tr( err.c_str( ) )
361       );
362 }
363
364 // -------------------------------------------------------------------------
365 void ImageMPR::
366 _triggered_actionImageToImage( )
367 {
368   if( this->m_InputImage.IsNull( ) )
369     return;
370
371   // Get filter name
372   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
373   if( action == NULL )
374     return;
375   std::string name = action->text( ).toStdString( );
376
377   // Configure filter
378   TPluginFilter::Pointer filter =
379     this->m_Plugins.CreateProcessObject( name );
380   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
381   if( !dlg_ok )
382     return;
383
384   // Execute filter
385   QApplication::setOverrideCursor( Qt::WaitCursor );
386   this->setEnabled( false );
387   filter->SetInput( 0, this->m_InputImage );
388   std::string err = filter->Update( );
389   QApplication::restoreOverrideCursor( );
390   this->setEnabled( true );
391
392   // Update image
393   if( err == "" )
394   {
395     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
396     result->DisconnectPipeline( );
397     this->m_InputImage = result;
398     if( this->m_InputImage.IsNotNull( ) )
399       this->m_MPRObjects->SetImage( this->m_InputImage->GetVTKImageData( ) );
400   }
401   else
402     QMessageBox::critical(
403       this,
404       tr( "Error executing filter" ),
405       tr( err.c_str( ) )
406       );
407 }
408
409 // -------------------------------------------------------------------------
410 void ImageMPR::
411 _triggered_actionImageToMesh( )
412 {
413   if( this->m_InputImage.IsNull( ) )
414     return;
415
416   // Get filter name
417   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
418   if( action == NULL )
419     return;
420   std::string name = action->text( ).toStdString( );
421
422   // Configure filter
423   TPluginFilter::Pointer filter =
424     this->m_Plugins.CreateProcessObject( name );
425   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
426   if( !dlg_ok )
427     return;
428
429   // Execute filter
430   QApplication::setOverrideCursor( Qt::WaitCursor );
431   this->setEnabled( false );
432   filter->SetInput( 0, this->m_InputImage );
433   std::string err = filter->Update( );
434   QApplication::restoreOverrideCursor( );
435   this->setEnabled( true );
436
437   // Update image
438   if( err == "" )
439   {
440     TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
441     result->DisconnectPipeline( );
442     this->m_InputMesh = result;
443     if( this->m_InputMesh.IsNotNull( ) )
444       this->m_MPRObjects->Get3DRenderer( )->AddActor(
445         this->m_InputMesh->GetVTKActor( )
446         );
447   }
448   else
449     QMessageBox::critical(
450       this,
451       tr( "Error executing filter" ),
452       tr( err.c_str( ) )
453       );
454 }
455
456 // eof - $RCSfile$