#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 ) { typedef cpPluginsWidgets::SeedWidget::TImageActor _TImageActor; auto actor = dynamic_cast< _TImageActor* >( caller ); if( id == vtkCommand::InteractionEvent && actor != NULL ) { int slice = actor->GetSliceNumber( ); if( this->Data->ActualWidgetId != slice ) { this->Data->Widgets[ this->Data->ActualWidgetId ]->EnabledOff( ); this->Data->Widgets[ slice ]->EnabledOn( ); this->Data->ActualWidgetId = slice; } // fi } else if( ( id == vtkCommand::CursorChangedEvent || id == vtkCommand::PlacePointEvent ) && this->Widget != NULL ) this->Widget->Modified( ); } protected: SeedWidgetCallback( ) : vtkCommand( ), Widget( NULL ), Data( NULL ) { } virtual ~SeedWidgetCallback( ) { } public: SeedWidget* Widget; SeedWidget::TWidgetData* Data; }; } // ecapseman // ------------------------------------------------------------------------- cpPluginsWidgets::SeedWidget:: SeedWidget( ) : Superclass( ), m_Configured( false ) { typedef cpPlugins::BaseObjects::DataObject _TData; typedef cpPlugins::DataObjects::Mesh _TMesh; this->_ConfigureInput< _TData >( "Input", false, false ); this->_ConfigureOutput< _TMesh >( "Output" ); } // ------------------------------------------------------------------------- cpPluginsWidgets::SeedWidget:: ~SeedWidget( ) { for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w ) delete *w; this->m_Widgets.clear( ); } // ------------------------------------------------------------------------- void cpPluginsWidgets::SeedWidget:: _GenerateData( ) { 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( ) { 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." ); } // ------------------------------------------------------------------------- template< class _TImage > void cpPluginsWidgets::SeedWidget:: _GD0_Image( _TImage* image ) { for( auto p = this->m_Props.begin( ); p != this->m_Props.end( ); ++p ) { TWidgetData* d = new TWidgetData( this, dynamic_cast< TImageActor* >( p->first ), p->second ); this->m_Widgets.push_back( d ); } // rof } // ------------------------------------------------------------------------- cpPluginsWidgets::SeedWidget::TWidgetData:: TWidgetData( SeedWidget* seedWidget, TImageActor* actor, vtkRenderWindowInteractor* iren ) { 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( ); } // ------------------------------------------------------------------------- cpPluginsWidgets::SeedWidget::TWidgetData:: ~TWidgetData( ) { } // eof - $RCSfile$