From 9586180ab9da1ba2778099482b0231b933192719 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Thu, 8 Oct 2015 23:44:49 -0500 Subject: [PATCH] Widget integration (step 5/6): Just one step leftgit shortlog ! --- .../Visualization/ImageInteractorStyle.cxx | 34 ++++ .../Visualization/ImageInteractorStyle.h | 9 +- .../Visualization/ImageSliceActors.cxx | 57 ++++++- .../Visualization/ImageSliceActors.h | 11 ++ lib/cpExtensions/Visualization/MPRActors.cxx | 35 ++++ lib/cpExtensions/Visualization/MPRActors.h | 2 + .../BasicFilters/FloodFillImageFilter.cxx | 159 ++++++++++++++++++ .../BasicFilters/FloodFillImageFilter.h | 60 +++++++ 8 files changed, 362 insertions(+), 5 deletions(-) create mode 100644 lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx create mode 100644 lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h diff --git a/lib/cpExtensions/Visualization/ImageInteractorStyle.cxx b/lib/cpExtensions/Visualization/ImageInteractorStyle.cxx index f0f01b1..55df632 100644 --- a/lib/cpExtensions/Visualization/ImageInteractorStyle.cxx +++ b/lib/cpExtensions/Visualization/ImageInteractorStyle.cxx @@ -26,6 +26,18 @@ AssociateImageActor( vtkImageActor* actor ) this->Modified( ); } +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::ImageInteractorStyle:: +AssociateInteractor( vtkRenderWindowInteractor* rwi ) +{ + if( rwi != NULL ) + { + this->AssociatedInteractors.push_back( rwi ); + this->Modified( ); + + } // fi +} + // ------------------------------------------------------------------------- void cpExtensions::Visualization::ImageInteractorStyle:: OnMouseMove( ) @@ -50,6 +62,7 @@ OnMouseMove( ) // Invoke possible events this->MouseMoveCommand( this->Data, button, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -68,6 +81,7 @@ OnMouseWheelForward( ) // Invoke possible events this->MouseWheelCommand( this->Data, 1, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -86,6 +100,7 @@ OnMouseWheelBackward( ) // Invoke possible events this->MouseWheelCommand( this->Data, -1, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -110,6 +125,7 @@ OnLeftClick( ) this->Data, Self::ButtonID_Left, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -134,6 +150,7 @@ OnLeftDoubleClick( ) this->Data, Self::ButtonID_Left, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -158,6 +175,7 @@ OnMiddleClick( ) this->Data, Self::ButtonID_Middle, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -182,6 +200,7 @@ OnMiddleDoubleClick( ) this->Data, Self::ButtonID_Middle, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -206,6 +225,7 @@ OnRightClick( ) this->Data, Self::ButtonID_Right, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -230,6 +250,7 @@ OnRightDoubleClick( ) this->Data, Self::ButtonID_Right, pos, alt, ctr, sft ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -241,6 +262,7 @@ OnChar( ) return; this->KeyCommand( this->Data, rwi->GetKeyCode( ) ); rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -251,6 +273,7 @@ OnExpose( ) if( rwi == NULL ) return; rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -261,6 +284,7 @@ OnConfigure( ) if( rwi == NULL ) return; rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -271,6 +295,7 @@ OnEnter( ) if( rwi == NULL ) return; rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -281,6 +306,7 @@ OnLeave( ) if( rwi == NULL ) return; rwi->Render( ); + this->_RenderAssociatedInteractors( ); } // ------------------------------------------------------------------------- @@ -326,6 +352,14 @@ _PickPosition( double pos[ 3 ] ) return( true ); } +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::ImageInteractorStyle:: +_RenderAssociatedInteractors( ) +{ + for( unsigned int i = 0; i < this->AssociatedInteractors.size( ); ++i ) + this->AssociatedInteractors[ i ]->Render( ); +} + /* #include #include diff --git a/lib/cpExtensions/Visualization/ImageInteractorStyle.h b/lib/cpExtensions/Visualization/ImageInteractorStyle.h index e58c28d..169f09b 100644 --- a/lib/cpExtensions/Visualization/ImageInteractorStyle.h +++ b/lib/cpExtensions/Visualization/ImageInteractorStyle.h @@ -3,12 +3,12 @@ #include +#include + #include #include /* TODO - #include - #include #include @@ -64,6 +64,7 @@ namespace cpExtensions virtual void AssociateView( void* data ); virtual void AssociateImageActor( vtkImageActor* actor ); + virtual void AssociateInteractor( vtkRenderWindowInteractor* rwi ); // Possible mouse motion events virtual void OnMouseMove( ); @@ -92,6 +93,7 @@ namespace cpExtensions virtual ~ImageInteractorStyle( ); bool _PickPosition( double pos[ 3 ] ); + void _RenderAssociatedInteractors( ); private: // Purposely not implemented @@ -101,6 +103,9 @@ namespace cpExtensions protected: vtkSmartPointer< vtkPropPicker > PropPicker; + std::vector< vtkSmartPointer< vtkRenderWindowInteractor > > + AssociatedInteractors; + // Commands void* Data; TMouseCommand MouseMoveCommand; diff --git a/lib/cpExtensions/Visualization/ImageSliceActors.cxx b/lib/cpExtensions/Visualization/ImageSliceActors.cxx index fc2e1a4..558fed7 100644 --- a/lib/cpExtensions/Visualization/ImageSliceActors.cxx +++ b/lib/cpExtensions/Visualization/ImageSliceActors.cxx @@ -101,6 +101,7 @@ Clear( ) this->ImageMaps.clear( ); this->SliceMappers.clear( ); this->ImageActors.clear( ); + this->AssociatedSlices.clear( ); this->AssociatedActors.clear( ); // Reconfigure unique objects @@ -180,6 +181,23 @@ Clear( ) coord->SetValue( 0.01, 0.01 ); } +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::ImageSliceActors:: +AssociateSlice( Self* other ) +{ + this->AssociatedSlices.push_back( other ); + this->Modified( ); +} + +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::ImageSliceActors:: +SetSlicesCommand( TCursorCommand cmd, void* data ) +{ + this->SlicesCommand = cmd; + this->SlicesData = data; + this->Modified( ); +} + // ------------------------------------------------------------------------- vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors:: GetStyle( ) @@ -783,8 +801,38 @@ SetSliceNumber( const int& slice ) // Update text this->UpdateText( ); + + // Associated slices + for( unsigned int i = 0; i < this->AssociatedSlices.size( ); ++i ) + if( this->AssociatedSlices[ i ]->GetAxis( ) == this->GetAxis( ) ) + this->AssociatedSlices[ i ]->SetSliceNumber( slice ); } +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::ImageSliceActors:: +SetSlice( double* pos ) +{ + vtkImageData* image; + if( this->ImageMaps[ 0 ] != NULL ) + image = + dynamic_cast< vtkImageData* >( this->ImageMaps[ 0 ]->GetInput( ) ); + else + image = this->SliceMappers[ 0 ]->GetInput( ); + + int ijk[ 3 ]; + double pcoords[ 3 ]; + image->ComputeStructuredCoordinates( pos, ijk, pcoords ); + this->SetSliceNumber( ijk[ this->GetAxis( ) ] ); +} + +// ------------------------------------------------------------------------- +/* TODO + void cpExtensions::Visualization::ImageSliceActors:: + SetSlices( double pos[ 3 ] ) + { + } +*/ + // ------------------------------------------------------------------------- void cpExtensions::Visualization::ImageSliceActors:: UpdateText( ) @@ -903,6 +951,8 @@ ImageSliceActors( ) { this->Clear( ); + this->SlicesCommand = NULL; + // Connect this view with a controller this->Style = vtkSmartPointer< ImageInteractorStyle >::New( ); this->Style->AssociateView( this ); @@ -1048,6 +1098,8 @@ _MouseMoveCommand( } else if( btn == ImageInteractorStyle::ButtonID_Left ) { + if( !alt && ctr && !sft && actors->SlicesCommand != NULL ) + actors->SlicesCommand( pos, actors->GetAxis( ), actors->SlicesData ); } else if( btn == ImageInteractorStyle::ButtonID_Middle ) { @@ -1114,10 +1166,9 @@ _MouseDoubleClickCommand( if( btn == ImageInteractorStyle::ButtonID_Left ) { if( !alt && !ctr && !sft ) - { actors->SetCursor( pos ); - - } // fi + else if( !alt && ctr && !sft && actors->SlicesCommand != NULL ) + actors->SlicesCommand( pos, actors->GetAxis( ), actors->SlicesData ); } else if( btn == ImageInteractorStyle::ButtonID_Middle ) { diff --git a/lib/cpExtensions/Visualization/ImageSliceActors.h b/lib/cpExtensions/Visualization/ImageSliceActors.h index 4708e07..962c8f2 100644 --- a/lib/cpExtensions/Visualization/ImageSliceActors.h +++ b/lib/cpExtensions/Visualization/ImageSliceActors.h @@ -36,6 +36,8 @@ namespace cpExtensions public: typedef ImageSliceActors Self; + typedef void ( *TCursorCommand )( double*, int, void* ); + public: vtkTypeMacro( ImageSliceActors, vtkPropCollection ); @@ -61,6 +63,9 @@ namespace cpExtensions LUTType lut = Self::LUTType_None ); void Clear( ); + void AssociateSlice( Self* other ); + void SetSlicesCommand( TCursorCommand cmd, void* data ); + vtkInteractorStyle* GetStyle( ); const vtkInteractorStyle* GetStyle( ) const; @@ -104,6 +109,7 @@ namespace cpExtensions int GetSliceNumberMinValue( ) const; int GetSliceNumberMaxValue( ) const; void SetSliceNumber( const int& slice ); + void SetSlice( double* pos ); void UpdateText( ); void UpdateText( double pos[ 3 ] ); void UpdateText( const double& w, const double& l ); @@ -154,6 +160,11 @@ namespace cpExtensions std::vector< vtkSmartPointer< vtkImageActor > > ImageActors; bool Interpolate; + // Other associated slices + std::vector< vtkSmartPointer< Self > > AssociatedSlices; + TCursorCommand SlicesCommand; + void* SlicesData; + // 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 72bf719..4498a2b 100644 --- a/lib/cpExtensions/Visualization/MPRActors.cxx +++ b/lib/cpExtensions/Visualization/MPRActors.cxx @@ -193,6 +193,20 @@ PushActorsInto( } // rof if( wren != NULL ) wren->AddActor( this->ImageOutlineActor ); + + for( unsigned int j = 0; j < 3; ++j ) + { + ImageInteractorStyle* st = + dynamic_cast< ImageInteractorStyle* >( this->Slices[ 0 ][ j ]->GetStyle( ) ); + if( w != NULL ) + st->AssociateInteractor( w->GetInteractor( ) ); + for( unsigned int l = 0; l < 3; ++l ) + if( j != l ) + st->AssociateInteractor( + this->Slices[ 0 ][ l ]->GetStyle( )->GetInteractor( ) + ); + + } // rof } // ------------------------------------------------------------------------- @@ -606,6 +620,14 @@ MPRActors( ) for( unsigned int i = 0; i < 2; ++i ) for( unsigned int j = 0; j < 3; ++j ) this->Slices[ i ][ j ] = vtkSmartPointer< ImageSliceActors >::New( ); + + this->Slices[ 0 ][ 0 ]->AssociateSlice( this->Slices[ 1 ][ 0 ] ); + this->Slices[ 0 ][ 1 ]->AssociateSlice( this->Slices[ 1 ][ 1 ] ); + this->Slices[ 0 ][ 2 ]->AssociateSlice( this->Slices[ 1 ][ 2 ] ); + + this->Slices[ 0 ][ 0 ]->SetSlicesCommand( Self::_SetSlices, this ); + this->Slices[ 0 ][ 1 ]->SetSlicesCommand( Self::_SetSlices, this ); + this->Slices[ 0 ][ 2 ]->SetSlicesCommand( Self::_SetSlices, this ); } // ------------------------------------------------------------------------- @@ -691,4 +713,17 @@ _Update( unsigned int i ) */ } +// ------------------------------------------------------------------------- +void cpExtensions::Visualization::MPRActors:: +_SetSlices( double* pos, int axis, void* data ) +{ + MPRActors* actors = reinterpret_cast< MPRActors* >( data ); + if( actors == NULL ) + return; + for( unsigned int j = 0; j < 3; ++j ) + if( actors->Slices[ 0 ][ j ]->GetAxis( ) != axis ) + actors->Slices[ 0 ][ j ]->SetSlice( pos ); + actors->Modified( ); +} + // eof - $RCSfile$ diff --git a/lib/cpExtensions/Visualization/MPRActors.h b/lib/cpExtensions/Visualization/MPRActors.h index ac49dc6..f9fb213 100644 --- a/lib/cpExtensions/Visualization/MPRActors.h +++ b/lib/cpExtensions/Visualization/MPRActors.h @@ -104,6 +104,8 @@ namespace cpExtensions vtkImageData* _Image( unsigned int i ) const; void _Update( unsigned int i ); + static void _SetSlices( double* pos, int axis, void* data ); + private: // Purposely not implemented MPRActors( const Self& ); diff --git a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx new file mode 100644 index 0000000..471c10b --- /dev/null +++ b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx @@ -0,0 +1,159 @@ +#include "FloodFillImageFilter.h" +#include + +#include +#include + +// ------------------------------------------------------------------------- +cpPlugins::BasicFilters::FloodFillImageFilter:: +FloodFillImageFilter( ) + : Superclass( ) +{ + this->SetNumberOfInputs( 1 ); + this->SetNumberOfOutputs( 1 ); + this->_MakeOutput< cpPlugins::Interface::Image >( 0 ); + + using namespace cpPlugins::Interface; + this->m_DefaultParameters.Configure( Parameters::Point, "Seed" ); + this->m_DefaultParameters.Configure( Parameters::Real, "InsideValue" ); + this->m_DefaultParameters.Configure( Parameters::Real, "OutsideValue" ); + this->m_DefaultParameters.SetValueAsPoint( "Seed", 3, 0, 0, 0 ); + this->m_DefaultParameters.SetValueAsReal( "InsideValue", 255 ); + this->m_DefaultParameters.SetValueAsReal( "OutsideValue", 0 ); + this->m_Parameters = this->m_DefaultParameters; +} + +// ------------------------------------------------------------------------- +cpPlugins::BasicFilters::FloodFillImageFilter:: +~FloodFillImageFilter( ) +{ +} + +// ------------------------------------------------------------------------- +std::string cpPlugins::BasicFilters::FloodFillImageFilter:: +_GenerateData( ) +{ + cpPlugins::Interface::Image* image = + this->GetInput< cpPlugins::Interface::Image >( 0 ); + if( image == NULL ) + return( "FloodFillImageFilter: No input image." ); + + itk::DataObject* itk_image = NULL; + std::string r = ""; + cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _GD0 ); + else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 ); + else r = "FloodFillImageFilter: Input image type not supported."; + return( r ); +} + +// ------------------------------------------------------------------------- +template< class I > +std::string cpPlugins::BasicFilters::FloodFillImageFilter:: +_GD0( itk::DataObject* image ) +{ + return( + this->_RealGD< I, itk::Image< unsigned char, I::ImageDimension > >( + image + ) + ); +} + +// ------------------------------------------------------------------------- +template< class I, class R = float > +class cpPlugins_BasicFilters_FloodFillImageFilter_Function + : public itk::ImageFunction< I, bool, R > +{ +public: + typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function Self; + typedef itk::ImageFunction< I, bool, R > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef typename Superclass::PointType TPoint; + typedef typename Superclass::IndexType TIndex; + typedef typename Superclass::ContinuousIndexType TCIndex; + +public: + itkNewMacro( Self ); + itkTypeMacro( + cpPlugins_BasicFilters_FloodFillImageFilter_Function, + itkImageFunction + ); + +public: + virtual bool Evaluate( const TPoint& point ) const + { + return( true ); + } + virtual bool EvaluateAtIndex( const TIndex& index ) const + { + return( true ); + } + virtual bool EvaluateAtContinuousIndex( const TCIndex& index ) const + { + return( true ); + } + +protected: + cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) + : Superclass( ) + { + } + virtual ~cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) + { + } + +private: + // Purposely not implemented + cpPlugins_BasicFilters_FloodFillImageFilter_Function( const Self& other ); + Self& operator=( const Self& other ); +}; + +// ------------------------------------------------------------------------- +template< class I, class O > +inline std::string cpPlugins::BasicFilters::FloodFillImageFilter:: +_RealGD( itk::DataObject* image ) +{ + typedef typename O::PixelType _OP; + typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function< I > _F; + typedef itk::FloodFilledImageFunctionConditionalConstIterator< I, _F > _It; + + typename I::PointType pseed; + pseed = this->m_Parameters.GetValueAsPoint< typename I::PointType >( "Seed" ); + _OP in_val = _OP( this->m_Parameters.GetValueAsReal( "InsideValue" ) ); + _OP out_val = _OP( this->m_Parameters.GetValueAsReal( "OutsideValue" ) ); + + const I* in = dynamic_cast< const I* >( image ); + typename I::IndexType seed; + in->TransformPhysicalPointToIndex( pseed, seed ); + + typename O::Pointer out = O::New( ); + out->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) ); + out->SetRequestedRegion( in->GetRequestedRegion( ) ); + out->SetBufferedRegion( in->GetBufferedRegion( ) ); + out->SetOrigin( in->GetOrigin( ) ); + out->SetDirection( in->GetDirection( ) ); + out->SetSpacing( in->GetSpacing( ) ); + out->Allocate( ); + out->FillBuffer( out_val ); + + typename _F::Pointer f = _F::New( ); + _It i( in, f ); + i.AddSeed( seed ); + + for( i.GoToBegin( ); !i.IsAtEnd( ); ++i ) + out->SetPixel( i.GetIndex( ), in_val ); + + // Connect output + cpPlugins::Interface::Image* out_port = + this->GetOutput< cpPlugins::Interface::Image >( 0 ); + if( out_port != NULL ) + { + out_port->SetITK< O >( out ); + return( "" ); + } + else + return( "FloodFillImageFilter: output not correctly created." ); +} + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h new file mode 100644 index 0000000..e50ae24 --- /dev/null +++ b/lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.h @@ -0,0 +1,60 @@ +#ifndef __CPPLUGINS__PLUGINS__FLOODFILLIMAGEFILTER__H__ +#define __CPPLUGINS__PLUGINS__FLOODFILLIMAGEFILTER__H__ + +#include +#include + +namespace cpPlugins +{ + namespace BasicFilters + { + /** + */ + class cpPluginsBasicFilters_EXPORT FloodFillImageFilter + : public cpPlugins::Interface::ImageToImageFilter + { + public: + typedef FloodFillImageFilter Self; + typedef cpPlugins::Interface::ImageToImageFilter Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkNewMacro( Self ); + itkTypeMacro( + FloodFillImageFilter, + cpPluginsInterfaceImageToImageFilter + ); + cpPlugins_Id_Macro( + cpPlugins::BasicFilters::FloodFillImageFilter, + "ImageToImageFilter" + ); + + protected: + FloodFillImageFilter( ); + virtual ~FloodFillImageFilter( ); + + virtual std::string _GenerateData( ); + + template< class I > + inline std::string _GD0( itk::DataObject* image ); + + template< class I, class O > + inline std::string _RealGD( itk::DataObject* image ); + + private: + // Purposely not implemented + FloodFillImageFilter( const Self& ); + Self& operator=( const Self& ); + }; + + // --------------------------------------------------------------------- + CPPLUGINS_INHERIT_PROVIDER( FloodFillImageFilter ); + + } // ecapseman + +} // ecapseman + +#endif // __CPPLUGINS__PLUGINS__FLOODFILLIMAGEFILTER__H__ + +// eof - $RCSfile$ -- 2.45.1