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