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 // -------------------------------------------------------------------------
141 std::string data_name = this->m_UI->MPR->GetSelectedData( );
142 TPlugins::TImage* image = dynamic_cast< TPlugins::TImage* >(
143 this->m_Objects[ data_name ].second.GetPointer( )
147 this->m_Plugins->WriteImage( image, true );
150 // -------------------------------------------------------------------------
152 _aSaveSegmentation( )
156 // -------------------------------------------------------------------------
160 std::string data_name = this->m_UI->MPR->GetSelectedData( );
161 TPlugins::TMesh* mesh = dynamic_cast< TPlugins::TMesh* >(
162 this->m_Objects[ data_name ].second.GetPointer( )
166 this->m_Plugins->WriteMesh( mesh, true );
169 // -------------------------------------------------------------------------
175 // -------------------------------------------------------------------------
181 // -------------------------------------------------------------------------
185 this->m_Plugins->DialogLoadPlugins( );
186 this->m_Plugins->AssociatePluginsToMenu(
187 this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
191 // -------------------------------------------------------------------------
197 // -------------------------------------------------------------------------
202 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
205 QMenu* menu = dynamic_cast< QMenu* >( action->parentWidget( ) );
208 std::string filter_cate = menu->title( ).toStdString( );
209 std::string filter_name = action->text( ).toStdString( );
212 TPlugins::TProcessObject::Pointer filter;
213 if( !( this->m_Plugins->CreateFilter( filter, filter_name ) ) )
215 QMessageBox::critical(
217 tr( "Error creating filter" ),
219 std::string( "No valid filter \"" ) +
221 std::string( "\"defined." )
229 if( !( filter->ExecConfigurationDialog( this ) ) )
233 std::string data_name = this->m_UI->MPR->GetSelectedData( );
234 std::vector< std::string > inputs_names = filter->GetInputsNames( );
235 if( inputs_names.size( ) == 1 )
237 TTree::iterator iIt = this->m_Objects.find( data_name );
238 if( iIt == this->m_Objects.end( ) )
240 QMessageBox::critical(
242 tr( "Error configuring filter" ),
243 tr( "No valid input found. Please select a valid input." )
248 filter->SetInput( inputs_names[ 0 ], iIt->second.second );
250 else if( inputs_names.size( ) > 1 )
252 QMessageBox::critical(
254 tr( "Error executing" ),
255 tr( "Filter has multiple inputs: NOT YET IMPLEMENTED!!!" )
263 std::string filter_err = filter->Update( );
265 if( filter_err != "" )
267 QMessageBox::critical(
269 tr( "Error executing" ),
270 tr( filter_err.c_str( ) )
277 std::vector< std::string > outputs_names = filter->GetOutputsNames( );
279 auto oIt = outputs_names.begin( );
280 oIt != outputs_names.end( );
284 std::string out_name = filter_name + "_" + *oIt;
286 TPlugins::TImage* image = filter->GetOutput< TPlugins::TImage >( *oIt );
289 if( filter_cate == "ImageToBinaryImageFilter" )
291 this->m_UI->MPR->ShowImage(
292 image->GetVTK< vtkImageData >( ),
297 else if( filter_cate == "ImageToImageFilter" )
301 // Keep a track on a local data tree and go to next output
302 this->m_Objects[ out_name ] = TTreeNode( data_name, image );
307 TPlugins::TMesh* mesh = filter->GetOutput< TPlugins::TMesh >( *oIt );
312 this->m_UI->MPR->ShowMesh(
313 mesh->GetVTK< vtkPolyData >( ),
319 // Keep a track on a local data tree and go to next output
320 this->m_Objects[ out_name ] = TTreeNode( data_name, mesh );
328 // -------------------------------------------------------------------------
331 _CursorCommand( double* pos, int axis, void* data )
333 Self* app = reinterpret_cast< Self* >( data );
336 if( !( app->m_Flooding ) )
339 cpPlugins::Interface::ProcessObject::Pointer filter =
340 app->m_UI->MPR->CreateFilter(
341 "cpPlugins::BasicFilters::FloodFillImageFilter"
343 if( filter.IsNull( ) )
346 cpPlugins::Interface::Parameters* params = filter->GetParameters( );
347 params->SetPoint( "Seed", 3, pos );
348 params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) );
349 params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) );
350 params->SetUint( "InsideValue", 1 );
351 params->SetUint( "OutsideValue", 0 );
352 filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) );
353 app->m_UI->MPR->Block( );
354 std::string err = filter->Update( );
355 cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" );
356 filter->DisconnectOutputs( );
357 app->m_UI->MPR->AddImage( "Segmentation", image );
358 app->m_UI->MPR->Unblock( );
361 << "CursorCommand ==> "
366 << data << std::endl;
371 #include "MementoState.h"
373 #include <vtkProperty.h>
374 #include <vtkRenderWindow.h>
375 #include <vtkMetaImageReader.h>
377 #include <QFileDialog>
378 #include <QMessageBox>
381 # define PLUGIN_PREFIX ""
382 # define PLUGIN_EXT "dll"
383 # define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
385 # define PLUGIN_PREFIX "lib"
386 # define PLUGIN_EXT "so"
387 # define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
390 // -------------------------------------------------------------------------
391 ImageMPR::ImageMPR( QWidget* parent )
392 : QMainWindow( parent ),
393 m_UI( new Ui::ImageMPR ),
394 m_ImageReaderClass( "" ),
395 m_ImageWriterClass( "" ),
396 m_MeshReaderClass( "" ),
397 m_MeshWriterClass( "" ),
398 m_MeshCutterClass( "" ),
403 this->m_UI->setupUi( this );
405 // Create and associate renderers
406 this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
407 this->m_MPRObjects->SetRenderWindows(
408 this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
409 this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
410 this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
411 this->m_UI->m_3DVTK->GetRenderWindow( )
416 this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
417 this, SLOT( _triggered_actionOpenPlugins( ) )
420 this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
421 this, SLOT( _triggered_actionOpenInputImage( ) )
424 this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
425 this, SLOT( _triggered_actionOpenSegmentation( ) )
428 this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
429 this, SLOT( _triggered_actionOpenInputPolyData( ) )
432 this->m_UI->actionUndo, SIGNAL(triggered()),
433 this, SLOT(_triggered_actionUndo())
436 this->m_UI->actionRedo, SIGNAL(triggered()),
437 this, SLOT(_triggered_actionRedo())
440 // Start: load all disponible plugins
442 std::string( PLUGIN_PREFIX ) +
443 std::string( "cpPluginsIO." ) +
444 std::string( PLUGIN_EXT )
447 std::string( PLUGIN_PREFIX ) +
448 std::string( "cpPluginsBasicFilters." ) +
449 std::string( PLUGIN_EXT )
453 // -------------------------------------------------------------------------
457 // Close all connections
458 this->m_Plugins.UnloadAll( );
464 // -------------------------------------------------------------------------
466 _LoadPlugins( const std::string& filename )
468 QApplication::setOverrideCursor( Qt::WaitCursor );
469 this->setEnabled( false );
471 this->m_ImageReaderClass = "";
472 this->m_ImageWriterClass = "";
473 this->m_MeshReaderClass = "";
474 this->m_MeshWriterClass = "";
475 this->m_MeshCutterClass = "";
476 this->m_UI->MenuImageToImage->clear( );
477 this->m_UI->MenuImageToMesh->clear( );
479 if( !( this->m_Plugins.Load( filename ) ) )
482 typedef TPluginsInterface::TClasses _TClasses;
483 _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
484 for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
486 TPluginFilter::Pointer o =
487 this->m_Plugins.CreateProcessObject( cIt->first );
488 std::string name = o->GetClassName( );
489 std::string category = o->GetClassCategory( );
490 if( category == "ImageReader" )
491 this->m_ImageReaderClass = name;
492 else if( category == "ImageWriter" )
493 this->m_ImageWriterClass = name;
494 else if( category == "MeshReader" )
495 this->m_MeshReaderClass = name;
496 else if( category == "MeshWriter" )
497 this->m_MeshWriterClass = name;
498 else if( category == "MeshToMeshFilter" )
500 if( name.find_last_of( "Cutter" ) != std::string::npos )
501 this->m_MeshCutterClass = name;
503 else if( category == "ImageToImageFilter" )
506 this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
508 action, SIGNAL( triggered( ) ),
509 this, SLOT( _triggered_actionImageToImage( ) )
512 else if( category == "ImageToMeshFilter" )
515 this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
517 action, SIGNAL( triggered( ) ),
518 this, SLOT( _triggered_actionImageToMesh( ) )
524 QApplication::restoreOverrideCursor( );
525 this->setEnabled( true );
530 // -------------------------------------------------------------------------
531 std::string ImageMPR::
532 _LoadImage( TPluginImage::Pointer& image )
534 std::string ret = "";
537 // Get a reader from loaded plugins
538 TPluginFilter::Pointer reader =
539 this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
540 if( reader.IsNotNull( ) )
542 if( reader->ExecConfigurationDialog( this ) )
545 QApplication::setOverrideCursor( Qt::WaitCursor );
546 this->setEnabled( false );
548 // Execute and get error message, if any
549 ret = reader->Update( );
551 // Assign fresh image, if any
554 image = reader->GetOutput< TPluginImage >( 0 );
555 reader->DisconnectOutputs( );
559 // Unblock application
560 QApplication::restoreOverrideCursor( );
561 this->setEnabled( true );
566 ret = "No suitable reader object found in loaded plugins.";
571 // -------------------------------------------------------------------------
572 std::string ImageMPR::
573 _ConfigureMeshActors( )
575 if( this->m_Mesh.IsNull( ) )
576 return( "Valid mesh not found." );
578 this->m_Mesh->CreateVTKActor( );
579 vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
580 if( vtk_actor != NULL )
582 this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
583 this->m_MPRObjects->Render( 4 );
587 TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
589 std::string err = "";
590 for( unsigned int i = 0; i < 3; ++i )
592 this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
593 this->m_Planes[ i ] = TPluginImplicitFunction::New( );
594 this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
595 this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
596 this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
597 std::string lerr = this->m_Cutters[ i ]->Update( );
600 this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
601 vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
602 mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
604 this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
606 this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
608 this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
614 this->m_MPRObjects->RenderAll( );
618 // -------------------------------------------------------------------------
620 _triggered_actionOpenPlugins( )
622 // Show dialog and check if it was accepted
623 QFileDialog dialog( this );
624 dialog.setFileMode( QFileDialog::ExistingFile );
625 dialog.setDirectory( "." );
626 dialog.setNameFilter( tr( PLUGIN_REGEX ) );
627 dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
628 if( !( dialog.exec( ) ) )
631 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
632 if( !( _LoadPlugins( fname ) ) )
633 QMessageBox::critical(
635 tr( "Ignoring plugin" ),
640 // -------------------------------------------------------------------------
642 _triggered_actionOpenInputImage( )
645 std::string err = this->_LoadImage( this->m_Image );
648 vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
651 this->m_MPRObjects->SetImage( vtk_id );
652 this->m_MPRObjects->ActivateInteractors( );
653 this->m_MPRObjects->ResetCameras( );
654 this->m_MPRObjects->RenderAll( );
656 MementoState(m_state, this->m_Image);
660 QMessageBox::critical(
662 tr( "Error message" ),
663 tr( "Read image does not have a valid VTK converter." )
667 QMessageBox::critical(
669 tr( "Error reading single image" ),
674 // -------------------------------------------------------------------------
676 _triggered_actionOpenSegmentation( )
678 if( this->m_Image.IsNull( ) )
680 QMessageBox::critical(
682 tr( "Error message" ),
683 tr( "Before reading a segmentation, first load a raw image." )
690 std::string err = this->_LoadImage( this->m_Segmentation );
693 vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
696 this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
697 this->m_MPRObjects->RenderAll( );
700 QMessageBox::critical(
702 tr( "Error message" ),
703 tr( "Read image does not have a valid VTK converter." )
707 QMessageBox::critical(
709 tr( "Error reading single image" ),
714 // -------------------------------------------------------------------------
716 _triggered_actionOpenInputPolyData( )
720 // Get a reader from plugins
721 TPluginFilter::Pointer reader =
722 this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
724 if( reader.IsNotNull( ) )
727 if( reader->ExecConfigurationDialog( this ) )
729 // Execute and get error message, if any
730 QApplication::setOverrideCursor( Qt::WaitCursor );
731 this->setEnabled( false );
732 std::string err = reader->Update( );
733 QApplication::restoreOverrideCursor( );
734 this->setEnabled( true );
736 // Assign fresh mesh, if any
739 this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
740 reader->DisconnectOutputs( );
741 err = this->_ConfigureMeshActors( );
743 QMessageBox::critical(
745 tr( "Error message" ),
750 QMessageBox::critical(
752 tr( "Error reading mesh" ),
759 QMessageBox::critical(
761 tr( "Error reading single mesh" ),
762 tr( "No suitable mesh reader found in loaded plugins." )
766 // -------------------------------------------------------------------------
768 _triggered_actionImageToImage( )
770 if( this->m_Image.IsNull( ) )
774 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
777 std::string name = action->text( ).toStdString( );
780 TPluginFilter::Pointer filter =
781 this->m_Plugins.CreateProcessObject( name );
782 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
787 QApplication::setOverrideCursor( Qt::WaitCursor );
788 this->setEnabled( false );
789 filter->SetInput( 0, this->m_Image );
790 std::string err = filter->Update( );
791 QApplication::restoreOverrideCursor( );
792 this->setEnabled( true );
797 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
798 result->DisconnectPipeline( );
799 this->m_Image = result;
800 if( this->m_Image.IsNotNull( ) )
801 this->m_MPRObjects->SetImage(
802 this->m_Image->GetVTK< vtkImageData >( )
807 MementoState(this->m_state, this->m_Image);
809 if (this->m_state > this->m_max_state)
811 this->m_max_state = this->m_state;
815 QMessageBox::critical(
817 tr( "Error executing filter" ),
822 // -------------------------------------------------------------------------
824 _triggered_actionImageToMesh( )
826 if( this->m_Image.IsNull( ) )
830 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
833 std::string name = action->text( ).toStdString( );
836 TPluginFilter::Pointer filter =
837 this->m_Plugins.CreateProcessObject( name );
838 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
843 QApplication::setOverrideCursor( Qt::WaitCursor );
844 this->setEnabled( false );
845 filter->SetInput( 0, this->m_Image );
846 std::string err = filter->Update( );
847 QApplication::restoreOverrideCursor( );
848 this->setEnabled( true );
853 TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
854 result->DisconnectPipeline( );
855 this->m_Mesh = result;
856 err = this->_ConfigureMeshActors( );
858 QMessageBox::critical(
860 tr( "Error message" ),
865 QMessageBox::critical(
867 tr( "Error executing filter" ),
872 // -------------------------------------------------------------------------
874 _triggered_actionUndo()
876 MementoState memento = MementoState();
881 this->m_MPRObjects->SetImage(
882 memento.getMemento(this->m_state)->GetOutput()
886 QMessageBox::warning(
889 tr("No history to undo")
895 // -------------------------------------------------------------------------
897 _triggered_actionRedo()
899 MementoState memento = MementoState();
900 if (this->m_state + 1 <= m_max_state)
903 this->m_MPRObjects->SetImage(
904 memento.getMemento(this->m_state)->GetOutput()
908 QMessageBox::warning(
911 tr("No history to redo")