]> Creatis software - cpPlugins.git/blob - plugins/VTKWidgets/SeedWidget.cxx
d0db73eaa6f8b14837cb91494fe4a22271cf6ca6
[cpPlugins.git] / plugins / VTKWidgets / SeedWidget.cxx
1 #include <VTKWidgets/SeedWidget.h>
2
3 #include <cpPlugins/OS/String.h>
4 #include <cpInstances/DataObjects/Image.h>
5 #include <cpInstances/DataObjects/Mesh.h>
6
7 #include <cpExtensions/Interaction/SeedWidget.h>
8 #include <cpExtensions/Interaction/ImageSlicePointPlacer.h>
9 #include <cpExtensions/Visualization/WindowLevelImageActor.h>
10
11 #include <vtkHandleWidget.h>
12 #include <vtkImageData.h>
13 #include <vtkPlane.h>
14 #include <vtkPointHandleRepresentation3D.h>
15 #include <vtkProperty.h>
16 #include <vtkRendererCollection.h>
17 #include <vtkRenderWindow.h>
18 #include <vtkSeedRepresentation.h>
19
20 // -------------------------------------------------------------------------
21 void cpPluginsVTKWidgets::SeedWidget::
22 Clear( )
23 {
24 }
25
26 // -------------------------------------------------------------------------
27 void cpPluginsVTKWidgets::SeedWidget::
28 SetEnabled( bool v )
29 {
30   for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
31   {
32     if( v ) w->second->RestartInteraction( );
33     else    w->second->CompleteInteraction( );
34     w->second->SetEnabled( v );
35     w->second->Render( );
36
37   } // rof
38 }
39
40 // -------------------------------------------------------------------------
41 bool cpPluginsVTKWidgets::SeedWidget::
42 GetEnabled( ) const
43 {
44   if( this->m_Widgets.size( ) > 0 )
45   {
46     auto i = this->m_Widgets.begin( );
47     TWidget* w = const_cast< TWidget* >( i->second.GetPointer( ) );
48     return( w->GetEnabled( ) != 0 );
49   }
50   else
51     return( false );
52 }
53
54 // -------------------------------------------------------------------------
55 cpPluginsVTKWidgets::SeedWidget::
56 SeedWidget( )
57   : Superclass( )
58 {
59   typedef cpPlugins::Pipeline::DataObject _TData;
60   typedef cpInstances::DataObjects::Mesh       _TMesh;
61
62   // Create ports
63   this->_ConfigureInput< _TData >( "Input", false, false );
64   this->_ConfigureOutput< _TMesh >( "Output" );
65
66   // Create output data
67   auto out = this->_CreateVTK< vtkPolyData >( );
68   out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
69   out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
70   out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
71   out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
72   out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
73   this->GetOutput( "Output" )->SetVTK( out );
74 }
75
76 // -------------------------------------------------------------------------
77 cpPluginsVTKWidgets::SeedWidget::
78 ~SeedWidget( )
79 {
80   /* TODO
81      for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
82      w->second->EnabledOff( );
83      this->m_Widgets.clear( );
84   */
85 }
86
87 // -------------------------------------------------------------------------
88 void cpPluginsVTKWidgets::SeedWidget::
89 _GenerateData( )
90 {
91   auto image = this->GetInputData< vtkImageData >( "Input" );
92   if( image != NULL )
93     this->_GD0_Image( image );
94   else
95     this->_Error( "Invalid input image." );
96 }
97
98 // -------------------------------------------------------------------------
99 void cpPluginsVTKWidgets::SeedWidget::
100 _GD0_Image( vtkImageData* image )
101 {
102   auto seeds = this->GetOutputData< vtkPolyData >( "Output" );
103   if( this->m_Widgets.size( ) == 0 )
104   {
105     this->m_Command = vtkSmartPointer< TCallback >::New( );
106     this->m_Command->SetSeeds( seeds );
107     for(
108       auto inIt = this->m_Interactors.begin( );
109       inIt != this->m_Interactors.end( );
110       ++inIt
111       )
112     {
113       auto rends = ( *inIt )->GetRenderWindow( )->GetRenderers( );
114       std::set< TImageActor* > all_props;
115       if( rends != NULL )
116       {
117         rends->InitTraversal( );
118         while( vtkRenderer* ren = rends->GetNextItem( ) )
119         {
120           auto props = ren->GetViewProps( );
121           props->InitTraversal( );
122           while( vtkProp* p = props->GetNextProp( ) )
123           {
124             auto image_actor = dynamic_cast< TImageActor* >( p );
125             if( image_actor != NULL )
126             {
127               if( image_actor->GetImage( ) == image )
128                 all_props.insert( image_actor );
129
130             } // fi
131
132           } // elihw
133
134         } // elihw
135
136       } // fi
137       if( all_props.size( ) == 1 )
138       {
139         if( this->m_Widgets.find( *inIt ) == this->m_Widgets.end( ) )
140         {
141           auto act = *( all_props.begin( ) );
142           auto pla = vtkSmartPointer< TPlacer >::New( );
143           auto hnd = vtkSmartPointer< THandleRep >::New( );
144           auto rep = vtkSmartPointer< TSeedRep >::New( );
145           auto wdg = vtkSmartPointer< TWidget >::New( );
146
147           pla->SetImageSlice( act );
148           hnd->GetProperty( )->SetColor( 1, 0, 0 );
149           hnd->SetPointPlacer( pla );
150           rep->SetHandleRepresentation( hnd );
151           wdg->SetRepresentation( rep );
152           wdg->SetInteractor( *inIt );
153           act->AddObserver( vtkCommand::InteractionEvent, this->m_Command );
154           wdg->AddObserver( vtkCommand::PlacePointEvent, this->m_Command );
155           wdg->AddObserver( vtkCommand::CursorChangedEvent, this->m_Command );
156           this->m_Widgets[ *inIt ] = wdg;
157
158         } // fi
159
160       } // fi
161
162     } // rof
163
164     // Associate input text
165     std::string text = this->m_Parameters.GetString( "Text" );
166     std::vector< std::string > tok1, tok2;
167     tok1 = cpPlugins::OS::String::Tokenize( text, "#" );
168     if( tok1.size( ) > seeds->GetPoints( )->GetNumberOfPoints( ) )
169     {
170       for( auto t1 = tok1.begin( ); t1 != tok1.end( ); ++t1 )
171       {
172         if( *t1 != "" )
173         {
174           tok2 = cpPlugins::OS::String::Tokenize( *t1, " " );
175           double x[ 3 ];
176           for( unsigned int d = 0; d < 3; ++d )
177           {
178             if( d < tok2.size( ) )
179             {
180               std::istringstream str( tok2[ d ] );
181               str >> x[ d ];
182             }
183             else
184               x[ d ] = double( 0 );
185
186           } // rof
187
188           seeds->GetPoints( )->InsertNextPoint( x );
189           seeds->GetVerts( )->InsertNextCell( 1 );
190           seeds->GetVerts( )->InsertCellPoint(
191             seeds->GetPoints( )->GetNumberOfPoints( ) - 1
192             );
193           seeds->Modified( );
194
195         } // fi
196
197       } // rof
198
199     } // fi
200   }
201   else
202   {
203     double x[ 3 ];
204     std::stringstream text;
205     for( long i = 0; i < seeds->GetNumberOfPoints( ); ++i )
206     {
207       seeds->GetPoint( i, x );
208       text << x[ 0 ] << " " << x[ 1 ] << " " << x[ 2 ] << "#";
209
210     } // rof
211     this->m_Parameters.SetString( "Text", text.str( ) );
212
213   } // fi
214 }
215
216 // -------------------------------------------------------------------------
217 cpPluginsVTKWidgets::SeedWidget::TCallback*
218 cpPluginsVTKWidgets::SeedWidget::TCallback::
219 New( )
220 {
221   return( new TCallback );
222 }
223
224 // -------------------------------------------------------------------------
225 void cpPluginsVTKWidgets::SeedWidget::TCallback::
226 Execute( vtkObject* caller, unsigned long id, void* data )
227 {
228   static const double EPS = 1e-5;
229   auto src_act = dynamic_cast< TImageActor* >( caller );
230   auto src_wdg = dynamic_cast< TWidget* >( caller );
231
232   if( id == vtkCommand::InteractionEvent && src_act != NULL )
233   {
234     TWidget* widget = NULL;
235     TSeedRep* seed_rep = NULL;
236
237     auto w = this->m_Widgets.begin( );
238     while( w != this->m_Widgets.end( ) && widget == NULL )
239     {
240       auto rep =
241         dynamic_cast< vtkSeedRepresentation* >(
242           ( *w )->GetRepresentation( )
243           );
244       if( rep != NULL )
245       {
246         auto hnd = rep->GetHandleRepresentation( );
247         if( hnd != NULL )
248         {
249           auto pla =
250             dynamic_cast< SeedWidget::TPlacer* >(
251               hnd->GetPointPlacer( )
252               );
253           if( pla != NULL )
254           {
255             auto act = pla->GetImageSlice( );
256             if( act == src_act )
257             {
258               widget = *w;
259               seed_rep = rep;
260
261             } // fi
262
263           } // fi
264
265         } // fi
266
267       } // fi
268       w++;
269
270     } // elihw
271
272     if( widget != NULL )
273     {
274       // Cut through given seeds
275       auto plane = src_act->GetSlicePlane( );
276       double x[ 3 ];
277       std::vector< long > ids;
278       for( long i = 0; i < this->m_Seeds->GetNumberOfPoints( ); ++i )
279       {
280         this->m_Seeds->GetPoint( i, x );
281         double d = plane->DistanceToPlane( x );
282         if( d <= EPS )
283           ids.push_back( i );
284
285       } // rof
286
287       // Erase seeds
288       widget->CompleteInteraction( );
289       widget->EnabledOff( );
290       int nSeeds = seed_rep->GetNumberOfSeeds ();
291       for( int i = 0; i < nSeeds; ++i )
292       {
293         seed_rep->RemoveLastHandle( );
294         widget->DeleteSeed( seed_rep->GetNumberOfSeeds( ) );
295
296       } // rof
297
298       if( ids.size( ) > 0 )
299       {
300         auto ren = widget->GetInteractor( )->FindPokedRenderer(
301           widget->GetInteractor( )->GetEventPosition( )[ 0 ],
302           widget->GetInteractor( )->GetEventPosition( )[ 1 ]
303           );
304
305         // Add seeds
306         seed_rep->BuildRepresentation( );
307         for( auto id = ids.begin( ); id != ids.end( ); ++id )
308         {
309           this->m_Seeds->GetPoint( *id, x );
310           widget->ComputeWorldToDisplay(
311             ren, x[ 0 ], x[ 1 ], x[ 2 ], x
312             );
313           x[ 2 ] = double( 0 );
314           int s = seed_rep->CreateHandle( x );
315           vtkHandleWidget* curr_hnd = widget->CreateNewHandle( );
316           seed_rep->SetSeedDisplayPosition( s, x );
317           curr_hnd->SetEnabled( 1 );
318
319         } // rof
320
321       } // fi
322
323       // Reactivate widget
324       widget->RestartInteraction( );
325       widget->EnabledOn( );
326       widget->Render( );
327
328     } // fi
329   }
330   else if( id == vtkCommand::PlacePointEvent && src_wdg != NULL )
331   {
332     this->m_Widgets.insert( src_wdg );
333     auto rep =
334       dynamic_cast< vtkSeedRepresentation* >(
335         src_wdg->GetRepresentation( )
336         );
337     if( rep != NULL )
338     {
339       unsigned long nSeeds = rep->GetNumberOfSeeds( );
340       if( nSeeds > 0 )
341       {
342         double pos[ 3 ];
343         rep->GetSeedWorldPosition( nSeeds - 1, pos );
344
345         this->m_Seeds->GetPoints( )->InsertNextPoint( pos );
346         this->m_Seeds->GetVerts( )->InsertNextCell( 1 );
347         this->m_Seeds->GetVerts( )->InsertCellPoint(
348           this->m_Seeds->GetPoints( )->GetNumberOfPoints( ) - 1
349           );
350         this->m_Seeds->Modified( );
351
352       } // fi
353
354     } // fi
355
356   } // fi
357 }
358
359 // -------------------------------------------------------------------------
360 void cpPluginsVTKWidgets::SeedWidget::TCallback::
361 SetSeeds( vtkPolyData* seeds )
362 {
363   this->m_Seeds = seeds;
364 }
365
366 // -------------------------------------------------------------------------
367 cpPluginsVTKWidgets::SeedWidget::TCallback::
368 TCallback( )
369   : vtkCommand( ),
370     m_Seeds( NULL )
371 {
372 }
373
374 // -------------------------------------------------------------------------
375 cpPluginsVTKWidgets::SeedWidget::TCallback::
376 ~TCallback( )
377 {
378 }
379
380 // eof - $RCSfile$