]> Creatis software - cpPlugins.git/blob - plugins/Widgets/SeedWidget.cxx
Architecture updated.
[cpPlugins.git] / plugins / Widgets / SeedWidget.cxx
1 #include <plugins/Widgets/SeedWidget.h>
2 #include <cpPlugins/DataObjects/Image.h>
3 #include <cpPlugins/DataObjects/Mesh.h>
4
5 #include <vtkCommand.h>
6 #include <vtkImageActor.h>
7 #include <vtkProperty.h>
8 #include <vtkRenderer.h>
9 #include <vtkRenderWindowInteractor.h>
10 #include <cpExtensions/QT/SimpleMPRWidget.h>
11
12 // -------------------------------------------------------------------------
13 // This callback is responsible for changing update time
14 namespace cpPluginsWidgets
15 {
16   /**
17    */
18   class SeedWidgetCallback
19     : public vtkCommand
20   {
21   public:
22     static SeedWidgetCallback* New( )
23       { return( new SeedWidgetCallback ); }
24     virtual void Execute( vtkObject* caller, unsigned long id, void* data )
25       {
26         typedef cpPluginsWidgets::SeedWidget::TImageActor _TImageActor;
27         auto actor = dynamic_cast< _TImageActor* >( caller );
28
29         if( id == vtkCommand::InteractionEvent && actor != NULL )
30         {
31           int slice = actor->GetSliceNumber( );
32           if( this->Data->ActualWidgetId != slice )
33           {
34             this->Data->Widgets[ this->Data->ActualWidgetId ]->EnabledOff( );
35             this->Data->Widgets[ slice ]->EnabledOn( );
36             this->Data->ActualWidgetId = slice;
37
38           } // fi
39         }
40         else if(
41           (
42             id == vtkCommand::CursorChangedEvent ||
43             id == vtkCommand::PlacePointEvent
44             ) &&
45           this->Widget != NULL
46           )
47            this->Widget->Modified( );
48       }
49
50   protected:
51     SeedWidgetCallback( )
52       : vtkCommand( ),
53         Widget( NULL ),
54         Data( NULL )
55       { }
56     virtual ~SeedWidgetCallback( ) { }
57
58   public:
59     SeedWidget* Widget;
60     SeedWidget::TWidgetData* Data;
61   };
62
63 } // ecapseman
64
65 // -------------------------------------------------------------------------
66 cpPluginsWidgets::SeedWidget::
67 SeedWidget( )
68   : Superclass( ),
69     m_Configured( false )
70 {
71   typedef cpPlugins::BaseObjects::DataObject _TData;
72   typedef cpPlugins::DataObjects::Mesh _TMesh;
73
74   this->_ConfigureInput< _TData >( "Input", false, false );
75   this->_ConfigureOutput< _TMesh >( "Output" );
76 }
77
78 // -------------------------------------------------------------------------
79 cpPluginsWidgets::SeedWidget::
80 ~SeedWidget( )
81 {
82   for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
83     delete *w;
84   this->m_Widgets.clear( );
85 }
86
87 // -------------------------------------------------------------------------
88 void cpPluginsWidgets::SeedWidget::
89 _GenerateData( )
90 {
91   static vtkPolyData* prev_pdata = NULL;
92   auto pdata = this->_CreateVTK< vtkPolyData >( );
93   if( prev_pdata != pdata )
94   {
95     pdata->SetPoints( vtkPoints::New( ) );
96     pdata->SetVerts( vtkCellArray::New( ) );
97     pdata->SetLines( vtkCellArray::New( ) );
98     pdata->SetPolys( vtkCellArray::New( ) );
99     pdata->SetStrips( vtkCellArray::New( ) );
100     prev_pdata = pdata;
101
102   } // fi
103   auto points = pdata->GetPoints( );
104   auto verts = pdata->GetVerts( );
105
106   if( this->m_Configured )
107   {
108     if( points->GetNumberOfPoints( ) == 0 )
109     {
110       std::stringstream text;
111       bool start = true;
112       for( auto w = this->m_Widgets.begin( ); w != this->m_Widgets.end( ); ++w )
113       {
114         for( auto r = ( *w )->Widgets.begin( ); r != ( *w )->Widgets.end( ); ++r )
115         {
116           auto rep =
117             dynamic_cast< vtkSeedRepresentation* >(
118               ( *r )->GetRepresentation( )
119               );
120           if( rep != NULL )
121           {
122             double pos[ 3 ];
123             for( unsigned int i = 0; i < rep->GetNumberOfSeeds( ); ++i )
124             {
125               rep->GetSeedWorldPosition( i, pos );
126               if( !start )
127                 text << "#";
128               start = false;
129               text << pos[ 0 ] << " " << pos[ 1 ] << " " << pos[ 2 ];
130               points->InsertNextPoint( pos );
131
132             } // rof
133
134           } // rof
135           ( *r )->EnabledOff( );
136
137         } // rof
138
139       } // rof
140       this->m_Parameters.SetString( "Text", text.str( ) );
141
142     } // fi
143   }
144   else
145   {
146     auto init_seeds = this->m_Parameters.GetString( "Text" );
147     std::vector< std::string > tokens;
148     cpExtensions::Tokenize( tokens, init_seeds, "#" );
149     for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
150     {
151       std::vector< std::string > coords;
152       cpExtensions::Tokenize( coords, *tIt, " \t" );
153       int dim = ( coords.size( ) < 3 )? coords.size( ): 3;
154       double pos[ 3 ];
155       for( unsigned int d = 0; d < 3; ++d )
156       {
157         pos[ d ] = double( 0 );
158         if( d < dim )
159         {
160           std::istringstream value( coords[ d ] );
161           value >> pos[ d ];
162
163         } // fi
164
165       } // rof
166       verts->InsertNextCell( 1 );
167       verts->InsertCellPoint( points->GetNumberOfPoints( ) );
168       points->InsertNextPoint( pos );
169
170     } // rof
171     this->_Configure( );
172     this->Modified( );
173     this->m_Configured = true;
174
175   } // fi
176   this->GetOutput( "Output" )->SetVTK( pdata );
177 }
178
179 // -------------------------------------------------------------------------
180 void cpPluginsWidgets::SeedWidget::
181 _Configure( )
182 {
183   typedef cpPlugins::DataObjects::Image _TImage;
184
185   auto image = this->GetInput< _TImage >( "Input" );
186   if( image != NULL )
187   {
188     // Update actors
189     auto vtk_image = image->GetVTK< vtkImageData >( );
190     auto iIt = this->m_Interactors.begin( );
191     for( ; iIt != this->m_Interactors.end( ); ++iIt )
192     {
193       auto ren = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( );
194       if( ren != NULL )
195       {
196         auto props = ren->GetViewProps( );
197         if( props != NULL )
198         {
199           props->InitTraversal( );
200           while( vtkProp* prop = props->GetNextProp( ) )
201           {
202             auto actor = dynamic_cast< TImageActor* >( prop );
203             if( actor != NULL )
204               if( actor->GetImage( ) == vtk_image )
205                 this->m_Props[ actor ] = *iIt;
206
207           } // elihw
208
209         } // fi
210
211       } // fi
212
213     } // rof
214
215     // Process image
216     if( this->m_Props.size( ) > 0 )
217     {
218       cpPlugins_Demangle_ImageVisualDims( image->GetITK( ), _GD0_Image );
219       else this->_Error( "Invalid input image." );
220     }
221     else
222       this->_Error( "Could not create a valid widget: no actors." );
223   }
224   else
225     this->_Error( "Could not create a valid widget: no input." );
226 }
227
228 // -------------------------------------------------------------------------
229 template< class _TImage >
230 void cpPluginsWidgets::SeedWidget::
231 _GD0_Image( _TImage* image )
232 {
233   for( auto p = this->m_Props.begin( ); p != this->m_Props.end( ); ++p )
234   {
235     TWidgetData* d =
236       new TWidgetData(
237         this, dynamic_cast< TImageActor* >( p->first ), p->second
238         );
239     this->m_Widgets.push_back( d );
240
241   } // rof
242 }
243
244 // -------------------------------------------------------------------------
245 cpPluginsWidgets::SeedWidget::TWidgetData::
246 TWidgetData(
247   SeedWidget* seedWidget,
248   TImageActor* actor,
249   vtkRenderWindowInteractor* iren
250   )
251 {
252   auto cb = vtkSmartPointer< SeedWidgetCallback >::New( );
253   cb->Widget = seedWidget;
254   cb->Data = this;
255   this->Command = cb;
256   actor->AddObserver( vtkCommand::InteractionEvent, cb );
257
258   auto image = actor->GetImage( );
259   int ori = actor->GetOrientation( );
260   int ext[ 6 ];
261   image->GetExtent( ext );
262   for( int i = ext[ ori << 1 ]; i <= ext[ ( ori << 1 ) + 1 ]; ++i )
263   {
264     auto placer = vtkSmartPointer< _TPlacer >::New( );
265     auto handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
266     auto rep = vtkSmartPointer< vtkSeedRepresentation >::New( );
267     auto wdg = vtkSmartPointer< _TWidget >::New( );
268
269     placer->SetImageSlice( actor );
270     handle->GetProperty( )->SetColor( 1, 0, 0 );
271     handle->SetPointPlacer( placer );
272     rep->SetHandleRepresentation( handle );
273     wdg->SetRepresentation( rep );
274     wdg->SetInteractor( iren );
275     wdg->AddObserver( vtkCommand::PlacePointEvent, cb );
276     wdg->AddObserver( vtkCommand::CursorChangedEvent, cb );
277     wdg->EnabledOff( );
278
279     this->Widgets.push_back( wdg );
280     this->Placers.push_back( placer );
281     this->Handles.push_back( handle );
282     this->Representations.push_back( rep );
283
284   } // rof
285
286   this->ActualWidgetId = actor->GetSliceNumber( );
287   this->Widgets[ this->ActualWidgetId ]->EnabledOn( );
288 }
289
290 // -------------------------------------------------------------------------
291 cpPluginsWidgets::SeedWidget::TWidgetData::
292 ~TWidgetData( )
293 {
294 }
295
296 // eof - $RCSfile$