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;
47 // id == vtkCommand::CursorChangedEvent ||
48 if( id == vtkCommand::PlacePointEvent )
50 auto wdg = dynamic_cast< cpExtensions::Interaction::SeedWidget* >( caller );
54 dynamic_cast< vtkSeedRepresentation* >(
55 wdg->GetRepresentation( )
59 unsigned long nSeeds = rep->GetNumberOfSeeds( );
63 rep->GetSeedWorldPosition( nSeeds - 1, pos );
65 Seeds->GetPoints( )->InsertNextPoint( pos );
66 Seeds->GetVerts( )->InsertNextCell( 1 );
67 Seeds->GetVerts( )->InsertCellPoint( nSeeds - 1 );
86 virtual ~SeedWidgetCallback( ) { }
92 SeedWidget::TWidgetData* Data;
98 // -------------------------------------------------------------------------
99 cpPluginsWidgets::SeedWidget::
104 m_Configured( false )
107 typedef cpPlugins::BaseObjects::DataObject _TData;
108 typedef cpPlugins::DataObjects::Mesh _TMesh;
111 this->_ConfigureInput< _TData >( "Input", false, false );
112 this->_ConfigureOutput< _TMesh >( "Output" );
114 // Create output data
115 auto out = this->_CreateVTK< vtkPolyData >( );
116 out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
117 out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
118 out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
119 out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
120 out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
121 this->GetOutput( "Output" )->SetVTK( out );
124 // -------------------------------------------------------------------------
125 cpPluginsWidgets::SeedWidget::
128 for( auto i = this->m_Data.begin( ); i != this->m_Data.end( ); ++i )
130 this->m_Data.clear( );
133 // -------------------------------------------------------------------------
134 void cpPluginsWidgets::SeedWidget::
137 auto image = this->GetInputData< vtkImageData >( "Input" );
139 this->_GD0_Image( image );
141 this->_Error( "Invalid input image." );
143 // TODO: std::string init_value = this->m_Parameters.GetString( "Text" );
146 static vtkPolyData* prev_pdata = NULL;
147 auto pdata = this->_CreateVTK< vtkPolyData >( );
148 if( prev_pdata != pdata )
150 pdata->SetPoints( vtkPoints::New( ) );
151 pdata->SetVerts( vtkCellArray::New( ) );
152 pdata->SetLines( vtkCellArray::New( ) );
153 pdata->SetPolys( vtkCellArray::New( ) );
154 pdata->SetStrips( vtkCellArray::New( ) );
158 auto points = pdata->GetPoints( );
159 auto verts = pdata->GetVerts( );
161 if( this->m_Configured )
163 if( points->GetNumberOfPoints( ) == 0 )
165 std::stringstream text;
167 for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
169 for( auto r = ( *w )->Widgets.begin( ); r != ( *w )->Widgets.end( ); ++r )
172 dynamic_cast< vtkSeedRepresentation* >(
173 ( *r )->GetRepresentation( )
178 for( unsigned int i = 0; i < rep->GetNumberOfSeeds( ); ++i )
180 rep->GetSeedWorldPosition( i, pos );
184 text << pos[ 0 ] << " " << pos[ 1 ] << " " << pos[ 2 ];
185 points->InsertNextPoint( pos );
190 ( *r )->EnabledOff( );
195 this->m_Parameters.SetString( "Text", text.str( ) );
201 auto init_seeds = this->m_Parameters.GetString( "Text" );
202 std::vector< std::string > tokens;
203 cpExtensions::Tokenize( tokens, init_seeds, "#" );
204 for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
206 std::vector< std::string > coords;
207 cpExtensions::Tokenize( coords, *tIt, " \t" );
208 int dim = ( coords.size( ) < 3 )? coords.size( ): 3;
210 for( unsigned int d = 0; d < 3; ++d )
212 pos[ d ] = double( 0 );
215 std::istringstream value( coords[ d ] );
221 verts->InsertNextCell( 1 );
222 verts->InsertCellPoint( points->GetNumberOfPoints( ) );
223 points->InsertNextPoint( pos );
228 this->m_Configured = true;
231 this->GetOutput( "Output" )->SetVTK( pdata );
235 // -------------------------------------------------------------------------
236 void cpPluginsWidgets::SeedWidget::
240 typedef cpPlugins::DataObjects::Image _TImage;
242 auto image = this->GetInput< _TImage >( "Input" );
246 auto vtk_image = image->GetVTK< vtkImageData >( );
247 auto iIt = this->m_Interactors.begin( );
248 for( ; iIt != this->m_Interactors.end( ); ++iIt )
250 auto ren = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( );
253 auto props = ren->GetViewProps( );
256 props->InitTraversal( );
257 while( vtkProp* prop = props->GetNextProp( ) )
259 auto actor = dynamic_cast< TImageActor* >( prop );
261 if( actor->GetImage( ) == vtk_image )
262 this->m_Props[ actor ] = *iIt;
273 if( this->m_Props.size( ) > 0 )
275 cpPlugins_Demangle_ImageVisualDims( image->GetITK( ), _GD0_Image );
276 else this->_Error( "Invalid input image." );
279 this->_Error( "Could not create a valid widget: no actors." );
282 this->_Error( "Could not create a valid widget: no input." );
286 // -------------------------------------------------------------------------
287 void cpPluginsWidgets::SeedWidget::
288 _GD0_Image( vtkImageData* image )
290 if( this->m_Data.size( ) == 0 )
292 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
293 cb->Seeds = this->GetOutputData< vtkPolyData >( "Output" );
294 this->m_Command = cb;
297 auto inIt = this->m_Interactors.begin( );
298 inIt != this->m_Interactors.end( );
302 auto rends = ( *inIt )->GetRenderWindow( )->GetRenderers( );
303 std::set< TImageActor* > all_props;
306 rends->InitTraversal( );
307 while( vtkRenderer* ren = rends->GetNextItem( ) )
309 auto props = ren->GetViewProps( );
310 props->InitTraversal( );
311 while( vtkProp* p = props->GetNextProp( ) )
313 auto image_actor = dynamic_cast< TImageActor* >( p );
314 if( image_actor != NULL )
316 if( image_actor->GetImage( ) == image )
317 all_props.insert( image_actor );
325 if( all_props.size( ) == 1 )
327 this->m_Data[ *inIt ] =
328 new TWidgetData( this, *( all_props.begin( ) ), *inIt, this->m_Command );
340 // -------------------------------------------------------------------------
341 cpPluginsWidgets::SeedWidget::TWidgetData::
343 SeedWidget* seedWidget,
345 vtkRenderWindowInteractor* iren,
349 auto cb = dynamic_cast< SeedWidgetCallback* >( cmd );
351 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
352 cb->Widget = seedWidget;
355 actor->AddObserver( vtkCommand::InteractionEvent, cb );
358 auto image = actor->GetImage( );
359 int ori = actor->GetOrientation( );
361 image->GetExtent( ext );
362 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
365 this->Placer = vtkSmartPointer< _TPlacer >::New( );
366 this->Handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
367 this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( );
368 this->Widget = vtkSmartPointer< _TWidget >::New( );
370 this->Placer->SetImageSlice( actor );
371 this->Handle->GetProperty( )->SetColor( 1, 0, 0 );
372 this->Handle->SetPointPlacer( this->Placer );
373 this->Representation->SetHandleRepresentation( this->Handle );
374 this->Widget->SetRepresentation( this->Representation );
375 this->Widget->SetInteractor( iren );
378 this->Widget->AddObserver( vtkCommand::PlacePointEvent, cb );
379 this->Widget->AddObserver( vtkCommand::CursorChangedEvent, cb );
381 this->Widget->EnabledOn( );
384 this->Widgets.push_back( wdg );
385 this->Placers.push_back( placer );
386 this->Handles.push_back( handle );
387 this->Representations.push_back( rep );
392 this->ActualWidgetId = actor->GetSliceNumber( );
393 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
397 auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
398 cb->Widget = seedWidget;
401 actor->AddObserver( vtkCommand::InteractionEvent, cb );
403 auto image = actor->GetImage( );
404 int ori = actor->GetOrientation( );
406 image->GetExtent( ext );
407 for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
409 auto placer = vtkSmartPointer< _TPlacer >::New( );
410 auto handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
411 auto rep = vtkSmartPointer< vtkSeedRepresentation >::New( );
412 auto wdg = vtkSmartPointer< _TWidget >::New( );
414 placer->SetImageSlice( actor );
415 handle->GetProperty( )->SetColor( 1, 0, 0 );
416 handle->SetPointPlacer( placer );
417 rep->SetHandleRepresentation( handle );
418 wdg->SetRepresentation( rep );
419 wdg->SetInteractor( iren );
420 wdg->AddObserver( vtkCommand::PlacePointEvent, cb );
421 wdg->AddObserver( vtkCommand::CursorChangedEvent, cb );
424 this->Widgets.push_back( wdg );
425 this->Placers.push_back( placer );
426 this->Handles.push_back( handle );
427 this->Representations.push_back( rep );
431 this->ActualWidgetId = actor->GetSliceNumber( );
432 this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
436 // -------------------------------------------------------------------------
437 cpPluginsWidgets::SeedWidget::TWidgetData::