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 ),
21 this->m_UI->setupUi( this );
22 this->m_Plugins->SetWidget( 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 // 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( ) )
44 // -------------------------------------------------------------------------
49 delete this->m_Plugins;
52 // -------------------------------------------------------------------------
56 if( this->m_MainImage.IsNotNull( ) )
57 this->m_UI->MPR->ClearAll( );
58 if( this->m_Plugins->ReadImage( this->m_MainImage, true ) )
60 vtkImageData* vimage = this->m_MainImage->GetVTK< vtkImageData >( );
62 QMessageBox::critical(
64 QMessageBox::tr( "Error showing image." ),
66 "Image was read, but no valid VTK conversion was found."
70 this->m_UI->MPR->ShowImage( vimage );
75 // -------------------------------------------------------------------------
79 if( this->m_MainImage.IsNotNull( ) )
80 this->m_UI->MPR->ClearAll( );
81 if( this->m_Plugins->ReadDicomSeries( this->m_MainImage ) )
83 vtkImageData* vimage = this->m_MainImage->GetVTK< vtkImageData >( );
85 QMessageBox::critical(
87 QMessageBox::tr( "Error showing image." ),
89 "Image was read, but no valid VTK conversion was found."
93 this->m_UI->MPR->ShowImage( vimage );
98 // -------------------------------------------------------------------------
100 _aOpenSegmentation( )
103 if( this->m_ImageLoaded != "" )
104 this->m_ImageLoaded = this->m_UI->MPR->LoadImage( );
108 // -------------------------------------------------------------------------
114 // -------------------------------------------------------------------------
118 if( this->m_MainImage.IsNotNull( ) )
119 this->m_Plugins->WriteImage( this->m_MainImage, true );
122 // -------------------------------------------------------------------------
124 _aSaveSegmentation( )
128 // -------------------------------------------------------------------------
134 // -------------------------------------------------------------------------
140 // -------------------------------------------------------------------------
146 // -------------------------------------------------------------------------
150 this->m_Plugins->DialogLoadPlugins( );
151 this->m_Plugins->AssociatePluginsToMenu(
152 this->m_UI->MenuFilters, this, SLOT( _execPlugin( ) )
156 // -------------------------------------------------------------------------
162 // -------------------------------------------------------------------------
167 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
170 QMenu* menu = dynamic_cast< QMenu* >( action->parentWidget( ) );
173 std::string cate = menu->title( ).toStdString( );
174 std::string name = action->text( ).toStdString( );
175 std::string err = "";
177 TPlugins::TProcessObject::Pointer filter;
178 if( this->m_Plugins->CreateFilter( filter, name ) )
180 if( cate == "ImageToMeshFilter" )
182 if( filter->ExecConfigurationDialog( this ) )
184 filter->SetInput( "Input", this->m_MainImage );
186 err = filter->Update( );
188 TPlugins::TMesh::Pointer mesh =
189 filter->GetOutput< TPlugins::TMesh >( "Input" );
190 mesh->Print( std::cout );
197 QMessageBox::critical(
199 tr( "Error creating filter" ),
200 tr( "No valid filter defined." )
204 if( name == "cpPlugins::BasicFilters::FloodFillImageFilter" )
206 this->m_Flooding = true;
210 this->m_Flooding = false;
211 this->m_UI->MPR->ExecuteFilter(
212 name, this->m_ImageLoaded, "SegmentedImage"
220 TPluginFilter::Pointer filter =
221 this->m_Plugins.CreateProcessObject( name );
222 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
227 QApplication::setOverrideCursor( Qt::WaitCursor );
228 this->setEnabled( false );
229 filter->SetInput( 0, this->m_Image );
230 std::string err = filter->Update( );
231 QApplication::restoreOverrideCursor( );
232 this->setEnabled( true );
237 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
238 result->DisconnectPipeline( );
239 this->m_Image = result;
240 if( this->m_Image.IsNotNull( ) )
241 this->m_MPRObjects->SetImage(
242 this->m_Image->GetVTK< vtkImageData >( )
244 MementoState(this->m_state, this->m_Image);
246 if (this->m_state > this->m_max_state)
248 this->m_max_state = this->m_state;
252 QMessageBox::critical(
254 tr( "Error executing filter" ),
260 // -------------------------------------------------------------------------
263 _CursorCommand( double* pos, int axis, void* data )
265 Self* app = reinterpret_cast< Self* >( data );
268 if( !( app->m_Flooding ) )
271 cpPlugins::Interface::ProcessObject::Pointer filter =
272 app->m_UI->MPR->CreateFilter(
273 "cpPlugins::BasicFilters::FloodFillImageFilter"
275 if( filter.IsNull( ) )
278 cpPlugins::Interface::Parameters* params = filter->GetParameters( );
279 params->SetPoint( "Seed", 3, pos );
280 params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) );
281 params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) );
282 params->SetUint( "InsideValue", 1 );
283 params->SetUint( "OutsideValue", 0 );
284 filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) );
285 app->m_UI->MPR->Block( );
286 std::string err = filter->Update( );
287 cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" );
288 filter->DisconnectOutputs( );
289 app->m_UI->MPR->AddImage( "Segmentation", image );
290 app->m_UI->MPR->Unblock( );
293 << "CursorCommand ==> "
298 << data << std::endl;
303 #include "MementoState.h"
305 #include <vtkProperty.h>
306 #include <vtkRenderWindow.h>
307 #include <vtkMetaImageReader.h>
309 #include <QFileDialog>
310 #include <QMessageBox>
313 # define PLUGIN_PREFIX ""
314 # define PLUGIN_EXT "dll"
315 # define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
317 # define PLUGIN_PREFIX "lib"
318 # define PLUGIN_EXT "so"
319 # define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
322 // -------------------------------------------------------------------------
323 ImageMPR::ImageMPR( QWidget* parent )
324 : QMainWindow( parent ),
325 m_UI( new Ui::ImageMPR ),
326 m_ImageReaderClass( "" ),
327 m_ImageWriterClass( "" ),
328 m_MeshReaderClass( "" ),
329 m_MeshWriterClass( "" ),
330 m_MeshCutterClass( "" ),
335 this->m_UI->setupUi( this );
337 // Create and associate renderers
338 this->m_MPRObjects = vtkSmartPointer< TMPRObjects >::New( );
339 this->m_MPRObjects->SetRenderWindows(
340 this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
341 this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
342 this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
343 this->m_UI->m_3DVTK->GetRenderWindow( )
348 this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
349 this, SLOT( _triggered_actionOpenPlugins( ) )
352 this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
353 this, SLOT( _triggered_actionOpenInputImage( ) )
356 this->m_UI->actionOpenSegmentation, SIGNAL( triggered( ) ),
357 this, SLOT( _triggered_actionOpenSegmentation( ) )
360 this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
361 this, SLOT( _triggered_actionOpenInputPolyData( ) )
364 this->m_UI->actionUndo, SIGNAL(triggered()),
365 this, SLOT(_triggered_actionUndo())
368 this->m_UI->actionRedo, SIGNAL(triggered()),
369 this, SLOT(_triggered_actionRedo())
372 // Start: load all disponible plugins
374 std::string( PLUGIN_PREFIX ) +
375 std::string( "cpPluginsIO." ) +
376 std::string( PLUGIN_EXT )
379 std::string( PLUGIN_PREFIX ) +
380 std::string( "cpPluginsBasicFilters." ) +
381 std::string( PLUGIN_EXT )
385 // -------------------------------------------------------------------------
389 // Close all connections
390 this->m_Plugins.UnloadAll( );
396 // -------------------------------------------------------------------------
398 _LoadPlugins( const std::string& filename )
400 QApplication::setOverrideCursor( Qt::WaitCursor );
401 this->setEnabled( false );
403 this->m_ImageReaderClass = "";
404 this->m_ImageWriterClass = "";
405 this->m_MeshReaderClass = "";
406 this->m_MeshWriterClass = "";
407 this->m_MeshCutterClass = "";
408 this->m_UI->MenuImageToImage->clear( );
409 this->m_UI->MenuImageToMesh->clear( );
411 if( !( this->m_Plugins.Load( filename ) ) )
414 typedef TPluginsInterface::TClasses _TClasses;
415 _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
416 for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
418 TPluginFilter::Pointer o =
419 this->m_Plugins.CreateProcessObject( cIt->first );
420 std::string name = o->GetClassName( );
421 std::string category = o->GetClassCategory( );
422 if( category == "ImageReader" )
423 this->m_ImageReaderClass = name;
424 else if( category == "ImageWriter" )
425 this->m_ImageWriterClass = name;
426 else if( category == "MeshReader" )
427 this->m_MeshReaderClass = name;
428 else if( category == "MeshWriter" )
429 this->m_MeshWriterClass = name;
430 else if( category == "MeshToMeshFilter" )
432 if( name.find_last_of( "Cutter" ) != std::string::npos )
433 this->m_MeshCutterClass = name;
435 else if( category == "ImageToImageFilter" )
438 this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
440 action, SIGNAL( triggered( ) ),
441 this, SLOT( _triggered_actionImageToImage( ) )
444 else if( category == "ImageToMeshFilter" )
447 this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
449 action, SIGNAL( triggered( ) ),
450 this, SLOT( _triggered_actionImageToMesh( ) )
456 QApplication::restoreOverrideCursor( );
457 this->setEnabled( true );
462 // -------------------------------------------------------------------------
463 std::string ImageMPR::
464 _LoadImage( TPluginImage::Pointer& image )
466 std::string ret = "";
469 // Get a reader from loaded plugins
470 TPluginFilter::Pointer reader =
471 this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
472 if( reader.IsNotNull( ) )
474 if( reader->ExecConfigurationDialog( this ) )
477 QApplication::setOverrideCursor( Qt::WaitCursor );
478 this->setEnabled( false );
480 // Execute and get error message, if any
481 ret = reader->Update( );
483 // Assign fresh image, if any
486 image = reader->GetOutput< TPluginImage >( 0 );
487 reader->DisconnectOutputs( );
491 // Unblock application
492 QApplication::restoreOverrideCursor( );
493 this->setEnabled( true );
498 ret = "No suitable reader object found in loaded plugins.";
503 // -------------------------------------------------------------------------
504 std::string ImageMPR::
505 _ConfigureMeshActors( )
507 if( this->m_Mesh.IsNull( ) )
508 return( "Valid mesh not found." );
510 this->m_Mesh->CreateVTKActor( );
511 vtkActor* vtk_actor = this->m_Mesh->GetVTKActor( );
512 if( vtk_actor != NULL )
514 this->m_MPRObjects->Get3DRenderer( )->AddActor( vtk_actor );
515 this->m_MPRObjects->Render( 4 );
519 TMPRObjects::TMPRActors* mprActors = this->m_MPRObjects->GetMPRActors( );
521 std::string err = "";
522 for( unsigned int i = 0; i < 3; ++i )
524 this->m_Cutters[ i ] = this->m_Plugins.CreateProcessObject( this->m_MeshCutterClass );
525 this->m_Planes[ i ] = TPluginImplicitFunction::New( );
526 this->m_Planes[ i ]->SetFunction( mprActors->GetSliceActors( i )->GetPlaneFunction( ) );
527 this->m_Cutters[ i ]->SetInput( 0, this->m_Mesh );
528 this->m_Cutters[ i ]->SetInput( 1, this->m_Planes[ i ] );
529 std::string lerr = this->m_Cutters[ i ]->Update( );
532 this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->CreateVTKActor( );
533 vtkActor* actor = this->m_Cutters[ i ]->GetOutput< TPluginMesh >( 0 )->GetVTKActor( );
534 mprActors->GetSliceActors( i )->AddActor( this->m_Cutters[ i ]->GetVTK< vtkAlgorithm >( ), actor );
536 this->m_MPRObjects->GetXRenderer( )->AddActor( actor );
538 this->m_MPRObjects->GetYRenderer( )->AddActor( actor );
540 this->m_MPRObjects->GetZRenderer( )->AddActor( actor );
546 this->m_MPRObjects->RenderAll( );
550 // -------------------------------------------------------------------------
552 _triggered_actionOpenPlugins( )
554 // Show dialog and check if it was accepted
555 QFileDialog dialog( this );
556 dialog.setFileMode( QFileDialog::ExistingFile );
557 dialog.setDirectory( "." );
558 dialog.setNameFilter( tr( PLUGIN_REGEX ) );
559 dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
560 if( !( dialog.exec( ) ) )
563 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
564 if( !( _LoadPlugins( fname ) ) )
565 QMessageBox::critical(
567 tr( "Ignoring plugin" ),
572 // -------------------------------------------------------------------------
574 _triggered_actionOpenInputImage( )
577 std::string err = this->_LoadImage( this->m_Image );
580 vtkImageData* vtk_id = this->m_Image->GetVTK< vtkImageData >( );
583 this->m_MPRObjects->SetImage( vtk_id );
584 this->m_MPRObjects->ActivateInteractors( );
585 this->m_MPRObjects->ResetCameras( );
586 this->m_MPRObjects->RenderAll( );
588 MementoState(m_state, this->m_Image);
592 QMessageBox::critical(
594 tr( "Error message" ),
595 tr( "Read image does not have a valid VTK converter." )
599 QMessageBox::critical(
601 tr( "Error reading single image" ),
606 // -------------------------------------------------------------------------
608 _triggered_actionOpenSegmentation( )
610 if( this->m_Image.IsNull( ) )
612 QMessageBox::critical(
614 tr( "Error message" ),
615 tr( "Before reading a segmentation, first load a raw image." )
622 std::string err = this->_LoadImage( this->m_Segmentation );
625 vtkImageData* vtk_id = this->m_Segmentation->GetVTK< vtkImageData >( );
628 this->m_MPRObjects->AddAuxiliaryImage( vtk_id );
629 this->m_MPRObjects->RenderAll( );
632 QMessageBox::critical(
634 tr( "Error message" ),
635 tr( "Read image does not have a valid VTK converter." )
639 QMessageBox::critical(
641 tr( "Error reading single image" ),
646 // -------------------------------------------------------------------------
648 _triggered_actionOpenInputPolyData( )
652 // Get a reader from plugins
653 TPluginFilter::Pointer reader =
654 this->m_Plugins.CreateProcessObject( this->m_MeshReaderClass );
656 if( reader.IsNotNull( ) )
659 if( reader->ExecConfigurationDialog( this ) )
661 // Execute and get error message, if any
662 QApplication::setOverrideCursor( Qt::WaitCursor );
663 this->setEnabled( false );
664 std::string err = reader->Update( );
665 QApplication::restoreOverrideCursor( );
666 this->setEnabled( true );
668 // Assign fresh mesh, if any
671 this->m_Mesh = reader->GetOutput< TPluginMesh >( 0 );
672 reader->DisconnectOutputs( );
673 err = this->_ConfigureMeshActors( );
675 QMessageBox::critical(
677 tr( "Error message" ),
682 QMessageBox::critical(
684 tr( "Error reading mesh" ),
691 QMessageBox::critical(
693 tr( "Error reading single mesh" ),
694 tr( "No suitable mesh reader found in loaded plugins." )
698 // -------------------------------------------------------------------------
700 _triggered_actionImageToImage( )
702 if( this->m_Image.IsNull( ) )
706 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
709 std::string name = action->text( ).toStdString( );
712 TPluginFilter::Pointer filter =
713 this->m_Plugins.CreateProcessObject( name );
714 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
719 QApplication::setOverrideCursor( Qt::WaitCursor );
720 this->setEnabled( false );
721 filter->SetInput( 0, this->m_Image );
722 std::string err = filter->Update( );
723 QApplication::restoreOverrideCursor( );
724 this->setEnabled( true );
729 TPluginImage* result = filter->GetOutput< TPluginImage >( 0 );
730 result->DisconnectPipeline( );
731 this->m_Image = result;
732 if( this->m_Image.IsNotNull( ) )
733 this->m_MPRObjects->SetImage(
734 this->m_Image->GetVTK< vtkImageData >( )
739 MementoState(this->m_state, this->m_Image);
741 if (this->m_state > this->m_max_state)
743 this->m_max_state = this->m_state;
747 QMessageBox::critical(
749 tr( "Error executing filter" ),
754 // -------------------------------------------------------------------------
756 _triggered_actionImageToMesh( )
758 if( this->m_Image.IsNull( ) )
762 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
765 std::string name = action->text( ).toStdString( );
768 TPluginFilter::Pointer filter =
769 this->m_Plugins.CreateProcessObject( name );
770 bool dlg_ok = filter->ExecConfigurationDialog( NULL );
775 QApplication::setOverrideCursor( Qt::WaitCursor );
776 this->setEnabled( false );
777 filter->SetInput( 0, this->m_Image );
778 std::string err = filter->Update( );
779 QApplication::restoreOverrideCursor( );
780 this->setEnabled( true );
785 TPluginMesh* result = filter->GetOutput< TPluginMesh >( 0 );
786 result->DisconnectPipeline( );
787 this->m_Mesh = result;
788 err = this->_ConfigureMeshActors( );
790 QMessageBox::critical(
792 tr( "Error message" ),
797 QMessageBox::critical(
799 tr( "Error executing filter" ),
804 // -------------------------------------------------------------------------
806 _triggered_actionUndo()
808 MementoState memento = MementoState();
813 this->m_MPRObjects->SetImage(
814 memento.getMemento(this->m_state)->GetOutput()
818 QMessageBox::warning(
821 tr("No history to undo")
827 // -------------------------------------------------------------------------
829 _triggered_actionRedo()
831 MementoState memento = MementoState();
832 if (this->m_state + 1 <= m_max_state)
835 this->m_MPRObjects->SetImage(
836 memento.getMemento(this->m_state)->GetOutput()
840 QMessageBox::warning(
843 tr("No history to redo")