]> Creatis software - cpPlugins.git/blob - plugins/Widgets/SplineWidget.cxx
258c0bd677a43e923f501aeb51001f9565e3b112
[cpPlugins.git] / plugins / Widgets / SplineWidget.cxx
1 #include <Widgets/SplineWidget.h>
2 #include <cpPlugins/DataObjects/Image.h>
3 #include <cpPlugins/DataObjects/Mesh.h>
4 #include <cpExtensions/Visualization/WindowLevelImageActor.h>
5
6 #include <itkVector.h>
7
8 #include <vtkImageData.h>
9 #include <vtkPolyData.h>
10 #include <vtkRenderer.h>
11 #include <vtkSplineWidget.h>
12 #include <vtkParametricSpline.h>
13
14 // -------------------------------------------------------------------------
15 void cpPluginsWidgets::SplineWidget::
16 Clear( )
17 {
18 }
19
20 // -------------------------------------------------------------------------
21 void cpPluginsWidgets::SplineWidget::
22 SetEnabled( bool v )
23 {
24   auto wdg = this->GetVTK< vtkSplineWidget >( );
25   if( wdg != NULL )
26   {
27     wdg->SetEnabled( v );
28     wdg->GetInteractor( )->Render( );
29
30   } // fi
31 }
32
33 // -------------------------------------------------------------------------
34 bool cpPluginsWidgets::SplineWidget::
35 GetEnabled( ) const
36 {
37   auto wdg = this->GetVTK< const vtkSplineWidget >( );
38   if( wdg != NULL )
39   {
40     vtkSplineWidget* w = const_cast< vtkSplineWidget* >( wdg );
41     return( w->GetEnabled( ) != 0 );
42   }
43   else
44     return( false );
45 }
46
47 // -------------------------------------------------------------------------
48 cpPluginsWidgets::SplineWidget::
49 SplineWidget( )
50   : Superclass( ),
51     m_Configured( false )
52 {
53   typedef cpPlugins::BaseObjects::DataObject _TData;
54   typedef cpPlugins::DataObjects::Mesh       _TMesh;
55
56   this->_ConfigureInput< _TData >( "Input", false, false );
57   this->_ConfigureOutput< _TMesh >( "Output" );
58   this->m_Contour = vtkSmartPointer< vtkPolyData >::New( );
59   this->m_Contour->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
60   this->m_Contour->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
61   this->m_Contour->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
62   this->m_Contour->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
63   this->m_Contour->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
64   this->GetOutput( "Output" )->SetVTK( this->m_Contour );
65
66   this->m_Parameters.ConfigureAsBool( "Extend" );
67   this->m_Parameters.SetBool( "Extend", false );
68 }
69
70 // -------------------------------------------------------------------------
71 cpPluginsWidgets::SplineWidget::
72 ~SplineWidget( )
73 {
74 }
75
76 // -------------------------------------------------------------------------
77 void cpPluginsWidgets::SplineWidget::
78 _GenerateData( )
79 {
80   typedef cpExtensions::Visualization::WindowLevelImageActor _TActor;
81
82   auto image = this->GetInputData< vtkImageData >( "Input" );
83   if( image == NULL )
84     this->_Error( "Invalid input image." );
85   if( this->m_Interactors.size( ) == 0 )
86     this->_Error( "Give at least one interactor." );
87
88   auto wdg = this->_CreateVTK< vtkSplineWidget >( );
89   if( this->m_Configured )
90   {
91     if( this->m_Parameters.GetBool( "Extend" ) )
92     {
93       wdg->GetPolyData( this->m_Contour.GetPointer( ) );
94
95       typedef itk::Vector< double, 3 > _TVector;
96       typedef std::vector< _TVector > _TVectors;
97
98       unsigned long nPoints = this->m_Contour->GetNumberOfPoints( );
99       unsigned long support = nPoints / 10;
100       _TVectors pp, qp;
101       for( unsigned long i = 0; i < support; ++i )
102       {
103         double p[ 3 ], q[ 3 ];
104         this->m_Contour->GetPoint( i, p );
105         this->m_Contour->GetPoint( nPoints - 1 - i, q );
106
107         _TVector pv, qv;
108         pv[ 0 ] = p[ 0 ];
109         pv[ 1 ] = p[ 1 ];
110         pv[ 2 ] = p[ 2 ];
111         qv[ 0 ] = q[ 0 ];
112         qv[ 1 ] = q[ 1 ];
113         qv[ 2 ] = q[ 2 ];
114         pp.push_back( pv );
115         qp.push_back( qv );
116
117       } // rof
118
119       _TVectors pt, qt;
120       pt.push_back( pp[ 1 ] - pp[ 0 ] );
121       qt.push_back( qp[ 1 ] - qp[ 0 ] );
122       for( unsigned long i = 1; i < support - 1; ++i )
123       {
124         pt.push_back( pp[ i + 1 ] - pp[ i - 1 ] );
125         qt.push_back( qp[ i + 1 ] - qp[ i - 1 ] );
126
127       } // rof
128       pt.push_back( pp[ support - 1 ] - pp[ support - 2 ] );
129       qt.push_back( qp[ support - 1 ] - qp[ support - 2 ] );
130
131       _TVector t0( double( 0 ) ), t1( double( 0 ) );
132       long real0 = 0, real1 = 0;
133       for( unsigned long i = 0; i < support; ++i )
134       {
135         double n0 = pt[ i ].GetNorm( );
136         if( n0 > double( 0 ) )
137         {
138           t0 += pt[ i ] / n0;
139           real0++;
140
141         } // fi
142
143         double n1 = qt[ i ].GetNorm( );
144         if( n1 > double( 0 ) )
145         {
146           t1 += qt[ i ] / n1;
147           real1++;
148
149         } // fi
150
151       } // rof
152
153       if( real0 > 0 )
154         t0 /= double( -real0 );
155       if( real1 > 0 )
156         t1 /= double( -real1 );
157
158       t0 *= ( pp[ 0 ] - qp[ 0 ] ).GetNorm( );
159       t1 *= ( pp[ 0 ] - qp[ 0 ] ).GetNorm( );
160
161       _TVector p0 = pp[ 0 ] + t0;
162       _TVector p1 = qp[ 0 ] + t1;
163
164       vtkSmartPointer< vtkPolyData > cnt = this->m_Contour;
165       this->m_Contour = vtkSmartPointer< vtkPolyData >::New( );
166       this->m_Contour->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
167       this->m_Contour->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
168       this->m_Contour->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
169       this->m_Contour->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
170       this->m_Contour->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
171       this->GetOutput( "Output" )->SetVTK( this->m_Contour );
172
173       this->m_Contour->GetPoints( )->
174         InsertNextPoint( p0[ 0 ], p0[ 1 ], p0[ 2 ] );
175       for( unsigned long i = 0; i < nPoints; ++i )
176       {
177         double p[ 3 ];
178         cnt->GetPoints( )->GetPoint( i, p );
179         this->m_Contour->GetPoints( )->InsertNextPoint( p );
180
181       } // rof
182       this->m_Contour->GetPoints( )->
183         InsertNextPoint( p1[ 0 ], p1[ 1 ], p1[ 2 ] );
184       this->m_Contour->Modified( );
185     }
186     else
187       wdg->GetPolyData( this->m_Contour.GetPointer( ) );
188   }
189   else
190   {
191     auto iIt = this->m_Interactors.begin( );
192     vtkRenderWindowInteractor* iren = NULL;
193     vtkRenderer* ren = NULL;
194     _TActor* actor = NULL;
195     for( ; iIt != this->m_Interactors.end( ); ++iIt )
196     {
197       auto r = ( *iIt )->GetInteractorStyle( )->GetCurrentRenderer( );
198       if( r != NULL )
199       {
200         auto props = r->GetViewProps( );
201         if( props != NULL )
202         {
203           props->InitTraversal( );
204           while( vtkProp* prop = props->GetNextProp( ) )
205           {
206             auto a = dynamic_cast< _TActor* >( prop );
207             if( a != NULL )
208               if( a->GetImage( ) == image )
209               {
210                 iren = *iIt;
211                 actor = a;
212                 ren = r;
213
214               } // fi
215
216           } // elihw
217
218         } // fi
219
220       } // fi
221
222     } // rof
223     if( actor == NULL || ren == NULL || iren == NULL )
224       this->_Error( "Invalid actor and/or renderer." );
225
226     // Widget configuration
227     wdg->SetCurrentRenderer( ren );
228     wdg->SetDefaultRenderer( ren );
229     wdg->SetInputData( image );
230     wdg->SetProp3D( actor );
231     wdg->SetInteractor( iren );
232     double bnds[ 6 ];
233     image->GetBounds( bnds );
234     wdg->PlaceWidget(
235       bnds[ 0 ], bnds[ 1 ],
236       bnds[ 2 ], bnds[ 3 ],
237       bnds[ 4 ], bnds[ 5 ]
238       );
239     wdg->ProjectToPlaneOn( );
240     wdg->SetProjectionNormalToZAxes( );
241     wdg->SetProjectionPosition(
242       (
243         actor->GetBounds( )[ 4 ] +
244         actor->GetBounds( )[ 5 ]
245         ) / double( 2 )
246       );
247     wdg->SetHandleSize( 0.005 );
248     wdg->SetNumberOfHandles( 3 );
249     this->m_Configured = true;
250
251   } // fi
252 }
253
254 // eof - $RCSfile$