]> Creatis software - cpMesh.git/blob - appli/InteractiveDeformableMeshSegmentation/MainWnd.cxx
...
[cpMesh.git] / appli / InteractiveDeformableMeshSegmentation / MainWnd.cxx
1 #include "MainWnd.h"
2 #include "ui_MainWnd.h"
3
4 #include <algorithm>
5 #include <cctype>
6 #include <fstream>
7
8 #include <QFileDialog>
9 #include <QMessageBox>
10
11 #include <vtkAnnotatedCubeActor.h>
12 #include <vtkAxesActor.h>
13 #include <vtkPropAssembly.h>
14 #include <vtkProperty.h>
15 #include <vtkRenderWindow.h>
16
17 #include <cpPlugins/Interface/Image.h>
18
19 // -------------------------------------------------------------------------
20 #define IDMS_QT_ACTION( name )                                         \
21   QObject::connect(                                                    \
22     this->m_UI->action##name, SIGNAL( triggered( ) ),                  \
23     this, SLOT( _triggered_action##name( ) )                           \
24     )
25
26 // -------------------------------------------------------------------------
27 MainWnd::MainWnd( QWidget* parent )
28 {}
29   /*
30   : QMainWindow( parent ),
31     m_UI( new Ui::MainWnd ),
32     m_InputImage( NULL ),
33     m_SegmentedImage( NULL ),
34     m_ActivePlugin( NULL ),
35     m_ActiveParameters( NULL ),
36     m_ActivePluginType( Self::NonePluginType ),
37     m_ActivePluginCategory( Self::NonePluginCategory )
38 {
39   this->m_UI->setupUi( this );
40
41   // Configuration files
42   this->m_ApplicationPreferencesFile = "idms.config";
43   this->m_PluginsConfigurationFile = "idms.plugins";
44   this->_LoadApplicationPreferences( );
45
46   // Create MPR objects
47   this->m_MPR = new TMPR(
48     this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
49     this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
50     this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
51     this->m_UI->m_3DVTK->GetRenderWindow( )
52     );
53
54   // Associate observer
55   this->m_DoubleClickCommand =
56     vtkSmartPointer< DoubleClickCommand >::New( );
57   this->m_DoubleClickCommand->SetMainWnd( this );
58   // this->m_MPR->AddDoubleClickObserver( this->m_DoubleClickCommand );
59
60   // Orientation marks
61      vtkSmartPointer< vtkAnnotatedCubeActor > oCube =
62      vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
63      oCube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
64      oCube->GetTextEdgesProperty( )->SetLineWidth( 1 );
65      oCube->GetTextEdgesProperty( )->SetDiffuse( 0 );
66      oCube->GetTextEdgesProperty( )->SetAmbient( 1 );
67      oCube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
68      oCube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
69      oCube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
70      oCube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
71      oCube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
72      oCube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
73      oCube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
74      oCube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
75      oCube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
76      oCube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
77      oCube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
78      oCube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
79      oCube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
80
81      vtkSmartPointer< vtkAxesActor > oAxes =
82      vtkSmartPointer< vtkAxesActor >::New( );
83      oAxes->AxisLabelsOff( );
84      oAxes->SetShaftTypeToCylinder( );
85      oAxes->SetTotalLength( 2.5, 2.5, 2.5 );
86
87      vtkSmartPointer< vtkPropAssembly > oActors =
88      vtkSmartPointer< vtkPropAssembly >::New( );
89      oActors->AddPart( oCube );
90      oActors->AddPart( oAxes );
91
92      this->m_3DOrientationWidget =
93      vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
94      this->m_3DOrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
95      this->m_3DOrientationWidget->SetOrientationMarker( oActors );
96      this->m_3DOrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
97
98      // Add actors, widgets, stuff, ...
99      this->m_3DOrientationWidget->
100      SetInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
101      this->m_3DOrientationWidget->SetEnabled( 1 );
102      this->m_3DOrientationWidget->InteractiveOff( );
103
104   // Qt signals <-> slots
105   IDMS_QT_ACTION( ReloadPlugins );
106   IDMS_QT_ACTION( OpenInputImage );
107   IDMS_QT_ACTION( OpenSegmentedImage );
108   QObject::connect(
109     this->m_UI->actionNavigation, SIGNAL( triggered( ) ),
110     this, SLOT( _triggered_actionSwitchMode( ) )
111     );
112   QObject::connect(
113     this->m_UI->actionSegmentationInteractiveDeformation,
114     SIGNAL( triggered( ) ),
115     this, SLOT( _triggered_actionSwitchMode( ) )
116     );
117
118   // Historic configuration
119   this->m_LastOpenedFile = ".";
120
121   // Start: load all disponible plugins
122   this->_triggered_actionReloadPlugins( );
123 }
124 */
125 // -------------------------------------------------------------------------
126 MainWnd::
127 ~MainWnd( )
128 {
129 //   // Close all connections
130 //   this->m_Plugins.UnloadAll( );
131
132 //   // Delete objects
133 //   delete this->m_UI;
134 //   // delete this->m_MPR;
135 //   if( this->m_ActiveParameters != NULL )
136 //   {
137 //     this->m_ActiveParameters->close( );
138 //     delete this->m_ActiveParameters;
139
140 //   } // fi
141 //   if( this->m_ActivePlugin != NULL ) delete this->m_ActivePlugin;
142 //   if( this->m_InputImage != NULL ) delete this->m_InputImage;
143 //   if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage;
144 }
145
146 // -------------------------------------------------------------------------
147 void MainWnd::
148 _LoadApplicationPreferences( )
149 {
150 //   this->m_ApplicationPreferences.clear( );
151 //   std::ifstream in( this->m_ApplicationPreferencesFile.c_str( ) );
152 //   if( in )
153 //   {
154 //     std::string line;
155 //     std::getline( in, line );
156 //     while( !( in.eof( ) ) )
157 //     {
158 //       long pos = line.find_last_of( "=" );
159 //       std::string key = line.substr( 0, pos );
160 //       std::string value = line.substr( pos + 1 );
161 //       key.erase(
162 //         std::remove_if( key.begin( ), key.end( ), isspace ), key.end( )
163 //         );
164 //       value.erase(
165 //         std::remove_if( value.begin( ), value.end( ), isspace ), value.end( )
166 //         );
167 //       this->m_ApplicationPreferences[ key ] = value;
168 //       std::getline( in, line );
169
170 //     } // elihw
171 //   }
172 //   else
173 //   {
174 //     this->m_ApplicationPreferences[ "data_dimensions" ] = "3";
175 //     this->m_ApplicationPreferences[ "input_image_type" ]  = "short";
176 //     this->m_ApplicationPreferences[ "segmented_image_type" ]  = "uchar";
177 //     this->m_ApplicationPreferences[ "mesh_type" ]  = "double";
178
179 //   } // fi
180 //   in.close( );
181 }
182
183 // -------------------------------------------------------------------------
184 MainWnd::
185 TPluginImage* MainWnd::
186 _LoadImage( const std::string& image_type, const std::string& image_dim )
187 {
188 //   // Show dialog and check if it was accepted
189 //   QFileDialog dialog( this );
190 //   dialog.setFileMode( QFileDialog::ExistingFiles );
191 //   dialog.setDirectory( tr( this->m_LastOpenedFile.c_str( ) ) );
192 //   dialog.setNameFilter(
193 //     tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
194 //     );
195 //   dialog.setDefaultSuffix( tr( "mhd" ) );
196 //   if( !( dialog.exec( ) ) )
197 //     return( NULL );
198
199 //   TPluginImage* ret = NULL;
200 //   unsigned int nFiles = dialog.selectedFiles( ).size( );
201 //   if( nFiles == 1 )
202 //   {
203 //     if( this->m_BaseClasses[ "ImageReader" ] == "" )
204 //     {
205 //       QMessageBox::critical(
206 //         this,
207 //         tr( "No plugin to read a single image file found!" ),
208 //         tr( "No plugin to read a single image file found!" )
209 //         );
210 //       return( ret );
211
212 //     } // fi
213
214 //     std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
215 //     this->m_LastOpenedFile = fname;
216
217 //     TPlugin* reader =
218 //       dynamic_cast< TPlugin* >(
219 //         this->m_Plugins.CreateObject( this->m_BaseClasses[ "ImageReader" ] )
220 //         );
221
222 //     TParameters reader_params = reader->GetDefaultParameters( );
223 //     reader_params[ "FileName" ].second = fname;
224 //     reader_params[ "PixelType" ].second = image_type;
225 //     reader_params[ "ImageDimension" ].second = image_dim;
226 //     reader_params[ "IsColorImage" ].second = "0";
227 //     reader->SetParameters( reader_params );
228 //     std::string err = reader->Update( );
229
230 //     if( err == "" )
231 //     {
232 //       ret = dynamic_cast< TPluginImage* >( reader->GetOutput( 0 ) );
233 //       reader->DisconnectOutputs( );
234 //     }
235 //     else
236 //       QMessageBox::critical(
237 //         this,
238 //         tr( "Error reading single image" ),
239 //         tr( err.c_str( ) )
240 //         );
241 //     delete reader;
242 //   }
243 //   else if( nFiles > 1 )
244 //   {
245 //     /* TODO
246 //        if( this->m_ImageSeriesReaderClassName == "" )
247 //        {
248 //        QMessageBox::critical(
249 //        this,
250 //        tr( "No plugin to read an image series found!" ),
251 //        tr( "No plugin to read an image series found!" )
252 //        );
253 //        return( ret );
254
255 //        } // fi
256 //        std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
257 //        this->m_LastOpenedFile = fname;
258 //     */
259
260 //   } // fi
261 //   return( ret );
262 }
263
264 // -------------------------------------------------------------------------
265 void MainWnd::
266 _UpdateEnabledFlags( )
267 {
268 //   bool img = ( this->m_InputImage != NULL );
269 //   this->m_UI->menuSegmentInputImage->setEnabled( img );
270 //   this->m_UI->actionOpenSegmentedImage->setEnabled( img );
271 //   this->m_UI->m_3DVTK->setEnabled( img );
272 //   this->m_UI->m_XPlaneVTK->setEnabled( img );
273 //   this->m_UI->m_YPlaneVTK->setEnabled( img );
274 //   this->m_UI->m_ZPlaneVTK->setEnabled( img );
275 //   this->m_UI->m_AuxVTK->setEnabled( img );
276
277 //   bool seg = ( this->m_SegmentedImage != NULL );
278 //   this->m_UI->menuFilterSegmentedImage->setEnabled( seg );
279 //   this->m_UI->menuExtractMesh->setEnabled( seg );
280 //   this->m_UI->menuProcessMesh->setEnabled( seg );
281 //   this->m_UI->actionOpenMesh->setEnabled( seg );
282
283 //   this->m_UI->actionNavigation->setEnabled( img && seg );
284 //   this->m_UI->actionSegmentationInteractiveDeformation->
285 //     setEnabled( img && seg );
286 }
287
288 // -------------------------------------------------------------------------
289 void MainWnd::
290 _triggered_actionReloadPlugins( )
291 {
292 //   if( !( this->_LoadPlugins( ) ) )
293 //   {
294 //     QMessageBox::critical(
295 //       this,
296 //       tr( "Could not load plugins from given file." ),
297 //       tr( "Could not load plugins from given file." )
298 //       );
299
300 //   } // fi
301 //   this->_UpdateEnabledFlags( );
302 }
303
304 // -------------------------------------------------------------------------
305 void MainWnd::
306 _triggered_actionOpenInputImage( )
307 {
308 //   if( this->m_InputImage != NULL )
309 //     delete this->m_InputImage;
310 //   this->m_InputImage =
311 //     this->_LoadImage(
312 //       this->m_ApplicationPreferences[ "input_image_type" ],
313 //       this->m_ApplicationPreferences[ "data_dimensions" ]
314 //       );
315 //   if( this->m_InputImage != NULL )
316 //   {
317 //     // this->m_MPR->SetImage( this->m_InputImage->GetVTKImageData( ) );
318
319 //     // Update activations
320 //     this->_UpdateEnabledFlags( );
321 //     this->m_UI->actionNavigation->setChecked( true );
322 //     this->_triggered_actionSwitchMode( );
323
324 //   } // fi
325 }
326
327 // -------------------------------------------------------------------------
328 void MainWnd::
329 _triggered_actionOpenSegmentedImage( )
330 {
331 //   if( this->m_SegmentedImage != NULL )
332 //     delete this->m_SegmentedImage;
333 //   this->m_SegmentedImage =
334 //     this->_LoadImage(
335 //       this->m_ApplicationPreferences[ "segmented_image_type" ],
336 //       this->m_ApplicationPreferences[ "data_dimensions" ]
337 //       );
338 //   if( this->m_SegmentedImage != NULL )
339 //   {
340 //     /*
341 //     this->m_MPR->SetSegmentation(
342 //       this->m_SegmentedImage->GetVTKImageData( )
343 //       );
344 //       */
345 //     /* TODO
346 //        cpPlugins::Interface::Image* img = 
347 //        dynamic_cast< cpPlugins::Interface::Image* >( this->m_SegmentedImage );
348 //        this->m_ImageActors->SetSegmentation( img->GetVTKImageData( ) );
349 //     */
350
351 //     // Ok, start!
352 //     /*
353 //     this->m_MPR->Render( 0 );
354 //     this->m_MPR->Render( 1 );
355 //     this->m_MPR->Render( 2 );
356 //     */
357 //     this->_UpdateEnabledFlags( );
358
359 //   } // fi
360 }
361
362 // -------------------------------------------------------------------------
363 void MainWnd::
364 _triggered_actionSwitchMode( )
365 {
366 //   QAction* snd = dynamic_cast< QAction* >( this->sender( ) );
367 //   if( snd == this->m_UI->actionNavigation )
368 //   {
369 //     this->m_UI->actionSegmentationInteractiveDeformation->setChecked(
370 //       !( this->m_UI->actionNavigation->isChecked( ) )
371 //       );
372 //   }
373 //   else if( snd == this->m_UI->actionSegmentationInteractiveDeformation )
374 //   {
375 //     this->m_UI->actionNavigation->setChecked(
376 //       !( this->m_UI->actionSegmentationInteractiveDeformation->isChecked( ) )
377 //       );
378 //   }
379 //   else
380 //   {
381 //     this->m_UI->actionNavigation->setChecked( true );
382 //     this->m_UI->actionSegmentationInteractiveDeformation->setChecked( false );
383
384 //   } // fi
385
386 //   /* TODO
387 //      if( this->m_UI->aNavigation->isChecked( ) )
388 //      {
389 //      this->m_XStyle->SetModeToNavigation( );
390 //      this->m_YStyle->SetModeToNavigation( );
391 //      this->m_ZStyle->SetModeToNavigation( );
392 //      this->m_ImageActors->HideRegion( 0 );
393 //      this->m_ImageActors->HideRegion( 1 );
394 //      this->m_ImageActors->HideRegion( 2 );
395 //      this->m_3DRenderer->RemoveActor(
396 //      this->m_ImageActors->GetCursorActor( )
397 //      );
398 //      this->m_3DRenderer->RemoveActor(
399 //      this->m_ImageActors->GetRegionActor( )
400 //      );
401 //      this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
402 //      }
403 //      else if( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) )
404 //      {
405 //      this->m_XStyle->SetModeToDeformation( );
406 //      this->m_YStyle->SetModeToDeformation( );
407 //      this->m_ZStyle->SetModeToDeformation( );
408 //      this->m_ImageActors->ShowRegion( 0 );
409 //      this->m_ImageActors->ShowRegion( 1 );
410 //      this->m_ImageActors->ShowRegion( 2 );
411 //      this->m_3DRenderer->AddActor(
412 //      this->m_ImageActors->GetCursorActor( )
413 //      );
414 //      this->m_3DRenderer->AddActor(
415 //      this->m_ImageActors->GetRegionActor( )
416 //      );
417 //      this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
418
419 //      } // fi
420 //   */
421 }
422
423 // -------------------------------------------------------------------------
424 /* TODO
425
426 // -------------------------------------------------------------------------
427 bool MainWnd::
428 _ParametersDialog( TParameters& parameters )
429 {
430   QDialog dlg( this );
431   QGridLayout gridLayout( &dlg );
432   QVBoxLayout verticalLayout;
433
434   // Put values
435   typedef std::map< std::string, QWidget* > _TWidgets;
436   _TWidgets widgets;
437   TParameters::const_iterator pIt = parameters.begin( );
438   for( ; pIt != parameters.end( ); ++pIt )
439   {
440     unsigned long pos = pIt->first.find_last_of( ":" );
441     std::string v_name = pIt->first.substr( 0, pos );
442     std::string v_type = pIt->first.substr( pos + 1 );
443
444     QHBoxLayout* horizontalLayout = new QHBoxLayout( );
445     QLabel* label = new QLabel( &dlg );
446     label->setText( QString( v_name.c_str( ) ) );
447     horizontalLayout->addWidget( label );
448     if( v_type == "real" )
449     {
450       QDoubleSpinBox* v_double = new QDoubleSpinBox( &dlg );
451       v_double->setDecimals( 3 );
452       v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
453       v_double->setMaximum( std::numeric_limits< double >::max( ) );
454       v_double->setValue( std::atof( pIt->second.c_str( ) ) );
455       horizontalLayout->addWidget( v_double );
456       widgets[ pIt->first ] = v_double;
457     }
458     else if( v_type == "atomic_real" )
459     {
460       if( v_name == "MeshType" )
461       {
462         QLabel* info = new QLabel( &dlg );
463         if( typeid( TScalar ) == typeid( float ) )
464           info->setText( QString( "float" ) );
465         else if( typeid( TScalar ) == typeid( double ) )
466           info->setText( QString( "double" ) );
467         horizontalLayout->addWidget( info );
468         widgets[ pIt->first ] = info;
469
470       } // fi
471
472     } // fi
473     verticalLayout.addLayout( horizontalLayout );
474
475   } // rof
476   gridLayout.addLayout( &verticalLayout, 0, 0, 1, 1 );
477
478   // Buttons box
479   QDialogButtonBox buttonBox( &dlg );
480   buttonBox.setOrientation( Qt::Horizontal );
481   buttonBox.setStandardButtons(
482     QDialogButtonBox::Cancel | QDialogButtonBox::Ok
483     );
484   gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 );
485   QObject::connect(
486     &buttonBox, SIGNAL( accepted( ) ),
487     &dlg, SLOT( accept( ) )
488     );
489   QObject::connect(
490     &buttonBox, SIGNAL( rejected( ) ),
491     &dlg, SLOT( reject( ) )
492     );
493   QMetaObject::connectSlotsByName( &dlg );
494
495   // Execute dialog
496   if( dlg.exec( ) == QDialog::Accepted )
497   {
498     _TWidgets::const_iterator wIt = widgets.begin( );
499     for( ; wIt != widgets.end( ); ++wIt )
500     {
501       unsigned long pos = wIt->first.find_last_of( ":" );
502       std::string v_name = wIt->first.substr( 0, pos );
503       std::string v_type = wIt->first.substr( pos + 1 );
504       std::stringstream sstr;
505       if( v_type == "real" )
506       {
507         QDoubleSpinBox* v_double =
508           dynamic_cast< QDoubleSpinBox* >( wIt->second );
509         if( v_double != NULL )
510           sstr << v_double->value( );
511       }
512       else if( v_type == "atomic_real" )
513       {
514         if( v_name == "MeshType" )
515         {
516           QLabel* info = dynamic_cast< QLabel* >( wIt->second );
517           if( info != NULL )
518             sstr << info->text( ).toStdString( );
519
520         } // fi
521
522       } // fi
523       parameters[ wIt->first ] = sstr.str( );
524
525     } // rof
526     return( true );
527   }
528   return( false );
529   }
530
531 // -------------------------------------------------------------------------
532 void MainWnd::
533 triggered_aFilterSegmentedImage( )
534 {
535   // Get filter name
536   if( this->m_Segmentation.IsNull( ) )
537     return;
538   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
539   if( action == NULL )
540     return;
541   std::string filter_name = action->text( ).toStdString( );
542
543   // Create filter
544   TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
545   if( filter == NULL )
546     return;
547
548   TParameters parameters = filter->GetDefaultParameters( );
549   if( !( this->_ParametersDialog( parameters ) ) )
550     return;
551   filter->SetInput( this->m_Segmentation );
552   filter->SetParameters( parameters );
553   std::string result = filter->Update( );
554
555   // Get modified segmentation
556      this->m_Mesh = filter->GetCastedOutput< TMesh >( );
557      if( this->m_Mesh.IsNotNull( ) )
558      {
559      this->m_Mesh->DisconnectPipeline( );
560
561      } // fi
562   // Ok, it seems to have runned fine
563   delete filter;
564 }
565
566 // -------------------------------------------------------------------------
567 void MainWnd::
568 triggered_aSegmentedImageToMesh( )
569 {
570   // Get filter name
571   if( this->m_Segmentation.IsNull( ) )
572     return;
573   QAction* action = dynamic_cast< QAction* >( this->sender( ) );
574   if( action == NULL )
575     return;
576   std::string filter_name = action->text( ).toStdString( );
577
578   // Create filter
579   TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
580   if( filter == NULL )
581     return;
582
583   TParameters parameters = filter->GetDefaultParameters( );
584   if( !( this->_ParametersDialog( parameters ) ) )
585     return;
586   filter->SetInput( this->m_Segmentation );
587   filter->SetParameters( parameters );
588   std::string result = filter->Update( );
589
590   // Get mesh
591   this->m_Mesh = filter->GetCastedOutput< TMesh >( );
592   if( this->m_Mesh.IsNotNull( ) )
593   {
594     this->m_Mesh->DisconnectPipeline( );
595
596   } // fi
597
598   // Ok, it seems to have runned fine
599   delete filter;
600 }
601 */
602
603 // -------------------------------------------------------------------------
604 /*
605   void MainWnd::
606   _SliceMesh( int axis )
607   {
608   TCutter* cutter = NULL;
609   if( axis == 2 ) cutter = this->m_ZCutter;
610
611   if( cutter == NULL )
612   return;
613
614   vtkPlane* vplane = this->m_ImageActors->GetSlicePlane( axis );
615   double vorigin[ 3 ], vnormal[ 3 ];
616   vplane->GetOrigin( vorigin );
617   vplane->GetNormal( vnormal );
618
619   TCutter::TVector corigin, cnormal;
620   corigin[ 0 ] = TScalar( vorigin[ 0 ] );
621   corigin[ 1 ] = TScalar( vorigin[ 1 ] );
622   corigin[ 2 ] = TScalar( vorigin[ 2 ] );
623   cnormal[ 0 ] = TScalar( vnormal[ 0 ] );
624   cnormal[ 1 ] = TScalar( vnormal[ 1 ] );
625   cnormal[ 2 ] = TScalar( vnormal[ 2 ] );
626
627   cutter->SetPlanePoint( corigin );
628   cutter->SetPlaneNormal( cnormal );
629   cutter->Update( );
630   }
631
632   // -------------------------------------------------------------------------
633   void MainWnd::
634   _SliceEventCallback(
635   vtkObject* caller,
636   long unsigned int eventId,
637   void* clientData, void* callData
638   )
639   {
640   if( clientData == NULL || callData == NULL )
641   return;
642   MainWnd* wnd = reinterpret_cast< MainWnd* >( clientData );
643   int axis = *( reinterpret_cast< int* >( callData ) );
644   if( wnd == NULL )
645   return;
646   if( eventId == idms::InteractorStyleImage::SliceEvent )
647   wnd->_SliceMesh( axis );
648   }
649
650   // -------------------------------------------------------------------------
651   void MainWnd::
652   triggered_aLoadImage( )
653   {
654   if( this->_LoadImage< TImage >( this->m_Image ) )
655   {
656   // Connect image to VTK
657   this->m_VTKImage->SetInput( this->m_Image );
658   this->m_VTKImage->Update( );
659   this->m_ImageActors->Configure(
660   this->m_VTKImage->GetOutput( ),
661   this->m_UI->m_XPlaneVTK->GetInteractor( ),
662   this->m_UI->m_YPlaneVTK->GetInteractor( ),
663   this->m_UI->m_ZPlaneVTK->GetInteractor( )
664   );
665   this->m_ImageActors->
666   AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
667
668   // Associate actors
669   this->m_3DRenderer->AddActor(
670   this->m_ImageActors->GetImageOutlineActor( )
671   );
672   this->m_3DRenderer->AddActor(
673   this->m_ImageActors->GetXBoundsActor( )
674   );
675   this->m_3DRenderer->AddActor(
676   this->m_ImageActors->GetYBoundsActor( )
677   );
678   this->m_3DRenderer->AddActor(
679   this->m_ImageActors->GetZBoundsActor( )
680   );
681
682   // Reset all cameras
683   this->m_3DRenderer->ResetCamera( );
684   this->m_ImageActors->ResetCameras( );
685
686   // Ok, start!
687   this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
688   this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
689   this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
690   this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
691
692   // Activate controls
693   this->m_UI->aLoadSegmentedImage->setEnabled( true );
694   this->m_UI->aSegmentImage->setEnabled( true );
695   this->m_UI->m_3DVTK->setEnabled( true );
696   this->m_UI->m_XPlaneVTK->setEnabled( true );
697   this->m_UI->m_YPlaneVTK->setEnabled( true );
698   this->m_UI->m_ZPlaneVTK->setEnabled( true );
699
700   } // fi
701   }
702
703   // -------------------------------------------------------------------------
704   void MainWnd::
705   triggered_aLoadSegmentedImage( )
706   {
707   if( this->m_Mesh.IsNotNull( ) )
708   {
709   QMessageBox::critical(
710   this,
711   tr( "Mesh already loaded!" ),
712   tr( "Mesh already loaded!" )
713   );
714   return;
715
716   } // fi
717
718   if( this->_LoadImage< TImage >( this->m_Segmentation ) )
719   {
720   // Compute segmentation values
721   itk::MinimumMaximumImageCalculator< TImage >::Pointer minmax =
722   itk::MinimumMaximumImageCalculator< TImage >::New( );
723   minmax->SetImage( this->m_Segmentation );
724   minmax->Compute( );
725   TPixel min_v = minmax->GetMinimum( );
726   TPixel max_v = minmax->GetMaximum( );
727   double thr = double( max_v + min_v ) / double( 2 );
728
729   typedef itk::Image< TScalar, Dimension > _TScalarImage;
730   typedef
731   itk::BinaryMinMaxCurvatureFlowImageFilter< TImage, _TScalarImage >
732   _TFilter;
733   typedef _TFilter::TimeStepType    _TTimeStep;
734   typedef _TFilter::RadiusValueType _TRadius;
735
736   _TFilter::Pointer filter = _TFilter::New( );
737   filter->SetInput( this->m_Segmentation );
738   filter->SetTimeStep( _TTimeStep( 0.0625 ) );
739   filter->SetNumberOfIterations( 10 );
740   filter->SetStencilRadius( _TRadius( 3 ) );
741   filter->SetThreshold( thr );
742   filter->Update( );
743
744   itk::ImageFileWriter< _TScalarImage >::Pointer w =
745   itk::ImageFileWriter< _TScalarImage >::New( );
746   w->SetInput( filter->GetOutput( ) );
747   w->SetFileName( "no_noise.mhd" );
748   w->Update( );
749   std::exit( 1 );
750
751   typedef
752   itk::LaplacianRecursiveGaussianImageFilter< TImage, _TScalarImage >
753   _TFilter;
754   _TFilter::Pointer filter = _TFilter::New( );
755   filter->SetInput( this->m_Segmentation );
756   filter->SetSigma( 3 ); // in spacing units
757   filter->SetNormalizeAcrossScale( false );
758
759   typedef itk::ThresholdImageFilter< _TScalarImage > _TThreshold;
760   _TThreshold::Pointer threshold = _TThreshold::New( );
761   threshold->SetInput( filter->GetOutput( ) );
762   threshold->ThresholdAbove( TScalar( 0 ) );
763   threshold->InPlaceOff( );
764   threshold->Update( );
765
766   itk::MinimumMaximumImageCalculator< _TScalarImage >::Pointer t_minmax =
767   itk::MinimumMaximumImageCalculator< _TScalarImage >::New( );
768   t_minmax->SetImage( threshold->GetOutput( ) );
769   t_minmax->Compute( );
770   TScalar min_t = t_minmax->GetMinimum( );
771
772   std::cout << min_t << " " << t_minmax->GetMaximum( ) << std::endl;
773
774   itk::SubtractImageFilter< _TScalarImage >::Pointer subtract =
775   itk::SubtractImageFilter< _TScalarImage >::New( );
776   subtract->SetInput1( threshold->GetOutput( ) );
777   subtract->SetConstant2( min_t );
778
779   itk::ImageFileWriter< _TScalarImage >::Pointer w =
780   itk::ImageFileWriter< _TScalarImage >::New( );
781   w->SetInput( subtract->GetOutput( ) );
782   w->SetFileName( "no_noise_laplace_2.mhd" );
783   w->Update( );
784   std::exit( 1 );
785
786   // Pass segmentation to VTK
787   this->m_VTKSegmentation = TVTKImage::New( );
788   this->m_VTKSegmentation->SetInput( this->m_Segmentation );
789   this->m_VTKSegmentation->Update( );
790
791   // Use VTK's marching cubes (it is smoother)
792   vtkSmartPointer< vtkImageMarchingCubes > segmentation_mc =
793   vtkSmartPointer< vtkImageMarchingCubes >::New( );
794   segmentation_mc->SetInputData( this->m_VTKSegmentation->GetOutput( ) );
795   segmentation_mc->SetValue( 0, thr );
796   segmentation_mc->Update( );
797
798   // Go back to ITK world
799   typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > _TVTKPDataToMesh;
800   _TVTKPDataToMesh::Pointer itk_mc = _TVTKPDataToMesh::New( );
801   itk_mc->SetInput( segmentation_mc->GetOutput( ) );
802   itk_mc->Update( );
803   this->m_Mesh = itk_mc->GetOutput( );
804   this->m_Mesh->DisconnectPipeline( );
805
806   this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
807   this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
808
809   this->m_MeshMapper->SetInputData( this->m_Mesh );
810   this->m_MeshActor->SetMapper( this->m_MeshMapper );
811   this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
812   this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
813   this->m_3DRenderer->AddActor( this->m_MeshActor );
814   this->m_3DRenderer->ResetCamera( );
815   this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
816
817   unsigned int reduction = 20;
818
819   typedef TImage::SpacingType::ValueType _TValue;
820
821
822   // Compute downsize parameters
823   TImage::SizeType o_size =
824   segmentation->GetLargestPossibleRegion( ).GetSize( );
825   TImage::SpacingType o_spac = segmentation->GetSpacing( );
826   _TValue min_spac = std::numeric_limits< _TValue >::max( );
827   for( unsigned int d = 0; d < Dimension; ++d )
828   min_spac = ( o_spac[ d ] < min_spac )? o_spac[ d ]: min_spac;
829   min_spac *= _TValue( reduction );
830   TImage::SpacingType n_spac( min_spac );
831   TImage::SizeType n_size;
832   for( unsigned int d = 0; d < Dimension; ++d )
833   n_size[ d ] = ( unsigned long )(
834   _TValue( o_size[ d ] ) * o_spac[ d ] / min_spac
835   );
836
837   // Downsize image
838   typedef itk::Image< TScalar, Dimension > _TScalarImage;
839   typedef itk::IdentityTransform< TScalar, Dimension > _TTransform;
840   typedef
841   itk::LinearInterpolateImageFunction< TImage, TScalar >
842   _TInterpolator;
843   typedef
844   itk::ResampleImageFilter< TImage, _TScalarImage, TScalar, TScalar >
845   _TResample;
846   _TResample::Pointer resample = _TResample::New( );
847   resample->SetInput( segmentation );
848   resample->SetSize( n_size );
849   resample->SetOutputDirection( segmentation->GetDirection( ) );
850   resample->SetOutputOrigin( segmentation->GetOrigin( ) );
851   resample->SetOutputSpacing( n_spac );
852   resample->SetTransform( _TTransform::New( ) );
853   resample->SetInterpolator( _TInterpolator::New( ) );
854   resample->UpdateLargestPossibleRegion( );
855
856   // Try to smooth
857   typedef
858   itk::SignedDanielssonDistanceMapImageFilter< _TScalarImage, _TScalarImage >
859   _TDanielsson;
860   _TDanielsson::Pointer danielsson = _TDanielsson::New( );
861   danielsson->SetInput( resample->GetOutput( ) );
862   danielsson->Update( );
863
864   // Go back to ITK world
865   typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > TVTKPDataToMesh;
866   TVTKPDataToMesh::Pointer itk_mc = TVTKPDataToMesh::New( );
867   itk_mc->SetInput( danielsson_mc->GetOutput( ) );
868   itk_mc->Update( );
869   this->m_Mesh = itk_mc->GetOutput( );
870   this->m_Mesh->DisconnectPipeline( );
871
872   this->m_ZCutter = TCutter::New( );
873   this->m_ZCutter->SetInput( this->m_Mesh );
874
875   this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
876   this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
877
878   this->m_MeshMapper->SetInputData( this->m_Mesh );
879   this->m_MeshActor->SetMapper( this->m_MeshMapper );
880   this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
881   this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
882   this->m_3DRenderer->AddActor( this->m_MeshActor );
883   this->m_3DRenderer->ResetCamera( );
884   this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
885
886   } // fi
887   }
888 */
889
890 // eof - $RCSfile$