2 #include "ui_ImageMPR.h"
7 // -------------------------------------------------------------------------
8 #define ImageMPR_ConnectAction( ACTION ) \
10 this->m_UI->a##ACTION, SIGNAL( triggered( ) ), \
11 this, SLOT( _a##ACTION( ) ) \
14 // -------------------------------------------------------------------------
16 ImageMPR( QWidget* parent )
17 : QMainWindow( parent ),
18 m_UI( new Ui::ImageMPR )
20 this->m_UI->setupUi( this );
21 this->m_Plugins.SetWidget( this );
22 this->m_Plugins.SetApplication( this );
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 );
37 // Associate model with view
38 for( unsigned int i = 0; i < 4; ++i )
39 this->m_Plugins.AddInteractor( this->m_UI->MPR->GetInteractor( i ) );
41 // Try to load default plugins
42 QStringList args = QApplication::arguments( );
43 QFileInfo info( args.at( 0 ) );
44 this->m_Plugins.LoadPluginsPath(
45 info.absolutePath( ).toStdString( ), true
48 // Put loaded plugins into menu
49 this->_AssociatePluginsToMenu( );
52 // -------------------------------------------------------------------------
59 // -------------------------------------------------------------------------
63 if( !( this->m_Plugins.HasActiveFilter( ) ) )
67 TPlugins::TStringContainer outputs;
70 this->m_Plugins.UpdateActiveFilter(
71 outputs, this->m_ActiveFilterMainInput
78 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
80 std::string parent = this->m_Plugins.GetParent( *oIt );
81 TDataObject* dobj = this->m_Plugins.GetData< TDataObject >( *oIt );
82 if( this->m_UI->MPR->AddData( dobj, *oIt, parent ) )
83 this->m_UI->MPR->ShowData( *oIt );
88 // -------------------------------------------------------------------------
90 _AssociatePluginsToMenu( )
92 this->m_UI->MenuFilters->clear( );
94 TPlugins::TStringContainer categories;
95 this->m_Plugins.GetLoadedCategories( categories );
96 for( auto cIt = categories.begin( ); cIt != categories.end( ); ++cIt )
98 QMenu* category = this->m_UI->MenuFilters->addMenu( cIt->c_str( ) );
99 const TPlugins::TStringContainer& filters =
100 this->m_Plugins.GetLoadedFilters( *cIt );
101 for( auto fIt = filters.begin( ); fIt != filters.end( ); ++fIt )
103 QAction* filter = category->addAction( fIt->c_str( ) );
105 filter, SIGNAL( triggered( ) ),
106 this, SLOT( _execPlugin( ) )
114 // -------------------------------------------------------------------------
115 #define ImageMPR_ReadImage( F ) \
116 this->m_UI->MPR->DeleteAllData( ); \
117 this->m_Plugins.ClearDataObjects( ); \
120 std::string name = this->m_Plugins.Read##F( "" ); \
123 TImage* image = this->m_Plugins.GetData< TImage >( name ); \
124 this->m_UI->MPR->AddData( image, name, "" ); \
125 this->m_UI->MPR->SetMainImage( name ); \
126 this->m_UI->MPR->ShowData( name ); \
128 catch( std::exception& err ) \
130 QMessageBox::critical( \
132 QMessageBox::tr( "Error reading image." ), \
133 QMessageBox::tr( err.what( ) ) \
137 void ImageMPR::_aOpenImage( ) { ImageMPR_ReadImage( Image ) }
138 void ImageMPR::_aOpenDICOMSeries( ) { ImageMPR_ReadImage( DicomSeries ) }
140 // -------------------------------------------------------------------------
142 _aOpenSegmentation( )
145 if( this->m_ImageLoaded != "" )
146 this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
150 // -------------------------------------------------------------------------
156 // -------------------------------------------------------------------------
161 std::string data_name = this->m_UI->MPR->GetSelectedData( );
162 this->m_Plugins->WriteImage( data_name );
166 // -------------------------------------------------------------------------
168 _aSaveSegmentation( )
172 // -------------------------------------------------------------------------
178 // -------------------------------------------------------------------------
184 // -------------------------------------------------------------------------
190 // -------------------------------------------------------------------------
194 this->m_Plugins.DialogLoadPlugins( );
195 this->_AssociatePluginsToMenu( );
198 // -------------------------------------------------------------------------
204 // -------------------------------------------------------------------------
209 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
212 std::string filter_name = action->text( ).toStdString( );
215 if( !( this->m_Plugins.ActivateFilter( filter_name ) ) )
219 TPlugins::TStringContainer inputs;
220 this->m_Plugins.GetActiveFilterInputsNames( inputs );
223 if( inputs.size( ) > 1 )
227 else if( inputs.size( ) == 1 )
229 this->m_ActiveFilterMainInput = this->m_UI->MPR->GetSelectedData( );
230 this->m_Plugins.ConnectInputInActiveFilter(
231 this->m_ActiveFilterMainInput, *( inputs.begin( ) )
236 // Configure paramereters
237 auto dlg_res = this->m_Plugins.ConfigureActiveFilter( );
238 if( dlg_res == TPlugins::TProcessObject::DialogResult_Cancel )
240 // Just deactivate filter, since it was canceled
241 this->m_Plugins.DeactivateFilter( );
244 else if( dlg_res == TPlugins::TProcessObject::DialogResult_NoModal )
246 // Execute automatic filter and associate outputs
247 this->UpdateActualFilter( );
248 this->m_Plugins.DeactivateFilter( );
253 // -------------------------------------------------------------------------
256 _CursorCommand( double* pos, int axis, void* data )
258 Self* app = reinterpret_cast< Self* >( data );
261 if( !( app->m_Flooding ) )
264 cpPlugins::Interface::ProcessObject::Pointer filter =
265 app->m_UI->MPR->CreateFilter(
266 "cpPlugins::BasicFilters::FloodFillImageFilter"
268 if( filter.IsNull( ) )
271 cpPlugins::Interface::Parameters* params = filter->GetParameters( );
272 params->SetPoint( "Seed", 3, pos );
273 params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) );
274 params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) );
275 params->SetUint( "InsideValue", 1 );
276 params->SetUint( "OutsideValue", 0 );
277 filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) );
278 app->m_UI->MPR->Block( );
279 std::string err = filter->Update( );
280 cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" );
281 filter->DisconnectOutputs( );
282 app->m_UI->MPR->AddImage( "Segmentation", image );
283 app->m_UI->MPR->Unblock( );
286 << "CursorCommand ==> "
291 << data << std::endl;
296 #include "MementoState.h"
298 #include <vtkProperty.h>
299 #include <vtkRenderWindow.h>
300 #include <vtkMetaImageReader.h>
302 #include <QFileDialog>
303 #include <QMessageBox>
306 # define PLUGIN_PREFIX ""
307 # define PLUGIN_EXT "dll"
308 # define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
310 # define PLUGIN_PREFIX "lib"
311 # define PLUGIN_EXT "so"
312 # define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
315 // -------------------------------------------------------------------------
316 ImageMPR::ImageMPR( QWidget* parent )
317 : QMainWindow( parent ),
318 m_UI( new Ui::ImageMPR ),
319 m_ImageReaderClass( "" ),
320 m_ImageWriterClass( "" ),
321 m_MeshReaderClass( "" ),
322 m_MeshWriterClass( "" ),
323 m_MeshCutterClass( "" ),
328 this->m_UI->setupUi( this );
330 // Create and associate renderers
331 this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
332 this->m_MPRObjects->SetRenderWindows(
333 this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
334 this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
335 this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
336 this->m_UI->m_3DVTK->GetRenderWindow( )
341 this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
342 this, SLOT( _triggered_actionOpenPlugins( ) )
345 this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
346 this, SLOT( _triggered_actionOpenInputImage( ) )
349 this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
350 this, SLOT( _triggered_actionOpenSegmentation( ) )
353 this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
354 this, SLOT( _triggered_actionOpenInputPolyData( ) )
357 this->m_UI->actionUndo, SIGNAL(triggered()),
358 this, SLOT(_triggered_actionUndo())
361 this->m_UI->actionRedo, SIGNAL(triggered()),
362 this, SLOT(_triggered_actionRedo())
365 // Start: load all disponible plugins
367 std::string( PLUGIN_PREFIX ) +
368 std::string( "cpPluginsIO." ) +
369 std::string( PLUGIN_EXT )
372 std::string( PLUGIN_PREFIX ) +
373 std::string( "cpPluginsBasicFilters." ) +
374 std::string( PLUGIN_EXT )
378 // -------------------------------------------------------------------------
382 // Close all connections
383 this->m_Plugins.UnloadAll( );
389 // -------------------------------------------------------------------------
391 _LoadPlugins( const std::string& filename )
393 QApplication::setOverrideCursor( Qt::WaitCursor );
394 this->setEnabled( false );
396 this->m_ImageReaderClass = "";
397 this->m_ImageWriterClass = "";
398 this->m_MeshReaderClass = "";
399 this->m_MeshWriterClass = "";
400 this->m_MeshCutterClass = "";
401 this->m_UI->MenuImageToImage->clear( );
402 this->m_UI->MenuImageToMesh->clear( );
404 if( !( this->m_Plugins.Load( filename ) ) )
407 typedef TPluginsInterface::TClasses _TClasses;
408 _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
409 for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
411 TPluginFilter::Pointer o =
412 this->m_Plugins.CreateProcessObject( cIt->first );
413 std::string name = o->GetClassName( );
414 std::string category = o->GetClassCategory( );
415 if( category == "ImageReader" )
416 this->m_ImageReaderClass = name;
417 else if( category == "ImageWriter" )
418 this->m_ImageWriterClass = name;
419 else if( category == "MeshReader" )
420 this->m_MeshReaderClass = name;
421 else if( category == "MeshWriter" )
422 this->m_MeshWriterClass = name;
423 else if( category == "MeshToMeshFilter" )
425 if( name.find_last_of( "Cutter" ) != std::string::npos )
426 this->m_MeshCutterClass = name;
428 else if( category == "ImageToImageFilter" )
431 this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
433 action, SIGNAL( triggered( ) ),
434 this, SLOT( _triggered_actionImageToImage( ) )
437 else if( category == "ImageToMeshFilter" )
440 this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
442 action, SIGNAL( triggered( ) ),
443 this, SLOT( _triggered_actionImageToMesh( ) )
449 QApplication::restoreOverrideCursor( );
450 this->setEnabled( true );
455 // -------------------------------------------------------------------------
456 std::string ImageMPR::
457 _LoadImage( TPluginImage::Pointer& image )
459 std::string ret = "";
462 // Get a reader from loaded plugins
463 TPluginFilter::Pointer reader =
464 this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
465 if( reader.IsNotNull( ) )
467 if( reader->ExecConfigurationDialog( this ) )
470 QApplication::setOverrideCursor( Qt::WaitCursor );
471 this->setEnabled( false );
473 // Execute and get error message, if any
474 ret = reader->Update( );
476 // Assign fresh image, if any
479 image = reader->GetOutput< TPluginImage >( 0 );
480 reader->DisconnectOutputs( );
484 // Unblock application
485 QApplication::restoreOverrideCursor( );
486 this->setEnabled( true );
491 ret = "No suitable reader object found in loaded plugins.";
496 // -------------------------------------------------------------------------
497 std::string ImageMPR::
498 _ConfigureMeshActors( )
500 if( this->m_Mesh.IsNull( ) )
501 return( "Valid mesh not found." );
503 this->m_Mesh->CreateVTKActor( );
504 vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
505 if( vtk_actor != NULL )
507 this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
508 this->m_MPRObjects->Render( 4 );
512 TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
514 std::string err = "";
515 for( unsigned int i = 0; i < 3; ++i )
517 this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
518 this->m_Planes[ i ] = TPluginImplicitFunction::New( );
519 this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
520 this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
521 this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
522 std::string lerr = this->m_Cutters[ i ]->Update( );
525 this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
526 vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
527 mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
529 this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
531 this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
533 this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
539 this->m_MPRObjects->RenderAll( );
543 // -------------------------------------------------------------------------
545 _triggered_actionOpenPlugins( )
547 // Show dialog and check if it was accepted
548 QFileDialog dialog( this );
549 dialog.setFileMode( QFileDialog::ExistingFile );
550 dialog.setDirectory( "." );
551 dialog.setNameFilter( tr( PLUGIN_REGEX ) );
552 dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
553 if( !( dialog.exec( ) ) )
556 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
557 if( !( _LoadPlugins( fname ) ) )
558 QMessageBox::critical(
560 tr( "Ignoring plugin" ),
565 // -------------------------------------------------------------------------
567 _triggered_actionOpenInputImage( )
570 std::string err = this->_LoadImage( this->m_Image );
573 vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
576 this->m_MPRObjects->SetImage( vtk_id );
577 this->m_MPRObjects->ActivateInteractors( );
578 this->m_MPRObjects->ResetCameras( );
579 this->m_MPRObjects->RenderAll( );
581 MementoState(m_state, this->m_Image);
585 QMessageBox::critical(
587 tr( "Error message" ),
588 tr( "Read image does not have a valid VTK converter." )
592 QMessageBox::critical(
594 tr( "Error reading single image" ),
599 // -------------------------------------------------------------------------
601 _triggered_actionOpenSegmentation( )
603 if( this->m_Image.IsNull( ) )
605 QMessageBox::critical(
607 tr( "Error message" ),
608 tr( "Before reading a segmentation, first load a raw image." )
615 std::string err = this->_LoadImage( this->m_Segmentation );
618 vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
621 this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
622 this->m_MPRObjects->RenderAll( );
625 QMessageBox::critical(
627 tr( "Error message" ),
628 tr( "Read image does not have a valid VTK converter." )
632 QMessageBox::critical(
634 tr( "Error reading single image" ),
639 // -------------------------------------------------------------------------
641 _triggered_actionOpenInputPolyData( )
645 // Get a reader from plugins
646 TPluginFilter::Pointer reader =
647 this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
649 if( reader.IsNotNull( ) )
652 if( reader->ExecConfigurationDialog( this ) )
654 // Execute and get error message, if any
655 QApplication::setOverrideCursor( Qt::WaitCursor );
656 this->setEnabled( false );
657 std::string err = reader->Update( );
658 QApplication::restoreOverrideCursor( );
659 this->setEnabled( true );
661 // Assign fresh mesh, if any
664 this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
665 reader->DisconnectOutputs( );
666 err = this->_ConfigureMeshActors( );
668 QMessageBox::critical(
670 tr( "Error message" ),
675 QMessageBox::critical(
677 tr( "Error reading mesh" ),
684 QMessageBox::critical(
686 tr( "Error reading single mesh" ),
687 tr( "No suitable mesh reader found in loaded plugins." )
691 // -------------------------------------------------------------------------
693 _triggered_actionImageToImage( )
695 if( this->m_Image.IsNull( ) )
699 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
702 std::string name = action->text( ).toStdString( );
705 TPluginFilter::Pointer filter =
706 this->m_Plugins.CreateProcessObject( name );
707 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
712 QApplication::setOverrideCursor( Qt::WaitCursor );
713 this->setEnabled( false );
714 filter->SetInput( 0, this->m_Image );
715 std::string err = filter->Update( );
716 QApplication::restoreOverrideCursor( );
717 this->setEnabled( true );
722 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
723 result->DisconnectPipeline( );
724 this->m_Image = result;
725 if( this->m_Image.IsNotNull( ) )
726 this->m_MPRObjects->SetImage(
727 this->m_Image->GetVTK< vtkImageData >( )
732 MementoState(this->m_state, this->m_Image);
734 if (this->m_state > this->m_max_state)
736 this->m_max_state = this->m_state;
740 QMessageBox::critical(
742 tr( "Error executing filter" ),
747 // -------------------------------------------------------------------------
749 _triggered_actionImageToMesh( )
751 if( this->m_Image.IsNull( ) )
755 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
758 std::string name = action->text( ).toStdString( );
761 TPluginFilter::Pointer filter =
762 this->m_Plugins.CreateProcessObject( name );
763 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
768 QApplication::setOverrideCursor( Qt::WaitCursor );
769 this->setEnabled( false );
770 filter->SetInput( 0, this->m_Image );
771 std::string err = filter->Update( );
772 QApplication::restoreOverrideCursor( );
773 this->setEnabled( true );
778 TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
779 result->DisconnectPipeline( );
780 this->m_Mesh = result;
781 err = this->_ConfigureMeshActors( );
783 QMessageBox::critical(
785 tr( "Error message" ),
790 QMessageBox::critical(
792 tr( "Error executing filter" ),
797 // -------------------------------------------------------------------------
799 _triggered_actionUndo()
801 MementoState memento = MementoState();
806 this->m_MPRObjects->SetImage(
807 memento.getMemento(this->m_state)->GetOutput()
811 QMessageBox::warning(
814 tr("No history to undo")
820 // -------------------------------------------------------------------------
822 _triggered_actionRedo()
824 MementoState memento = MementoState();
825 if (this->m_state + 1 <= m_max_state)
828 this->m_MPRObjects->SetImage(
829 memento.getMemento(this->m_state)->GetOutput()
833 QMessageBox::warning(
836 tr("No history to redo")