]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
Parameters are now part of the pipeline update process
[cpPlugins.git] / appli / ImageMPR / ImageMPR.cxx
1 #include "ImageMPR.h"
2 #include "ui_ImageMPR.h"
3
4 // -------------------------------------------------------------------------
5 #define ImageMPR_ConnectAction( ACTION )                \
6   QObject::connect(                                     \
7     this->m_UI->a##ACTION, SIGNAL( triggered( ) ),      \
8     this, SLOT( _a##ACTION( ) )                         \
9     )
10
11 // -------------------------------------------------------------------------
12 ImageMPR::
13 ImageMPR( QWidget* parent )
14   : QMainWindow( parent ),
15     m_UI( new Ui::ImageMPR ),
16     m_ImageLoaded( false )
17 {
18   this->m_UI->setupUi( this );
19
20   // Connect actions
21   ImageMPR_ConnectAction( OpenImage );
22   ImageMPR_ConnectAction( OpenSegmentation );
23   ImageMPR_ConnectAction( OpenPolyData );
24   ImageMPR_ConnectAction( SaveImage );
25   ImageMPR_ConnectAction( SaveSegmentation );
26   ImageMPR_ConnectAction( SavePolyData );
27   ImageMPR_ConnectAction( Undo );
28   ImageMPR_ConnectAction( Redo );
29   ImageMPR_ConnectAction( LoadPlugins );
30   ImageMPR_ConnectAction( ShowPlugins );
31
32   // Try to load default plugins
33   this->m_UI->MPR->LoadPlugins( );
34   this->m_UI->MPR->AssociatePluginsToMenu(
35     this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
36     );
37 }
38
39 // -------------------------------------------------------------------------
40 ImageMPR::
41 ~ImageMPR( )
42 {
43   delete this->m_UI;
44 }
45
46 // -------------------------------------------------------------------------
47 void ImageMPR::
48 _aOpenImage( )
49 {
50   if( this->m_ImageLoaded )
51     this->m_UI->MPR->ClearAll( );
52   this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
53 }
54
55 // -------------------------------------------------------------------------
56 void ImageMPR::
57 _aOpenSegmentation( )
58 {
59   if( this->m_ImageLoaded )
60     this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
61 }
62
63 // -------------------------------------------------------------------------
64 void ImageMPR::
65 _aOpenPolyData( )
66 {
67 }
68
69 // -------------------------------------------------------------------------
70 void ImageMPR::
71 _aSaveImage( )
72 {
73 }
74
75 // -------------------------------------------------------------------------
76 void ImageMPR::
77 _aSaveSegmentation( )
78 {
79 }
80
81 // -------------------------------------------------------------------------
82 void ImageMPR::
83 _aSavePolyData( )
84 {
85 }
86
87 // -------------------------------------------------------------------------
88 void ImageMPR::
89 _aUndo( )
90 {
91 }
92
93 // -------------------------------------------------------------------------
94 void ImageMPR::
95 _aRedo( )
96 {
97 }
98
99 // -------------------------------------------------------------------------
100 void ImageMPR::
101 _aLoadPlugins( )
102 {
103   this->m_UI->MPR->DialogLoadPlugins( );
104   this->m_UI->MPR->AssociatePluginsToMenu(
105     this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
106     );
107 }
108
109 // -------------------------------------------------------------------------
110 void ImageMPR::
111 _aShowPlugins( )
112 {
113 }
114
115 // -------------------------------------------------------------------------
116 void ImageMPR::
117 _execPlugin( )
118 {
119   // Get filter name
120   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
121   if( action == NULL )
122     return;
123   std::string name = action->text( ).toStdString( );
124   this->m_UI->MPR->ExecuteFilter( name, 0 );
125
126   // Configure filter
127   /*
128     TPluginFilter::Pointer filter =
129     this->m_Plugins.CreateProcessObject( name );
130     bool dlg_ok = filter->ExecConfigurationDialog( NULL );
131     if( !dlg_ok )
132     return;
133
134     // Execute filter
135     QApplication::setOverrideCursor( Qt::WaitCursor );
136     this->setEnabled( false );
137     filter->SetInput( 0, this->m_Image );
138     std::string err = filter->Update( );
139     QApplication::restoreOverrideCursor( );
140     this->setEnabled( true );
141
142     // Update image
143     if( err == "" )
144     {
145     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
146     result->DisconnectPipeline( );
147     this->m_Image = result;
148     if( this->m_Image.IsNotNull( ) )
149     this->m_MPRObjects->SetImage(
150     this->m_Image->GetVTK< vtkImageData >( )
151     );
152     MementoState(this->m_state, this->m_Image);
153     this->m_state++;
154     if (this->m_state > this->m_max_state)
155     {
156     this->m_max_state = this->m_state;
157     }
158     }
159     else
160     QMessageBox::critical(
161     this,
162     tr( "Error executing filter" ),
163     tr( err.c_str( ) )
164     );
165   */
166 }
167
168 /*
169 #include "MementoState.h"
170
171 #include <vtkProperty.h>
172 #include <vtkRenderWindow.h>
173 #include <vtkMetaImageReader.h>
174
175 #include <QFileDialog>
176 #include <QMessageBox>
177
178 #ifdef _WIN32
179 #  define PLUGIN_PREFIX ""
180 #  define PLUGIN_EXT "dll"
181 #  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
182 #else
183 #  define PLUGIN_PREFIX "lib"
184 #  define PLUGIN_EXT "so"
185 #  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
186 #endif // _WIN32
187
188 // -------------------------------------------------------------------------
189 ImageMPR::ImageMPR( QWidget* parent )
190   : QMainWindow( parent ),
191     m_UI( new Ui::ImageMPR ),
192     m_ImageReaderClass( "" ),
193     m_ImageWriterClass( "" ),
194     m_MeshReaderClass( "" ),
195     m_MeshWriterClass( "" ),
196     m_MeshCutterClass( "" ),
197     m_Image( NULL ),
198         m_state(0),
199         m_max_state(0)
200 {
201   this->m_UI->setupUi( this );
202
203   // Create and associate renderers
204   this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
205   this->m_MPRObjects->SetRenderWindows(
206     this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
207     this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
208     this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
209     this->m_UI->m_3DVTK->GetRenderWindow( )
210     );
211
212   // signals <-> slots
213   QObject::connect(
214     this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
215     this, SLOT( _triggered_actionOpenPlugins( ) )
216     );
217   QObject::connect(
218     this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
219     this, SLOT( _triggered_actionOpenInputImage( ) )
220     );
221   QObject::connect(
222     this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
223     this, SLOT( _triggered_actionOpenSegmentation( ) )
224     );
225   QObject::connect(
226     this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
227     this, SLOT( _triggered_actionOpenInputPolyData( ) )
228     );
229   QObject::connect(
230         this->m_UI->actionUndo, SIGNAL(triggered()),
231         this, SLOT(_triggered_actionUndo())
232         );
233   QObject::connect(
234         this->m_UI->actionRedo, SIGNAL(triggered()),
235         this, SLOT(_triggered_actionRedo())
236         );
237
238   // Start: load all disponible plugins
239   this->_LoadPlugins(
240     std::string( PLUGIN_PREFIX ) +
241     std::string( "cpPluginsIO." ) +
242     std::string( PLUGIN_EXT )
243     );
244   this->_LoadPlugins(
245     std::string( PLUGIN_PREFIX ) +
246     std::string( "cpPluginsBasicFilters." ) +
247     std::string( PLUGIN_EXT )
248     );
249 }
250
251 // -------------------------------------------------------------------------
252 ImageMPR::
253 ~ImageMPR( )
254 {
255   // Close all connections
256   this->m_Plugins.UnloadAll( );
257
258   // Delete objects
259   delete this->m_UI;
260 }
261
262 // -------------------------------------------------------------------------
263 bool ImageMPR::
264 _LoadPlugins( const std::string& filename )
265 {
266   QApplication::setOverrideCursor( Qt::WaitCursor );
267   this->setEnabled( false );
268
269   this->m_ImageReaderClass = "";
270   this->m_ImageWriterClass = "";
271   this->m_MeshReaderClass = "";
272   this->m_MeshWriterClass = "";
273   this->m_MeshCutterClass = "";
274   this->m_UI->MenuImageToImage->clear( );
275   this->m_UI->MenuImageToMesh->clear( );
276
277   if( !( this->m_Plugins.Load( filename ) ) )
278     return( false );
279
280   typedef TPluginsInterface::TClasses _TClasses;
281   _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
282   for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
283   {
284     TPluginFilter::Pointer o =
285       this->m_Plugins.CreateProcessObject( cIt->first );
286     std::string name = o->GetClassName( );
287     std::string category = o->GetClassCategory( );
288     if( category == "ImageReader" )
289       this->m_ImageReaderClass = name;
290     else if( category == "ImageWriter" )
291       this->m_ImageWriterClass = name;
292     else if( category == "MeshReader" )
293       this->m_MeshReaderClass = name;
294     else if( category == "MeshWriter" )
295       this->m_MeshWriterClass = name;
296     else if( category == "MeshToMeshFilter" )
297     {
298       if( name.find_last_of( "Cutter" ) != std::string::npos )
299         this->m_MeshCutterClass = name;
300     }
301     else if( category == "ImageToImageFilter" )
302     {
303       QAction* action =
304         this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
305       QObject::connect(
306         action, SIGNAL( triggered( ) ),
307         this, SLOT( _triggered_actionImageToImage( ) )
308         );
309     }
310     else if( category == "ImageToMeshFilter" )
311     {
312       QAction* action =
313         this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
314       QObject::connect(
315         action, SIGNAL( triggered( ) ),
316         this, SLOT( _triggered_actionImageToMesh( ) )
317         );
318
319     } // fi
320
321   } // rof
322   QApplication::restoreOverrideCursor( );
323   this->setEnabled( true );
324
325   return( true );
326 }
327
328 // -------------------------------------------------------------------------
329 std::string ImageMPR::
330 _LoadImage( TPluginImage::Pointer& image )
331 {
332   std::string ret = "";
333   image = NULL;
334
335   // Get a reader from loaded plugins
336   TPluginFilter::Pointer reader =
337     this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
338   if( reader.IsNotNull( ) )
339   {
340     if( reader->ExecConfigurationDialog( this ) )
341     {
342       // Block application
343       QApplication::setOverrideCursor( Qt::WaitCursor );
344       this->setEnabled( false );
345
346       // Execute and get error message, if any
347       ret = reader->Update( );
348
349       // Assign fresh image, if any
350       if( ret == "" )
351       {
352         image = reader->GetOutput< TPluginImage >( 0 );
353         reader->DisconnectOutputs( );
354
355       } // fi
356
357       // Unblock application
358       QApplication::restoreOverrideCursor( );
359       this->setEnabled( true );
360
361     } // fi
362   }
363   else
364     ret = "No suitable reader object found in loaded plugins.";
365   
366   return( ret );
367 }
368
369 // -------------------------------------------------------------------------
370 std::string ImageMPR::
371 _ConfigureMeshActors( )
372 {
373   if( this->m_Mesh.IsNull( ) )
374     return( "Valid mesh not found." );
375
376   this->m_Mesh->CreateVTKActor( );
377   vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
378   if( vtk_actor != NULL )
379   {
380     this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
381     this->m_MPRObjects->Render( 4 );
382
383   } // fi
384
385   TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
386
387   std::string err = "";
388   for( unsigned int i = 0; i < 3; ++i )
389   {
390     this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
391     this->m_Planes[ i ] = TPluginImplicitFunction::New( );
392     this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
393     this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
394     this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
395     std::string lerr = this->m_Cutters[ i ]->Update( );
396     if( lerr == "" )
397     {
398       this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
399       vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
400       mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
401       if( i == 0 )
402         this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
403       else if( i == 1 )
404         this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
405       else if( i == 2 )
406         this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
407
408     } // fi
409     err += lerr;
410
411   } // rof
412   this->m_MPRObjects->RenderAll( );
413   return( err );
414 }
415
416 // -------------------------------------------------------------------------
417 void ImageMPR::
418 _triggered_actionOpenPlugins( )
419 {
420   // Show dialog and check if it was accepted
421   QFileDialog dialog( this );
422   dialog.setFileMode( QFileDialog::ExistingFile );
423   dialog.setDirectory( "." );
424   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
425   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
426   if( !( dialog.exec( ) ) )
427     return;
428   
429   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
430   if( !( _LoadPlugins( fname ) ) )
431     QMessageBox::critical(
432       this,
433       tr( "Ignoring plugin" ),
434       tr( fname.c_str( ) )
435       );
436 }
437
438 // -------------------------------------------------------------------------
439 void ImageMPR::
440 _triggered_actionOpenInputImage( )
441 {
442   // Read image
443   std::string err = this->_LoadImage( this->m_Image );
444   if( err == "" )
445   {
446     vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
447     if( vtk_id != NULL )
448     {
449       this->m_MPRObjects->SetImage( vtk_id );
450       this->m_MPRObjects->ActivateInteractors( );
451       this->m_MPRObjects->ResetCameras( );
452       this->m_MPRObjects->RenderAll( );
453
454           MementoState(m_state, this->m_Image);  
455           this->m_state++;
456     }
457     else
458       QMessageBox::critical(
459         this,
460         tr( "Error message" ),
461         tr( "Read image does not have a valid VTK converter." )
462         );
463   }
464   else
465     QMessageBox::critical(
466       this,
467       tr( "Error reading single image" ),
468       tr( err.c_str( ) )
469       );
470 }
471
472 // -------------------------------------------------------------------------
473 void ImageMPR::
474 _triggered_actionOpenSegmentation( )
475 {
476   if( this->m_Image.IsNull( ) )
477   {
478     QMessageBox::critical(
479       this,
480       tr( "Error message" ),
481       tr( "Before reading a segmentation, first load a raw image." )
482       );
483     return;
484
485   } // fi
486
487   // Read image
488   std::string err = this->_LoadImage( this->m_Segmentation );
489   if( err == "" )
490   {
491     vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
492     if( vtk_id != NULL )
493     {
494       this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
495       this->m_MPRObjects->RenderAll( );
496     }
497     else
498       QMessageBox::critical(
499         this,
500         tr( "Error message" ),
501         tr( "Read image does not have a valid VTK converter." )
502         );
503   }
504   else
505     QMessageBox::critical(
506       this,
507       tr( "Error reading single image" ),
508       tr( err.c_str( ) )
509       );
510 }
511
512 // -------------------------------------------------------------------------
513 void ImageMPR::
514 _triggered_actionOpenInputPolyData( )
515 {
516   this->m_Mesh = NULL;
517
518   // Get a reader from plugins
519   TPluginFilter::Pointer reader =
520     this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
521
522   if( reader.IsNotNull( ) )
523   {
524     // Configure reader
525     if( reader->ExecConfigurationDialog( this ) )
526     {
527       // Execute and get error message, if any
528       QApplication::setOverrideCursor( Qt::WaitCursor );
529       this->setEnabled( false );
530       std::string err = reader->Update( );
531       QApplication::restoreOverrideCursor( );
532       this->setEnabled( true );
533
534       // Assign fresh mesh, if any
535       if( err == "" )
536       {
537         this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
538         reader->DisconnectOutputs( );
539         err = this->_ConfigureMeshActors( );
540         if( err != "" )
541           QMessageBox::critical(
542             this,
543             tr( "Error message" ),
544             tr( err.c_str( ) )
545             );
546       }
547       else
548         QMessageBox::critical(
549           this,
550           tr( "Error reading mesh" ),
551           tr( err.c_str( ) )
552           );
553
554     } // fi
555   }
556   else
557     QMessageBox::critical(
558       this,
559       tr( "Error reading single mesh" ),
560       tr( "No suitable mesh reader found in loaded plugins." )
561       );
562 }
563
564 // -------------------------------------------------------------------------
565 void ImageMPR::
566 _triggered_actionImageToImage( )
567 {
568   if( this->m_Image.IsNull( ) )
569     return;
570
571   // Get filter name
572   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
573   if( action == NULL )
574     return;
575   std::string name = action->text( ).toStdString( );
576
577   // Configure filter
578   TPluginFilter::Pointer filter =
579     this->m_Plugins.CreateProcessObject( name );
580   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
581   if( !dlg_ok )
582     return;
583
584   // Execute filter
585   QApplication::setOverrideCursor( Qt::WaitCursor );
586   this->setEnabled( false );
587   filter->SetInput( 0, this->m_Image );
588   std::string err = filter->Update( );
589   QApplication::restoreOverrideCursor( );
590   this->setEnabled( true );
591
592   // Update image
593   if( err == "" )
594   {
595     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
596     result->DisconnectPipeline( );
597     this->m_Image = result;
598     if( this->m_Image.IsNotNull( ) )
599       this->m_MPRObjects->SetImage(
600         this->m_Image->GetVTK< vtkImageData >( )
601
602                 );
603         
604         
605         MementoState(this->m_state, this->m_Image);
606         this->m_state++;
607         if (this->m_state > this->m_max_state)
608         {
609                 this->m_max_state = this->m_state;
610         }
611   }
612   else
613     QMessageBox::critical(
614       this,
615       tr( "Error executing filter" ),
616       tr( err.c_str( ) )
617       );
618 }
619
620 // -------------------------------------------------------------------------
621 void ImageMPR::
622 _triggered_actionImageToMesh( )
623 {
624   if( this->m_Image.IsNull( ) )
625     return;
626
627   // Get filter name
628   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
629   if( action == NULL )
630     return;
631   std::string name = action->text( ).toStdString( );
632
633   // Configure filter
634   TPluginFilter::Pointer filter =
635     this->m_Plugins.CreateProcessObject( name );
636   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
637   if( !dlg_ok )
638     return;
639
640   // Execute filter
641   QApplication::setOverrideCursor( Qt::WaitCursor );
642   this->setEnabled( false );
643   filter->SetInput( 0, this->m_Image );
644   std::string err = filter->Update( );
645   QApplication::restoreOverrideCursor( );
646   this->setEnabled( true );
647
648   // Update image
649   if( err == "" )
650   {
651     TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
652     result->DisconnectPipeline( );
653     this->m_Mesh = result;
654     err = this->_ConfigureMeshActors( );
655     if( err != "" )
656       QMessageBox::critical(
657         this,
658         tr( "Error message" ),
659         tr( err.c_str( ) )
660         );
661   }
662   else
663     QMessageBox::critical(
664       this,
665       tr( "Error executing filter" ),
666       tr( err.c_str( ) )
667       );
668 }
669
670 // -------------------------------------------------------------------------
671 void ImageMPR::
672 _triggered_actionUndo()
673 {
674         MementoState memento = MementoState();
675     
676         if (this->m_state>1)
677         {
678                 this->m_state--;
679                 this->m_MPRObjects->SetImage(
680                         memento.getMemento(this->m_state)->GetOutput()
681                         );
682         } else
683         {
684                 QMessageBox::warning(
685                         this,
686                         tr("message"),
687                         tr("No history to undo")
688                         );
689         }
690
691 }
692
693 // -------------------------------------------------------------------------
694 void ImageMPR::
695 _triggered_actionRedo()
696 {
697         MementoState memento = MementoState();
698                 if (this->m_state + 1 <= m_max_state)
699                 {
700                         this->m_state++;
701                         this->m_MPRObjects->SetImage(
702                                 memento.getMemento(this->m_state)->GetOutput()
703                                 );
704                 } else
705                 {
706                         QMessageBox::warning(
707                                 this,
708                                 tr("message"),
709                                 tr("No history to redo")
710                                 );
711                 }
712         
713 }
714         
715 */
716
717 // eof - $RCSfile$