1 #include <plugins/Widgets/SeedWidget.h>
2 #include <cpPlugins/DataObjects/Image.h>
3 #include <cpPlugins/DataObjects/Mesh.h>
5 #include <vtkCommand.h>
6 #include <vtkImageActor.h>
7 #include <vtkImageData.h>
8 #include <vtkProperty.h>
9 #include <vtkRenderer.h>
10 #include <vtkRendererCollection.h>
11 #include <vtkRenderWindow.h>
12 #include <vtkRenderWindowInteractor.h>
13 #include <cpExtensions/QT/SimpleMPRWidget.h>
14 #include <cpExtensions/Interaction/SeedWidget.h>
16 // -------------------------------------------------------------------------
17 // This callback is responsible for changing update time
18 namespace cpPluginsWidgets
22 class SeedWidgetCallback
26 static SeedWidgetCallback* New( )
27 { return( new SeedWidgetCallback ); }
28 virtual void Execute( vtkObject* caller, unsigned long id, void* data )
30 if( id == vtkCommand::InteractionEvent )
32 std::cout << id << std::endl;
33 auto actor = dynamic_cast< SeedWidget::TImageActor* >( caller );
36 int slice = actor->GetSliceNumber( );
38 std::cout << slice << std::endl;
42 typedef cpPluginsWidgets::SeedWidget::TImageActor _TImageActor;
45 if( this->Data->ActualWidgetId != slice )
47 this->Data->Widgets[ this->Data->ActualWidgetId ]->EnabledOff( );
48 this->Data->Widgets[ slice ]->EnabledOn( );
49 this->Data->ActualWidgetId = slice;
55 else if( id == vtkCommand::PlacePointEvent )
57 // TODO: id == vtkCommand::CursorChangedEvent ||
58 auto wdg = dynamic_cast< SeedWidget::TWidget* >( caller );
62 dynamic_cast< vtkSeedRepresentation* >(
63 wdg->GetRepresentation( )
67 unsigned long nSeeds = rep->GetNumberOfSeeds( );
71 rep->GetSeedWorldPosition( nSeeds - 1, pos );
73 Seeds->GetPoints( )->InsertNextPoint( pos );
74 Seeds->GetVerts( )->InsertNextCell( 1 );
75 Seeds->GetVerts( )->InsertCellPoint( nSeeds - 1 );
96 virtual ~SeedWidgetCallback( ) { }
102 SeedWidget::TWidgetData* Data;
108 // -------------------------------------------------------------------------
109 cpPluginsWidgets::SeedWidget::
114 m_Configured( false )
117 typedef cpPlugins::BaseObjects::DataObject _TData;
118 typedef cpPlugins::DataObjects::Mesh _TMesh;
121 this->_ConfigureInput< _TData >( "Input", false, false );
122 this->_ConfigureOutput< _TMesh >( "Output" );
124 // Create output data
125 auto out = this->_CreateVTK< vtkPolyData >( );
126 out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
127 out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
128 out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
129 out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
130 out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
131 this->GetOutput( "Output" )->SetVTK( out );
134 // -------------------------------------------------------------------------
135 cpPluginsWidgets::SeedWidget::
138 for( auto i = this->m_Data.begin( ); i != this->m_Data.end( ); ++i )
140 this->m_Data.clear( );
143 // -------------------------------------------------------------------------
144 void cpPluginsWidgets::SeedWidget::
147 auto image = this->GetInputData< vtkImageData >( "Input" );
149 this->_GD0_Image( image );
151 this->_Error( "Invalid input image." );
153 // TODO: std::string init_value = this->m_Parameters.GetString( "Text" );
156 static vtkPolyData* prev_pdata = NULL;
157 auto pdata = this->_CreateVTK< vtkPolyData >( );
158 if( prev_pdata != pdata )
160 pdata->SetPoints( vtkPoints::New( ) );
161 pdata->SetVerts( vtkCellArray::New( ) );
162 pdata->SetLines( vtkCellArray::New( ) );
163 pdata->SetPolys( vtkCellArray::New( ) );
164 pdata->SetStrips( vtkCellArray::New( ) );
168 auto points = pdata->GetPoints( );
169 auto verts = pdata->GetVerts( );
171 if( this->m_Configured )
173 if( points->GetNumberOfPoints( ) == 0 )
175 std::stringstream text;
177 for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
179 for( auto r = ( *w )->Widgets.begin( ); r != ( *w )->Widgets.end( ); ++r )
182 dynamic_cast< vtkSeedRepresentation* >(
183 ( *r )->GetRepresentation( )
188 for( unsigned int i = 0; i < rep->GetNumberOfSeeds( ); ++i )
190 rep->GetSeedWorldPosition( i, pos );
194 text << pos[ 0 ] << " " << pos[ 1 ] << " " << pos[ 2 ];
195 points->InsertNextPoint( pos );
200 ( *r )->EnabledOff( );
205 this->m_Parameters.SetString( "Text", text.str( ) );
211 auto init_seeds = this->m_Parameters.GetString( "Text" );
212 std::vector< std::string > tokens;
213 cpExtensions::Tokenize( tokens, init_seeds, "#" );
214 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
216 std::vector< std::string > coords;
217 cpExtensions::Tokenize( coords, *tIt, " \t" );
218 int dim = ( coords.size( ) < 3 )? coords.size( ): 3;
220 for( unsigned int d = 0; d < 3; ++d )
222 pos[ d ] = double( 0 );
225 std::istringstream value( coords[ d ] );
231 verts->InsertNextCell( 1 );
232 verts->InsertCellPoint( points->GetNumberOfPoints( ) );
233 points->InsertNextPoint( pos );
238 this->m_Configured = true;
241 this->GetOutput( "Output" )->SetVTK( pdata );
245 // -------------------------------------------------------------------------
246 void cpPluginsWidgets::SeedWidget::
250 typedef cpPlugins::DataObjects::Image _TImage;
252 auto image = this->GetInput< _TImage >( "Input" );
256 auto vtk_image = image->GetVTK< vtkImageData >( );
257 auto iIt = this->m_Interactors.begin( );
258 for( ; iIt != this->m_Interactors.end( ); ++iIt )
260 auto ren = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( );
263 auto props = ren->GetViewProps( );
266 props->InitTraversal( );
267 while( vtkProp* prop = props->GetNextProp( ) )
269 auto actor = dynamic_cast< TImageActor* >( prop );
271 if( actor->GetImage( ) == vtk_image )
272 this->m_Props[ actor ] = *iIt;
283 if( this->m_Props.size( ) > 0 )
285 cpPlugins_Demangle_ImageVisualDims( image->GetITK( ), _GD0_Image );
286 else this->_Error( "Invalid input image." );
289 this->_Error( "Could not create a valid widget: no actors." );
292 this->_Error( "Could not create a valid widget: no input." );
296 // -------------------------------------------------------------------------
297 void cpPluginsWidgets::SeedWidget::
298 _GD0_Image( vtkImageData* image )
300 if( this->m_Data.size( ) == 0 )
302 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
303 cb->Seeds = this->GetOutputData< vtkPolyData >( "Output" );
304 this->m_Command = cb;
307 auto inIt = this->m_Interactors.begin( );
308 inIt != this->m_Interactors.end( );
312 auto rends = ( *inIt )->GetRenderWindow( )->GetRenderers( );
313 std::set< TImageActor* > all_props;
316 rends->InitTraversal( );
317 while( vtkRenderer* ren = rends->GetNextItem( ) )
319 auto props = ren->GetViewProps( );
320 props->InitTraversal( );
321 while( vtkProp* p = props->GetNextProp( ) )
323 auto image_actor = dynamic_cast< TImageActor* >( p );
324 if( image_actor != NULL )
326 if( image_actor->GetImage( ) == image )
327 all_props.insert( image_actor );
336 if( all_props.size( ) == 1 )
338 this->m_Data[ *inIt ] =
340 this, *( all_props.begin( ) ), *inIt, this->m_Command
354 // -------------------------------------------------------------------------
355 cpPluginsWidgets::SeedWidget::TWidgetData::
357 SeedWidget* seedWidget,
359 vtkRenderWindowInteractor* iren,
363 auto cb = dynamic_cast< SeedWidgetCallback* >( cmd );
364 actor->AddObserver( vtkCommand::InteractionEvent, cb );
366 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
367 cb->Widget = seedWidget;
372 auto image = actor->GetImage( );
373 int ori = actor->GetOrientation( );
375 image->GetExtent( ext );
376 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
379 this->Placer = vtkSmartPointer< _TPlacer >::New( );
380 this->Handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
381 this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( );
382 this->Widget = vtkSmartPointer< TWidget >::New( );
384 this->Placer->SetImageSlice( actor );
385 this->Handle->GetProperty( )->SetColor( 1, 0, 0 );
386 this->Handle->SetPointPlacer( this->Placer );
387 this->Representation->SetHandleRepresentation( this->Handle );
388 this->Widget->SetRepresentation( this->Representation );
389 this->Widget->SetInteractor( iren );
392 this->Widget->AddObserver( vtkCommand::PlacePointEvent, cb );
393 this->Widget->AddObserver( vtkCommand::CursorChangedEvent, cb );
395 this->Widget->EnabledOn( );
398 this->Widgets.push_back( wdg );
399 this->Placers.push_back( placer );
400 this->Handles.push_back( handle );
401 this->Representations.push_back( rep );
406 this->ActualWidgetId = actor->GetSliceNumber( );
407 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
411 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
412 cb->Widget = seedWidget;
415 actor->AddObserver( vtkCommand::InteractionEvent, cb );
417 auto image = actor->GetImage( );
418 int ori = actor->GetOrientation( );
420 image->GetExtent( ext );
421 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
423 auto placer = vtkSmartPointer< _TPlacer >::New( );
424 auto handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
425 auto rep = vtkSmartPointer< vtkSeedRepresentation >::New( );
426 auto wdg = vtkSmartPointer< TWidget >::New( );
428 placer->SetImageSlice( actor );
429 handle->GetProperty( )->SetColor( 1, 0, 0 );
430 handle->SetPointPlacer( placer );
431 rep->SetHandleRepresentation( handle );
432 wdg->SetRepresentation( rep );
433 wdg->SetInteractor( iren );
434 wdg->AddObserver( vtkCommand::PlacePointEvent, cb );
435 wdg->AddObserver( vtkCommand::CursorChangedEvent, cb );
438 this->Widgets.push_back( wdg );
439 this->Placers.push_back( placer );
440 this->Handles.push_back( handle );
441 this->Representations.push_back( rep );
445 this->ActualWidgetId = actor->GetSliceNumber( );
446 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
450 // -------------------------------------------------------------------------
451 cpPluginsWidgets::SeedWidget::TWidgetData::