]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
7fffc2732df90c2864acef0691e53db90bc2e463
[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   vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
199   if( vtk_actor != NULL )
200   {
201     this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
202     this->m_MPRObjects->Render( 4 );
203
204   } // fi
205
206   TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
207
208   std::string err = "";
209   for( unsigned int i = 0; i < 3; ++i )
210   {
211     this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
212     this->m_Planes[ i ] = TPluginImplicitFunction::New( );
213     this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
214     this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
215     this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
216     std::string lerr = this->m_Cutters[ i ]->Update( );
217     if( lerr == "" )
218     {
219       vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
220       mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTKAlgorithm( ), actor );
221       if( i == 0 )
222         this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
223       else if( i == 1 )
224         this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
225       else if( i == 2 )
226         this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
227
228     } // fi
229     err += lerr;
230
231   } // rof
232   this->m_MPRObjects->RenderAll( );
233   return( err );
234 }
235
236 // -------------------------------------------------------------------------
237 void ImageMPR::
238 _triggered_actionOpenPlugins( )
239 {
240   // Show dialog and check if it was accepted
241   QFileDialog dialog( this );
242   dialog.setFileMode( QFileDialog::ExistingFile );
243   dialog.setDirectory( "." );
244   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
245   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
246   if( !( dialog.exec( ) ) )
247     return;
248   
249   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
250   if( !( _LoadPlugins( fname ) ) )
251     QMessageBox::critical(
252       this,
253       tr( "Ignoring plugin" ),
254       tr( fname.c_str( ) )
255       );
256 }
257
258 // -------------------------------------------------------------------------
259 void ImageMPR::
260 _triggered_actionOpenInputImage( )
261 {
262   // Read image
263   std::string err = this->_LoadImage( this->m_Image );
264   if( err == "" )
265   {
266     vtkImageData* vtk_id = this->m_Image->GetVTKImageData( );
267     if( vtk_id != NULL )
268     {
269       this->m_MPRObjects->SetImage( vtk_id );
270       this->m_MPRObjects->ActivateInteractors( );
271       this->m_MPRObjects->ResetCameras( );
272       this->m_MPRObjects->RenderAll( );
273     }
274     else
275       QMessageBox::critical(
276         this,
277         tr( "Error message" ),
278         tr( "Read image does not have a valid VTK converter." )
279         );
280   }
281   else
282     QMessageBox::critical(
283       this,
284       tr( "Error reading single image" ),
285       tr( err.c_str( ) )
286       );
287 }
288
289 // -------------------------------------------------------------------------
290 void ImageMPR::
291 _triggered_actionOpenSegmentation( )
292 {
293   if( this->m_Image.IsNull( ) )
294   {
295     QMessageBox::critical(
296       this,
297       tr( "Error message" ),
298       tr( "Before reading a segmentation, first load a raw image." )
299       );
300     return;
301
302   } // fi
303
304   // Read image
305   std::string err = this->_LoadImage( this->m_Segmentation );
306   if( err == "" )
307   {
308     vtkImageData* vtk_id = this->m_Segmentation->GetVTKImageData( );
309     if( vtk_id != NULL )
310     {
311       this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
312       this->m_MPRObjects->RenderAll( );
313     }
314     else
315       QMessageBox::critical(
316         this,
317         tr( "Error message" ),
318         tr( "Read image does not have a valid VTK converter." )
319         );
320   }
321   else
322     QMessageBox::critical(
323       this,
324       tr( "Error reading single image" ),
325       tr( err.c_str( ) )
326       );
327 }
328
329 // -------------------------------------------------------------------------
330 void ImageMPR::
331 _triggered_actionOpenInputPolyData( )
332 {
333   this->m_Mesh = NULL;
334
335   // Get a reader from plugins
336   TPluginFilter::Pointer reader =
337     this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
338
339   if( reader.IsNotNull( ) )
340   {
341     // Configure reader
342     if( reader->ExecConfigurationDialog( this ) )
343     {
344       // Execute and get error message, if any
345       QApplication::setOverrideCursor( Qt::WaitCursor );
346       this->setEnabled( false );
347       std::string err = reader->Update( );
348       QApplication::restoreOverrideCursor( );
349       this->setEnabled( true );
350
351       // Assign fresh mesh, if any
352       if( err == "" )
353       {
354         this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
355         reader->DisconnectOutputs( );
356         err = this->_ConfigureMeshActors( );
357         if( err != "" )
358           QMessageBox::critical(
359             this,
360             tr( "Error message" ),
361             tr( err.c_str( ) )
362             );
363       }
364       else
365         QMessageBox::critical(
366           this,
367           tr( "Error reading mesh" ),
368           tr( err.c_str( ) )
369           );
370
371     } // fi
372   }
373   else
374     QMessageBox::critical(
375       this,
376       tr( "Error reading single mesh" ),
377       tr( "No suitable mesh reader found in loaded plugins." )
378       );
379 }
380
381 // -------------------------------------------------------------------------
382 void ImageMPR::
383 _triggered_actionImageToImage( )
384 {
385   if( this->m_Image.IsNull( ) )
386     return;
387
388   // Get filter name
389   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
390   if( action == NULL )
391     return;
392   std::string name = action->text( ).toStdString( );
393
394   // Configure filter
395   TPluginFilter::Pointer filter =
396     this->m_Plugins.CreateProcessObject( name );
397   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
398   if( !dlg_ok )
399     return;
400
401   // Execute filter
402   QApplication::setOverrideCursor( Qt::WaitCursor );
403   this->setEnabled( false );
404   filter->SetInput( 0, this->m_Image );
405   std::string err = filter->Update( );
406   QApplication::restoreOverrideCursor( );
407   this->setEnabled( true );
408
409   // Update image
410   if( err == "" )
411   {
412     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
413     result->DisconnectPipeline( );
414     this->m_Image = result;
415     if( this->m_Image.IsNotNull( ) )
416       this->m_MPRObjects->SetImage( this->m_Image->GetVTKImageData( ) );
417   }
418   else
419     QMessageBox::critical(
420       this,
421       tr( "Error executing filter" ),
422       tr( err.c_str( ) )
423       );
424 }
425
426 // -------------------------------------------------------------------------
427 void ImageMPR::
428 _triggered_actionImageToMesh( )
429 {
430   if( this->m_Image.IsNull( ) )
431     return;
432
433   // Get filter name
434   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
435   if( action == NULL )
436     return;
437   std::string name = action->text( ).toStdString( );
438
439   // Configure filter
440   TPluginFilter::Pointer filter =
441     this->m_Plugins.CreateProcessObject( name );
442   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
443   if( !dlg_ok )
444     return;
445
446   // Execute filter
447   QApplication::setOverrideCursor( Qt::WaitCursor );
448   this->setEnabled( false );
449   filter->SetInput( 0, this->m_Image );
450   std::string err = filter->Update( );
451   QApplication::restoreOverrideCursor( );
452   this->setEnabled( true );
453
454   // Update image
455   if( err == "" )
456   {
457     TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
458     result->DisconnectPipeline( );
459     this->m_Mesh = result;
460     err = this->_ConfigureMeshActors( );
461     if( err != "" )
462       QMessageBox::critical(
463         this,
464         tr( "Error message" ),
465         tr( err.c_str( ) )
466         );
467   }
468   else
469     QMessageBox::critical(
470       this,
471       tr( "Error executing filter" ),
472       tr( err.c_str( ) )
473       );
474 }
475
476 // eof - $RCSfile$