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>
15 // -------------------------------------------------------------------------
16 // This callback is responsible for changing update time
17 namespace cpPluginsWidgets
21 class SeedWidgetCallback
25 static SeedWidgetCallback* New( )
26 { return( new SeedWidgetCallback ); }
27 virtual void Execute( vtkObject* caller, unsigned long id, void* data )
30 typedef cpPluginsWidgets::SeedWidget::TImageActor _TImageActor;
31 auto actor = dynamic_cast< _TImageActor* >( caller );
34 if( id == vtkCommand::InteractionEvent && actor != NULL )
36 int slice = actor->GetSliceNumber( );
37 if( this->Data->ActualWidgetId != slice )
39 this->Data->Widgets[ this->Data->ActualWidgetId ]->EnabledOff( );
40 this->Data->Widgets[ slice ]->EnabledOn( );
41 this->Data->ActualWidgetId = slice;
46 // id == vtkCommand::CursorChangedEvent ||
47 if( id == vtkCommand::PlacePointEvent )
49 auto wdg = dynamic_cast< cpExtensions::Interaction::SeedWidget* >( caller );
53 dynamic_cast< vtkSeedRepresentation* >(
54 wdg->GetRepresentation( )
58 unsigned long nSeeds = rep->GetNumberOfSeeds( );
62 rep->GetSeedWorldPosition( nSeeds - 1, pos );
64 Seeds->GetPoints( )->InsertNextPoint( pos );
65 Seeds->GetVerts( )->InsertNextCell( 1 );
66 Seeds->GetVerts( )->InsertCellPoint( nSeeds - 1 );
87 virtual ~SeedWidgetCallback( ) { }
93 SeedWidget::TWidgetData* Data;
99 // -------------------------------------------------------------------------
100 cpPluginsWidgets::SeedWidget::
105 m_Configured( false )
108 typedef cpPlugins::BaseObjects::DataObject _TData;
109 typedef cpPlugins::DataObjects::Mesh _TMesh;
112 this->_ConfigureInput< _TData >( "Input", false, false );
113 this->_ConfigureOutput< _TMesh >( "Output" );
115 // Create output data
116 auto out = this->_CreateVTK< vtkPolyData >( );
117 out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
118 out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
119 out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
120 out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
121 out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
122 this->GetOutput( "Output" )->SetVTK( out );
125 // -------------------------------------------------------------------------
126 cpPluginsWidgets::SeedWidget::
129 for( auto i = this->m_Data.begin( ); i != this->m_Data.end( ); ++i )
131 this->m_Data.clear( );
134 // -------------------------------------------------------------------------
135 void cpPluginsWidgets::SeedWidget::
138 auto image = this->GetInputData< vtkImageData >( "Input" );
140 this->_GD0_Image( image );
142 this->_Error( "Invalid input image." );
144 // TODO: std::string init_value = this->m_Parameters.GetString( "Text" );
147 static vtkPolyData* prev_pdata = NULL;
148 auto pdata = this->_CreateVTK< vtkPolyData >( );
149 if( prev_pdata != pdata )
151 pdata->SetPoints( vtkPoints::New( ) );
152 pdata->SetVerts( vtkCellArray::New( ) );
153 pdata->SetLines( vtkCellArray::New( ) );
154 pdata->SetPolys( vtkCellArray::New( ) );
155 pdata->SetStrips( vtkCellArray::New( ) );
159 auto points = pdata->GetPoints( );
160 auto verts = pdata->GetVerts( );
162 if( this->m_Configured )
164 if( points->GetNumberOfPoints( ) == 0 )
166 std::stringstream text;
168 for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
170 for( auto r = ( *w )->Widgets.begin( ); r != ( *w )->Widgets.end( ); ++r )
173 dynamic_cast< vtkSeedRepresentation* >(
174 ( *r )->GetRepresentation( )
179 for( unsigned int i = 0; i < rep->GetNumberOfSeeds( ); ++i )
181 rep->GetSeedWorldPosition( i, pos );
185 text << pos[ 0 ] << " " << pos[ 1 ] << " " << pos[ 2 ];
186 points->InsertNextPoint( pos );
191 ( *r )->EnabledOff( );
196 this->m_Parameters.SetString( "Text", text.str( ) );
202 auto init_seeds = this->m_Parameters.GetString( "Text" );
203 std::vector< std::string > tokens;
204 cpExtensions::Tokenize( tokens, init_seeds, "#" );
205 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
207 std::vector< std::string > coords;
208 cpExtensions::Tokenize( coords, *tIt, " \t" );
209 int dim = ( coords.size( ) < 3 )? coords.size( ): 3;
211 for( unsigned int d = 0; d < 3; ++d )
213 pos[ d ] = double( 0 );
216 std::istringstream value( coords[ d ] );
222 verts->InsertNextCell( 1 );
223 verts->InsertCellPoint( points->GetNumberOfPoints( ) );
224 points->InsertNextPoint( pos );
229 this->m_Configured = true;
232 this->GetOutput( "Output" )->SetVTK( pdata );
236 // -------------------------------------------------------------------------
237 void cpPluginsWidgets::SeedWidget::
241 typedef cpPlugins::DataObjects::Image _TImage;
243 auto image = this->GetInput< _TImage >( "Input" );
247 auto vtk_image = image->GetVTK< vtkImageData >( );
248 auto iIt = this->m_Interactors.begin( );
249 for( ; iIt != this->m_Interactors.end( ); ++iIt )
251 auto ren = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( );
254 auto props = ren->GetViewProps( );
257 props->InitTraversal( );
258 while( vtkProp* prop = props->GetNextProp( ) )
260 auto actor = dynamic_cast< TImageActor* >( prop );
262 if( actor->GetImage( ) == vtk_image )
263 this->m_Props[ actor ] = *iIt;
274 if( this->m_Props.size( ) > 0 )
276 cpPlugins_Demangle_ImageVisualDims( image->GetITK( ), _GD0_Image );
277 else this->_Error( "Invalid input image." );
280 this->_Error( "Could not create a valid widget: no actors." );
283 this->_Error( "Could not create a valid widget: no input." );
287 // -------------------------------------------------------------------------
288 void cpPluginsWidgets::SeedWidget::
289 _GD0_Image( vtkImageData* image )
291 if( this->m_Data.size( ) == 0 )
293 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
294 cb->Seeds = this->GetOutputData< vtkPolyData >( "Output" );
295 this->m_Command = cb;
298 auto inIt = this->m_Interactors.begin( );
299 inIt != this->m_Interactors.end( );
303 auto rends = ( *inIt )->GetRenderWindow( )->GetRenderers( );
304 std::set< TImageActor* > all_props;
307 rends->InitTraversal( );
308 while( vtkRenderer* ren = rends->GetNextItem( ) )
310 auto props = ren->GetViewProps( );
311 props->InitTraversal( );
312 while( vtkProp* p = props->GetNextProp( ) )
314 auto image_actor = dynamic_cast< TImageActor* >( p );
315 if( image_actor != NULL )
317 if( image_actor->GetImage( ) == image )
318 all_props.insert( image_actor );
326 if( all_props.size( ) == 1 )
328 this->m_Data[ *inIt ] =
329 new TWidgetData( this, *( all_props.begin( ) ), *inIt, this->m_Command );
341 // -------------------------------------------------------------------------
342 cpPluginsWidgets::SeedWidget::TWidgetData::
344 SeedWidget* seedWidget,
346 vtkRenderWindowInteractor* iren,
350 auto cb = dynamic_cast< SeedWidgetCallback* >( cmd );
352 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
353 cb->Widget = seedWidget;
356 actor->AddObserver( vtkCommand::InteractionEvent, cb );
359 auto image = actor->GetImage( );
360 int ori = actor->GetOrientation( );
362 image->GetExtent( ext );
363 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
366 this->Placer = vtkSmartPointer< _TPlacer >::New( );
367 this->Handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
368 this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( );
369 this->Widget = vtkSmartPointer< _TWidget >::New( );
371 this->Placer->SetImageSlice( actor );
372 this->Handle->GetProperty( )->SetColor( 1, 0, 0 );
373 this->Handle->SetPointPlacer( this->Placer );
374 this->Representation->SetHandleRepresentation( this->Handle );
375 this->Widget->SetRepresentation( this->Representation );
376 this->Widget->SetInteractor( iren );
379 this->Widget->AddObserver( vtkCommand::PlacePointEvent, cb );
380 this->Widget->AddObserver( vtkCommand::CursorChangedEvent, cb );
382 this->Widget->EnabledOn( );
385 this->Widgets.push_back( wdg );
386 this->Placers.push_back( placer );
387 this->Handles.push_back( handle );
388 this->Representations.push_back( rep );
393 this->ActualWidgetId = actor->GetSliceNumber( );
394 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
398 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
399 cb->Widget = seedWidget;
402 actor->AddObserver( vtkCommand::InteractionEvent, cb );
404 auto image = actor->GetImage( );
405 int ori = actor->GetOrientation( );
407 image->GetExtent( ext );
408 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
410 auto placer = vtkSmartPointer< _TPlacer >::New( );
411 auto handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
412 auto rep = vtkSmartPointer< vtkSeedRepresentation >::New( );
413 auto wdg = vtkSmartPointer< _TWidget >::New( );
415 placer->SetImageSlice( actor );
416 handle->GetProperty( )->SetColor( 1, 0, 0 );
417 handle->SetPointPlacer( placer );
418 rep->SetHandleRepresentation( handle );
419 wdg->SetRepresentation( rep );
420 wdg->SetInteractor( iren );
421 wdg->AddObserver( vtkCommand::PlacePointEvent, cb );
422 wdg->AddObserver( vtkCommand::CursorChangedEvent, cb );
425 this->Widgets.push_back( wdg );
426 this->Placers.push_back( placer );
427 this->Handles.push_back( handle );
428 this->Representations.push_back( rep );
432 this->ActualWidgetId = actor->GetSliceNumber( );
433 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
437 // -------------------------------------------------------------------------
438 cpPluginsWidgets::SeedWidget::TWidgetData::