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