2 #include "ui_ImageMPR.h"
6 // -------------------------------------------------------------------------
7 #define ImageMPR_ConnectAction( ACTION ) \
9 this->m_UI->a##ACTION, SIGNAL( triggered( ) ), \
10 this, SLOT( _a##ACTION( ) ) \
13 // -------------------------------------------------------------------------
15 ImageMPR( QWidget* parent )
16 : QMainWindow( parent ),
17 m_UI( new Ui::ImageMPR ),
18 m_Plugins( new TPlugins )
20 this->m_UI->setupUi( this );
21 this->m_Plugins->SetWidget( this );
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 );
36 // Try to load default plugins
37 this->m_Plugins->LoadPluginsConfigurationFile( "Plugins.cfg" );
38 this->m_Plugins->AssociatePluginsToMenu(
39 this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
43 // -------------------------------------------------------------------------
48 delete this->m_Plugins;
51 // -------------------------------------------------------------------------
55 // Clear all, since we are loading the main image
56 if( this->m_Objects.size( ) > 0 )
58 this->m_UI->MPR->ClearAll( );
59 this->m_Objects.clear( );
63 // Read and show image, if possible
64 TPlugins::TImage::Pointer image;
65 if( this->m_Plugins->ReadImage( image, true ) )
67 vtkImageData* vimage = image->GetVTK< vtkImageData >( );
69 QMessageBox::critical(
71 QMessageBox::tr( "Error showing image." ),
73 "Image was read, but no valid VTK conversion was found."
77 this->m_UI->MPR->ShowImage( vimage, image->GetName( ) );
79 // Keep a track on a local data tree
80 this->m_Objects[ image->GetName( ) ] =
81 TTreeNode( "", image.GetPointer( ) );
86 // -------------------------------------------------------------------------
90 // Clear all, since we are loading the main image
91 if( this->m_Objects.size( ) > 0 )
93 this->m_UI->MPR->ClearAll( );
94 this->m_Objects.clear( );
98 // Read and show image, if possible
99 TPlugins::TImage::Pointer image;
100 if( this->m_Plugins->ReadDicomSeries( image ) )
102 vtkImageData* vimage = image->GetVTK< vtkImageData >( );
104 QMessageBox::critical(
106 QMessageBox::tr( "Error showing image." ),
108 "Image was read, but no valid VTK conversion was found."
112 this->m_UI->MPR->ShowImage( vimage, image->GetName( ) );
114 // Keep a track on a local data tree
115 this->m_Objects[ image->GetName( ) ] =
116 TTreeNode( "", image.GetPointer( ) );
121 // -------------------------------------------------------------------------
123 _aOpenSegmentation( )
126 if( this->m_ImageLoaded != "" )
127 this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
131 // -------------------------------------------------------------------------
137 // -------------------------------------------------------------------------
142 if( this->m_MainImage.IsNotNull( ) )
143 this->m_Plugins->WriteImage( this->m_MainImage, true );
147 // -------------------------------------------------------------------------
149 _aSaveSegmentation( )
153 // -------------------------------------------------------------------------
159 // -------------------------------------------------------------------------
165 // -------------------------------------------------------------------------
171 // -------------------------------------------------------------------------
175 this->m_Plugins->DialogLoadPlugins( );
176 this->m_Plugins->AssociatePluginsToMenu(
177 this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
181 // -------------------------------------------------------------------------
187 // -------------------------------------------------------------------------
192 typedef std::map< std::string, TPlugins::TImage::Pointer > _TImages;
193 typedef std::map< std::string, TPlugins::TMesh::Pointer > _TMeshes;
196 // std::string data_name = this->m_UI->MPR->GetSelectedData( );
199 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
202 QMenu* menu = dynamic_cast< QMenu* >( action->parentWidget( ) );
205 std::string filter_cate = menu->title( ).toStdString( );
206 std::string filter_name = action->text( ).toStdString( );
209 TPlugins::TProcessObject::Pointer filter;
210 if( !( this->m_Plugins->CreateFilter( filter, filter_name ) ) )
212 QMessageBox::critical(
214 tr( "Error creating filter" ),
216 std::string( "No valid filter \"" ) +
218 std::string( "\"defined." )
226 std::vector< std::string > inputs_names = filter->GetInputsNames( );
227 if( inputs_names.size( ) == 1 )
229 std::string data_name = this->m_UI->MPR->GetSelectedData( );
230 _TImages::iterator iIt = this->m_Images.find( data_name );
231 _TImages::iterator mIt = this->m_Meshes.find( data_name );
232 filter->SetInput( inputs_names[ 0 ]);
234 else if( inputs_names.size( ) > 1 )
239 std::vector< std::string > outputs_names = filter->GetOutputsNames( );
245 if( filter_cate == "ImageToMeshFilter" )
248 _TImages::iterator iIt = this->m_Images.find( data_name );
249 if( iIt == this->m_Images.end( ) )
251 QMessageBox::critical(
253 tr( "Error creating filter" ),
254 tr( "No valid input selected." )
260 // Execute configuration dialog
261 if( !( filter->ExecConfigurationDialog( this ) ) )
265 filter->SetInput( "Input", iIt->second );
267 std::string filter_err = filter->Update( );
269 if( filter_err != "" )
271 QMessageBox::critical(
273 tr( "Error executing" ),
274 tr( filter_err.c_str( ) )
280 // Keep and show results
281 TPlugins::TMesh::Pointer mesh =
282 filter->GetOutput< TPlugins::TMesh >( "Output" );
283 this->m_Meshes[ filter_name ] = mesh;
285 this->m_UI->MPR->ShowMesh(
286 mesh->GetVTK< vtkPolyData >( ),
296 if( this->m_Plugins->CreateFilter( filter, name ) )
298 if( filter->ExecConfigurationDialog( this ) )
300 filter->SetInput( "Input", this->m_MainImage );
302 err = filter->Update( );
304 TPlugins::TMesh::Pointer mesh =
305 filter->GetOutput< TPlugins::TMesh >( "Output" );
306 this->m_Meshes.push_back( mesh );
307 mesh->CreateVTKActor( );
308 vtkActor* actor = mesh->GetVTKActor( );
310 this->m_UI->MPR->Add3DActor( actor );
317 QMessageBox::critical(
319 tr( "Error creating filter" ),
320 tr( "No valid filter defined." )
324 if( name == "cpPlugins::BasicFilters::FloodFillImageFilter" )
326 this->m_Flooding = true;
330 this->m_Flooding = false;
331 this->m_UI->MPR->ExecuteFilter(
332 name, this->m_ImageLoaded, "SegmentedImage"
340 TPluginFilter::Pointer filter =
341 this->m_Plugins.CreateProcessObject( name );
342 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
347 QApplication::setOverrideCursor( Qt::WaitCursor );
348 this->setEnabled( false );
349 filter->SetInput( 0, this->m_Image );
350 std::string err = filter->Update( );
351 QApplication::restoreOverrideCursor( );
352 this->setEnabled( true );
357 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
358 result->DisconnectPipeline( );
359 this->m_Image = result;
360 if( this->m_Image.IsNotNull( ) )
361 this->m_MPRObjects->SetImage(
362 this->m_Image->GetVTK< vtkImageData >( )
364 MementoState(this->m_state, this->m_Image);
366 if (this->m_state > this->m_max_state)
368 this->m_max_state = this->m_state;
372 QMessageBox::critical(
374 tr( "Error executing filter" ),
380 // -------------------------------------------------------------------------
383 _CursorCommand( double* pos, int axis, void* data )
385 Self* app = reinterpret_cast< Self* >( data );
388 if( !( app->m_Flooding ) )
391 cpPlugins::Interface::ProcessObject::Pointer filter =
392 app->m_UI->MPR->CreateFilter(
393 "cpPlugins::BasicFilters::FloodFillImageFilter"
395 if( filter.IsNull( ) )
398 cpPlugins::Interface::Parameters* params = filter->GetParameters( );
399 params->SetPoint( "Seed", 3, pos );
400 params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) );
401 params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) );
402 params->SetUint( "InsideValue", 1 );
403 params->SetUint( "OutsideValue", 0 );
404 filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) );
405 app->m_UI->MPR->Block( );
406 std::string err = filter->Update( );
407 cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" );
408 filter->DisconnectOutputs( );
409 app->m_UI->MPR->AddImage( "Segmentation", image );
410 app->m_UI->MPR->Unblock( );
413 << "CursorCommand ==> "
418 << data << std::endl;
423 #include "MementoState.h"
425 #include <vtkProperty.h>
426 #include <vtkRenderWindow.h>
427 #include <vtkMetaImageReader.h>
429 #include <QFileDialog>
430 #include <QMessageBox>
433 # define PLUGIN_PREFIX ""
434 # define PLUGIN_EXT "dll"
435 # define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
437 # define PLUGIN_PREFIX "lib"
438 # define PLUGIN_EXT "so"
439 # define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
442 // -------------------------------------------------------------------------
443 ImageMPR::ImageMPR( QWidget* parent )
444 : QMainWindow( parent ),
445 m_UI( new Ui::ImageMPR ),
446 m_ImageReaderClass( "" ),
447 m_ImageWriterClass( "" ),
448 m_MeshReaderClass( "" ),
449 m_MeshWriterClass( "" ),
450 m_MeshCutterClass( "" ),
455 this->m_UI->setupUi( this );
457 // Create and associate renderers
458 this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
459 this->m_MPRObjects->SetRenderWindows(
460 this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
461 this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
462 this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
463 this->m_UI->m_3DVTK->GetRenderWindow( )
468 this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
469 this, SLOT( _triggered_actionOpenPlugins( ) )
472 this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
473 this, SLOT( _triggered_actionOpenInputImage( ) )
476 this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
477 this, SLOT( _triggered_actionOpenSegmentation( ) )
480 this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
481 this, SLOT( _triggered_actionOpenInputPolyData( ) )
484 this->m_UI->actionUndo, SIGNAL(triggered()),
485 this, SLOT(_triggered_actionUndo())
488 this->m_UI->actionRedo, SIGNAL(triggered()),
489 this, SLOT(_triggered_actionRedo())
492 // Start: load all disponible plugins
494 std::string( PLUGIN_PREFIX ) +
495 std::string( "cpPluginsIO." ) +
496 std::string( PLUGIN_EXT )
499 std::string( PLUGIN_PREFIX ) +
500 std::string( "cpPluginsBasicFilters." ) +
501 std::string( PLUGIN_EXT )
505 // -------------------------------------------------------------------------
509 // Close all connections
510 this->m_Plugins.UnloadAll( );
516 // -------------------------------------------------------------------------
518 _LoadPlugins( const std::string& filename )
520 QApplication::setOverrideCursor( Qt::WaitCursor );
521 this->setEnabled( false );
523 this->m_ImageReaderClass = "";
524 this->m_ImageWriterClass = "";
525 this->m_MeshReaderClass = "";
526 this->m_MeshWriterClass = "";
527 this->m_MeshCutterClass = "";
528 this->m_UI->MenuImageToImage->clear( );
529 this->m_UI->MenuImageToMesh->clear( );
531 if( !( this->m_Plugins.Load( filename ) ) )
534 typedef TPluginsInterface::TClasses _TClasses;
535 _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
536 for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
538 TPluginFilter::Pointer o =
539 this->m_Plugins.CreateProcessObject( cIt->first );
540 std::string name = o->GetClassName( );
541 std::string category = o->GetClassCategory( );
542 if( category == "ImageReader" )
543 this->m_ImageReaderClass = name;
544 else if( category == "ImageWriter" )
545 this->m_ImageWriterClass = name;
546 else if( category == "MeshReader" )
547 this->m_MeshReaderClass = name;
548 else if( category == "MeshWriter" )
549 this->m_MeshWriterClass = name;
550 else if( category == "MeshToMeshFilter" )
552 if( name.find_last_of( "Cutter" ) != std::string::npos )
553 this->m_MeshCutterClass = name;
555 else if( category == "ImageToImageFilter" )
558 this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
560 action, SIGNAL( triggered( ) ),
561 this, SLOT( _triggered_actionImageToImage( ) )
564 else if( category == "ImageToMeshFilter" )
567 this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
569 action, SIGNAL( triggered( ) ),
570 this, SLOT( _triggered_actionImageToMesh( ) )
576 QApplication::restoreOverrideCursor( );
577 this->setEnabled( true );
582 // -------------------------------------------------------------------------
583 std::string ImageMPR::
584 _LoadImage( TPluginImage::Pointer& image )
586 std::string ret = "";
589 // Get a reader from loaded plugins
590 TPluginFilter::Pointer reader =
591 this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
592 if( reader.IsNotNull( ) )
594 if( reader->ExecConfigurationDialog( this ) )
597 QApplication::setOverrideCursor( Qt::WaitCursor );
598 this->setEnabled( false );
600 // Execute and get error message, if any
601 ret = reader->Update( );
603 // Assign fresh image, if any
606 image = reader->GetOutput< TPluginImage >( 0 );
607 reader->DisconnectOutputs( );
611 // Unblock application
612 QApplication::restoreOverrideCursor( );
613 this->setEnabled( true );
618 ret = "No suitable reader object found in loaded plugins.";
623 // -------------------------------------------------------------------------
624 std::string ImageMPR::
625 _ConfigureMeshActors( )
627 if( this->m_Mesh.IsNull( ) )
628 return( "Valid mesh not found." );
630 this->m_Mesh->CreateVTKActor( );
631 vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
632 if( vtk_actor != NULL )
634 this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
635 this->m_MPRObjects->Render( 4 );
639 TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
641 std::string err = "";
642 for( unsigned int i = 0; i < 3; ++i )
644 this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
645 this->m_Planes[ i ] = TPluginImplicitFunction::New( );
646 this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
647 this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
648 this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
649 std::string lerr = this->m_Cutters[ i ]->Update( );
652 this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
653 vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
654 mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
656 this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
658 this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
660 this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
666 this->m_MPRObjects->RenderAll( );
670 // -------------------------------------------------------------------------
672 _triggered_actionOpenPlugins( )
674 // Show dialog and check if it was accepted
675 QFileDialog dialog( this );
676 dialog.setFileMode( QFileDialog::ExistingFile );
677 dialog.setDirectory( "." );
678 dialog.setNameFilter( tr( PLUGIN_REGEX ) );
679 dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
680 if( !( dialog.exec( ) ) )
683 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
684 if( !( _LoadPlugins( fname ) ) )
685 QMessageBox::critical(
687 tr( "Ignoring plugin" ),
692 // -------------------------------------------------------------------------
694 _triggered_actionOpenInputImage( )
697 std::string err = this->_LoadImage( this->m_Image );
700 vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
703 this->m_MPRObjects->SetImage( vtk_id );
704 this->m_MPRObjects->ActivateInteractors( );
705 this->m_MPRObjects->ResetCameras( );
706 this->m_MPRObjects->RenderAll( );
708 MementoState(m_state, this->m_Image);
712 QMessageBox::critical(
714 tr( "Error message" ),
715 tr( "Read image does not have a valid VTK converter." )
719 QMessageBox::critical(
721 tr( "Error reading single image" ),
726 // -------------------------------------------------------------------------
728 _triggered_actionOpenSegmentation( )
730 if( this->m_Image.IsNull( ) )
732 QMessageBox::critical(
734 tr( "Error message" ),
735 tr( "Before reading a segmentation, first load a raw image." )
742 std::string err = this->_LoadImage( this->m_Segmentation );
745 vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
748 this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
749 this->m_MPRObjects->RenderAll( );
752 QMessageBox::critical(
754 tr( "Error message" ),
755 tr( "Read image does not have a valid VTK converter." )
759 QMessageBox::critical(
761 tr( "Error reading single image" ),
766 // -------------------------------------------------------------------------
768 _triggered_actionOpenInputPolyData( )
772 // Get a reader from plugins
773 TPluginFilter::Pointer reader =
774 this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
776 if( reader.IsNotNull( ) )
779 if( reader->ExecConfigurationDialog( this ) )
781 // Execute and get error message, if any
782 QApplication::setOverrideCursor( Qt::WaitCursor );
783 this->setEnabled( false );
784 std::string err = reader->Update( );
785 QApplication::restoreOverrideCursor( );
786 this->setEnabled( true );
788 // Assign fresh mesh, if any
791 this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
792 reader->DisconnectOutputs( );
793 err = this->_ConfigureMeshActors( );
795 QMessageBox::critical(
797 tr( "Error message" ),
802 QMessageBox::critical(
804 tr( "Error reading mesh" ),
811 QMessageBox::critical(
813 tr( "Error reading single mesh" ),
814 tr( "No suitable mesh reader found in loaded plugins." )
818 // -------------------------------------------------------------------------
820 _triggered_actionImageToImage( )
822 if( this->m_Image.IsNull( ) )
826 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
829 std::string name = action->text( ).toStdString( );
832 TPluginFilter::Pointer filter =
833 this->m_Plugins.CreateProcessObject( name );
834 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
839 QApplication::setOverrideCursor( Qt::WaitCursor );
840 this->setEnabled( false );
841 filter->SetInput( 0, this->m_Image );
842 std::string err = filter->Update( );
843 QApplication::restoreOverrideCursor( );
844 this->setEnabled( true );
849 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
850 result->DisconnectPipeline( );
851 this->m_Image = result;
852 if( this->m_Image.IsNotNull( ) )
853 this->m_MPRObjects->SetImage(
854 this->m_Image->GetVTK< vtkImageData >( )
859 MementoState(this->m_state, this->m_Image);
861 if (this->m_state > this->m_max_state)
863 this->m_max_state = this->m_state;
867 QMessageBox::critical(
869 tr( "Error executing filter" ),
874 // -------------------------------------------------------------------------
876 _triggered_actionImageToMesh( )
878 if( this->m_Image.IsNull( ) )
882 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
885 std::string name = action->text( ).toStdString( );
888 TPluginFilter::Pointer filter =
889 this->m_Plugins.CreateProcessObject( name );
890 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
895 QApplication::setOverrideCursor( Qt::WaitCursor );
896 this->setEnabled( false );
897 filter->SetInput( 0, this->m_Image );
898 std::string err = filter->Update( );
899 QApplication::restoreOverrideCursor( );
900 this->setEnabled( true );
905 TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
906 result->DisconnectPipeline( );
907 this->m_Mesh = result;
908 err = this->_ConfigureMeshActors( );
910 QMessageBox::critical(
912 tr( "Error message" ),
917 QMessageBox::critical(
919 tr( "Error executing filter" ),
924 // -------------------------------------------------------------------------
926 _triggered_actionUndo()
928 MementoState memento = MementoState();
933 this->m_MPRObjects->SetImage(
934 memento.getMemento(this->m_state)->GetOutput()
938 QMessageBox::warning(
941 tr("No history to undo")
947 // -------------------------------------------------------------------------
949 _triggered_actionRedo()
951 MementoState memento = MementoState();
952 if (this->m_state + 1 <= m_max_state)
955 this->m_MPRObjects->SetImage(
956 memento.getMemento(this->m_state)->GetOutput()
960 QMessageBox::warning(
963 tr("No history to redo")