X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=appli%2FImageMPR%2FImageMPR.cxx;h=0100a138a5faadb54c3841b5c0fb0baa299c5435;hb=a4bc3b8e36e91e45f37a3b7eecb5789c635aa5c0;hp=6ee1fb02454f29fc0780cda1142d1690d6f08d18;hpb=b2504685e7688dff1870c5fc1807cbc7f251aea7;p=cpPlugins.git diff --git a/appli/ImageMPR/ImageMPR.cxx b/appli/ImageMPR/ImageMPR.cxx index 6ee1fb0..0100a13 100644 --- a/appli/ImageMPR/ImageMPR.cxx +++ b/appli/ImageMPR/ImageMPR.cxx @@ -1,108 +1,45 @@ #include "ImageMPR.h" #include "ui_ImageMPR.h" +#include #include #include #include -/* -#include -#include -#include - -#include -#include -#include -#include - -#include - -// ------------------------------------------------------------------------- -#define IDMS_QT_ACTION( name ) \ - QObject::connect( \ - this->m_UI->action##name, SIGNAL( triggered( ) ), \ - this, SLOT( _triggered_action##name( ) ) \ - ) -*/ +#ifdef _WIN32 +# define PLUGIN_PREFIX "" +# define PLUGIN_EXT "dll" +# define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)" +#else +# define PLUGIN_PREFIX "lib" +# define PLUGIN_EXT "so" +# define PLUGIN_REGEX "Plugins file (*.so);;All files (*)" +#endif // _WIN32 // ------------------------------------------------------------------------- ImageMPR::ImageMPR( QWidget* parent ) : QMainWindow( parent ), m_UI( new Ui::ImageMPR ), - m_InputImage( NULL ) + m_ImageReaderClass( "" ), + m_ImageWriterClass( "" ), + m_MeshReaderClass( "" ), + m_MeshWriterClass( "" ), + m_MeshCutterClass( "" ), + m_Image( NULL ) { this->m_UI->setupUi( this ); // Create and associate renderers - this->m_3DRenderer = vtkSmartPointer< vtkRenderer >::New( ); - this->m_XPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); - this->m_YPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); - this->m_ZPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); - this->m_3DRenderer->SetBackground( 0.2, 0.2, 0.2 ); - this->m_XPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); - this->m_YPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); - this->m_ZPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); - this->m_UI->m_3DVTK->GetRenderWindow( )-> - AddRenderer( this->m_3DRenderer ); - this->m_UI->m_XPlaneVTK->GetRenderWindow( )-> - AddRenderer( this->m_XPlaneRenderer ); - this->m_UI->m_YPlaneVTK->GetRenderWindow( )-> - AddRenderer( this->m_YPlaneRenderer ); - this->m_UI->m_ZPlaneVTK->GetRenderWindow( )-> - AddRenderer( this->m_ZPlaneRenderer ); - - // Configure MPR actors - this->m_MPRActors = vtkSmartPointer< TMPRActors >::New( ); - - // Prepare interaction - this->m_XStyle = vtkSmartPointer< TStyle >::New( ); - this->m_YStyle = vtkSmartPointer< TStyle >::New( ); - this->m_ZStyle = vtkSmartPointer< TStyle >::New( ); - this->m_XStyle-> - Configure( this->m_MPRActors->GetSliceActors( 0 ), this->m_MPRActors ); - this->m_YStyle-> - Configure( this->m_MPRActors->GetSliceActors( 1 ), this->m_MPRActors ); - this->m_ZStyle-> - Configure( this->m_MPRActors->GetSliceActors( 2 ), this->m_MPRActors ); - this->m_XStyle-> - SetInteractor( this->m_UI->m_XPlaneVTK->GetInteractor( ), 0 ); - this->m_YStyle-> - SetInteractor( this->m_UI->m_YPlaneVTK->GetInteractor( ), 1 ); - this->m_ZStyle-> - SetInteractor( this->m_UI->m_ZPlaneVTK->GetInteractor( ), 2 ); - this->m_XStyle->SetModeToNavigation( ); - this->m_YStyle->SetModeToNavigation( ); - this->m_ZStyle->SetModeToNavigation( ); - - this->m_XStyle->AssociateInteractor( - this->m_UI->m_YPlaneVTK->GetInteractor( ) - ); - this->m_XStyle->AssociateInteractor( - this->m_UI->m_ZPlaneVTK->GetInteractor( ) - ); - this->m_XStyle->AssociateInteractor( - this->m_UI->m_3DVTK->GetInteractor( ) - ); - this->m_YStyle->AssociateInteractor( - this->m_UI->m_XPlaneVTK->GetInteractor( ) - ); - this->m_YStyle->AssociateInteractor( - this->m_UI->m_ZPlaneVTK->GetInteractor( ) - ); - this->m_YStyle->AssociateInteractor( - this->m_UI->m_3DVTK->GetInteractor( ) - ); - this->m_ZStyle->AssociateInteractor( - this->m_UI->m_XPlaneVTK->GetInteractor( ) - ); - this->m_ZStyle->AssociateInteractor( - this->m_UI->m_YPlaneVTK->GetInteractor( ) - ); - this->m_ZStyle->AssociateInteractor( - this->m_UI->m_3DVTK->GetInteractor( ) + this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( ); + this->m_MPRObjects->SetRenderWindows( + this->m_UI->m_XPlaneVTK->GetRenderWindow( ), + this->m_UI->m_YPlaneVTK->GetRenderWindow( ), + this->m_UI->m_ZPlaneVTK->GetRenderWindow( ), + this->m_UI->m_3DVTK->GetRenderWindow( ) ); + // signals <-> slots QObject::connect( this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ), this, SLOT( _triggered_actionOpenPlugins( ) ) @@ -111,9 +48,26 @@ ImageMPR::ImageMPR( QWidget* parent ) this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ), this, SLOT( _triggered_actionOpenInputImage( ) ) ); + QObject::connect( + this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ), + this, SLOT( _triggered_actionOpenSegmentation( ) ) + ); + QObject::connect( + this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ), + this, SLOT( _triggered_actionOpenInputPolyData( ) ) + ); // Start: load all disponible plugins - this->_triggered_actionOpenPlugins( ); + this->_LoadPlugins( + std::string( PLUGIN_PREFIX ) + + std::string( "cpPluginsIO." ) + + std::string( PLUGIN_EXT ) + ); + this->_LoadPlugins( + std::string( PLUGIN_PREFIX ) + + std::string( "cpPluginsBasicFilters." ) + + std::string( PLUGIN_EXT ) + ); } // ------------------------------------------------------------------------- @@ -125,7 +79,160 @@ ImageMPR:: // Delete objects delete this->m_UI; - if( this->m_InputImage != NULL ) delete this->m_InputImage; +} + +// ------------------------------------------------------------------------- +bool ImageMPR:: +_LoadPlugins( const std::string& filename ) +{ + QApplication::setOverrideCursor( Qt::WaitCursor ); + this->setEnabled( false ); + + this->m_ImageReaderClass = ""; + this->m_ImageWriterClass = ""; + this->m_MeshReaderClass = ""; + this->m_MeshWriterClass = ""; + this->m_MeshCutterClass = ""; + this->m_UI->MenuImageToImage->clear( ); + this->m_UI->MenuImageToMesh->clear( ); + + if( !( this->m_Plugins.Load( filename ) ) ) + return( false ); + + typedef TPluginsInterface::TClasses _TClasses; + _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( ); + for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt ) + { + TPluginFilter::Pointer o = + this->m_Plugins.CreateProcessObject( cIt->first ); + std::string name = o->GetClassName( ); + std::string category = o->GetClassCategory( ); + if( category == "ImageReader" ) + this->m_ImageReaderClass = name; + else if( category == "ImageWriter" ) + this->m_ImageWriterClass = name; + else if( category == "MeshReader" ) + this->m_MeshReaderClass = name; + else if( category == "MeshWriter" ) + this->m_MeshWriterClass = name; + else if( category == "MeshToMeshFilter" ) + { + if( name.find_last_of( "Cutter" ) != std::string::npos ) + this->m_MeshCutterClass = name; + } + else if( category == "ImageToImageFilter" ) + { + QAction* action = + this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) ); + QObject::connect( + action, SIGNAL( triggered( ) ), + this, SLOT( _triggered_actionImageToImage( ) ) + ); + } + else if( category == "ImageToMeshFilter" ) + { + QAction* action = + this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) ); + QObject::connect( + action, SIGNAL( triggered( ) ), + this, SLOT( _triggered_actionImageToMesh( ) ) + ); + + } // fi + + } // rof + QApplication::restoreOverrideCursor( ); + this->setEnabled( true ); + + return( true ); +} + +// ------------------------------------------------------------------------- +std::string ImageMPR:: +_LoadImage( TPluginImage::Pointer& image ) +{ + std::string ret = ""; + image = NULL; + + // Get a reader from loaded plugins + TPluginFilter::Pointer reader = + this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass ); + if( reader.IsNotNull( ) ) + { + if( reader->ExecConfigurationDialog( this ) ) + { + // Block application + QApplication::setOverrideCursor( Qt::WaitCursor ); + this->setEnabled( false ); + + // Execute and get error message, if any + ret = reader->Update( ); + + // Assign fresh image, if any + if( ret == "" ) + { + image = reader->GetOutput< TPluginImage >( 0 ); + reader->DisconnectOutputs( ); + + } // fi + + // Unblock application + QApplication::restoreOverrideCursor( ); + this->setEnabled( true ); + + } // fi + } + else + ret = "No suitable reader object found in loaded plugins."; + + return( ret ); +} + +// ------------------------------------------------------------------------- +std::string ImageMPR:: +_ConfigureMeshActors( ) +{ + if( this->m_Mesh.IsNull( ) ) + return( "Valid mesh not found." ); + + this->m_Mesh->CreateVTKActor( ); + vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( ); + if( vtk_actor != NULL ) + { + this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor ); + this->m_MPRObjects->Render( 4 ); + + } // fi + + TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( ); + + std::string err = ""; + for( unsigned int i = 0; i < 3; ++i ) + { + this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass ); + this->m_Planes[ i ] = TPluginImplicitFunction::New( ); + this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) ); + this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh ); + this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] ); + std::string lerr = this->m_Cutters[ i ]->Update( ); + if( lerr == "" ) + { + this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( ); + vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( ); + mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor ); + if( i == 0 ) + this->m_MPRObjects->GetXRenderer( )->AddActor( actor ); + else if( i == 1 ) + this->m_MPRObjects->GetYRenderer( )->AddActor( actor ); + else if( i == 2 ) + this->m_MPRObjects->GetZRenderer( )->AddActor( actor ); + + } // fi + err += lerr; + + } // rof + this->m_MPRObjects->RenderAll( ); + return( err ); } // ------------------------------------------------------------------------- @@ -136,126 +243,238 @@ _triggered_actionOpenPlugins( ) QFileDialog dialog( this ); dialog.setFileMode( QFileDialog::ExistingFile ); dialog.setDirectory( "." ); - dialog.setNameFilter( - tr( "Plugins file (*.so);;All files (*)" ) - ); - dialog.setDefaultSuffix( tr( "so" ) ); + dialog.setNameFilter( tr( PLUGIN_REGEX ) ); + dialog.setDefaultSuffix( tr( PLUGIN_EXT ) ); if( !( dialog.exec( ) ) ) return; std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( ); - this->m_Plugins.UnloadAll( ); - if( !( this->m_Plugins.Load( fname ) ) ) - { + if( !( _LoadPlugins( fname ) ) ) QMessageBox::critical( this, tr( "Ignoring plugin" ), tr( fname.c_str( ) ) ); - this->m_Plugins.UnloadAll( ); - return; - - } // fi - - this->m_BaseClasses[ "ImageReader" ] = - "cpPlugins::Plugins::ImageReader"; - this->m_BaseClasses[ "ImageSeriesReader" ] = - "cpPlugins::Plugins::ImageSeriesReader"; } // ------------------------------------------------------------------------- void ImageMPR:: _triggered_actionOpenInputImage( ) { - // Show dialog and check if it was accepted - QFileDialog dialog( this ); - dialog.setFileMode( QFileDialog::ExistingFiles ); - dialog.setDirectory( tr( "." ) ); - dialog.setNameFilter( - tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" ) - ); - dialog.setDefaultSuffix( tr( "mhd" ) ); - if( !( dialog.exec( ) ) ) - return; - - if( this->m_InputImage != NULL ) - delete this->m_InputImage; - this->m_InputImage = NULL; - unsigned int nFiles = dialog.selectedFiles( ).size( ); - if( nFiles == 1 ) + // Read image + std::string err = this->_LoadImage( this->m_Image ); + if( err == "" ) { - std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( ); - - TPlugin* reader = - dynamic_cast< TPlugin* >( - this->m_Plugins.CreateObject( this->m_BaseClasses[ "ImageReader" ] ) + vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( ); + if( vtk_id != NULL ) + { + this->m_MPRObjects->SetImage( vtk_id ); + this->m_MPRObjects->ActivateInteractors( ); + this->m_MPRObjects->ResetCameras( ); + this->m_MPRObjects->RenderAll( ); + } + else + QMessageBox::critical( + this, + tr( "Error message" ), + tr( "Read image does not have a valid VTK converter." ) ); + } + else + QMessageBox::critical( + this, + tr( "Error reading single image" ), + tr( err.c_str( ) ) + ); +} + +// ------------------------------------------------------------------------- +void ImageMPR:: +_triggered_actionOpenSegmentation( ) +{ + if( this->m_Image.IsNull( ) ) + { + QMessageBox::critical( + this, + tr( "Error message" ), + tr( "Before reading a segmentation, first load a raw image." ) + ); + return; - TParameters reader_params = reader->GetDefaultParameters( ); - reader_params[ "FileName" ].second = fname; - reader_params[ "PixelType" ].second = "short"; - reader_params[ "ImageDimension" ].second = "3"; - reader_params[ "IsColorImage" ].second = "0"; - reader->SetParameters( reader_params ); - std::string err = reader->Update( ); + } // fi - if( err == "" ) + // Read image + std::string err = this->_LoadImage( this->m_Segmentation ); + if( err == "" ) + { + vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( ); + if( vtk_id != NULL ) { - this->m_InputImage = - dynamic_cast< TPluginImage* >( reader->GetOutput( 0 ) ); - reader->DisconnectOutputs( ); + this->m_MPRObjects->AddAuxiliaryImage( vtk_id ); + this->m_MPRObjects->RenderAll( ); } else QMessageBox::critical( this, - tr( "Error reading single image" ), - tr( err.c_str( ) ) + tr( "Error message" ), + tr( "Read image does not have a valid VTK converter." ) ); - delete reader; } - else if( nFiles > 1 ) + else + QMessageBox::critical( + this, + tr( "Error reading single image" ), + tr( err.c_str( ) ) + ); +} + +// ------------------------------------------------------------------------- +void ImageMPR:: +_triggered_actionOpenInputPolyData( ) +{ + this->m_Mesh = NULL; + + // Get a reader from plugins + TPluginFilter::Pointer reader = + this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass ); + + if( reader.IsNotNull( ) ) { - /* TODO - if( this->m_ImageSeriesReaderClassName == "" ) - { - QMessageBox::critical( - this, - tr( "No plugin to read an image series found!" ), - tr( "No plugin to read an image series found!" ) - ); - return( ret ); - - } // fi - std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( ); - this->m_LastOpenedFile = fname; - return( ret ); - */ + // Configure reader + if( reader->ExecConfigurationDialog( this ) ) + { + // Execute and get error message, if any + QApplication::setOverrideCursor( Qt::WaitCursor ); + this->setEnabled( false ); + std::string err = reader->Update( ); + QApplication::restoreOverrideCursor( ); + this->setEnabled( true ); - } // fi + // Assign fresh mesh, if any + if( err == "" ) + { + this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 ); + reader->DisconnectOutputs( ); + err = this->_ConfigureMeshActors( ); + if( err != "" ) + QMessageBox::critical( + this, + tr( "Error message" ), + tr( err.c_str( ) ) + ); + } + else + QMessageBox::critical( + this, + tr( "Error reading mesh" ), + tr( err.c_str( ) ) + ); + + } // fi + } + else + QMessageBox::critical( + this, + tr( "Error reading single mesh" ), + tr( "No suitable mesh reader found in loaded plugins." ) + ); +} + +// ------------------------------------------------------------------------- +void ImageMPR:: +_triggered_actionImageToImage( ) +{ + if( this->m_Image.IsNull( ) ) + return; - if( this->m_InputImage != NULL ) + // Get filter name + QAction* action = dynamic_cast< QAction* >( this->sender( ) ); + if( action == NULL ) + return; + std::string name = action->text( ).toStdString( ); + + // Configure filter + TPluginFilter::Pointer filter = + this->m_Plugins.CreateProcessObject( name ); + bool dlg_ok = filter->ExecConfigurationDialog( NULL ); + if( !dlg_ok ) + return; + + // Execute filter + QApplication::setOverrideCursor( Qt::WaitCursor ); + this->setEnabled( false ); + filter->SetInput( 0, this->m_Image ); + std::string err = filter->Update( ); + QApplication::restoreOverrideCursor( ); + this->setEnabled( true ); + + // Update image + if( err == "" ) { - this->m_MPRActors->SetInputData( this->m_InputImage->GetVTKImageData( ) ); - this->m_MPRActors->PushDataInto( - this->m_XPlaneRenderer, - this->m_YPlaneRenderer, - this->m_ZPlaneRenderer, - this->m_3DRenderer + TPluginImage* result = filter->GetOutput< TPluginImage >( 0 ); + result->DisconnectPipeline( ); + this->m_Image = result; + if( this->m_Image.IsNotNull( ) ) + this->m_MPRObjects->SetImage( + this->m_Image->GetVTK< vtkImageData >( ) + ); + } + else + QMessageBox::critical( + this, + tr( "Error executing filter" ), + tr( err.c_str( ) ) ); +} + +// ------------------------------------------------------------------------- +void ImageMPR:: +_triggered_actionImageToMesh( ) +{ + if( this->m_Image.IsNull( ) ) + return; - // Reset all cameras - this->m_3DRenderer->ResetCamera( ); - this->m_XPlaneRenderer->ResetCamera( ); - this->m_YPlaneRenderer->ResetCamera( ); - this->m_ZPlaneRenderer->ResetCamera( ); + // Get filter name + QAction* action = dynamic_cast< QAction* >( this->sender( ) ); + if( action == NULL ) + return; + std::string name = action->text( ).toStdString( ); - // Ok, start! - this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); - this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( ); - this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( ); - this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( ); + // Configure filter + TPluginFilter::Pointer filter = + this->m_Plugins.CreateProcessObject( name ); + bool dlg_ok = filter->ExecConfigurationDialog( NULL ); + if( !dlg_ok ) + return; - } // fi + // Execute filter + QApplication::setOverrideCursor( Qt::WaitCursor ); + this->setEnabled( false ); + filter->SetInput( 0, this->m_Image ); + std::string err = filter->Update( ); + QApplication::restoreOverrideCursor( ); + this->setEnabled( true ); + + // Update image + if( err == "" ) + { + TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 ); + result->DisconnectPipeline( ); + this->m_Mesh = result; + err = this->_ConfigureMeshActors( ); + if( err != "" ) + QMessageBox::critical( + this, + tr( "Error message" ), + tr( err.c_str( ) ) + ); + } + else + QMessageBox::critical( + this, + tr( "Error executing filter" ), + tr( err.c_str( ) ) + ); } // eof - $RCSfile$