]> Creatis software - cpPlugins.git/blob - appli/ImageMPR/ImageMPR.cxx
...
[cpPlugins.git] / appli / ImageMPR / ImageMPR.cxx
1 #include "ImageMPR.h"
2 #include "ui_ImageMPR.h"
3
4 #include <vtkProperty.h>
5 #include <vtkRenderWindow.h>
6
7 #include <QDialogButtonBox>
8 #include <QDoubleSpinBox>
9 #include <QFileDialog>
10 #include <QLabel>
11 #include <QMessageBox>
12
13 #ifdef _WIN32
14 #  define PLUGIN_PREFIX ""
15 #  define PLUGIN_EXT "dll"
16 #  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
17 #else
18 #  define PLUGIN_PREFIX "lib"
19 #  define PLUGIN_EXT "so"
20 #  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
21 #endif // _WIN32
22
23 // -------------------------------------------------------------------------
24 ImageMPR::ImageMPR( QWidget* parent )
25   : QMainWindow( parent ),
26     m_UI( new Ui::ImageMPR ),
27     m_ImageReaderClass( "" ),
28     m_ImageWriterClass( "" ),
29     m_InputImage( NULL ),
30     m_ParametersDlg( NULL )
31 {
32   this->m_UI->setupUi( this );
33
34   // Create and associate renderers
35   this->m_MPR = new TMPR(
36     this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
37     this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
38     this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
39     this->m_UI->m_3DVTK->GetRenderWindow( )
40     );
41
42   // signals <-> slots
43   QObject::connect(
44     this->m_UI->actionOpenPlugins, SIGNAL( triggered( ) ),
45     this, SLOT( _triggered_actionOpenPlugins( ) )
46     );
47   QObject::connect(
48     this->m_UI->actionOpenInputImage, SIGNAL( triggered( ) ),
49     this, SLOT( _triggered_actionOpenInputImage( ) )
50     );
51   QObject::connect(
52     this->m_UI->actionOpenInputPolyData, SIGNAL( triggered( ) ),
53     this, SLOT( _triggered_actionOpenInputPolyData( ) )
54     );
55
56   // Start: load all disponible plugins
57   this->_LoadPlugins(
58     std::string( PLUGIN_PREFIX ) +
59     std::string( "cpPlugins." ) +
60     std::string( PLUGIN_EXT )
61     );
62 }
63
64 // -------------------------------------------------------------------------
65 ImageMPR::
66 ~ImageMPR( )
67 {
68   // Close all connections
69   this->m_Plugins.UnloadAll( );
70
71   // Delete objects
72   delete this->m_UI;
73   delete this->m_MPR;
74   if( this->m_ParametersDlg != NULL )
75   {
76     this->m_ParametersDlg->close( );
77     delete this->m_ParametersDlg;
78
79   } // fi
80 }
81
82 // -------------------------------------------------------------------------
83 bool ImageMPR::
84 _LoadPlugins( const std::string& filename )
85 {
86   this->m_ImageReaderClass = "";
87   this->m_ImageWriterClass = "";
88   this->m_MeshReaderClass = "";
89   this->m_MeshWriterClass = "";
90   this->m_ImageToImageFilters.clear( );
91   this->m_ImageToMeshFilters.clear( );
92
93   this->m_Plugins.UnloadAll( );
94   if( !( this->m_Plugins.Load( filename ) ) )
95   {
96     this->m_Plugins.UnloadAll( );
97     return( false );
98
99   } // fi
100
101   typedef TPluginsInterface::TClasses _TClasses;
102   _TClasses::const_iterator cIt = this->m_Plugins.GetClasses( ).begin( );
103   for( ; cIt != this->m_Plugins.GetClasses( ).end( ); ++cIt )
104   {
105     TPluginFilter::Pointer o =
106       this->m_Plugins.CreateProcessObject( cIt->first );
107     std::string name = o->GetClassName( );
108     std::string category = o->GetClassCategory( );
109     if( category == "ImageReader" )
110       this->m_ImageReaderClass = name;
111     else if( category == "ImageWriter" )
112       this->m_ImageWriterClass = name;
113     else if( category == "MeshReader" )
114       this->m_MeshReaderClass = name;
115     else if( category == "MeshWriter" )
116       this->m_MeshWriterClass = name;
117     else if( category == "ImageToImageFilter" )
118     {
119       this->m_ImageToImageFilters.insert( name );
120       QAction* action =
121         this->m_UI->MenuImageToImage->addAction( QString( name.c_str( ) ) );
122       QObject::connect(
123         action, SIGNAL( triggered( ) ),
124         this, SLOT( _triggered_actionImageToImage( ) )
125         );
126     }
127     else if( category == "ImageToMeshFilter" )
128     {
129       this->m_ImageToMeshFilters.insert( name );
130       QAction* action =
131         this->m_UI->MenuImageToMesh->addAction( QString( name.c_str( ) ) );
132       QObject::connect(
133         action, SIGNAL( triggered( ) ),
134         this, SLOT( _triggered_actionImageToMesh( ) )
135         );
136
137     } // fi
138
139   } // rof
140   return( true );
141 }
142
143 // -------------------------------------------------------------------------
144 bool ImageMPR::
145 _ParametersDialog( TPluginFilter* filter )
146 {
147   if( this->m_ParametersDlg != NULL )
148   { 
149     this->m_ParametersDlg->close( );
150     delete this->m_ParametersDlg;
151
152   } // fi
153   this->m_ParametersDlg = new QDialog( NULL );
154   this->m_ParametersDlg->setWindowFlags( Qt::FramelessWindowHint ); 
155   this->m_ParametersDlg->setWindowFlags( Qt::WindowTitleHint );
156
157   QGridLayout* gridLayout = new QGridLayout( this->m_ParametersDlg );
158   QVBoxLayout* verticalLayout = new QVBoxLayout( );
159
160   // Put a title
161   QLabel* title = new QLabel( this->m_ParametersDlg );
162   title->setText( filter->GetClassName( ).c_str( ) );
163   verticalLayout->addWidget( title );
164
165   // Put values
166   TParameters parameters = filter->GetDefaultParameters( );
167   std::vector< std::string > names = parameters.GetParameters( );
168   std::vector< std::string >::const_iterator nIt = names.begin( );
169   for( ; nIt != names.end( ); ++nIt )
170   {
171     std::string par_name = *nIt;
172     TParameters::Type par_type = parameters.GetParameterType( par_name );
173
174     /* TODO
175        enum Type
176        {
177        String = 0,
178        Bool,
179        Int,
180        Uint,
181        Real,
182        Index,
183        Point,
184        StringList,
185        BoolList,
186        IntList,
187        UintList,
188        RealList,
189        IndexList,
190        PointList,
191        NoType
192        };
193     */
194     QHBoxLayout* horizontalLayout = new QHBoxLayout( );
195     QLabel* label = new QLabel( this->m_ParametersDlg );
196     label->setText( QString( par_name.c_str( ) ) );
197     horizontalLayout->addWidget( label );
198
199     QWidget* w_input = NULL;
200     if( par_type == TParameters::Uint )
201     {
202       QSpinBox* v_uint =
203         new QSpinBox( this->m_ParametersDlg );
204       v_uint->setMinimum( -100 );
205       v_uint->setMaximum( std::numeric_limits< int >::max( ) );
206       v_uint->setValue( parameters.GetValueAsUint( par_name ) );
207       v_uint->setObjectName( QString( par_name.c_str( ) ) );
208       w_input = v_uint;
209     }
210     else if( par_type == TParameters::Int )
211     {
212       QSpinBox* v_int =
213         new QSpinBox( this->m_ParametersDlg );
214       v_int->setMinimum( -std::numeric_limits< int >::max( ) );
215       v_int->setMaximum( std::numeric_limits< int >::max( ) );
216       v_int->setValue( parameters.GetValueAsInt( par_name ) );
217       v_int->setObjectName( QString( par_name.c_str( ) ) );
218       w_input = v_int;
219     }
220     else if( par_type == TParameters::Real )
221     {
222       QDoubleSpinBox* v_double =
223         new QDoubleSpinBox( this->m_ParametersDlg );
224       v_double->setDecimals( 3 );
225       v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
226       v_double->setMaximum( std::numeric_limits< double >::max( ) );
227       v_double->setValue( parameters.GetValueAsReal( par_name ) );
228       v_double->setObjectName( QString( par_name.c_str( ) ) );
229       w_input = v_double;
230
231     } // fi
232
233     if( w_input != NULL )
234     {
235       horizontalLayout->addWidget( w_input );
236       verticalLayout->addLayout( horizontalLayout );
237
238     } // fi
239
240   } // rof
241
242   // Add buttons
243   QDialogButtonBox* bb = new QDialogButtonBox(
244     QDialogButtonBox::Ok | QDialogButtonBox::Cancel
245     );
246   QObject::connect(
247     bb, SIGNAL( accepted( ) ), this->m_ParametersDlg, SLOT( accept( ) )
248     );
249   QObject::connect(
250     bb, SIGNAL( rejected( ) ), this->m_ParametersDlg, SLOT( reject( ) )
251     );
252   verticalLayout->addWidget( bb );
253   gridLayout->addLayout( verticalLayout, 0, 0, 1, 1 );
254
255   // Execute
256   QMetaObject::connectSlotsByName( this->m_ParametersDlg );
257   if( !( this->m_ParametersDlg->exec( ) ) )
258     return( false );
259
260   // Get values back
261   nIt = names.begin( );
262   for( ; nIt != names.end( ); ++nIt )
263   {
264     std::string par_name = *nIt;
265     TParameters::Type par_type = parameters.GetParameterType( par_name );
266     if( par_type == TParameters::Uint )
267     {
268       QSpinBox* v_uint =
269         this->m_ParametersDlg->findChild< QSpinBox* >( par_name.c_str( ) );
270       if( v_uint != NULL )
271         parameters.SetValueAsUint( par_name, v_uint->value( ) );
272     }
273     else if( par_type == TParameters::Int )
274     {
275       QSpinBox* v_int =
276         this->m_ParametersDlg->findChild< QSpinBox* >( par_name.c_str( ) );
277       if( v_int != NULL )
278         parameters.SetValueAsInt( par_name, v_int->value( ) );
279     }
280     else if( par_type == TParameters::Real )
281     {
282       QDoubleSpinBox* v_double =
283         this->m_ParametersDlg->findChild< QDoubleSpinBox* >(
284           par_name.c_str( )
285           );
286       if( v_double != NULL )
287         parameters.SetValueAsReal( par_name, v_double->value( ) );
288
289     } // fi
290
291   } // rof
292   filter->SetParameters( parameters );
293   return( true );
294 }
295
296 // -------------------------------------------------------------------------
297 void ImageMPR::
298 _triggered_actionOpenPlugins( )
299 {
300   // Show dialog and check if it was accepted
301   QFileDialog dialog( this );
302   dialog.setFileMode( QFileDialog::ExistingFile );
303   dialog.setDirectory( "." );
304   dialog.setNameFilter( tr( PLUGIN_REGEX ) );
305   dialog.setDefaultSuffix( tr( PLUGIN_EXT ) );
306   if( !( dialog.exec( ) ) )
307     return;
308   
309   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
310   if( !( _LoadPlugins( fname ) ) )
311     QMessageBox::critical(
312       this,
313       tr( "Ignoring plugin" ),
314       tr( fname.c_str( ) )
315       );
316 }
317
318 // -------------------------------------------------------------------------
319 void ImageMPR::
320 _triggered_actionOpenInputImage( )
321 {
322   // Show dialog and check if it was accepted
323   QFileDialog dialog( this );
324   dialog.setFileMode( QFileDialog::ExistingFiles );
325   dialog.setDirectory( tr( "." ) );
326   dialog.setNameFilter(
327     tr( "Medical image files (*.mhd *.bin *.dcm *.nrri);;All files (*)" )
328     );
329   dialog.setDefaultSuffix( tr( "mhd" ) );
330   if( !( dialog.exec( ) ) )
331     return;
332   
333   this->m_InputImage = NULL;
334
335   // Get a reader from plugins
336   TPluginFilter::Pointer reader =
337     this->m_Plugins.CreateProcessObject( this->m_ImageReaderClass );
338
339   // Configure reader
340   TParameters reader_params = reader->GetDefaultParameters( );
341   QStringList q_fnames = dialog.selectedFiles( );
342   QStringList::const_iterator qIt = q_fnames.begin( );
343   for( ; qIt != q_fnames.end( ); ++qIt )
344     reader_params.AddValueToStringList( "FileNames", qIt->toStdString( ) );
345   reader->SetParameters( reader_params );
346
347   // Execute and get error message, if any
348   std::string err = reader->Update( );
349
350   // Assign fresh image, if any
351   if( err == "" )
352   {
353     this->m_InputImage =
354       dynamic_cast< TPluginImage* >( reader->GetOutput( 0 ) );
355     reader->DisconnectOutputs( );
356     if( this->m_InputImage.IsNotNull( ) )
357       this->m_MPR->SetImage( this->m_InputImage->GetVTKImageData( ) );
358   }
359   else
360     QMessageBox::critical(
361       this,
362       tr( "Error reading single image" ),
363       tr( err.c_str( ) )
364       );
365 }
366
367 // -------------------------------------------------------------------------
368 void ImageMPR::
369 _triggered_actionOpenInputPolyData( )
370 {
371   /*
372   // Show dialog and check if it was accepted
373   QFileDialog dialog( this );
374   dialog.setFileMode( QFileDialog::ExistingFile );
375   dialog.setDirectory( "." );
376   dialog.setNameFilter( tr( "VTK file (*.vtk);;All files (*)" ) );
377   dialog.setDefaultSuffix( tr( "vtk" ) );
378   if( !( dialog.exec( ) ) )
379     return;
380   
381   std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
382
383   this->m_InputMesh = NULL;
384
385   // Get a reader from plugins
386   TPluginFilter::Pointer reader =
387     this->m_Plugins.CreateProcessObject(
388       this->m_BaseClasses[ "MeshReader" ]
389       );
390
391   // Configure plugin
392   TParameters reader_params = reader->GetDefaultParameters( );
393   reader_params.SetValueAsString( "FileName", fname );
394   reader->SetParameters( reader_params );
395
396   // Execute and get error message, if any
397   std::string err = reader->Update( );
398
399   // Assign fresh image, if any
400   if( err == "" )
401   {
402     this->m_InputMesh =
403       dynamic_cast< TPluginMesh* >( reader->GetOutput( 0 ) );
404     reader->DisconnectOutputs( );
405     if( this->m_InputMesh.IsNotNull( ) )
406     {
407       this->m_InputMeshMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
408       this->m_InputMeshMapper->SetInputData( this->m_InputMesh->GetVTKPolyData( ) );
409       this->m_InputMeshActor = vtkSmartPointer< vtkActor >::New( );
410       this->m_InputMeshActor->SetMapper( this->m_InputMeshMapper );
411       this->m_MPR->Add3DActor( this->m_InputMeshActor );
412
413     } // fi
414   }
415   else
416     QMessageBox::critical(
417       this,
418       tr( "Error reading polydata" ),
419       tr( err.c_str( ) )
420       );
421   */
422 }
423
424 // -------------------------------------------------------------------------
425 void ImageMPR::
426 _triggered_actionImageToImage( )
427 {
428   if( this->m_InputImage.IsNull( ) )
429     return;
430
431   // Get filter name
432   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
433   if( action == NULL )
434     return;
435   std::string name = action->text( ).toStdString( );
436
437   // Configure filter
438   TPluginFilter::Pointer filter =
439     this->m_Plugins.CreateProcessObject( name );
440   if( !( this->_ParametersDialog( filter ) ) )
441     return;
442
443   // Execute filter
444   filter->SetInput( 0, this->m_InputImage );
445   filter->Update( );
446
447   // Update image
448   TPluginImage* result =
449     dynamic_cast< TPluginImage* >( filter->GetOutput( 0 ) );
450   result->DisconnectPipeline( );
451   this->m_InputImage = result;
452   if( this->m_InputImage.IsNotNull( ) )
453     this->m_MPR->SetImage( this->m_InputImage->GetVTKImageData( ) );
454 }
455
456 // -------------------------------------------------------------------------
457 void ImageMPR::
458 _triggered_actionImageToMesh( )
459 {
460   if( this->m_InputImage.IsNull( ) )
461     return;
462
463   // Get filter name
464   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
465   if( action == NULL )
466     return;
467   std::string name = action->text( ).toStdString( );
468 }
469
470 // eof - $RCSfile$