From 91f750d8a54e87cdd626566aad3d80940ae041fd Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Wed, 14 Oct 2015 18:30:05 -0500 Subject: [PATCH] Widget integration (step 6/6): Interactive architecture finished. Needs to be tested on windows --- appli/ImageMPR/ImageMPR.cxx | 68 ++++++++++++- appli/ImageMPR/ImageMPR.h | 16 +++- appli/examples/CMakeLists.txt | 8 +- appli/examples/example_MPR.cxx | 21 ++-- .../Visualization/ImageSliceActors.cxx | 95 ++++++++++--------- .../Visualization/ImageSliceActors.h | 20 ++++ lib/cpExtensions/Visualization/MPRActors.cxx | 41 ++++++++ lib/cpExtensions/Visualization/MPRActors.h | 28 ++++++ lib/cpExtensions/Visualization/MPRObjects.h | 26 +++++ lib/cpPlugins/Interface/BaseMPRWindow.cxx | 67 +++++++++---- lib/cpPlugins/Interface/BaseMPRWindow.h | 51 ++++++++-- lib/cpPlugins/Interface/Parameters.cxx | 28 +++++- lib/cpPlugins/Interface/Parameters.h | 9 ++ lib/cpPlugins/Interface/ProcessObject.cxx | 56 ++++++----- lib/cpPlugins/Interface/ProcessObject.h | 28 +++--- lib/cpPlugins/Interface/ProcessObject.hxx | 41 ++++---- .../BasicFilters/BinaryErodeImageFilter.cxx | 11 +-- .../BinaryThresholdImageFilter.cxx | 19 ++-- lib/cpPlugins/Plugins/BasicFilters/Cutter.cxx | 14 +-- .../BasicFilters/ExtractSliceImageFilter.cxx | 9 +- .../BasicFilters/FloodFillImageFilter.cxx | 54 +++++++++-- .../BasicFilters/FloodFillImageFilter.h | 2 +- .../Plugins/BasicFilters/MarchingCubes.cxx | 9 +- .../BasicFilters/MedianImageFilter.cxx | 9 +- .../BasicFilters/OtsuThresholdImageFilter.cxx | 7 +- .../RGBImageToOtherChannelsFilter.cxx | 9 +- .../Plugins/BasicFilters/SphereMeshSource.cxx | 6 +- lib/cpPlugins/Plugins/IO/ImageReader.cxx | 5 +- lib/cpPlugins/Plugins/IO/ImageWriter.cxx | 6 +- lib/cpPlugins/Plugins/IO/MeshReader.cxx | 5 +- lib/cpPlugins/Plugins/IO/MeshWriter.cxx | 4 +- 31 files changed, 557 insertions(+), 215 deletions(-) diff --git a/appli/ImageMPR/ImageMPR.cxx b/appli/ImageMPR/ImageMPR.cxx index ada90ea..58276cb 100644 --- a/appli/ImageMPR/ImageMPR.cxx +++ b/appli/ImageMPR/ImageMPR.cxx @@ -13,10 +13,14 @@ ImageMPR:: ImageMPR( QWidget* parent ) : QMainWindow( parent ), m_UI( new Ui::ImageMPR ), - m_ImageLoaded( false ) + m_ImageLoaded( "" ), + m_Flooding( false ) { this->m_UI->setupUi( this ); + // Associate callbacks + this->m_UI->MPR->AddCursorCommand( Self::_CursorCommand, this ); + // Connect actions ImageMPR_ConnectAction( OpenImage ); ImageMPR_ConnectAction( OpenSegmentation ); @@ -47,7 +51,7 @@ ImageMPR:: void ImageMPR:: _aOpenImage( ) { - if( this->m_ImageLoaded ) + if( this->m_ImageLoaded != "" ) this->m_UI->MPR->ClearAll( ); this->m_ImageLoaded = this->m_UI->MPR->LoadImage( ); } @@ -56,7 +60,7 @@ _aOpenImage( ) void ImageMPR:: _aOpenSegmentation( ) { - if( this->m_ImageLoaded ) + if( this->m_ImageLoaded != "" ) this->m_ImageLoaded = this->m_UI->MPR->LoadImage( ); } @@ -121,7 +125,19 @@ _execPlugin( ) if( action == NULL ) return; std::string name = action->text( ).toStdString( ); - this->m_UI->MPR->ExecuteFilter( name, 0 ); + + if( name == "cpPlugins::BasicFilters::FloodFillImageFilter" ) + { + this->m_Flooding = true; + } + else + { + this->m_Flooding = false; + this->m_UI->MPR->ExecuteFilter( + name, this->m_ImageLoaded, "SegmentedImage" + ); + + } // fi // Configure filter /* @@ -165,6 +181,50 @@ _execPlugin( ) */ } +// ------------------------------------------------------------------------- +void ImageMPR:: +_CursorCommand( double* pos, int axis, void* data ) +{ + Self* app = reinterpret_cast< Self* >( data ); + if( app == NULL ) + return; + if( !( app->m_Flooding ) ) + return; + + cpPlugins::Interface::ProcessObject::Pointer filter = + app->m_UI->MPR->CreateFilter( + "cpPlugins::BasicFilters::FloodFillImageFilter" + ); + if( filter.IsNull( ) ) + return; + + cpPlugins::Interface::Parameters* params = filter->GetParameters( ); + params->SetPoint( "Seed", 3, pos ); + params->SetReal( "Window", app->m_UI->MPR->GetWindow( ) ); + params->SetReal( "Level", app->m_UI->MPR->GetLevel( ) ); + params->SetUint( "InsideValue", 1 ); + params->SetUint( "OutsideValue", 0 ); + filter->SetInput( "Input", app->m_UI->MPR->GetImage( app->m_ImageLoaded ) ); + app->m_UI->MPR->Block( ); + std::string err = filter->Update( ); + cpPlugins::Interface::BaseMPRWindow::TImage::Pointer image = filter->GetOutput< cpPlugins::Interface::BaseMPRWindow::TImage >( "Output" ); + filter->DisconnectOutputs( ); + app->m_UI->MPR->AddImage( "Segmentation", image ); + app->m_UI->MPR->Unblock( ); + + + + /* TODO + std::cout + << "CursorCommand ==> " + << pos[ 0 ] << " " + << pos[ 1 ] << " " + << pos[ 2 ] << " : " + << axis << " " + << data << std::endl; + */ +} + /* #include "MementoState.h" diff --git a/appli/ImageMPR/ImageMPR.h b/appli/ImageMPR/ImageMPR.h index 1cc16c9..a89d0f9 100644 --- a/appli/ImageMPR/ImageMPR.h +++ b/appli/ImageMPR/ImageMPR.h @@ -119,6 +119,15 @@ class ImageMPR Q_OBJECT; public: + typedef ImageMPR Self; + typedef QMainWindow Superclass; + + typedef cpExtensions::Visualization::MPRObjects TMPRObjects; + typedef TMPRObjects::TCursorCommand TCursorCommand; + typedef TMPRObjects::TMouseCommand TMouseCommand; + typedef TMPRObjects::TMouseWheelCommand TMouseWheelCommand; + typedef TMPRObjects::TKeyCommand TKeyCommand; + // Plugins types /* typedef cpPlugins::Interface::Interface TPluginsInterface; @@ -157,11 +166,16 @@ private slots: void _execPlugin( ); +protected: + // Callbacks + static void _CursorCommand( double* pos, int axis, void* data ); + private: Ui::ImageMPR* m_UI; // Some state flags - bool m_ImageLoaded; + std::string m_ImageLoaded; + bool m_Flooding; // Plugins objects /* diff --git a/appli/examples/CMakeLists.txt b/appli/examples/CMakeLists.txt index 2fd980d..5174333 100644 --- a/appli/examples/CMakeLists.txt +++ b/appli/examples/CMakeLists.txt @@ -26,8 +26,9 @@ ENDFOREACH(prog) SET( EXAMPLES_PROGRAMS_WITH_PLUGINS - example_ReadWriteImage - example_View2DImage + #example_ReadWriteImage + #example_MPR + #example_View2DImage ##example_MarchingCubes ##example_OtsuFilter ##example_RGBImageToHSVChannels @@ -38,8 +39,7 @@ SET( ##example_MPR ) - -FOREACH(prog ${EXAMPLES_PROGRAMS}) +FOREACH(prog ${EXAMPLES_PROGRAMS_WITH_PLUGINS}) ADD_EXECUTABLE( ${prog} ${prog}.cxx diff --git a/appli/examples/example_MPR.cxx b/appli/examples/example_MPR.cxx index 9f6e113..dca9084 100644 --- a/appli/examples/example_MPR.cxx +++ b/appli/examples/example_MPR.cxx @@ -35,6 +35,7 @@ public: } virtual void Execute( vtkObject* caller, unsigned long eId , void* data ) { + /* vtkSliderWidget* wdg = reinterpret_cast< vtkSliderWidget* >( caller ); if( wdg == NULL ) @@ -56,6 +57,7 @@ public: this->Actors->SetWindow( 0, rep->GetValue( ) ); else if( title == "Level" ) this->Actors->SetLevel( 0, rep->GetValue( ) ); + */ } SliderCallback( ) : vtkCommand( ) @@ -126,19 +128,20 @@ int main( int argc, char* argv[] ) // Create reader TFilter::Pointer reader = - plugins.CreateProcessObject( "cpPlugins::ImageReader" ); + plugins.CreateProcessObject( "cpPlugins::IO::ImageReader" ); if( reader.IsNull( ) ) { - std::cerr << "No suitable image reader found in plugins." << std::endl; + std::cerr + << "ERROR: No suitable image reader found in plugins." + << std::endl; return( 1 ); } // fi // Configure reader - TParameters reader_params = reader->GetDefaultParameters( ); + TParameters* reader_params = reader->GetParameters( ); for( int i = 2; i < argc; ++i ) - reader_params.AddValueToStringList( "FileNames", argv[ i ] ); - reader->SetParameters( reader_params ); + reader_params->AddToStringList( "FileNames", argv[ i ] ); // Execute reader std::string msg = reader->Update( ); @@ -150,7 +153,8 @@ int main( int argc, char* argv[] ) } // fi // Get input image's vtk representation - vtkImageData* image = reader->GetOutput< TImage >( 0 )->GetVTKImageData( ); + vtkImageData* image = + reader->GetOutput< TImage >( "Output" )->GetVTK< vtkImageData >( ); if( image == NULL ) { std::cerr @@ -168,6 +172,7 @@ int main( int argc, char* argv[] ) // Renderers vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New( ); + renderer->SetBackground( 0, 0, 1 ); window->AddRenderer( renderer ); // Interactor @@ -179,13 +184,14 @@ int main( int argc, char* argv[] ) vtkSmartPointer< TMPRActors > mpr_actors = vtkSmartPointer< TMPRActors >::New( ); mpr_actors->AddInputData( image ); - mpr_actors->PushDataInto( NULL, NULL, NULL, renderer ); + mpr_actors->PushActorsInto( NULL, NULL, NULL, window ); // Callbacks vtkSmartPointer< SliderCallback > cb = vtkSmartPointer< SliderCallback >::New( ); cb->Actors = mpr_actors; + /* Slider x_slider( mpr_actors->GetSliceNumberMinValue( 0 ), mpr_actors->GetSliceNumberMaxValue( 0 ), @@ -221,6 +227,7 @@ int main( int argc, char* argv[] ) "Level", interactor, 0.300, 0.05, 0.490, 0.05, cb ); + */ // Begin interaction renderer->ResetCamera( ); diff --git a/lib/cpExtensions/Visualization/ImageSliceActors.cxx b/lib/cpExtensions/Visualization/ImageSliceActors.cxx index 250c2ed..5ecb83f 100644 --- a/lib/cpExtensions/Visualization/ImageSliceActors.cxx +++ b/lib/cpExtensions/Visualization/ImageSliceActors.cxx @@ -216,64 +216,58 @@ GetStyle( ) const void cpExtensions::Visualization::ImageSliceActors:: PushActorsInto( vtkRenderWindow* window, bool force_style ) { + if( window == NULL ) + return; vtkRenderWindowInteractor* rwi = window->GetInteractor( ); vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( ); - + if( rwi == NULL || renderer == NULL ) + return; + // Update style - if( rwi != NULL && force_style ) - { + if( force_style ) if( rwi->GetInteractorStyle( ) != this->Style.GetPointer( ) ) - { rwi->SetInteractorStyle( this->Style ); - } // fi - - } // fi + // Update actors + unsigned int N = this->GetNumberOfImageActors( ); + for( unsigned int n = 0; n < N; ++n ) + renderer->AddActor( this->GetImageActor( n ) ); + renderer->AddActor( this->CursorActor ); + renderer->AddActor( this->PlaneActor ); + renderer->AddActor( this->TextActor ); + renderer->Modified( ); + + // Configure camera + vtkCamera* camera = renderer->GetActiveCamera( ); + if( camera == NULL ) + return; - if( renderer != NULL ) + // Parallel projections are better when displaying 2D images + if( force_style ) { - // Update actors - unsigned int N = this->GetNumberOfImageActors( ); - for( unsigned int n = 0; n < N; ++n ) - renderer->AddActor( this->GetImageActor( n ) ); - renderer->AddActor( this->CursorActor ); - renderer->AddActor( this->PlaneActor ); - renderer->AddActor( this->TextActor ); - renderer->Modified( ); - - // Configure camera - vtkCamera* camera = renderer->GetActiveCamera( ); - if( camera == NULL ) - return; - - // Parallel projections are better when displaying 2D images - if( force_style ) + int axis = this->GetAxis( ); + camera->ParallelProjectionOn( ); + camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) ); + if( axis == 0 ) { - int axis = this->GetAxis( ); - camera->ParallelProjectionOn( ); - camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) ); - if( axis == 0 ) - { - camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) ); - camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) ); - } - else if( axis == 1 ) - { - camera->SetPosition( double( 0 ), double( 1 ), double( 0 ) ); - camera->SetViewUp ( double( 0 ), double( 0 ), double( -1 ) ); - } - else // if( axis == 2 ) - { - camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) ); - camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) ); - - } // fi + camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) ); + camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) ); + } + else if( axis == 1 ) + { + camera->SetPosition( double( 0 ), double( 1 ), double( 0 ) ); + camera->SetViewUp ( double( 0 ), double( 0 ), double( -1 ) ); + } + else // if( axis == 2 ) + { + camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) ); + camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) ); } // fi - renderer->ResetCamera( ); - rwi->Render( ); } // fi + renderer->ResetCamera( ); + rwi->Render( ); } // ------------------------------------------------------------------------- @@ -977,6 +971,7 @@ UpdateText( ) void cpExtensions::Visualization::ImageSliceActors:: UpdateText( double pos[ 3 ] ) { + /* TODO if( this->SliceMappers.size( ) > 0 ) { char axis; @@ -1033,6 +1028,7 @@ UpdateText( double pos[ 3 ] ) this->TextActor->SetInput( this->TextBuffer ); this->TextActor->Modified( ); this->Modified( ); + */ } // ------------------------------------------------------------------------- @@ -1248,7 +1244,16 @@ _MouseDoubleClickCommand( if( !alt && !ctr && !sft ) actors->SetCursor( pos ); else if( !alt && ctr && !sft && actors->SlicesCommand != NULL ) + { actors->SlicesCommand( pos, actors->GetAxis( ), actors->SlicesData ); + for( unsigned int i = 0; i < actors->CursorCommands.size( ); ++i ) + actors->CursorCommands[ i ].first( + pos, + actors->GetAxis( ), + actors->CursorCommands[ i ].second + ); + + } // fi } else if( btn == ImageInteractorStyle::ButtonID_Middle ) { diff --git a/lib/cpExtensions/Visualization/ImageSliceActors.h b/lib/cpExtensions/Visualization/ImageSliceActors.h index 22bfe6a..6c97448 100644 --- a/lib/cpExtensions/Visualization/ImageSliceActors.h +++ b/lib/cpExtensions/Visualization/ImageSliceActors.h @@ -38,6 +38,9 @@ namespace cpExtensions typedef ImageSliceActors Self; typedef void ( *TCursorCommand )( double*, int, void* ); + typedef ImageInteractorStyle::TMouseCommand TMouseCommand; + typedef ImageInteractorStyle::TMouseWheelCommand TMouseWheelCommand; + typedef ImageInteractorStyle::TKeyCommand TKeyCommand; public: vtkTypeMacro( ImageSliceActors, vtkPropCollection ); @@ -51,6 +54,15 @@ namespace cpExtensions // Creation static ImageSliceActors* New( ); + void AddCursorCommand( TCursorCommand command, void* data ) + { + this->CursorCommands.push_back( + std::pair< TCursorCommand, void* >( + command, data + ) + ); + } + void AddInputConnection( vtkAlgorithmOutput* aout, int axis = 2 ); void AddInputData( vtkImageData* data, int axis = 2 ); void Clear( ); @@ -166,6 +178,14 @@ namespace cpExtensions TCursorCommand SlicesCommand; void* SlicesData; + // Associated commands + std::vector< std::pair< TCursorCommand, void* > > CursorCommands; + std::vector< TMouseCommand > MouseCommands; + std::vector< TMouseCommand > MouseClickCommands; + std::vector< TMouseCommand > MouseDoubleClickCommands; + std::vector< TMouseWheelCommand > MouseWheelCommands; + std::vector< TKeyCommand > KeyCommands; + // Other associated actors typedef std::pair< vtkAlgorithm*, vtkActor* > TAssociatedActor; typedef std::vector< TAssociatedActor > TAssociatedActors; diff --git a/lib/cpExtensions/Visualization/MPRActors.cxx b/lib/cpExtensions/Visualization/MPRActors.cxx index 55f271c..a02c8bc 100644 --- a/lib/cpExtensions/Visualization/MPRActors.cxx +++ b/lib/cpExtensions/Visualization/MPRActors.cxx @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include #include @@ -40,6 +42,28 @@ AddInputConnection( vtkAlgorithmOutput* aout ) this->Slices[ i ][ j ]->AddInputConnection( ( ( imap != NULL )? imap->GetOutputPort( ): aout ), j ); + + // Create bounding box + vtkImageData* new_image = dynamic_cast< vtkImageData* >( + aout->GetProducer( )->GetOutputDataObject( aout->GetIndex( ) ) + ); + + // Create 3D outline + double bb[ 6 ]; + new_image->GetBounds( bb ); + + vtkSmartPointer< vtkOutlineSource > img_ol = + vtkSmartPointer< vtkOutlineSource >::New( ); + img_ol->SetBounds( bb ); + + vtkSmartPointer< vtkPolyDataMapper > img_ol_mapper = + vtkSmartPointer< vtkPolyDataMapper >::New( ); + img_ol_mapper->SetInputConnection( img_ol->GetOutputPort( ) ); + this->ImageOutlineActor->SetMapper( img_ol_mapper ); + this->ImageOutlineActor->GetProperty( )->SetColor( 1, 1, 1 ); + this->ImageOutlineActor->GetProperty( )->SetLineWidth( 1 ); + + this->AddItem( this->ImageOutlineActor ); } else { @@ -108,6 +132,23 @@ AddInputData( vtkImageData* new_image ) this->Slices[ i ][ j ]->AddInputData( new_image, j ); } // fi + + // Create 3D outline + double bb[ 6 ]; + new_image->GetBounds( bb ); + + vtkSmartPointer< vtkOutlineSource > img_ol = + vtkSmartPointer< vtkOutlineSource >::New( ); + img_ol->SetBounds( bb ); + + vtkSmartPointer< vtkPolyDataMapper > img_ol_mapper = + vtkSmartPointer< vtkPolyDataMapper >::New( ); + img_ol_mapper->SetInputConnection( img_ol->GetOutputPort( ) ); + this->ImageOutlineActor->SetMapper( img_ol_mapper ); + this->ImageOutlineActor->GetProperty( )->SetColor( 1, 1, 1 ); + this->ImageOutlineActor->GetProperty( )->SetLineWidth( 1 ); + + this->AddItem( this->ImageOutlineActor ); } else { diff --git a/lib/cpExtensions/Visualization/MPRActors.h b/lib/cpExtensions/Visualization/MPRActors.h index 85cee59..8b88fdc 100644 --- a/lib/cpExtensions/Visualization/MPRActors.h +++ b/lib/cpExtensions/Visualization/MPRActors.h @@ -18,6 +18,11 @@ namespace cpExtensions public: typedef MPRActors Self; + typedef ImageSliceActors::TCursorCommand TCursorCommand; + typedef ImageSliceActors::TMouseCommand TMouseCommand; + typedef ImageSliceActors::TMouseWheelCommand TMouseWheelCommand; + typedef ImageSliceActors::TKeyCommand TKeyCommand; + public: vtkTypeMacro( MPRActors, vtkPropCollection ); @@ -25,6 +30,13 @@ namespace cpExtensions // Creation static MPRActors* New( ); + void AddCursorCommand( TCursorCommand command, void* data ) + { + this->Slices[ 0 ][ 0 ]->AddCursorCommand( command, data ); + this->Slices[ 0 ][ 1 ]->AddCursorCommand( command, data ); + this->Slices[ 0 ][ 2 ]->AddCursorCommand( command, data ); + } + ImageSliceActors* GetSliceActors( const int& i ) const; int AddInputConnection( vtkAlgorithmOutput* aout ); @@ -49,6 +61,15 @@ namespace cpExtensions unsigned int i, double r, double g, double b ); + double GetWindow( ) + { + return( this->Slices[ 0 ][ 0 ]->GetWindow( ) ); + } + double GetLevel( ) + { + return( this->Slices[ 0 ][ 0 ]->GetLevel( ) ); + } + // Slice access int GetSliceNumberMinValue( const int& axis ) const; int GetSliceNumberMaxValue( const int& axis ) const; @@ -74,6 +95,13 @@ namespace cpExtensions protected: vtkSmartPointer< vtkActor > ImageOutlineActor; vtkSmartPointer< ImageSliceActors > Slices[ 2 ][ 3 ]; + + std::vector< TCursorCommand > CursorCommands; + std::vector< TMouseCommand > MouseCommands; + std::vector< TMouseCommand > MouseClickCommands; + std::vector< TMouseCommand > MouseDoubleClickCommands; + std::vector< TMouseWheelCommand > MouseWheelCommands; + std::vector< TKeyCommand > KeyCommands; }; } // ecapseman diff --git a/lib/cpExtensions/Visualization/MPRObjects.h b/lib/cpExtensions/Visualization/MPRObjects.h index 39e827f..1920bb7 100644 --- a/lib/cpExtensions/Visualization/MPRObjects.h +++ b/lib/cpExtensions/Visualization/MPRObjects.h @@ -21,6 +21,11 @@ namespace cpExtensions typedef MPRObjects Self; typedef cpExtensions::Visualization::MPRActors TMPRActors; + typedef TMPRActors::TCursorCommand TCursorCommand; + typedef TMPRActors::TMouseCommand TMouseCommand; + typedef TMPRActors::TMouseWheelCommand TMouseWheelCommand; + typedef TMPRActors::TKeyCommand TKeyCommand; + public: vtkTypeMacro( MPRObjects, vtkObject ); @@ -28,6 +33,11 @@ namespace cpExtensions // Creation static MPRObjects* New( ); + void AddCursorCommand( TCursorCommand command, void* data ) + { + this->m_MPRActors->AddCursorCommand( command, data ); + } + void SetRenderWindows( vtkRenderWindow* wx, vtkRenderWindow* wy, vtkRenderWindow* wz, vtkRenderWindow* w3D @@ -51,6 +61,15 @@ namespace cpExtensions TMPRActors* GetMPRActors( ); const TMPRActors* GetMPRActors( ) const; + double GetWindow( ) const + { + return( this->m_MPRActors->GetWindow( ) ); + } + double GetLevel( ) const + { + return( this->m_MPRActors->GetLevel( ) ); + } + protected: MPRObjects( ); virtual ~MPRObjects( ); @@ -67,6 +86,13 @@ namespace cpExtensions // Internal pipelines vtkSmartPointer< TMPRActors > m_MPRActors; vtkSmartPointer< vtkRenderer > m_Renderers[ 4 ]; + + std::vector< TCursorCommand > CursorCommands; + std::vector< TMouseCommand > MouseCommands; + std::vector< TMouseCommand > MouseClickCommands; + std::vector< TMouseCommand > MouseDoubleClickCommands; + std::vector< TMouseWheelCommand > MouseWheelCommands; + std::vector< TKeyCommand > KeyCommands; }; } // ecapseman diff --git a/lib/cpPlugins/Interface/BaseMPRWindow.cxx b/lib/cpPlugins/Interface/BaseMPRWindow.cxx index b439755..d55632c 100644 --- a/lib/cpPlugins/Interface/BaseMPRWindow.cxx +++ b/lib/cpPlugins/Interface/BaseMPRWindow.cxx @@ -158,17 +158,13 @@ LoadPlugins( ) } // ------------------------------------------------------------------------- -bool cpPlugins::Interface::BaseMPRWindow:: +std::string cpPlugins::Interface::BaseMPRWindow:: LoadImage( ) { std::string msg = ""; - bool ret = true; + std::string ret = ""; if( this->m_ImageReader.IsNull( ) ) - { msg = "No valid image reader. Please load a valid plugin file."; - ret = false; - - } // fi if( this->m_ImageReader->ExecConfigurationDialog( this ) ) { @@ -176,13 +172,16 @@ LoadImage( ) msg = this->m_ImageReader->Update( ); if( msg == "" ) { - this->m_Images.push_back( - this->m_ImageReader->GetOutput< TImage >( 0 ) - ); + TImage::Pointer image = + this->m_ImageReader->GetOutput< TImage >( "Output" ); + if( this->m_Images.size( ) == 0 ) + ret = image->GetName( ); + else + ret = "Segmentation"; + this->m_Images[ ret ] = image; this->m_ImageReader->DisconnectOutputs( ); this->m_ImageReader->GetParameters( )->ClearStringList( "FileNames" ); - vtkImageData* vtk_id = - this->m_Images.rbegin( )->GetPointer( )->GetVTK< vtkImageData >( ); + vtkImageData* vtk_id = image->GetVTK< vtkImageData >( ); if( vtk_id != NULL ) { this->m_MPRObjects->AddImage( vtk_id ); @@ -195,7 +194,7 @@ LoadImage( ) msg = "Read image does not have a valid VTK converter."; } else - ret = false; + ret = ""; } // fi @@ -209,33 +208,67 @@ LoadImage( ) } // ------------------------------------------------------------------------- -bool cpPlugins::Interface::BaseMPRWindow:: +std::string cpPlugins::Interface::BaseMPRWindow:: LoadMesh( ) { - return( false ); + return( "" ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::BaseMPRWindow:: -ExecuteFilter( const std::string& name, int input_id, int output_id ) +ExecuteFilter( + const std::string& name, + const std::string& input_id, + const std::string& output_id + ) { TProcessObject::Pointer filter = this->m_Interface.CreateProcessObject( name ); std::string category = filter->GetClassCategory( ); if( category == "ImageToBinaryImageFilter" ) { - if( input_id < this->m_Images.size( ) ) + TImages::iterator iIt = this->m_Images.find( input_id ); + if( iIt != this->m_Images.end( ) ) { - filter->SetInput( 0, this->m_Images[ input_id ] ); + filter->SetInput( "Input", this->m_Images[ input_id ] ); bool dlg_ok = filter->ExecConfigurationDialog( NULL ); if( !dlg_ok ) return; + std::string err = filter->Update( ); + std::cout << "ERR: " << err << std::endl; + if( err == "" ) + { + this->m_Images[ "Segmentation" ] = + filter->GetOutput< TImage >( "Output" ); + filter->DisconnectOutputs( ); + + vtkImageData* vtk_id = + this->m_Images[ "Segmentation" ]->GetVTK< vtkImageData >( ); + if( vtk_id != NULL ) + this->m_MPRObjects->AddImage( vtk_id ); + } + else + QMessageBox::critical( + this, tr( "Error with plugin" ), tr( err.c_str( ) ) + ); + } // fi } // fi } +// ------------------------------------------------------------------------- +void cpPlugins::Interface::BaseMPRWindow:: +AddImage( const std::string& name, TImage* image ) +{ + this->m_Images[ name ] = image; + vtkImageData* vtk_id = + this->m_Images[ name ]->GetVTK< vtkImageData >( ); + if( vtk_id != NULL ) + this->m_MPRObjects->AddImage( vtk_id ); +} + // ------------------------------------------------------------------------- void cpPlugins::Interface::BaseMPRWindow:: ClearAll( ) diff --git a/lib/cpPlugins/Interface/BaseMPRWindow.h b/lib/cpPlugins/Interface/BaseMPRWindow.h index d050967..9507d6f 100644 --- a/lib/cpPlugins/Interface/BaseMPRWindow.h +++ b/lib/cpPlugins/Interface/BaseMPRWindow.h @@ -6,9 +6,9 @@ #ifdef cpPlugins_Interface_QT4 +#include #include #include -#include #include #include @@ -41,15 +41,26 @@ namespace cpPlugins typedef cpPlugins::Interface::Image TImage; typedef cpPlugins::Interface::Mesh TMesh; - typedef std::vector< TImage::Pointer > TImages; - typedef std::vector< TMesh::Pointer > TMeshes; - typedef std::set< std::string > TOrderedStringContainer; + typedef cpExtensions::Visualization::MPRObjects TMPRObjects; + typedef TMPRObjects::TCursorCommand TCursorCommand; + typedef TMPRObjects::TMouseCommand TMouseCommand; + typedef TMPRObjects::TMouseWheelCommand TMouseWheelCommand; + typedef TMPRObjects::TKeyCommand TKeyCommand; + + typedef std::map< std::string, TImage::Pointer > TImages; + typedef std::map< std::string, TMesh::Pointer > TMeshes; + typedef std::set< std::string > TOrderedStringContainer; typedef std::map< std::string, std::set< std::string > > TFilters; public: explicit BaseMPRWindow( QWidget* parent = 0 ); virtual ~BaseMPRWindow( ); + void AddCursorCommand( TCursorCommand command, void* data ) + { + this->m_MPRObjects->AddCursorCommand( command, data ); + } + void DialogLoadPlugins( ); void AssociatePluginsToMenu( QMenu* menu, QObject* obj, const char* slot @@ -68,21 +79,45 @@ namespace cpPlugins bool LoadPlugins( const std::string& fname ); void LoadPlugins( ); - bool LoadImage( ); - bool LoadMesh( ); + std::string LoadImage( ); + std::string LoadMesh( ); void ExecuteFilter( const std::string& name, - int input_id, int output_id = -1 + const std::string& input_id, + const std::string& output_id ); + TProcessObject::Pointer CreateFilter( const std::string& name ) + { + return( this->m_Interface.CreateProcessObject( name ) ); + } + + void AddImage( const std::string& name, TImage* image ); + TImage* GetImage( std::string& name ) const + { + TImages::const_iterator i = this->m_Images.find( name ); + if( i != this->m_Images.end( ) ) + return( i->second ); + else + return( NULL ); + } + + double GetWindow( ) const + { + return( this->m_MPRObjects->GetWindow( ) ); + } + double GetLevel( ) const + { + return( this->m_MPRObjects->GetLevel( ) ); + } + void ClearAll( ); protected: void _UpdatePlugins( ); protected: - typedef cpExtensions::Visualization::MPRObjects TMPRObjects; vtkSmartPointer< TMPRObjects > m_MPRObjects; QVTKWidget* m_XVTK; diff --git a/lib/cpPlugins/Interface/Parameters.cxx b/lib/cpPlugins/Interface/Parameters.cxx index b02168b..af641e0 100644 --- a/lib/cpPlugins/Interface/Parameters.cxx +++ b/lib/cpPlugins/Interface/Parameters.cxx @@ -1,7 +1,32 @@ #include +#include #include +// ------------------------------------------------------------------------- +const cpPlugins::Interface:: +ProcessObject* cpPlugins::Interface::Parameters:: +GetProcessObject( ) const +{ + return( this->m_Process ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Parameters:: +SetProcessObject( ProcessObject* v ) +{ + this->m_Process = v; +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Parameters:: +Modified( ) const +{ + this->Superclass::Modified( ); + if( this->m_Process != NULL ) + this->m_Process->Modified( ); +} + // ------------------------------------------------------------------------- void cpPlugins::Interface::Parameters:: Clear( ) @@ -416,7 +441,8 @@ SetSelectedChoice( const TString& name, const TString& choice ) // ------------------------------------------------------------------------- cpPlugins::Interface::Parameters:: Parameters( ) - : Superclass( ) + : Superclass( ), + m_Process( NULL ) { this->Clear( ); } diff --git a/lib/cpPlugins/Interface/Parameters.h b/lib/cpPlugins/Interface/Parameters.h index abde990..858a90b 100644 --- a/lib/cpPlugins/Interface/Parameters.h +++ b/lib/cpPlugins/Interface/Parameters.h @@ -15,6 +15,9 @@ namespace cpPlugins { namespace Interface { + // Some forward declarations + class ProcessObject; + /** */ class cpPlugins_Interface_EXPORT Parameters @@ -52,6 +55,11 @@ namespace cpPlugins itkTypeMacro( cpPlugins::Interface::Parameters, itk::Object ); public: + // To impact pipeline + virtual const ProcessObject* GetProcessObject( ) const; + virtual void SetProcessObject( ProcessObject* v ); + virtual void Modified( ) const; + // Parameters container configuration void Clear( ); @@ -195,6 +203,7 @@ namespace cpPlugins protected: TParameters m_Parameters; + const ProcessObject* m_Process; }; } // ecapseman diff --git a/lib/cpPlugins/Interface/ProcessObject.cxx b/lib/cpPlugins/Interface/ProcessObject.cxx index f832743..ae4a1d3 100644 --- a/lib/cpPlugins/Interface/ProcessObject.cxx +++ b/lib/cpPlugins/Interface/ProcessObject.cxx @@ -4,6 +4,17 @@ #include #endif // cpPlugins_Interface_QT4 +// ------------------------------------------------------------------------- +void cpPlugins::Interface::ProcessObject:: +Modified( ) const +{ + if( this->m_ITKObject.IsNotNull( ) ) + this->m_ITKObject->Modified( ); + if( this->m_VTKObject.GetPointer( ) != NULL ) + this->m_VTKObject->Modified( ); + this->Superclass::Modified( ); +} + // ------------------------------------------------------------------------- cpPlugins::Interface::ProcessObject:: TParameters* cpPlugins::Interface::ProcessObject:: @@ -36,29 +47,12 @@ GetNumberOfOutputs( ) const // ------------------------------------------------------------------------- void cpPlugins::Interface::ProcessObject:: -SetNumberOfInputs( unsigned int n ) -{ - this->m_Inputs.clear( ); - this->m_Inputs.resize( n ); - this->Modified( ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Interface::ProcessObject:: -SetNumberOfOutputs( unsigned int n ) +SetInput( const std::string& id, cpPlugins::Interface::DataObject* dobj ) { - this->m_Outputs.clear( ); - this->m_Outputs.resize( n ); - this->Modified( ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Interface::ProcessObject:: -SetInput( unsigned int idx, cpPlugins::Interface::DataObject* dobj ) -{ - if( idx < this->m_Inputs.size( ) ) + _TDataContainer::iterator i = this->m_Inputs.find( id ); + if( i != this->m_Inputs.end( ) ) { - this->m_Inputs[ idx ] = dobj; + i->second = dobj; this->Modified( ); } // fi @@ -71,9 +65,10 @@ Update( ) std::string r = ""; // Force upstream updates - for( unsigned int i = 0; i < this->m_Inputs.size( ) && r == ""; ++i ) + _TDataContainer::iterator i = this->m_Inputs.begin( ); + for( ; i != this->m_Inputs.end( ) && r == ""; ++i ) { - Self* src = dynamic_cast< Self* >( this->m_Inputs[ i ]->GetSource( ) ); + Self* src = dynamic_cast< Self* >( i->second->GetSource( ) ); if( src != NULL ) r = src->Update( ); @@ -91,9 +86,10 @@ Update( ) void cpPlugins::Interface::ProcessObject:: DisconnectOutputs( ) { - for( unsigned int idx = 0; idx < this->m_Outputs.size( ); ++idx ) - if( this->m_Outputs[ idx ].IsNotNull( ) ) - this->m_Outputs[ idx ]->DisconnectPipeline( ); + _TDataContainer::iterator i = this->m_Outputs.begin( ); + for( ; i != this->m_Outputs.end( ); ++i ) + if( i->second.IsNotNull( ) ) + i->second->DisconnectPipeline( ); } // ------------------------------------------------------------------------- @@ -135,4 +131,12 @@ cpPlugins::Interface::ProcessObject:: { } +// ------------------------------------------------------------------------- +void cpPlugins::Interface::ProcessObject:: +_AddInput( const std::string& name ) +{ + this->m_Inputs[ name ] = NULL; + this->Modified( ); +} + // eof - $RCSfile$ diff --git a/lib/cpPlugins/Interface/ProcessObject.h b/lib/cpPlugins/Interface/ProcessObject.h index 9cf1924..9548d48 100644 --- a/lib/cpPlugins/Interface/ProcessObject.h +++ b/lib/cpPlugins/Interface/ProcessObject.h @@ -2,6 +2,9 @@ #define __CPPLUGINS__INTERFACE__PROCESSOBJECT__H__ #include + +#include + #include #include #include @@ -42,16 +45,16 @@ namespace cpPlugins ); public: + // To impact pipeline + virtual void Modified( ) const; + virtual TParameters* GetParameters( ); virtual const TParameters* GetParameters( ) const; virtual unsigned int GetNumberOfInputs( ) const; virtual unsigned int GetNumberOfOutputs( ) const; - virtual void SetNumberOfInputs( unsigned int n ); - virtual void SetNumberOfOutputs( unsigned int n ); - - virtual void SetInput( unsigned int idx, DataObject* dobj ); + virtual void SetInput( const std::string& id, DataObject* dobj ); virtual std::string Update( ); virtual void DisconnectOutputs( ); @@ -71,21 +74,23 @@ namespace cpPlugins inline const T* GetVTK( ) const; template< class T > - inline T* GetInput( unsigned int idx ); + inline T* GetInput( const std::string& id ); template< class T > - inline const T* GetInput( unsigned int idx ) const; + inline const T* GetInput( const std::string& id ) const; template< class T > - inline T* GetOutput( unsigned int idx ); + inline T* GetOutput( const std::string& id ); template< class T > - inline const T* GetOutput( unsigned int idx ) const; + inline const T* GetOutput( const std::string& id ) const; protected: ProcessObject( ); virtual ~ProcessObject( ); + virtual void _AddInput( const std::string& name ); + template< class F > inline F* _CreateITK( ); @@ -93,7 +98,7 @@ namespace cpPlugins inline F* _CreateVTK( ); template< class O > - inline void _MakeOutput( unsigned int idx ); + inline void _MakeOutput( const std::string& id ); virtual std::string _GenerateData( ) = 0; @@ -108,8 +113,9 @@ namespace cpPlugins Parameters::Pointer m_Parameters; - std::vector< DataObject::Pointer > m_Inputs; - std::vector< DataObject::Pointer > m_Outputs; + typedef std::map< std::string, DataObject::Pointer > _TDataContainer; + _TDataContainer m_Inputs; + _TDataContainer m_Outputs; }; } // ecapseman diff --git a/lib/cpPlugins/Interface/ProcessObject.hxx b/lib/cpPlugins/Interface/ProcessObject.hxx index 50c03ce..10b4dbe 100644 --- a/lib/cpPlugins/Interface/ProcessObject.hxx +++ b/lib/cpPlugins/Interface/ProcessObject.hxx @@ -36,10 +36,11 @@ GetVTK( ) const // ------------------------------------------------------------------------- template< class T > T* cpPlugins::Interface::ProcessObject:: -GetInput( unsigned int idx ) +GetInput( const std::string& id ) { - if( idx < this->m_Inputs.size( ) ) - return( dynamic_cast< T* >( this->m_Inputs[ idx ].GetPointer( ) ) ); + _TDataContainer::iterator i = this->m_Inputs.find( id ); + if( i != this->m_Inputs.end( ) ) + return( dynamic_cast< T* >( i->second.GetPointer( ) ) ); else return( NULL ); } @@ -47,12 +48,11 @@ GetInput( unsigned int idx ) // ------------------------------------------------------------------------- template< class T > const T* cpPlugins::Interface::ProcessObject:: -GetInput( unsigned int idx ) const +GetInput( const std::string& id ) const { - if( idx < this->m_Inputs.size( ) ) - return( - dynamic_cast< const T* >( this->m_Inputs[ idx ].GetPointer( ) ) - ); + _TDataContainer::const_iterator i = this->m_Inputs.find( id ); + if( i != this->m_Inputs.end( ) ) + return( dynamic_cast< const T* >( i->second.GetPointer( ) ) ); else return( NULL ); } @@ -60,10 +60,11 @@ GetInput( unsigned int idx ) const // ------------------------------------------------------------------------- template< class T > T* cpPlugins::Interface::ProcessObject:: -GetOutput( unsigned int idx ) +GetOutput( const std::string& id ) { - if( idx < this->m_Outputs.size( ) ) - return( dynamic_cast< T* >( this->m_Outputs[ idx ].GetPointer( ) ) ); + _TDataContainer::iterator i = this->m_Outputs.find( id ); + if( i != this->m_Outputs.end( ) ) + return( dynamic_cast< T* >( i->second.GetPointer( ) ) ); else return( NULL ); } @@ -71,12 +72,11 @@ GetOutput( unsigned int idx ) // ------------------------------------------------------------------------- template< class T > const T* cpPlugins::Interface::ProcessObject:: -GetOutput( unsigned int idx ) const +GetOutput( const std::string& id ) const { - if( idx < this->m_Outputs.size( ) ) - return( - dynamic_cast< const T* >( this->m_Outputs[ idx ].GetPointer( ) ) - ); + _TDataContainer::const_iterator i = this->m_Outputs.find( id ); + if( i != this->m_Outputs.end( ) ) + return( dynamic_cast< const T* >( i->second.GetPointer( ) ) ); else return( NULL ); } @@ -117,12 +117,11 @@ _CreateVTK( ) // ------------------------------------------------------------------------- template< class O > void cpPlugins::Interface::ProcessObject:: -_MakeOutput( unsigned int idx ) +_MakeOutput( const std::string& id ) { - if( idx >= this->m_Outputs.size( ) ) - return; - this->m_Outputs[ idx ] = O::New( ); - this->m_Outputs[ idx ]->SetSource( this ); + this->m_Outputs[ id ] = O::New( ); + this->m_Outputs[ id ]->SetSource( this ); + this->Modified( ); } #endif // __CPPLUGINS__INTERFACE__PROCESSOBJECT__HXX__ diff --git a/lib/cpPlugins/Plugins/BasicFilters/BinaryErodeImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/BinaryErodeImageFilter.cxx index 0713edf..7460520 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/BinaryErodeImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/BinaryErodeImageFilter.cxx @@ -10,11 +10,8 @@ cpPlugins::BasicFilters::BinaryErodeImageFilter:: BinaryErodeImageFilter( ) : Superclass( ) { - //this->m_ClassName = "cpPlugins::BasicFilters::BinaryErodeImageFilter"; - //this->m_ClassCategory = "ImageToImageFilter"; - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsUint( "Radius", 2 ); } @@ -30,7 +27,7 @@ std::string cpPlugins::BasicFilters::BinaryErodeImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "BinaryErodeImageFilter: No input image." ); @@ -82,7 +79,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/BinaryThresholdImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/BinaryThresholdImageFilter.cxx index 21df227..5dc60cb 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/BinaryThresholdImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/BinaryThresholdImageFilter.cxx @@ -8,14 +8,13 @@ cpPlugins::BasicFilters::BinaryThresholdImageFilter:: BinaryThresholdImageFilter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsReal( "LowerThresholdValue", 0 ); - this->m_Parameters->ConfigureAsReal( "UpperThresholdValue", 0 ); - this->m_Parameters->ConfigureAsUint( "InsideValue", 255 ); - this->m_Parameters->ConfigureAsUint( "OutsideValue", 1 ); + this->m_Parameters->ConfigureAsReal( "UpperThresholdValue", 10000 ); + this->m_Parameters->ConfigureAsUint( "InsideValue", 1 ); + this->m_Parameters->ConfigureAsUint( "OutsideValue", 0 ); } // ------------------------------------------------------------------------- @@ -29,7 +28,7 @@ std::string cpPlugins::BasicFilters::BinaryThresholdImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "BinaryThresholdImageFilter: No input image." ); @@ -66,8 +65,8 @@ _RealGD( itk::DataObject* image ) // Get parameters //unsigned int bins = // this->m_Parameters.GetValueAsUint( "NumberOfHistogramBins" ); - _IP lower_val = _IP( this->m_Parameters->GetReal( "LowerValue" ) ); - _IP upper_val = _IP( this->m_Parameters->GetReal( "UpperValue" ) ); + _IP lower_val = _IP( this->m_Parameters->GetReal( "LowerThresholdValue" ) ); + _IP upper_val = _IP( this->m_Parameters->GetReal( "UpperThresholdValue" ) ); _OP in_val = _OP( this->m_Parameters->GetUint( "InsideValue" ) ); _OP out_val = _OP( this->m_Parameters->GetUint( "OutsideValue" ) ); @@ -82,7 +81,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/Cutter.cxx b/lib/cpPlugins/Plugins/BasicFilters/Cutter.cxx index e3f1e2b..d0907b4 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/Cutter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/Cutter.cxx @@ -13,9 +13,9 @@ cpPlugins::BasicFilters::Cutter:: Cutter( ) : Superclass( ) { - this->SetNumberOfInputs( 2 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Mesh >( 0 ); + this->_AddInput( "InputMesh" ); + this->_AddInput( "InputFunction" ); + this->_MakeOutput< cpPlugins::Interface::Mesh >( "Output" ); } // ------------------------------------------------------------------------- @@ -30,9 +30,11 @@ _GenerateData( ) { // Get inputs cpPlugins::Interface::Mesh* mesh = - this->GetInput< cpPlugins::Interface::Mesh >( 0 ); + this->GetInput< cpPlugins::Interface::Mesh >( "InputMesh" ); cpPlugins::Interface::ImplicitFunction* function = - this->GetInput< cpPlugins::Interface::ImplicitFunction >( 1 ); + this->GetInput< cpPlugins::Interface::ImplicitFunction >( + "InputFunction" + ); if( function == NULL ) return( "Cutter: Input data 1 is not a valid implicit function." ); @@ -46,7 +48,7 @@ _GenerateData( ) // Execute filter cpPlugins::Interface::Mesh* out = - this->GetOutput< cpPlugins::Interface::Mesh >( 0 ); + this->GetOutput< cpPlugins::Interface::Mesh >( "Output" ); out->SetVTK( cutter->GetOutput( ) ); return( "" ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/ExtractSliceImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/ExtractSliceImageFilter.cxx index df46d6f..65a7080 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/ExtractSliceImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/ExtractSliceImageFilter.cxx @@ -8,9 +8,8 @@ cpPlugins::BasicFilters::ExtractSliceImageFilter:: ExtractSliceImageFilter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsUint( "Axis", 0 ); this->m_Parameters->ConfigureAsInt( "Slice", 0 ); @@ -27,7 +26,7 @@ std::string cpPlugins::BasicFilters::ExtractSliceImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "ExtractSliceImageFilter: No input image." ); @@ -79,7 +78,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx index 07fc939..71f90cc 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx @@ -9,12 +9,13 @@ cpPlugins::BasicFilters::FloodFillImageFilter:: FloodFillImageFilter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); double seed[ 3 ] = { double( 0 ) }; this->m_Parameters->ConfigureAsPoint( "Seed", 3, seed ); + this->m_Parameters->ConfigureAsReal( "Window", 0 ); + this->m_Parameters->ConfigureAsReal( "Level", 0 ); this->m_Parameters->ConfigureAsUint( "InsideValue", 0 ); this->m_Parameters->ConfigureAsUint( "OutsideValue", 255 ); } @@ -30,7 +31,7 @@ std::string cpPlugins::BasicFilters::FloodFillImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "FloodFillImageFilter: No input image." ); @@ -76,6 +77,9 @@ public: itkImageFunction ); + itkSetMacro( Window, double ); + itkSetMacro( Level, double ); + public: virtual bool Evaluate( const TPoint& point ) const { @@ -83,7 +87,29 @@ public: } virtual bool EvaluateAtIndex( const TIndex& index ) const { - return( true ); + if( !( this->IsInsideBuffer( index ) ) ) + return( false ); + + const I* image = this->GetInputImage( ); + double w2 = this->m_Window / double( 2 ); + double min = this->m_Level - w2; + double max = this->m_Level + w2; + unsigned char val = double( 0 ); + double x = double( image->GetPixel( index ) ); + double m = double( 100 ) / this->m_Window; + double b = ( this->m_Window - ( double( 2 ) * this->m_Level ) ); + b *= double( 50 ) / this->m_Window; + if( x > min && x < max ) + val = ( unsigned char )( ( m * x ) + b ); + + if( this->m_Start ) + { + this->m_StartValue = val; + this->m_Start = false; + return( true ); + } + else + return( std::abs( this->m_StartValue - val ) <= 2 ); } virtual bool EvaluateAtContinuousIndex( const TCIndex& index ) const { @@ -92,7 +118,10 @@ public: protected: cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) - : Superclass( ) + : Superclass( ), + m_Window( double( 0 ) ), + m_Level( double( 0 ) ), + m_Start( true ) { } virtual ~cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) @@ -103,6 +132,12 @@ private: // Purposely not implemented cpPlugins_BasicFilters_FloodFillImageFilter_Function( const Self& other ); Self& operator=( const Self& other ); + +protected: + double m_Window; + double m_Level; + mutable unsigned char m_StartValue; + mutable bool m_Start; }; // ------------------------------------------------------------------------- @@ -118,6 +153,8 @@ _RealGD( itk::DataObject* image ) pseed = this->m_Parameters->GetPoint< typename I::PointType >( "Seed", I::ImageDimension ); + double window = this->m_Parameters->GetReal( "Window" ); + double level = this->m_Parameters->GetReal( "Level" ); _OP in_val = _OP( this->m_Parameters->GetUint( "InsideValue" ) ); _OP out_val = _OP( this->m_Parameters->GetUint( "OutsideValue" ) ); @@ -136,6 +173,9 @@ _RealGD( itk::DataObject* image ) out->FillBuffer( out_val ); typename _F::Pointer f = _F::New( ); + f->SetInputImage( in ); + f->SetWindow( window ); + f->SetLevel( level ); _It i( in, f ); i.AddSeed( seed ); @@ -144,7 +184,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out_port = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out_port != NULL ) { out_port->SetITK< O >( out ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h index e50ae24..d6d61ea 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h +++ b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h @@ -27,7 +27,7 @@ namespace cpPlugins ); cpPlugins_Id_Macro( cpPlugins::BasicFilters::FloodFillImageFilter, - "ImageToImageFilter" + "ImageToBinaryImageFilter" ); protected: diff --git a/lib/cpPlugins/Plugins/BasicFilters/MarchingCubes.cxx b/lib/cpPlugins/Plugins/BasicFilters/MarchingCubes.cxx index e833675..625838c 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/MarchingCubes.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/MarchingCubes.cxx @@ -11,9 +11,8 @@ cpPlugins::BasicFilters::MarchingCubes:: MarchingCubes( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Mesh >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Mesh >( "Output" ); this->m_Parameters->ConfigureAsRealList( "Thresholds" ); } @@ -30,7 +29,7 @@ _GenerateData( ) { // Get input cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "MarchingCubes: Input data is not a valid image." ); vtkImageData* vtk_image = image->GetVTK< vtkImageData >( ); @@ -64,7 +63,7 @@ _GenerateData( ) // Execute filter cpPlugins::Interface::Mesh* out = - this->GetOutput< cpPlugins::Interface::Mesh >( 0 ); + this->GetOutput< cpPlugins::Interface::Mesh >( "Output" ); out->SetVTK( pd ); return( "" ); } diff --git a/lib/cpPlugins/Plugins/BasicFilters/MedianImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/MedianImageFilter.cxx index d1205e7..d47b500 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/MedianImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/MedianImageFilter.cxx @@ -8,9 +8,8 @@ cpPlugins::BasicFilters::MedianImageFilter:: MedianImageFilter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsUint( "Radius", 3 ); } @@ -26,7 +25,7 @@ std::string cpPlugins::BasicFilters::MedianImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "MedianImageFilter: No input image." ); @@ -71,7 +70,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/OtsuThresholdImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/OtsuThresholdImageFilter.cxx index 65df9e0..6bc538e 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/OtsuThresholdImageFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/OtsuThresholdImageFilter.cxx @@ -8,9 +8,8 @@ cpPlugins::BasicFilters::OtsuThresholdImageFilter:: OtsuThresholdImageFilter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsUint( "NumberOfHistogramBins", 100 ); this->m_Parameters->ConfigureAsUint( "InsideValue", 255 ); @@ -76,7 +75,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/RGBImageToOtherChannelsFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/RGBImageToOtherChannelsFilter.cxx index 31bd0fc..13e6732 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/RGBImageToOtherChannelsFilter.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/RGBImageToOtherChannelsFilter.cxx @@ -13,9 +13,8 @@ RGBImageToOtherChannelsFilter( ) { typedef cpPlugins::Interface::Parameters TParameters; - this->SetNumberOfInputs( 1 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_AddInput( "Input" ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); std::vector< std::string > choices; choices.push_back( "HSV" ); @@ -34,7 +33,7 @@ std::string cpPlugins::BasicFilters::RGBImageToOtherChannelsFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "RGBImageToOtherChannelsFilter: No input image." ); @@ -88,7 +87,7 @@ _RealGD( itk::DataObject* image ) // Connect output cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out != NULL ) { out->SetITK< _O >( filter->GetOutput( ) ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/SphereMeshSource.cxx b/lib/cpPlugins/Plugins/BasicFilters/SphereMeshSource.cxx index 78aff5f..c7c671b 100644 --- a/lib/cpPlugins/Plugins/BasicFilters/SphereMeshSource.cxx +++ b/lib/cpPlugins/Plugins/BasicFilters/SphereMeshSource.cxx @@ -10,9 +10,7 @@ cpPlugins::BasicFilters::SphereMeshSource:: SphereMeshSource( ) : Superclass( ) { - this->SetNumberOfInputs( 0 ); - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Mesh >( 0 ); + this->_MakeOutput< cpPlugins::Interface::Mesh >( "Output" ); double point[ 3 ] = { double( 0 ) }; this->m_Parameters->ConfigureAsPoint( "Center", 3, point ); @@ -47,7 +45,7 @@ _GenerateData( ) // Execute filter cpPlugins::Interface::Mesh* out = - this->GetOutput< cpPlugins::Interface::Mesh >( 0 ); + this->GetOutput< cpPlugins::Interface::Mesh >( "Output" ); out->SetVTK( src->GetOutput( ) ); return( "" ); } diff --git a/lib/cpPlugins/Plugins/IO/ImageReader.cxx b/lib/cpPlugins/Plugins/IO/ImageReader.cxx index 48deb00..6068c88 100644 --- a/lib/cpPlugins/Plugins/IO/ImageReader.cxx +++ b/lib/cpPlugins/Plugins/IO/ImageReader.cxx @@ -46,8 +46,7 @@ cpPlugins::IO::ImageReader:: ImageReader( ) : Superclass( ) { - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); this->m_Parameters->ConfigureAsStringList( "FileNames" ); this->m_Parameters->ConfigureAsBool( "VectorType", false ); @@ -352,7 +351,7 @@ std::string cpPlugins::IO::ImageReader:: _RealGD( const TStringList& names ) { cpPlugins::Interface::Image* out = - this->GetOutput< cpPlugins::Interface::Image >( 0 ); + this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out == NULL ) return( "ImageReader: No output object properly created." ); diff --git a/lib/cpPlugins/Plugins/IO/ImageWriter.cxx b/lib/cpPlugins/Plugins/IO/ImageWriter.cxx index 2b4d897..a654979 100644 --- a/lib/cpPlugins/Plugins/IO/ImageWriter.cxx +++ b/lib/cpPlugins/Plugins/IO/ImageWriter.cxx @@ -8,7 +8,7 @@ cpPlugins::IO::ImageWriter:: ImageWriter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); + this->_AddInput( "Input" ); this->m_Parameters->ConfigureAsString( "FileName", "" ); } @@ -39,7 +39,7 @@ std::string cpPlugins::IO::ImageWriter:: _GD0_Image( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "ImageWriter: No input image." ); @@ -57,7 +57,7 @@ std::string cpPlugins::IO::ImageWriter:: _GD0_VectorImage( ) { cpPlugins::Interface::Image* image = - this->GetInput< cpPlugins::Interface::Image >( 0 ); + this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "ImageWriter: No input image." ); diff --git a/lib/cpPlugins/Plugins/IO/MeshReader.cxx b/lib/cpPlugins/Plugins/IO/MeshReader.cxx index 397b644..077b969 100644 --- a/lib/cpPlugins/Plugins/IO/MeshReader.cxx +++ b/lib/cpPlugins/Plugins/IO/MeshReader.cxx @@ -42,8 +42,7 @@ cpPlugins::IO::MeshReader:: MeshReader( ) : Superclass( ) { - this->SetNumberOfOutputs( 1 ); - this->_MakeOutput< cpPlugins::Interface::Mesh >( 0 ); + this->_MakeOutput< cpPlugins::Interface::Mesh >( "Output" ); std::vector< TParameters::TString > valid_types; valid_types.push_back( "float" ); @@ -100,7 +99,7 @@ _GD1( ) pdr->Update( ); cpPlugins::Interface::Mesh* out = - this->GetOutput< cpPlugins::Interface::Mesh >( 0 ); + this->GetOutput< cpPlugins::Interface::Mesh >( "Output" ); if( out != NULL ) out->SetVTK( pdr->GetOutput( ) ); else diff --git a/lib/cpPlugins/Plugins/IO/MeshWriter.cxx b/lib/cpPlugins/Plugins/IO/MeshWriter.cxx index d865c57..94af3cc 100644 --- a/lib/cpPlugins/Plugins/IO/MeshWriter.cxx +++ b/lib/cpPlugins/Plugins/IO/MeshWriter.cxx @@ -10,7 +10,7 @@ cpPlugins::IO::MeshWriter:: MeshWriter( ) : Superclass( ) { - this->SetNumberOfInputs( 1 ); + this->_AddInput( "Input" ); this->m_Parameters->ConfigureAsString( "FileName", "" ); } @@ -26,7 +26,7 @@ std::string cpPlugins::IO::MeshWriter:: _GenerateData( ) { cpPlugins::Interface::Mesh* mesh = - this->GetInput< cpPlugins::Interface::Mesh >( 0 ); + this->GetInput< cpPlugins::Interface::Mesh >( "Input" ); if( mesh == NULL ) return( "MeshWriter: No input mesh." ); vtkPolyData* i = mesh->GetVTK< vtkPolyData >( ); -- 2.45.1