]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
Merge branch 'master' of ssh://git.creatis.insa-lyon.fr/cpPlugins
[cpPlugins.git] / appli / ImageMPR / ImageMPR.cxx
1 #include "ImageMPR.h"
2 #include "ui_ImageMPR.h"
3
4 #include <QMessageBox>
5
6 // -------------------------------------------------------------------------
7 #define ImageMPR_ConnectAction( ACTION )                \
8   QObject::connect(                                     \
9     this->m_UI->a##ACTION, SIGNAL( triggered( ) ),      \
10     this, SLOT( _a##ACTION( ) )                         \
11     )
12
13 // -------------------------------------------------------------------------
14 ImageMPR::
15 ImageMPR( QWidget* parent )
16   : QMainWindow( parent ),
17     m_UI( new Ui::ImageMPR ),
18     m_Plugins( new TPlugins )
19 {
20   this->m_UI->setupUi( this );
21   this->m_Plugins->SetWidget( this );
22
23   // Connect actions
24   ImageMPR_ConnectAction( OpenImage );
25   ImageMPR_ConnectAction( OpenDICOMSeries );
26   ImageMPR_ConnectAction( OpenSegmentation );
27   ImageMPR_ConnectAction( OpenPolyData );
28   ImageMPR_ConnectAction( SaveImage );
29   ImageMPR_ConnectAction( SaveSegmentation );
30   ImageMPR_ConnectAction( SavePolyData );
31   ImageMPR_ConnectAction( Undo );
32   ImageMPR_ConnectAction( Redo );
33   ImageMPR_ConnectAction( LoadPlugins );
34   ImageMPR_ConnectAction( ShowPlugins );
35
36   // Try to load default plugins    
37 #ifdef WIN32
38   this->m_Plugins->LoadPlugins("cpPluginsIO.dll");
39   this->m_Plugins->LoadPlugins("cpPluginsBasicFilters.dll");
40 #else
41   this->m_Plugins->LoadPluginsConfigurationFile("Plugins.cfg");
42 #endif
43   this->m_Plugins->AssociatePluginsToMenu(
44     this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
45     );
46 }
47
48 // -------------------------------------------------------------------------
49 ImageMPR::
50 ~ImageMPR( )
51 {
52   delete this->m_UI;
53   delete this->m_Plugins;
54 }
55
56 // -------------------------------------------------------------------------
57 void ImageMPR::
58 _aOpenImage( )
59 {
60   // Clear all, since we are loading the main image
61   if( this->m_Objects.size( ) > 0 )
62   {
63     this->m_UI->MPR->ClearAll( );
64     this->m_Objects.clear( );
65
66   } // fi
67
68   // Read and show image, if possible
69   TPlugins::TImage::Pointer image;
70   if( this->m_Plugins->ReadImage( image, true ) )
71   {
72     vtkImageData* vimage = image->GetVTK< vtkImageData >( );
73     if( vimage == NULL )
74       QMessageBox::critical(
75         this,
76         QMessageBox::tr( "Error showing image." ),
77         QMessageBox::tr(
78           "Image was read, but no valid VTK conversion was found."
79           )
80         );
81     else
82       this->m_UI->MPR->ShowImage( vimage, image->GetName( ) );
83
84     // Keep a track on a local data tree
85     this->m_Objects[ image->GetName( ) ] =
86       TTreeNode( "", image.GetPointer( ) );
87
88   } // fi
89 }
90
91 // -------------------------------------------------------------------------
92 void ImageMPR::
93 _aOpenDICOMSeries( )
94 {
95   // Clear all, since we are loading the main image
96   if( this->m_Objects.size( ) > 0 )
97   {
98     this->m_UI->MPR->ClearAll( );
99     this->m_Objects.clear( );
100
101   } // fi
102
103   // Read and show image, if possible
104   TPlugins::TImage::Pointer image;
105   if( this->m_Plugins->ReadDicomSeries( image ) )
106   {
107     vtkImageData* vimage = image->GetVTK< vtkImageData >( );
108     if( vimage == NULL )
109       QMessageBox::critical(
110         this,
111         QMessageBox::tr( "Error showing image." ),
112         QMessageBox::tr(
113           "Image was read, but no valid VTK conversion was found."
114           )
115         );
116     else
117       this->m_UI->MPR->ShowImage( vimage, image->GetName( ) );
118
119     // Keep a track on a local data tree
120     this->m_Objects[ image->GetName( ) ] =
121       TTreeNode( "", image.GetPointer( ) );
122
123   } // fi
124 }
125
126 // -------------------------------------------------------------------------
127 void ImageMPR::
128 _aOpenSegmentation( )
129 {
130   /*
131     if( this->m_ImageLoaded != "" )
132     this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
133   */
134 }
135
136 // -------------------------------------------------------------------------
137 void ImageMPR::
138 _aOpenPolyData( )
139 {
140 }
141
142 // -------------------------------------------------------------------------
143 void ImageMPR::
144 _aSaveImage( )
145 {
146   std::string data_name = this->m_UI->MPR->GetSelectedData( );
147   TPlugins::TImage* image = dynamic_cast< TPlugins::TImage* >(
148     this->m_Objects[ data_name ].second.GetPointer( )
149     );
150   if( image == NULL )
151     return;
152   this->m_Plugins->WriteImage( image, true );
153 }
154
155 // -------------------------------------------------------------------------
156 void ImageMPR::
157 _aSaveSegmentation( )
158 {
159 }
160
161 // -------------------------------------------------------------------------
162 void ImageMPR::
163 _aSavePolyData( )
164 {
165   std::string data_name = this->m_UI->MPR->GetSelectedData( );
166   TPlugins::TMesh* mesh = dynamic_cast< TPlugins::TMesh* >(
167     this->m_Objects[ data_name ].second.GetPointer( )
168     );
169   if( mesh == NULL )
170     return;
171   this->m_Plugins->WriteMesh( mesh, true );
172 }
173
174 // -------------------------------------------------------------------------
175 void ImageMPR::
176 _aUndo( )
177 {
178 }
179
180 // -------------------------------------------------------------------------
181 void ImageMPR::
182 _aRedo( )
183 {
184 }
185
186 // -------------------------------------------------------------------------
187 void ImageMPR::
188 _aLoadPlugins( )
189 {
190   this->m_Plugins->DialogLoadPlugins( );
191   this->m_Plugins->AssociatePluginsToMenu(
192     this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
193     );
194 }
195
196 // -------------------------------------------------------------------------
197 void ImageMPR::
198 _aShowPlugins( )
199 {
200 }
201
202 // -------------------------------------------------------------------------
203 void ImageMPR::
204 _execPlugin( )
205 {
206   // Get filter name
207   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
208   if( action == NULL )
209     return;
210   QMenu* menu = dynamic_cast< QMenu* >( action->parentWidget( ) );
211   if( menu == NULL )
212     return;
213   std::string filter_cate = menu->title( ).toStdString( );
214   std::string filter_name = action->text( ).toStdString( );
215
216   // Create filter
217   TPlugins::TProcessObject::Pointer filter;
218   if( !( this->m_Plugins->CreateFilter( filter, filter_name ) ) )
219   {
220     QMessageBox::critical(
221       this,
222       tr( "Error creating filter" ),
223       tr( (
224             std::string( "No valid filter \"" ) +
225             filter_name +
226             std::string( "\"defined." )
227             ).c_str( ) )
228       );
229     return;
230
231   } // fi
232
233   // Configure filter
234   if( !( filter->ExecConfigurationDialog( this ) ) )
235     return;
236
237   // Assign inputs
238   std::string data_name = this->m_UI->MPR->GetSelectedData( );
239   std::vector< std::string > inputs_names = filter->GetInputsNames( );
240   if( inputs_names.size( ) == 1 )
241   {
242     TTree::iterator iIt = this->m_Objects.find( data_name );
243     if( iIt == this->m_Objects.end( ) )
244     {
245       QMessageBox::critical(
246         this,
247         tr( "Error configuring filter" ),
248         tr( "No valid input found. Please select a valid input." )
249         );
250       return;
251
252     } //fi
253     filter->SetInput( inputs_names[ 0 ], iIt->second.second );
254   }
255   else if( inputs_names.size( ) > 1 )
256   {
257     QMessageBox::critical(
258       this,
259       tr( "Error executing" ),
260       tr( "Filter has multiple inputs: NOT YET IMPLEMENTED!!!" )
261       );
262     return;
263
264   } // fi
265
266   // Execute filter
267   this->_Block( );
268   std::string filter_err = filter->Update( );
269   this->_Unblock( );
270   if( filter_err != "" )
271   {
272     QMessageBox::critical(
273       this,
274       tr( "Error executing" ),
275       tr( filter_err.c_str( ) )
276       );
277     return;
278
279   } // fi
280
281   // Get outputs
282   std::vector< std::string > outputs_names = filter->GetOutputsNames( );
283   for(
284     auto oIt = outputs_names.begin( );
285     oIt != outputs_names.end( );
286     ++oIt
287     )
288   {
289     std::string out_name = filter_name + "_" + *oIt;
290
291     TPlugins::TImage* image = filter->GetOutput< TPlugins::TImage >( *oIt );
292     if( image != NULL )
293     {
294       if( filter_cate == "ImageToBinaryImageFilter" )
295       {
296         this->m_UI->MPR->ShowImage(
297           image->GetVTK< vtkImageData >( ),
298           out_name,
299           data_name, 1, 0, 0
300           );
301       }
302       else if( filter_cate == "ImageToImageFilter" )
303       {
304       } // fi
305
306       // Keep a track on a local data tree and go to next output
307       this->m_Objects[ out_name ] = TTreeNode( data_name, image );
308       continue;
309
310     } // fi
311
312     TPlugins::TMesh* mesh = filter->GetOutput< TPlugins::TMesh >( *oIt );
313     if( mesh != NULL )
314     {
315       // Show mesh
316       this->_Block( );
317       this->m_UI->MPR->ShowMesh(
318         mesh->GetVTK< vtkPolyData >( ),
319         out_name,
320         data_name
321         );
322       this->_Unblock( );
323
324       // Keep a track on a local data tree and go to next output
325       this->m_Objects[ out_name ] = TTreeNode( data_name, mesh );
326       continue;
327
328     } // fi
329
330   } // rof
331 }
332
333 // -------------------------------------------------------------------------
334 /* TODO
335    void ImageMPR::
336    _CursorCommand( double* pos, int axis, void* data )
337    {
338    Self* app = reinterpret_cast< Self* >( data );
339    if( app == NULL )
340    return;
341    if( !( app->m_Flooding ) )
342    return;
343
344    cpPlugins::Interface::ProcessObject::Pointer filter =
345    app->m_UI->MPR->CreateFilter(
346    "cpPlugins::BasicFilters::FloodFillImageFilter"
347    );
348    if( filter.IsNull( ) )
349    return;
350
351    cpPlugins::Interface::Parameters* params = filter->GetParameters( );
352    params->SetPoint( "Seed", 3, pos );
353    params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) );
354    params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) );
355    params->SetUint( "InsideValue", 1 );
356    params->SetUint( "OutsideValue", 0 );
357    filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) );
358    app->m_UI->MPR->Block( );
359    std::string err = filter->Update( );
360    cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" );
361    filter->DisconnectOutputs( );
362    app->m_UI->MPR->AddImage( "Segmentation", image );
363    app->m_UI->MPR->Unblock( );
364
365    std::cout
366    << "CursorCommand ==> "
367    << pos[ 0 ] << " "
368    << pos[ 1 ] << " "
369    << pos[ 2 ] << " : "
370    << axis << " "
371    << data << std::endl;
372    }
373 */
374
375 /*
376 #include "MementoState.h"
377
378 #include <vtkProperty.h>
379 #include <vtkRenderWindow.h>
380 #include <vtkMetaImageReader.h>
381
382 #include <QFileDialog>
383 #include <QMessageBox>
384
385 #ifdef _WIN32
386 #  define PLUGIN_PREFIX ""
387 #  define PLUGIN_EXT "dll"
388 #  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
389 #else
390 #  define PLUGIN_PREFIX "lib"
391 #  define PLUGIN_EXT "so"
392 #  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
393 #endif // _WIN32
394
395 // -------------------------------------------------------------------------
396 ImageMPR::ImageMPR( QWidget* parent )
397   : QMainWindow( parent ),
398     m_UI( new Ui::ImageMPR ),
399     m_ImageReaderClass( "" ),
400     m_ImageWriterClass( "" ),
401     m_MeshReaderClass( "" ),
402     m_MeshWriterClass( "" ),
403     m_MeshCutterClass( "" ),
404     m_Image( NULL ),
405         m_state(0),
406         m_max_state(0)
407 {
408   this->m_UI->setupUi( this );
409
410   // Create and associate renderers
411   this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
412   this->m_MPRObjects->SetRenderWindows(
413     this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
414     this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
415     this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
416     this->m_UI->m_3DVTK->GetRenderWindow( )
417     );
418
419   // signals <-> slots
420   QObject::connect(
421     this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
422     this, SLOT( _triggered_actionOpenPlugins( ) )
423     );
424   QObject::connect(
425     this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
426     this, SLOT( _triggered_actionOpenInputImage( ) )
427     );
428   QObject::connect(
429     this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
430     this, SLOT( _triggered_actionOpenSegmentation( ) )
431     );
432   QObject::connect(
433     this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
434     this, SLOT( _triggered_actionOpenInputPolyData( ) )
435     );
436   QObject::connect(
437         this->m_UI->actionUndo, SIGNAL(triggered()),
438         this, SLOT(_triggered_actionUndo())
439         );
440   QObject::connect(
441         this->m_UI->actionRedo, SIGNAL(triggered()),
442         this, SLOT(_triggered_actionRedo())
443         );
444
445   // Start: load all disponible plugins
446   this->_LoadPlugins(
447     std::string( PLUGIN_PREFIX ) +
448     std::string( "cpPluginsIO." ) +
449     std::string( PLUGIN_EXT )
450     );
451   this->_LoadPlugins(
452     std::string( PLUGIN_PREFIX ) +
453     std::string( "cpPluginsBasicFilters." ) +
454     std::string( PLUGIN_EXT )
455     );
456 }
457
458 // -------------------------------------------------------------------------
459 ImageMPR::
460 ~ImageMPR( )
461 {
462   // Close all connections
463   this->m_Plugins.UnloadAll( );
464
465   // Delete objects
466   delete this->m_UI;
467 }
468
469 // -------------------------------------------------------------------------
470 bool ImageMPR::
471 _LoadPlugins( const std::string& filename )
472 {
473   QApplication::setOverrideCursor( Qt::WaitCursor );
474   this->setEnabled( false );
475
476   this->m_ImageReaderClass = "";
477   this->m_ImageWriterClass = "";
478   this->m_MeshReaderClass = "";
479   this->m_MeshWriterClass = "";
480   this->m_MeshCutterClass = "";
481   this->m_UI->MenuImageToImage->clear( );
482   this->m_UI->MenuImageToMesh->clear( );
483
484   if( !( this->m_Plugins.Load( filename ) ) )
485     return( false );
486
487   typedef TPluginsInterface::TClasses _TClasses;
488   _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
489   for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
490   {
491     TPluginFilter::Pointer o =
492       this->m_Plugins.CreateProcessObject( cIt->first );
493     std::string name = o->GetClassName( );
494     std::string category = o->GetClassCategory( );
495     if( category == "ImageReader" )
496       this->m_ImageReaderClass = name;
497     else if( category == "ImageWriter" )
498       this->m_ImageWriterClass = name;
499     else if( category == "MeshReader" )
500       this->m_MeshReaderClass = name;
501     else if( category == "MeshWriter" )
502       this->m_MeshWriterClass = name;
503     else if( category == "MeshToMeshFilter" )
504     {
505       if( name.find_last_of( "Cutter" ) != std::string::npos )
506         this->m_MeshCutterClass = name;
507     }
508     else if( category == "ImageToImageFilter" )
509     {
510       QAction* action =
511         this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
512       QObject::connect(
513         action, SIGNAL( triggered( ) ),
514         this, SLOT( _triggered_actionImageToImage( ) )
515         );
516     }
517     else if( category == "ImageToMeshFilter" )
518     {
519       QAction* action =
520         this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
521       QObject::connect(
522         action, SIGNAL( triggered( ) ),
523         this, SLOT( _triggered_actionImageToMesh( ) )
524         );
525
526     } // fi
527
528   } // rof
529   QApplication::restoreOverrideCursor( );
530   this->setEnabled( true );
531
532   return( true );
533 }
534
535 // -------------------------------------------------------------------------
536 std::string ImageMPR::
537 _LoadImage( TPluginImage::Pointer& image )
538 {
539   std::string ret = "";
540   image = NULL;
541
542   // Get a reader from loaded plugins
543   TPluginFilter::Pointer reader =
544     this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
545   if( reader.IsNotNull( ) )
546   {
547     if( reader->ExecConfigurationDialog( this ) )
548     {
549       // Block application
550       QApplication::setOverrideCursor( Qt::WaitCursor );
551       this->setEnabled( false );
552
553       // Execute and get error message, if any
554       ret = reader->Update( );
555
556       // Assign fresh image, if any
557       if( ret == "" )
558       {
559         image = reader->GetOutput< TPluginImage >( 0 );
560         reader->DisconnectOutputs( );
561
562       } // fi
563
564       // Unblock application
565       QApplication::restoreOverrideCursor( );
566       this->setEnabled( true );
567
568     } // fi
569   }
570   else
571     ret = "No suitable reader object found in loaded plugins.";
572   
573   return( ret );
574 }
575
576 // -------------------------------------------------------------------------
577 std::string ImageMPR::
578 _ConfigureMeshActors( )
579 {
580   if( this->m_Mesh.IsNull( ) )
581     return( "Valid mesh not found." );
582
583   this->m_Mesh->CreateVTKActor( );
584   vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
585   if( vtk_actor != NULL )
586   {
587     this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
588     this->m_MPRObjects->Render( 4 );
589
590   } // fi
591
592   TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
593
594   std::string err = "";
595   for( unsigned int i = 0; i < 3; ++i )
596   {
597     this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
598     this->m_Planes[ i ] = TPluginImplicitFunction::New( );
599     this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
600     this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
601     this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
602     std::string lerr = this->m_Cutters[ i ]->Update( );
603     if( lerr == "" )
604     {
605       this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
606       vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
607       mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
608       if( i == 0 )
609         this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
610       else if( i == 1 )
611         this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
612       else if( i == 2 )
613         this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
614
615     } // fi
616     err += lerr;
617
618   } // rof
619   this->m_MPRObjects->RenderAll( );
620   return( err );
621 }
622
623 // -------------------------------------------------------------------------
624 void ImageMPR::
625 _triggered_actionOpenPlugins( )
626 {
627   // Show dialog and check if it was accepted
628   QFileDialog dialog( this );
629   dialog.setFileMode( QFileDialog::ExistingFile );
630   dialog.setDirectory( "." );
631   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
632   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
633   if( !( dialog.exec( ) ) )
634     return;
635   
636   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
637   if( !( _LoadPlugins( fname ) ) )
638     QMessageBox::critical(
639       this,
640       tr( "Ignoring plugin" ),
641       tr( fname.c_str( ) )
642       );
643 }
644
645 // -------------------------------------------------------------------------
646 void ImageMPR::
647 _triggered_actionOpenInputImage( )
648 {
649   // Read image
650   std::string err = this->_LoadImage( this->m_Image );
651   if( err == "" )
652   {
653     vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
654     if( vtk_id != NULL )
655     {
656       this->m_MPRObjects->SetImage( vtk_id );
657       this->m_MPRObjects->ActivateInteractors( );
658       this->m_MPRObjects->ResetCameras( );
659       this->m_MPRObjects->RenderAll( );
660
661           MementoState(m_state, this->m_Image);  
662           this->m_state++;
663     }
664     else
665       QMessageBox::critical(
666         this,
667         tr( "Error message" ),
668         tr( "Read image does not have a valid VTK converter." )
669         );
670   }
671   else
672     QMessageBox::critical(
673       this,
674       tr( "Error reading single image" ),
675       tr( err.c_str( ) )
676       );
677 }
678
679 // -------------------------------------------------------------------------
680 void ImageMPR::
681 _triggered_actionOpenSegmentation( )
682 {
683   if( this->m_Image.IsNull( ) )
684   {
685     QMessageBox::critical(
686       this,
687       tr( "Error message" ),
688       tr( "Before reading a segmentation, first load a raw image." )
689       );
690     return;
691
692   } // fi
693
694   // Read image
695   std::string err = this->_LoadImage( this->m_Segmentation );
696   if( err == "" )
697   {
698     vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
699     if( vtk_id != NULL )
700     {
701       this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
702       this->m_MPRObjects->RenderAll( );
703     }
704     else
705       QMessageBox::critical(
706         this,
707         tr( "Error message" ),
708         tr( "Read image does not have a valid VTK converter." )
709         );
710   }
711   else
712     QMessageBox::critical(
713       this,
714       tr( "Error reading single image" ),
715       tr( err.c_str( ) )
716       );
717 }
718
719 // -------------------------------------------------------------------------
720 void ImageMPR::
721 _triggered_actionOpenInputPolyData( )
722 {
723   this->m_Mesh = NULL;
724
725   // Get a reader from plugins
726   TPluginFilter::Pointer reader =
727     this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
728
729   if( reader.IsNotNull( ) )
730   {
731     // Configure reader
732     if( reader->ExecConfigurationDialog( this ) )
733     {
734       // Execute and get error message, if any
735       QApplication::setOverrideCursor( Qt::WaitCursor );
736       this->setEnabled( false );
737       std::string err = reader->Update( );
738       QApplication::restoreOverrideCursor( );
739       this->setEnabled( true );
740
741       // Assign fresh mesh, if any
742       if( err == "" )
743       {
744         this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
745         reader->DisconnectOutputs( );
746         err = this->_ConfigureMeshActors( );
747         if( err != "" )
748           QMessageBox::critical(
749             this,
750             tr( "Error message" ),
751             tr( err.c_str( ) )
752             );
753       }
754       else
755         QMessageBox::critical(
756           this,
757           tr( "Error reading mesh" ),
758           tr( err.c_str( ) )
759           );
760
761     } // fi
762   }
763   else
764     QMessageBox::critical(
765       this,
766       tr( "Error reading single mesh" ),
767       tr( "No suitable mesh reader found in loaded plugins." )
768       );
769 }
770
771 // -------------------------------------------------------------------------
772 void ImageMPR::
773 _triggered_actionImageToImage( )
774 {
775   if( this->m_Image.IsNull( ) )
776     return;
777
778   // Get filter name
779   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
780   if( action == NULL )
781     return;
782   std::string name = action->text( ).toStdString( );
783
784   // Configure filter
785   TPluginFilter::Pointer filter =
786     this->m_Plugins.CreateProcessObject( name );
787   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
788   if( !dlg_ok )
789     return;
790
791   // Execute filter
792   QApplication::setOverrideCursor( Qt::WaitCursor );
793   this->setEnabled( false );
794   filter->SetInput( 0, this->m_Image );
795   std::string err = filter->Update( );
796   QApplication::restoreOverrideCursor( );
797   this->setEnabled( true );
798
799   // Update image
800   if( err == "" )
801   {
802     TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
803     result->DisconnectPipeline( );
804     this->m_Image = result;
805     if( this->m_Image.IsNotNull( ) )
806       this->m_MPRObjects->SetImage(
807         this->m_Image->GetVTK< vtkImageData >( )
808
809                 );
810         
811         
812         MementoState(this->m_state, this->m_Image);
813         this->m_state++;
814         if (this->m_state > this->m_max_state)
815         {
816                 this->m_max_state = this->m_state;
817         }
818   }
819   else
820     QMessageBox::critical(
821       this,
822       tr( "Error executing filter" ),
823       tr( err.c_str( ) )
824       );
825 }
826
827 // -------------------------------------------------------------------------
828 void ImageMPR::
829 _triggered_actionImageToMesh( )
830 {
831   if( this->m_Image.IsNull( ) )
832     return;
833
834   // Get filter name
835   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
836   if( action == NULL )
837     return;
838   std::string name = action->text( ).toStdString( );
839
840   // Configure filter
841   TPluginFilter::Pointer filter =
842     this->m_Plugins.CreateProcessObject( name );
843   bool dlg_ok = filter->ExecConfigurationDialog( NULL );
844   if( !dlg_ok )
845     return;
846
847   // Execute filter
848   QApplication::setOverrideCursor( Qt::WaitCursor );
849   this->setEnabled( false );
850   filter->SetInput( 0, this->m_Image );
851   std::string err = filter->Update( );
852   QApplication::restoreOverrideCursor( );
853   this->setEnabled( true );
854
855   // Update image
856   if( err == "" )
857   {
858     TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
859     result->DisconnectPipeline( );
860     this->m_Mesh = result;
861     err = this->_ConfigureMeshActors( );
862     if( err != "" )
863       QMessageBox::critical(
864         this,
865         tr( "Error message" ),
866         tr( err.c_str( ) )
867         );
868   }
869   else
870     QMessageBox::critical(
871       this,
872       tr( "Error executing filter" ),
873       tr( err.c_str( ) )
874       );
875 }
876
877 // -------------------------------------------------------------------------
878 void ImageMPR::
879 _triggered_actionUndo()
880 {
881         MementoState memento = MementoState();
882     
883         if (this->m_state>1)
884         {
885                 this->m_state--;
886                 this->m_MPRObjects->SetImage(
887                         memento.getMemento(this->m_state)->GetOutput()
888                         );
889         } else
890         {
891                 QMessageBox::warning(
892                         this,
893                         tr("message"),
894                         tr("No history to undo")
895                         );
896         }
897
898 }
899
900 // -------------------------------------------------------------------------
901 void ImageMPR::
902 _triggered_actionRedo()
903 {
904         MementoState memento = MementoState();
905                 if (this->m_state + 1 <= m_max_state)
906                 {
907                         this->m_state++;
908                         this->m_MPRObjects->SetImage(
909                                 memento.getMemento(this->m_state)->GetOutput()
910                                 );
911                 } else
912                 {
913                         QMessageBox::warning(
914                                 this,
915                                 tr("message"),
916                                 tr("No history to redo")
917                                 );
918                 }
919         
920 }
921         
922 */
923
924 // eof - $RCSfile$