From: Leonardo Florez-Valencia Date: Mon, 3 Oct 2016 03:34:22 +0000 (-0500) Subject: ... X-Git-Tag: v0.1~102 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=bbf5fdea58d522fe9385f8cb506100e062348fe6;p=cpPlugins.git ... --- diff --git a/lib/cpExtensions/Visualization/ImageActor.cxx b/lib/cpExtensions/Visualization/ImageActor.cxx index 9ce91cf..0fcf21b 100644 --- a/lib/cpExtensions/Visualization/ImageActor.cxx +++ b/lib/cpExtensions/Visualization/ImageActor.cxx @@ -42,16 +42,18 @@ GetSliceNumber( ) const void cpExtensions::Visualization::ImageActor:: SetSliceNumber( int slice ) { + static int s = 0; auto image = this->m_Mapper->GetInput( ); if( image != NULL ) { // Update slice - int s = slice; + s = slice; if( s < this->m_Mapper->GetSliceNumberMinValue( ) ) s = this->m_Mapper->GetSliceNumberMinValue( ); if( s > this->m_Mapper->GetSliceNumberMaxValue( ) ) s = this->m_Mapper->GetSliceNumberMaxValue( ); this->m_Mapper->SetSliceNumber( s ); + this->InvokeEvent( vtkCommand::InteractionEvent, &s ); // Propagate modifications this->Modified( ); diff --git a/plugins/Widgets/SeedWidget.cxx b/plugins/Widgets/SeedWidget.cxx index 91d10a1..4400056 100644 --- a/plugins/Widgets/SeedWidget.cxx +++ b/plugins/Widgets/SeedWidget.cxx @@ -1,121 +1,28 @@ #include + #include #include -#include -#include +#include +#include +#include + +#include #include +#include +#include #include -#include #include #include -#include -#include -#include - -// ------------------------------------------------------------------------- -// This callback is responsible for changing update time -namespace cpPluginsWidgets -{ - /** - */ - class SeedWidgetCallback - : public vtkCommand - { - public: - static SeedWidgetCallback* New( ) - { return( new SeedWidgetCallback ); } - virtual void Execute( vtkObject* caller, unsigned long id, void* data ) - { - if( id == vtkCommand::InteractionEvent ) - { - std::cout << id << std::endl; - auto actor = dynamic_cast< SeedWidget::TImageActor* >( caller ); - if( actor != NULL ) - { - int slice = actor->GetSliceNumber( ); - - std::cout << slice << std::endl; - - } // fi - /* TODO - typedef cpPluginsWidgets::SeedWidget::TImageActor _TImageActor; - */ - /* TODO - if( this->Data->ActualWidgetId != slice ) - { - this->Data->Widgets[ this->Data->ActualWidgetId ]->EnabledOff( ); - this->Data->Widgets[ slice ]->EnabledOn( ); - this->Data->ActualWidgetId = slice; - } // fi - } - else - */ - } - else if( id == vtkCommand::PlacePointEvent ) - { - // TODO: id == vtkCommand::CursorChangedEvent || - auto wdg = dynamic_cast< SeedWidget::TWidget* >( caller ); - if( wdg != NULL ) - { - auto rep = - dynamic_cast< vtkSeedRepresentation* >( - wdg->GetRepresentation( ) - ); - if( rep != NULL ) - { - unsigned long nSeeds = rep->GetNumberOfSeeds( ); - if( nSeeds > 0 ) - { - double pos[ 3 ]; - rep->GetSeedWorldPosition( nSeeds - 1, pos ); - - Seeds->GetPoints( )->InsertNextPoint( pos ); - Seeds->GetVerts( )->InsertNextCell( 1 ); - Seeds->GetVerts( )->InsertCellPoint( nSeeds - 1 ); - - } // fi - - } // fi - - } // fi - - } // fi - } - - protected: - SeedWidgetCallback( ) - : vtkCommand( ), - Seeds( NULL ) - /* - , - Widget( NULL ), - Data( NULL ) - */ - { } - virtual ~SeedWidgetCallback( ) { } - public: - vtkPolyData* Seeds; - /* - public: - SeedWidget* Widget; - SeedWidget::TWidgetData* Data; - */ - }; - -} // ecapseman +#include // ------------------------------------------------------------------------- cpPluginsWidgets::SeedWidget:: SeedWidget( ) : Superclass( ) - /* TODO - , - m_Configured( false ) - */ { typedef cpPlugins::BaseObjects::DataObject _TData; - typedef cpPlugins::DataObjects::Mesh _TMesh; + typedef cpPlugins::DataObjects::Mesh _TMesh; // Create ports this->_ConfigureInput< _TData >( "Input", false, false ); @@ -135,9 +42,11 @@ SeedWidget( ) cpPluginsWidgets::SeedWidget:: ~SeedWidget( ) { - for( auto i = this->m_Data.begin( ); i != this->m_Data.end( ); ++i ) - delete i->second; - this->m_Data.clear( ); + /* TODO + for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w ) + w->second->EnabledOff( ); + this->m_Widgets.clear( ); + */ } // ------------------------------------------------------------------------- @@ -149,160 +58,17 @@ _GenerateData( ) this->_GD0_Image( image ); else this->_Error( "Invalid input image." ); - - // TODO: std::string init_value = this->m_Parameters.GetString( "Text" ); - - /* TODO - static vtkPolyData* prev_pdata = NULL; - auto pdata = this->_CreateVTK< vtkPolyData >( ); - if( prev_pdata != pdata ) - { - pdata->SetPoints( vtkPoints::New( ) ); - pdata->SetVerts( vtkCellArray::New( ) ); - pdata->SetLines( vtkCellArray::New( ) ); - pdata->SetPolys( vtkCellArray::New( ) ); - pdata->SetStrips( vtkCellArray::New( ) ); - prev_pdata = pdata; - - } // fi - auto points = pdata->GetPoints( ); - auto verts = pdata->GetVerts( ); - - if( this->m_Configured ) - { - if( points->GetNumberOfPoints( ) == 0 ) - { - std::stringstream text; - bool start = true; - for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w ) - { - for( auto r = ( *w )->Widgets.begin( ); r != ( *w )->Widgets.end( ); ++r ) - { - auto rep = - dynamic_cast< vtkSeedRepresentation* >( - ( *r )->GetRepresentation( ) - ); - if( rep != NULL ) - { - double pos[ 3 ]; - for( unsigned int i = 0; i < rep->GetNumberOfSeeds( ); ++i ) - { - rep->GetSeedWorldPosition( i, pos ); - if( !start ) - text << "#"; - start = false; - text << pos[ 0 ] << " " << pos[ 1 ] << " " << pos[ 2 ]; - points->InsertNextPoint( pos ); - - } // rof - - } // rof - ( *r )->EnabledOff( ); - - } // rof - - } // rof - this->m_Parameters.SetString( "Text", text.str( ) ); - - } // fi - } - else - { - auto init_seeds = this->m_Parameters.GetString( "Text" ); - std::vector< std::string > tokens; - cpExtensions::Tokenize( tokens, init_seeds, "#" ); - for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt ) - { - std::vector< std::string > coords; - cpExtensions::Tokenize( coords, *tIt, " \t" ); - int dim = ( coords.size( ) < 3 )? coords.size( ): 3; - double pos[ 3 ]; - for( unsigned int d = 0; d < 3; ++d ) - { - pos[ d ] = double( 0 ); - if( d < dim ) - { - std::istringstream value( coords[ d ] ); - value >> pos[ d ]; - - } // fi - - } // rof - verts->InsertNextCell( 1 ); - verts->InsertCellPoint( points->GetNumberOfPoints( ) ); - points->InsertNextPoint( pos ); - - } // rof - this->_Configure( ); - this->Modified( ); - this->m_Configured = true; - - } // fi - this->GetOutput( "Output" )->SetVTK( pdata ); - */ -} - -// ------------------------------------------------------------------------- -void cpPluginsWidgets::SeedWidget:: -_Configure( ) -{ - /* TODO - typedef cpPlugins::DataObjects::Image _TImage; - - auto image = this->GetInput< _TImage >( "Input" ); - if( image != NULL ) - { - // Update actors - auto vtk_image = image->GetVTK< vtkImageData >( ); - auto iIt = this->m_Interactors.begin( ); - for( ; iIt != this->m_Interactors.end( ); ++iIt ) - { - auto ren = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( ); - if( ren != NULL ) - { - auto props = ren->GetViewProps( ); - if( props != NULL ) - { - props->InitTraversal( ); - while( vtkProp* prop = props->GetNextProp( ) ) - { - auto actor = dynamic_cast< TImageActor* >( prop ); - if( actor != NULL ) - if( actor->GetImage( ) == vtk_image ) - this->m_Props[ actor ] = *iIt; - - } // elihw - - } // fi - - } // fi - - } // rof - - // Process image - if( this->m_Props.size( ) > 0 ) - { - cpPlugins_Demangle_ImageVisualDims( image->GetITK( ), _GD0_Image ); - else this->_Error( "Invalid input image." ); - } - else - this->_Error( "Could not create a valid widget: no actors." ); - } - else - this->_Error( "Could not create a valid widget: no input." ); - */ } // ------------------------------------------------------------------------- void cpPluginsWidgets::SeedWidget:: _GD0_Image( vtkImageData* image ) { - if( this->m_Data.size( ) == 0 ) + auto seeds = this->GetOutputData< vtkPolyData >( "Output" ); + if( this->m_Widgets.size( ) == 0 ) { - auto cb = vtkSmartPointer< SeedWidgetCallback >::New( ); - cb->Seeds = this->GetOutputData< vtkPolyData >( "Output" ); - this->m_Command = cb; - + this->m_Command = vtkSmartPointer< TCallback >::New( ); + this->m_Command->SetSeeds( seeds ); for( auto inIt = this->m_Interactors.begin( ); inIt != this->m_Interactors.end( ); @@ -326,7 +92,7 @@ _GD0_Image( vtkImageData* image ) if( image_actor->GetImage( ) == image ) all_props.insert( image_actor ); - } + } // fi } // elihw @@ -335,10 +101,60 @@ _GD0_Image( vtkImageData* image ) } // fi if( all_props.size( ) == 1 ) { - this->m_Data[ *inIt ] = - new TWidgetData( - this, *( all_props.begin( ) ), *inIt, this->m_Command - ); + if( this->m_Widgets.find( *inIt ) == this->m_Widgets.end( ) ) + { + auto act = *( all_props.begin( ) ); + auto pla = vtkSmartPointer< TPlacer >::New( ); + auto hnd = vtkSmartPointer< THandleRep >::New( ); + auto rep = vtkSmartPointer< TSeedRep >::New( ); + auto wdg = vtkSmartPointer< TWidget >::New( ); + + pla->SetImageSlice( act ); + hnd->GetProperty( )->SetColor( 1, 0, 0 ); + hnd->SetPointPlacer( pla ); + rep->SetHandleRepresentation( hnd ); + wdg->SetRepresentation( rep ); + wdg->SetInteractor( *inIt ); + act->AddObserver( vtkCommand::InteractionEvent, this->m_Command ); + wdg->AddObserver( vtkCommand::PlacePointEvent, this->m_Command ); + wdg->AddObserver( vtkCommand::CursorChangedEvent, this->m_Command ); + wdg->EnabledOn( ); + this->m_Widgets[ *inIt ] = wdg; + + } // fi + + } // fi + + } // rof + + // Associate input text + std::string text = this->m_Parameters.GetString( "Text" ); + std::vector< std::string > tok1, tok2; + cpExtensions::Tokenize( tok1, text, "#" ); + for( auto t1 = tok1.begin( ); t1 != tok1.end( ); ++t1 ) + { + if( *t1 != "" ) + { + cpExtensions::Tokenize( tok2, *t1, " " ); + double x[ 3 ]; + for( unsigned int d = 0; d < 3; ++d ) + { + if( d < tok2.size( ) ) + { + std::istringstream str( tok2[ d ] ); + str >> x[ d ]; + } + else + x[ d ] = double( 0 ); + + } // rof + + seeds->GetPoints( )->InsertNextPoint( x ); + seeds->GetVerts( )->InsertNextCell( 1 ); + seeds->GetVerts( )->InsertCellPoint( + seeds->GetPoints( )->GetNumberOfPoints( ) - 1 + ); + seeds->Modified( ); } // fi @@ -346,110 +162,180 @@ _GD0_Image( vtkImageData* image ) } else { - // akjhdaksjhd - } + double x[ 3 ]; + std::stringstream text; + for( long i = 0; i < seeds->GetNumberOfPoints( ); ++i ) + { + seeds->GetPoint( i, x ); + text << x[ 0 ] << " " << x[ 1 ] << " " << x[ 2 ] << "#"; + } // rof + this->m_Parameters.SetString( "Text", text.str( ) ); + + } // fi } // ------------------------------------------------------------------------- -cpPluginsWidgets::SeedWidget::TWidgetData:: -TWidgetData( - SeedWidget* seedWidget, - TImageActor* actor, - vtkRenderWindowInteractor* iren, - vtkCommand* cmd - ) +cpPluginsWidgets::SeedWidget::TCallback* +cpPluginsWidgets::SeedWidget::TCallback:: +New( ) { - auto cb = dynamic_cast< SeedWidgetCallback* >( cmd ); - actor->AddObserver( vtkCommand::InteractionEvent, cb ); - /* TODO - auto cb = vtkSmartPointer< SeedWidgetCallback >::New( ); - cb->Widget = seedWidget; - cb->Data = this; - this->Command = cb; - */ - /* TODO - auto image = actor->GetImage( ); - int ori = actor->GetOrientation( ); - int ext[ 6 ]; - image->GetExtent( ext ); - for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i ) - { - */ - this->Placer = vtkSmartPointer< _TPlacer >::New( ); - this->Handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( ); - this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( ); - this->Widget = vtkSmartPointer< TWidget >::New( ); - - this->Placer->SetImageSlice( actor ); - this->Handle->GetProperty( )->SetColor( 1, 0, 0 ); - this->Handle->SetPointPlacer( this->Placer ); - this->Representation->SetHandleRepresentation( this->Handle ); - this->Widget->SetRepresentation( this->Representation ); - this->Widget->SetInteractor( iren ); - if( cb != NULL ) + return( new TCallback ); +} + +// ------------------------------------------------------------------------- +void cpPluginsWidgets::SeedWidget::TCallback:: +Execute( vtkObject* caller, unsigned long id, void* data ) +{ + static const double EPS = 1e-5; + auto src_act = dynamic_cast< TImageActor* >( caller ); + auto src_wdg = dynamic_cast< TWidget* >( caller ); + + if( id == vtkCommand::InteractionEvent && src_act != NULL ) { - this->Widget->AddObserver( vtkCommand::PlacePointEvent, cb ); - this->Widget->AddObserver( vtkCommand::CursorChangedEvent, cb ); + TWidget* widget = NULL; + TSeedRep* seed_rep = NULL; + + auto w = this->m_Widgets.begin( ); + while( w != this->m_Widgets.end( ) && widget == NULL ) + { + auto rep = + dynamic_cast< vtkSeedRepresentation* >( + ( *w )->GetRepresentation( ) + ); + if( rep != NULL ) + { + auto hnd = rep->GetHandleRepresentation( ); + if( hnd != NULL ) + { + auto pla = + dynamic_cast< SeedWidget::TPlacer* >( + hnd->GetPointPlacer( ) + ); + if( pla != NULL ) + { + auto act = pla->GetImageSlice( ); + if( act == src_act ) + { + widget = *w; + seed_rep = rep; + + } // fi + + } // fi + + } // fi + + } // fi + w++; + + } // elihw + + if( widget != NULL ) + { + // Cut through given seeds + auto plane = src_act->GetSlicePlane( ); + double x[ 3 ]; + std::vector< long > ids; + for( long i = 0; i < this->m_Seeds->GetNumberOfPoints( ); ++i ) + { + this->m_Seeds->GetPoint( i, x ); + double d = plane->DistanceToPlane( x ); + if( d <= EPS ) + ids.push_back( i ); + + } // rof + + // Erase seeds + widget->CompleteInteraction( ); + widget->EnabledOff( ); + int nSeeds = seed_rep->GetNumberOfSeeds (); + for( int i = 0; i < nSeeds; ++i ) + { + seed_rep->RemoveLastHandle( ); + widget->DeleteSeed( seed_rep->GetNumberOfSeeds( ) ); + + } // rof + + if( ids.size( ) > 0 ) + { + auto ren = widget->GetInteractor( )->FindPokedRenderer( + widget->GetInteractor( )->GetEventPosition( )[ 0 ], + widget->GetInteractor( )->GetEventPosition( )[ 1 ] + ); + + // Add seeds + seed_rep->BuildRepresentation( ); + for( auto id = ids.begin( ); id != ids.end( ); ++id ) + { + this->m_Seeds->GetPoint( *id, x ); + widget->ComputeWorldToDisplay( + ren, x[ 0 ], x[ 1 ], x[ 2 ], x + ); + x[ 2 ] = double( 0 ); + int s = seed_rep->CreateHandle( x ); + vtkHandleWidget* curr_hnd = widget->CreateNewHandle( ); + seed_rep->SetSeedDisplayPosition( s, x ); + curr_hnd->SetEnabled( 1 ); + + } // rof + + } // fi + + // Reactivate widget + widget->RestartInteraction( ); + widget->EnabledOn( ); + widget->Render( ); + + } // fi } - this->Widget->EnabledOn( ); + else if( id == vtkCommand::PlacePointEvent && src_wdg != NULL ) + { + this->m_Widgets.insert( src_wdg ); + auto rep = + dynamic_cast< vtkSeedRepresentation* >( + src_wdg->GetRepresentation( ) + ); + if( rep != NULL ) + { + unsigned long nSeeds = rep->GetNumberOfSeeds( ); + if( nSeeds > 0 ) + { + double pos[ 3 ]; + rep->GetSeedWorldPosition( nSeeds - 1, pos ); - /* TODO - this->Widgets.push_back( wdg ); - this->Placers.push_back( placer ); - this->Handles.push_back( handle ); - this->Representations.push_back( rep ); - */ + this->m_Seeds->GetPoints( )->InsertNextPoint( pos ); + this->m_Seeds->GetVerts( )->InsertNextCell( 1 ); + this->m_Seeds->GetVerts( )->InsertCellPoint( + this->m_Seeds->GetPoints( )->GetNumberOfPoints( ) - 1 + ); + this->m_Seeds->Modified( ); - /* TODO - } // rof - this->ActualWidgetId = actor->GetSliceNumber( ); - this->Widgets[ this->ActualWidgetId ]->EnabledOn( ); - */ + } // fi - /* TODO - auto cb = vtkSmartPointer< SeedWidgetCallback >::New( ); - cb->Widget = seedWidget; - cb->Data = this; - this->Command = cb; - actor->AddObserver( vtkCommand::InteractionEvent, cb ); - - auto image = actor->GetImage( ); - int ori = actor->GetOrientation( ); - int ext[ 6 ]; - image->GetExtent( ext ); - for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i ) - { - auto placer = vtkSmartPointer< _TPlacer >::New( ); - auto handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( ); - auto rep = vtkSmartPointer< vtkSeedRepresentation >::New( ); - auto wdg = vtkSmartPointer< TWidget >::New( ); - - placer->SetImageSlice( actor ); - handle->GetProperty( )->SetColor( 1, 0, 0 ); - handle->SetPointPlacer( placer ); - rep->SetHandleRepresentation( handle ); - wdg->SetRepresentation( rep ); - wdg->SetInteractor( iren ); - wdg->AddObserver( vtkCommand::PlacePointEvent, cb ); - wdg->AddObserver( vtkCommand::CursorChangedEvent, cb ); - wdg->EnabledOff( ); - - this->Widgets.push_back( wdg ); - this->Placers.push_back( placer ); - this->Handles.push_back( handle ); - this->Representations.push_back( rep ); - - } // rof - - this->ActualWidgetId = actor->GetSliceNumber( ); - this->Widgets[ this->ActualWidgetId ]->EnabledOn( ); - */ + } // fi + + } // fi +} + +// ------------------------------------------------------------------------- +void cpPluginsWidgets::SeedWidget::TCallback:: +SetSeeds( vtkPolyData* seeds ) +{ + this->m_Seeds = seeds; +} + +// ------------------------------------------------------------------------- +cpPluginsWidgets::SeedWidget::TCallback:: +TCallback( ) + : vtkCommand( ), + m_Seeds( NULL ) +{ } // ------------------------------------------------------------------------- -cpPluginsWidgets::SeedWidget::TWidgetData:: -~TWidgetData( ) +cpPluginsWidgets::SeedWidget::TCallback:: +~TCallback( ) { } diff --git a/plugins/Widgets/SeedWidget.h b/plugins/Widgets/SeedWidget.h index 0f56596..b119bb9 100644 --- a/plugins/Widgets/SeedWidget.h +++ b/plugins/Widgets/SeedWidget.h @@ -4,16 +4,22 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - // ------------------------------------------------------------------------- -namespace cpExtensions { namespace Interaction { class SeedWidget; } } +class vtkPointHandleRepresentation3D; +class vtkPolyData; +class vtkSeedRepresentation; +namespace cpExtensions +{ + namespace Interaction + { + class ImageSlicePointPlacer; + class SeedWidget; + } + namespace Visualization + { + class WindowLevelImageActor; + } +} // ------------------------------------------------------------------------- namespace cpPluginsWidgets @@ -26,64 +32,40 @@ namespace cpPluginsWidgets cpPluginsObject( SeedWidget, cpPlugins::BaseObjects::Widget, Widgets ); public: + typedef vtkPointHandleRepresentation3D THandleRep; + typedef vtkSeedRepresentation TSeedRep; typedef cpExtensions::Interaction::SeedWidget TWidget; + typedef cpExtensions::Interaction::ImageSlicePointPlacer TPlacer; typedef cpExtensions::Visualization::WindowLevelImageActor TImageActor; - public: - /* TODO - struct TWidgetData - { - typedef cpExtensions::Interaction::SeedWidget _TWidget; - typedef cpExtensions::Interaction::ImageSlicePointPlacer _TPlacer; - - std::vector< vtkSmartPointer< _TWidget > > Widgets; - std::vector< vtkSmartPointer< _TPlacer > > Placers; - std::vector< vtkSmartPointer< vtkPointHandleRepresentation3D > > Handles; - std::vector< vtkSmartPointer< vtkSeedRepresentation > > Representations; - unsigned int ActualWidgetId; - vtkSmartPointer< vtkCommand > Command; - - TWidgetData( - SeedWidget* seedWidget, - TImageActor* actor, - vtkRenderWindowInteractor* iren - ); - virtual ~TWidgetData( ); - }; - */ - - struct TWidgetData + protected: + /** + */ + class TCallback + : public vtkCommand { - typedef cpExtensions::Interaction::ImageSlicePointPlacer _TPlacer; - - vtkSmartPointer< TWidget > Widget; - vtkSmartPointer< _TPlacer > Placer; - vtkSmartPointer< vtkPointHandleRepresentation3D > Handle; - vtkSmartPointer< vtkSeedRepresentation > Representation; - - TWidgetData( - SeedWidget* seedWidget, - TImageActor* actor, - vtkRenderWindowInteractor* iren, - vtkCommand* cmd - ); - virtual ~TWidgetData( ); + public: + static TCallback* New( ); + virtual void Execute( + vtkObject* caller, unsigned long id, void* data + ) cpPlugins_OVERRIDE; + void SetSeeds( vtkPolyData* seeds ); + + protected: + TCallback( ); + virtual ~TCallback( ); + + protected: + vtkPolyData* m_Seeds; + std::set< TWidget* > m_Widgets; }; protected: - void _Configure( ); - inline void _GD0_Image( vtkImageData* image ); protected: - std::map< vtkRenderWindowInteractor*, TWidgetData* > m_Data; - vtkSmartPointer< vtkCommand > m_Command; - - /* TODO - std::map< vtkProp*, vtkRenderWindowInteractor* > m_Props; - std::vector< TWidgetData* > m_Widgets; - bool m_Configured; - */ + std::map< vtkRenderWindowInteractor*, vtkSmartPointer< TWidget > > m_Widgets; + vtkSmartPointer< TCallback > m_Command; }; } // ecapseman