]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
6cc4ed1ccb1c85980acd0f4757286b16fec94a34
[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 )
139 {
140   std::string ret = "";
141   image = NULL;
142
143   // Get a reader from loaded plugins
144   TPluginFilter::Pointer reader =
145     this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
146   if( reader.IsNotNull( ) )
147   {
148     if( reader->ExecConfigurationDialog( this ) )
149     {
150       // Block application
151       QApplication::setOverrideCursor( Qt::WaitCursor );
152       this->setEnabled( false );
153
154       // Execute and get error message, if any
155       ret = reader->Update( );
156
157       // Assign fresh image, if any
158       if( ret == "" )
159       {
160         image = reader->GetOutput< TPluginImage >( 0 );
161         reader->DisconnectOutputs( );
162
163       } // fi
164
165       // Unblock application
166       QApplication::restoreOverrideCursor( );
167       this->setEnabled( true );
168
169     } // fi
170   }
171   else
172     ret = "No suitable reader object found in loaded plugins.";
173   
174   return( ret );
175 }
176
177 // -------------------------------------------------------------------------
178 void ImageMPR::
179 _triggered_actionOpenPlugins( )
180 {
181   // Show dialog and check if it was accepted
182   QFileDialog dialog( this );
183   dialog.setFileMode( QFileDialog::ExistingFile );
184   dialog.setDirectory( "." );
185   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
186   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
187   if( !( dialog.exec( ) ) )
188     return;
189   
190   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
191   if( !( _LoadPlugins( fname ) ) )
192     QMessageBox::critical(
193       this,
194       tr( "Ignoring plugin" ),
195       tr( fname.c_str( ) )
196       );
197 }
198
199 // -------------------------------------------------------------------------
200 void ImageMPR::
201 _triggered_actionOpenInputImage( )
202 {
203   // Read image
204   std::string err = this->_LoadImage( this->m_InputImage );
205   if( err == "" )
206   {
207     vtkImageData* vtk_id = this->m_InputImage->GetVTKImageData( );
208     if( vtk_id != NULL )
209     {
210       this->m_MPRObjects->SetImage( vtk_id );
211       this->m_MPRObjects->ActivateInteractors( );
212       this->m_MPRObjects->ResetCameras( );
213       this->m_MPRObjects->RenderAll( );
214     }
215     else
216       QMessageBox::critical(
217         this,
218         tr( "Error message" ),
219         tr( "Read image does not have a valid VTK converter." )
220         );
221   }
222   else
223     QMessageBox::critical(
224       this,
225       tr( "Error reading single image" ),
226       tr( err.c_str( ) )
227       );
228 }
229
230 // -------------------------------------------------------------------------
231 void ImageMPR::
232 _triggered_actionOpenSegmentation( )
233 {
234   if( this->m_InputImage.IsNull( ) )
235   {
236     QMessageBox::critical(
237       this,
238       tr( "Error message" ),
239       tr( "Before reading a segmentation, first load a raw image." )
240       );
241     return;
242
243   } // fi
244
245   // Read image
246   std::string err = this->_LoadImage( this->m_InputSegmentation );
247   if( err == "" )
248   {
249     vtkImageData* vtk_id = this->m_InputSegmentation->GetVTKImageData( );
250     if( vtk_id != NULL )
251     {
252       this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
253       this->m_MPRObjects->RenderAll( );
254     }
255     else
256       QMessageBox::critical(
257         this,
258         tr( "Error message" ),
259         tr( "Read image does not have a valid VTK converter." )
260         );
261   }
262   else
263     QMessageBox::critical(
264       this,
265       tr( "Error reading single image" ),
266       tr( err.c_str( ) )
267       );
268 }
269
270 // -------------------------------------------------------------------------
271 void ImageMPR::
272 _triggered_actionOpenInputPolyData( )
273 {
274   this->m_InputMesh = NULL;
275
276   // Get a reader from plugins
277   TPluginFilter::Pointer reader =
278     this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
279
280   if( reader.IsNotNull( ) )
281   {
282     // Configure reader
283     if( reader->ExecConfigurationDialog( this ) )
284     {
285       // Execute and get error message, if any
286       QApplication::setOverrideCursor( Qt::WaitCursor );
287       this->setEnabled( false );
288       std::string err = reader->Update( );
289       QApplication::restoreOverrideCursor( );
290       this->setEnabled( true );
291
292       // Assign fresh mesh, if any
293       if( err == "" )
294       {
295         this->m_InputMesh = reader->GetOutput< TPluginMesh >( 0 );
296         reader->DisconnectOutputs( );
297         if( this->m_InputMesh.IsNotNull( ) )
298         {
299           vtkActor* vtk_actor = this->m_InputMesh->GetVTKActor( );
300           if( vtk_actor != NULL )
301           {
302             this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
303             this->m_MPRObjects->Render( 4 );
304           }
305           else
306             QMessageBox::critical(
307               this,
308               tr( "Error message" ),
309               tr( "Read mesh does not have a valid vtkActor." )
310               );
311
312         } // fi
313       }
314       else
315         QMessageBox::critical(
316           this,
317           tr( "Error reading mesh" ),
318           tr( err.c_str( ) )
319           );
320
321     } // fi
322   }
323   else
324     QMessageBox::critical(
325       this,
326       tr( "Error reading single mesh" ),
327       tr( "No suitable mesh reader found in loaded plugins." )
328       );
329 }
330
331 // -------------------------------------------------------------------------
332 void ImageMPR::
333 _triggered_actionImageToImage( )
334 {
335   if( this->m_InputImage.IsNull( ) )
336     return;
337
338   // Get filter name
339   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
340   if( action == NULL )
341     return;
342   std::string name = action->text( ).toStdString( );
343
344   // Configure filter
345   TPluginFilter::Pointer filter =
346     this->m_Plugins.CreateProcessObject( name );
347   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
348   if( !dlg_ok )
349     return;
350
351   // Execute filter
352   QApplication::setOverrideCursor( Qt::WaitCursor );
353   this->setEnabled( false );
354   filter->SetInput( 0, this->m_InputImage );
355   std::string err = filter->Update( );
356   QApplication::restoreOverrideCursor( );
357   this->setEnabled( true );
358
359   // Update image
360   if( err == "" )
361   {
362     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
363     result->DisconnectPipeline( );
364     this->m_InputImage = result;
365     if( this->m_InputImage.IsNotNull( ) )
366       this->m_MPRObjects->SetImage( this->m_InputImage->GetVTKImageData( ) );
367   }
368   else
369     QMessageBox::critical(
370       this,
371       tr( "Error executing filter" ),
372       tr( err.c_str( ) )
373       );
374 }
375
376 // -------------------------------------------------------------------------
377 void ImageMPR::
378 _triggered_actionImageToMesh( )
379 {
380   if( this->m_InputImage.IsNull( ) )
381     return;
382
383   // Get filter name
384   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
385   if( action == NULL )
386     return;
387   std::string name = action->text( ).toStdString( );
388
389   // Configure filter
390   TPluginFilter::Pointer filter =
391     this->m_Plugins.CreateProcessObject( name );
392   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
393   if( !dlg_ok )
394     return;
395
396   // Execute filter
397   QApplication::setOverrideCursor( Qt::WaitCursor );
398   this->setEnabled( false );
399   filter->SetInput( 0, this->m_InputImage );
400   std::string err = filter->Update( );
401   QApplication::restoreOverrideCursor( );
402   this->setEnabled( true );
403
404   // Update image
405   if( err == "" )
406   {
407     TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
408     result->DisconnectPipeline( );
409     this->m_InputMesh = result;
410     if( this->m_InputMesh.IsNotNull( ) )
411       this->m_MPRObjects->Get3DRenderer( )->AddActor(
412         this->m_InputMesh->GetVTKActor( )
413         );
414   }
415   else
416     QMessageBox::critical(
417       this,
418       tr( "Error executing filter" ),
419       tr( err.c_str( ) )
420       );
421 }
422
423 // eof - $RCSfile$