]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Plugins/BasicFilters/MacheteFilter.cxx
Segmentated image write: Ok
[cpPlugins.git] / lib / cpPlugins / Plugins / BasicFilters / MacheteFilter.cxx
1 #include "MacheteFilter.h"
2
3 #include <cpPlugins/Interface/BaseApplication.h>
4 #include <cpPlugins/Interface/Plugins.h>
5
6 #include <cpPlugins/Interface/DataObject.h>
7 #include <cpPlugins/Interface/Image.h>
8 #include <cpPlugins/Interface/Mesh.h>
9
10 #include <cpExtensions/Interaction/ImageInteractorStyle.h>
11 #include <cpExtensions/DataStructures/InfinitePlaneSpatialObject.h>
12 #include <cpExtensions/Algorithms/SpatialObjectMaskImageFilter.h>
13
14 #include <itkPlaneSpatialObject.h>
15 #include <itkPoint.h>
16 #include <itkVector.h>
17
18 #include <vtkInteractorStyleSwitch.h>
19 #include <vtkPlaneWidget.h>
20 #include <vtkRenderWindowInteractor.h>
21
22 #ifdef cpPlugins_Interface_QT4
23 #include <QDialogButtonBox>
24
25 // -------------------------------------------------------------------------
26 cpPlugins::BasicFilters::MacheteFilter_Dialog::
27 MacheteFilter_Dialog(
28   QWidget* parent, MacheteFilter* filter, Qt::WindowFlags f
29   )
30   : QDialog( parent, f | Qt::WindowStaysOnTopHint ),
31     m_Filter( filter )
32 {
33   this->m_Title = new QLabel( this );
34   this->m_Title->setText( "Execute machete filter" );
35
36   this->m_MainLayout = new QGridLayout( this );
37   this->m_ToolsLayout = new QVBoxLayout( );
38   this->m_ToolsLayout->addWidget( this->m_Title );
39   this->m_MainLayout->addLayout( this->m_ToolsLayout, 0, 0, 1, 1 );
40
41   // Add buttons
42   QDialogButtonBox* bb = new QDialogButtonBox(
43     QDialogButtonBox::Cancel | QDialogButtonBox::Ok
44     );
45   QObject::connect( bb, SIGNAL( accepted( ) ), this, SLOT( accept( ) ) );
46   QObject::connect( bb, SIGNAL( rejected( ) ), this, SLOT( reject( ) ) );
47   this->m_ToolsLayout->addWidget( bb );
48 }
49
50 // -------------------------------------------------------------------------
51 cpPlugins::BasicFilters::MacheteFilter_Dialog::
52 ~MacheteFilter_Dialog( )
53 {
54   delete this->m_Title;
55   delete this->m_ToolsLayout;
56   delete this->m_MainLayout;
57 }
58
59 // -------------------------------------------------------------------------
60 void cpPlugins::BasicFilters::MacheteFilter_Dialog::
61 accept( )
62 {
63   // Get interactive widget
64   if( this->m_Filter == NULL )
65     return;
66   vtkPlaneWidget* wdg = this->m_Filter->m_PlaneWidget;
67   if( wdg == NULL )
68     return;
69
70   // Get/Set plane parameters
71   double center[ 3 ], normal[ 3 ];
72   wdg->GetCenter( center );
73   wdg->GetNormal( normal );
74
75   this->m_Filter->GetParameters( )->SetPoint( "PlaneCenter", 3, center );
76   this->m_Filter->GetParameters( )->SetVector( "PlaneNormal", 3, normal );
77
78   // Update filter
79   auto plugins = this->m_Filter->GetPlugins( );
80   if( plugins != NULL )
81   {
82     auto app = plugins->GetApplication( );
83     if( app != NULL )
84       app->UpdateActualFilter( );
85
86   } // fi
87 }
88
89 // -------------------------------------------------------------------------
90 void cpPlugins::BasicFilters::MacheteFilter_Dialog::
91 reject( )
92 {
93   auto plugins = this->m_Filter->GetPlugins( );
94   if( plugins != NULL )
95     plugins->DeactivateFilter( );
96   this->Superclass::reject( );
97 }
98
99 #endif // cpPlugins_Interface_QT4
100
101 // -------------------------------------------------------------------------
102 cpPlugins::BasicFilters::MacheteFilter::
103 DialogResult cpPlugins::BasicFilters::MacheteFilter::
104 ExecConfigurationDialog( QWidget* parent )
105 {
106 #ifdef cpPlugins_Interface_QT4
107
108   typedef cpExtensions::Interaction::ImageInteractorStyle _TImageStyle;
109
110   // Choose a valid 3D interactor
111   vtkRenderWindowInteractor* iren = NULL;
112   auto iIt = this->m_Interactors.begin( );
113   for( ; iIt != this->m_Interactors.end( ) && iren == NULL; ++iIt )
114   {
115     _TImageStyle* istyle =
116       dynamic_cast< _TImageStyle* >(
117         ( *iIt )->GetInteractorStyle( )
118         );
119     if( istyle == NULL )
120       iren = *iIt;
121     
122   } // rof
123   if( iren == NULL )
124     return( Self::DialogResult_Cancel );
125
126   // Get bounding box
127   double bbox[ 6 ];
128   cpPlugins::Interface::Image* image =
129     this->GetInput< cpPlugins::Interface::Image >( "Input" );
130   bool input_found = false;
131   if( image != NULL )
132   {
133     image->GetVTK< vtkImageData >( )->GetBounds( bbox );
134     input_found = true;
135
136   } // fi
137   cpPlugins::Interface::Mesh* mesh =
138     this->GetInput< cpPlugins::Interface::Mesh >( "Input" );
139   if( mesh != NULL )
140   {
141     mesh->GetVTK< vtkPolyData >( )->GetBounds( bbox );
142     input_found = true;
143
144   } // fi
145   if( !input_found )
146     return( Self::DialogResult_Cancel );
147
148   // Create plane widget
149   if( this->m_PlaneWidget != NULL )
150     this->m_PlaneWidget->Delete( );
151   this->m_PlaneWidget = vtkPlaneWidget::New( );
152   this->m_PlaneWidget->NormalToXAxisOn( );
153   this->m_PlaneWidget->SetCenter(
154     ( bbox[ 1 ] + bbox[ 0 ] ) * double( 0.5 ),
155     ( bbox[ 3 ] + bbox[ 2 ] ) * double( 0.5 ),
156     ( bbox[ 5 ] + bbox[ 4 ] ) * double( 0.5 )
157     );
158   this->m_PlaneWidget->SetOrigin(
159     ( bbox[ 1 ] + bbox[ 0 ] ) * double( 0.5 ),
160     bbox[ 2 ],
161     bbox[ 4 ]
162     );
163   this->m_PlaneWidget->SetPoint1(
164     ( bbox[ 1 ] + bbox[ 0 ] ) * double( 0.5 ),
165     bbox[ 3 ],
166     bbox[ 4 ]
167     );
168   this->m_PlaneWidget->SetPoint2(
169     ( bbox[ 1 ] + bbox[ 0 ] ) * double( 0.5 ),
170     bbox[ 2 ],
171     bbox[ 5 ]
172     );
173   this->m_PlaneWidget->SetResolution( 15 );
174   this->m_PlaneWidget->SetRepresentationToWireframe( );
175   this->m_PlaneWidget->SetInteractor( iren );
176   this->m_PlaneWidget->PlaceWidget( );
177   this->m_PlaneWidget->On( );
178
179   this->m_Dialog = new MacheteFilter_Dialog( NULL, this );
180   this->m_Dialog->show( );
181
182   return( Self::DialogResult_Modal );
183 #else // cpPlugins_Interface_QT4
184   return( Self::DialogResult_Cancel );
185 #endif // cpPlugins_Interface_QT4
186 }
187
188 // -------------------------------------------------------------------------
189 cpPlugins::BasicFilters::MacheteFilter::
190 MacheteFilter( )
191   : Superclass( ),
192     m_PlaneWidget( NULL )
193 {
194   this->_AddInput( "Input" );
195   this->_MakeOutput< cpPlugins::Interface::DataObject >( "PositiveOutput" );
196   this->_MakeOutput< cpPlugins::Interface::DataObject >( "NegativeOutput" );
197
198   itk::Point< double, 3 > center;
199   itk::Vector< double, 3 > normal;
200
201   center.Fill( double( 0 ) );
202   normal.Fill( double( 0 ) );
203   normal[ 0 ] = double( 1 );
204
205   this->m_Parameters->ConfigureAsPoint( "PlaneCenter", 3, center );
206   this->m_Parameters->ConfigureAsVector( "PlaneNormal", 3, normal );
207 }
208
209 // -------------------------------------------------------------------------
210 cpPlugins::BasicFilters::MacheteFilter::
211 ~MacheteFilter( )
212 {
213   if( this->m_PlaneWidget != NULL )
214     this->m_PlaneWidget->Delete( );
215 }
216
217 // -------------------------------------------------------------------------
218 std::string cpPlugins::BasicFilters::MacheteFilter::
219 _GenerateData( )
220 {
221   cpPlugins::Interface::Image* image =
222     this->GetInput< cpPlugins::Interface::Image >( "Input" );
223   if( image != NULL )
224     return( this->_FromImage( image ) );
225   cpPlugins::Interface::Mesh* mesh =
226     this->GetInput< cpPlugins::Interface::Mesh >( "Input" );
227   if( mesh == NULL )
228     return( this->_FromMesh( mesh ) );
229   return( "MacheteFilter: No valid input." );
230 }
231
232 // -------------------------------------------------------------------------
233 std::string cpPlugins::BasicFilters::MacheteFilter::
234 _FromImage( cpPlugins::Interface::Image* image )
235 {
236   itk::DataObject* itk_image = NULL;
237   std::string r = "";
238   cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _RealImage );
239   else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _RealImage );
240   else r = "MacheteFilter: Input image type not supported.";
241   return( r );
242 }
243
244 // -------------------------------------------------------------------------
245 std::string cpPlugins::BasicFilters::MacheteFilter::
246 _FromMesh( cpPlugins::Interface::Mesh* mesh )
247 {
248   return( "" );
249 }
250
251 // -------------------------------------------------------------------------
252 template< class I >
253 std::string cpPlugins::BasicFilters::MacheteFilter::
254 _RealImage( itk::DataObject* dobj )
255 {
256   typedef
257     cpExtensions::DataStructures::
258     InfinitePlaneSpatialObject< I::ImageDimension > _TPlane;
259   typedef
260     cpExtensions::Algorithms::
261     SpatialObjectMaskImageFilter< I, I > _TFilter;
262   typedef cpPlugins::Interface::DataObject _TObj;
263   typedef cpPlugins::Interface::Image      _TImage;
264   typedef typename _TPlane::PointType      _TPoint;
265   typedef typename _TPlane::VectorType     _TVector;
266   typedef typename I::PixelType            _TPixel;
267
268   I* image = dynamic_cast< I* >( dobj );
269
270   _TPoint c = this->m_Parameters->GetPoint< _TPoint >(
271     "PlaneCenter", I::ImageDimension
272     );
273   _TVector n = this->m_Parameters->GetVector< _TVector >(
274     "PlaneNormal", I::ImageDimension
275     );
276
277   typename _TPlane::Pointer plane = _TPlane::New( );
278   plane->SetCenter( c );
279   plane->SetNormal( n );
280
281   // Configure filter
282   _TFilter* filter = this->_CreateITK< _TFilter >( );
283   filter->SetInput( image );
284   filter->SetSpatialObject( plane );
285   filter->SetOutsideValue( _TPixel( 0 ) );
286   filter->Update( );
287
288   // Get output names
289   auto pos_name = this->GetOutput< _TObj >( "PositiveOutput" )->GetName( );
290   auto neg_name = this->GetOutput< _TObj >( "NegativeOutput" )->GetName( );
291
292   // Connect outputs (and correct their types and names)
293   _TImage* pos_out = this->GetOutput< _TImage >( "PositiveOutput" );
294   if( pos_out == NULL )
295   {
296     this->_MakeOutput< _TImage >( "PositiveOutput" );
297     pos_out = this->GetOutput< _TImage >( "PositiveOutput" );
298     pos_out->SetName( pos_name );
299
300   } // fi
301   _TImage* neg_out = this->GetOutput< _TImage >( "NegativeOutput" );
302   if( neg_out == NULL )
303   {
304     this->_MakeOutput< _TImage >( "NegativeOutput" );
305     neg_out = this->GetOutput< _TImage >( "NegativeOutput" );
306     neg_out->SetName( neg_name );
307
308   } // fi
309
310   // Assign outputs
311   pos_out->SetITK< I >( filter->GetPositiveOutput( ) );
312   neg_out->SetITK< I >( filter->GetNegativeOutput( ) );
313   return( "" );
314 }
315
316 // eof - $RCSfile$