]> Creatis software - clitk.git/blob - vv/vvSegmentationDialog.cxx
Initial revision
[clitk.git] / vv / vvSegmentationDialog.cxx
1 #ifndef _vvSegmentationDialog_CXX
2 #define _vvSegmentationDialog_CXX
3
4 /*=========================================================================
5
6 Program:   vv
7 Module:    $RCSfile: vvSegmentationDialog.cxx,v $
8 Language:  C++
9 Date:      $Date: 2010/01/06 13:31:58 $
10 Version:   $Revision: 1.1 $
11 Author :   David Sarrut (david.sarrut@gmail.com)
12
13 Copyright (C) 2008
14 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
15 CREATIS-LRMN http://www.creatis.insa-lyon.fr
16
17 This program is free software: you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation, version 3 of the License.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
29 =========================================================================*/
30 #include <QtGui>
31 #include <Qt>
32
33 #include "vvSegmentationDialog.h"
34 #include "vvProgressDialog.h"
35 #include "vvImageWriter.h"
36 #include "vvLandmarks.h"
37 #include "vvInteractorStyleNavigator.h"
38 #include "vvSlicer.h"
39
40 #include "vtkMarchingCubes.h"
41 #include "vtkMarchingSquares.h"
42 #include "vtkImageClip.h"
43 #include "vtkCamera.h"
44 #include "vtkRenderer.h"
45 #include "vtkProperty.h"
46 #include "vtkLookupTable.h"
47 #include "vtkClipPolyData.h"
48 #include "vtkImageToPolyDataFilter.h"
49 #include "vtkLookupTable.h"
50 #include "vtkDoubleArray.h"
51 #include "vtkPointData.h"
52 #include "vtkCellData.h"
53 #include "vtkImageMapToWindowLevelColors.h"
54 #include "vtkImageContinuousErode3D.h"
55 #include "vtkImageContinuousDilate3D.h"
56 #include "vtkImageLogic.h"
57 #include "vtkInteractorStyleTrackballCamera.h"
58 #include "vtkImageSeedConnectivity.h"
59 #include "vtkConnectivityFilter.h"
60 #include "vtkPolyData.h"
61 #include <vtkPolyDataMapper.h>
62 #include <vtkImageData.h>
63 #include "vtkInformation.h"
64 #include "vtkInformationVector.h"
65 #include "vtkStreamingDemandDrivenPipeline.h"
66 #include <vtkPolyDataWriter.h>
67
68 #include <QMessageBox>
69
70 //====================================================================
71 vvSegmentationDialog::vvSegmentationDialog(QWidget * parent, Qt::WindowFlags f)
72         :QDialog(parent,f), Ui::vvSegmentationDialog() {
73
74     // initialization
75     setupUi(this);
76     mManager = new vvSlicerManager(1);
77
78     mClipper = vtkImageClip::New();
79     mSquares1 = vtkMarchingSquares::New();
80     mSquaresMapper1 = vtkPolyDataMapper::New();
81     mSquaresActor1 = vtkActor::New();
82
83     mSquares2 = vtkMarchingSquares::New();
84     mSquaresMapper2 = vtkPolyDataMapper::New();
85     mSquaresActor2 = vtkActor::New();
86
87     //m3DMapper = vtkPolyDataMapper::New();
88     //m3DActor = vtkActor::New();
89     m3DExtractor = vtkMarchingCubes::New();
90     m3DMappers.clear();
91     m3DActors.clear();
92
93     mBinaireImages.clear();
94     mKernelValue = 2;
95
96     connect(clipping1Slider,SIGNAL(valueChanged(int)),this,SLOT(clippingvaluechanged(int)));
97     connect(clipping2Slider,SIGNAL(valueChanged(int)),this,SLOT(clippingvaluechanged(int)));
98     connect(binaryButton,SIGNAL(clicked()),this,SLOT(BinariseSurface()));
99     connect(saveButton,SIGNAL(clicked()),this,SLOT(Save()));
100     connect(erodeButton,SIGNAL(clicked()),this,SLOT(Erode()));
101     connect(dilateButton,SIGNAL(clicked()),this,SLOT(Dilate()));
102     connect(dimButton,SIGNAL(clicked()),this,SLOT(ChangeDimRendering()));
103     connect(kernelSpinBox,SIGNAL(valueChanged(int)),this,SLOT(KernelValueChanged(int)));
104
105     binaryButton->setEnabled(0);
106     erodeButton->setEnabled(0);
107     dilateButton->setEnabled(0);
108     infoLabel->setText("Select Up and Down threshold before clicking binarise !");
109 }
110
111 vvSegmentationDialog::~vvSegmentationDialog()
112 {
113     mClipper->Delete();
114
115     mSquaresActor1->Delete();
116     mSquaresMapper1->Delete();
117     mSquares1->Delete();
118
119     mSquaresActor2->Delete();
120     mSquaresMapper2->Delete();
121     mSquares2->Delete();
122
123     //m3DMapper->Delete();
124     //m3DActor->Delete();
125     m3DExtractor->Delete();
126
127     for (unsigned int i = 0; i < mBinaireImages.size(); i++)
128         mBinaireImages[i]->Delete();
129
130     for (unsigned int i = 0; i < m3DActors.size(); i++)
131         m3DActors[i]->Delete();
132
133     for (unsigned int i = 0; i < m3DMappers.size(); i++)
134         m3DMappers[i]->Delete();
135
136     delete mManager;
137 }
138
139 //----------------------------------------------------------------------------
140 // This templated function executes the filter for any type of data.
141 // Handles the one input operations
142 template <class T>
143 void vvImageBinarize(vtkImageData *in1Data, T *in1Ptr,
144                      int outExt[6],int clampMin, int clampMax)
145 {
146     int idxR, idxY, idxZ;
147     int maxY, maxZ;
148     vtkIdType inIncX, inIncY, inIncZ;
149     int rowLength;
150
151     // find the region to loop over
152     rowLength =
153         (outExt[1] - outExt[0]+1)*in1Data->GetNumberOfScalarComponents();
154     // What a pain. Maybe I should just make another filter.
155
156     maxY = outExt[3] - outExt[2];
157     maxZ = outExt[5] - outExt[4];
158
159     // Get increments to march through data
160     in1Data->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
161
162     for (idxZ = 0; idxZ <= maxZ; idxZ++)
163     {
164         for (idxY = 0; idxY <= maxY; idxY++)
165         {
166             for (idxR = 0; idxR < rowLength; idxR++)
167             {
168                 if (static_cast<double>(*in1Ptr) > clampMin && static_cast<double>(*in1Ptr) <= clampMax)
169                     *in1Ptr = static_cast<T>(1);
170                 else
171                     *in1Ptr = static_cast<T>(0);
172                 in1Ptr++;
173             }
174             in1Ptr += inIncY;
175         }
176         in1Ptr += inIncZ;
177     }
178 }
179
180 void vvSegmentationDialog::SetImage(vvImage::Pointer image)
181 {
182
183     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
184     mManager->SetImage(image);
185     mManager->SetSlicerWindow(0,viewWidget->GetRenderWindow());
186     vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
187     mManager->SetInteractorStyleNavigator(0,style);
188     style->Delete();
189
190     double range[2];
191     mManager->GetImage()->GetScalarRange(range);
192     mManager->GetSlicer(0)->SetColorWindow(range[1]-range[0]);
193     mManager->GetSlicer(0)->SetColorLevel((range[1]+range[0])/2);
194
195     clipping1Slider->setMinimum(range[0]);
196     clipping1Slider->setMaximum(range[1]);
197     clipping2Slider->setMinimum(range[0]);
198     clipping2Slider->setMaximum(range[1]);
199     clipping1Slider->setValue(range[0]);
200     clipping2Slider->setValue(range[1]);
201
202     mClipper->SetInput(mManager->GetSlicer(0)->GetInput());
203     mSquares1->SetValue(0,clipping1Slider->value());
204     mSquares2->SetValue(0,clipping2Slider->value());
205     mSquares1->SetInput(mClipper->GetOutput());
206     mSquares2->SetInput(mClipper->GetOutput());
207
208     mSquaresMapper1->SetInput(mSquares1->GetOutput());
209     mSquaresMapper2->SetInput(mSquares2->GetOutput());
210     mSquaresMapper1->ScalarVisibilityOff();
211     mSquaresMapper2->ScalarVisibilityOff();
212
213     mSquaresActor1->SetMapper(mSquaresMapper1);
214     mSquaresActor2->SetMapper(mSquaresMapper2);
215     mSquaresActor1->GetProperty()->SetColor(1.0,0,0);
216     mSquaresActor2->GetProperty()->SetColor(0,0,1.0);
217     mSquaresActor1->SetPickable(0);
218     mSquaresActor2->SetPickable(0);
219
220     mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor1);
221     mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor2);
222
223     mSquares1->Update();
224     mSquares2->Update();
225
226     UpdateSlice(0,mManager->GetSlicer(0)->GetSlice());
227
228     connect(mManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
229     connect(mManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
230     connect(mManager,SIGNAL(UpdateSliceRange(int,int,int,int,int)),this,SLOT(UpdateSlice(int, int)));
231     connect(mManager,SIGNAL(LandmarkAdded()),this,SLOT(InsertSeed()));
232     QApplication::restoreOverrideCursor();
233 }
234
235 void vvSegmentationDialog::UpdateSlice(int slicer,int slices)
236 {
237     int slice = mManager->GetSlicer(0)->GetSlice();
238     int tslice = mManager->GetSlicer(0)->GetTSlice();
239     mClipper->SetInput(mManager->GetSlicer(0)->GetInput());
240     int* extent = mManager->GetSlicer(0)->GetImageActor()->GetDisplayExtent();
241     mClipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],extent[3],extent[4],extent[5]);
242     int i;
243     for (i = 0; i < 6;i = i+2)
244     {
245         if (extent[i] == extent[i+1])
246         {
247             break;
248         }
249     }
250
251     switch (i)
252     {
253     case 0:
254         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice)
255         {
256             mSquaresActor1->SetPosition(1,0,0);
257             mSquaresActor2->SetPosition(1,0,0);
258         }
259         else
260         {
261             mSquaresActor1->SetPosition(-1,0,0);
262             mSquaresActor2->SetPosition(-1,0,0);
263         }
264         break;
265     case 2:
266         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice)
267         {
268             mSquaresActor1->SetPosition(0,1,0);
269             mSquaresActor2->SetPosition(0,1,0);
270         }
271         else
272         {
273             mSquaresActor1->SetPosition(0,-1,0);
274             mSquaresActor2->SetPosition(0,-1,0);
275         }
276         break;
277     case 4:
278         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice)
279         {
280             mSquaresActor1->SetPosition(0,0,1);
281             mSquaresActor2->SetPosition(0,0,1);
282         }
283         else
284         {
285             mSquaresActor1->SetPosition(0,0,-1);
286             mSquaresActor2->SetPosition(0,0,-1);
287         }
288         break;
289     }
290     mSquares1->Update();
291     mSquares2->Update();
292
293     if (m3DActors.size())
294     {
295         for (unsigned int i =0; i < m3DActors.size(); i++)
296         {
297             if (m3DActors[i]->GetVisibility())
298             {
299                 m3DActors[i]->VisibilityOff();
300             }
301         }
302         std::cout << "display " << tslice << " on " << m3DActors.size()  << std::endl;
303         m3DActors[tslice]->VisibilityOn();
304     }
305
306     mManager->Render();
307 }
308
309
310 void vvSegmentationDialog::clippingvaluechanged(int value)
311 {
312     binaryButton->setEnabled(1);
313     int min = (clipping1Slider->value() < clipping2Slider->value() ) ?
314               clipping1Slider->value():clipping2Slider->value();
315     int max = (clipping1Slider->value() > clipping2Slider->value() ) ?
316               clipping1Slider->value():clipping2Slider->value();
317     mSquares1->SetValue(0,min);
318     mSquares2->SetValue(0,max);
319
320     QString textMin = "<b> Min : </b>";
321     textMin += QString::number(min);
322     QString textMax = "\n <b> Max : </b>";
323     textMax += QString::number(max);
324     minLabel->setText(textMin);
325     maxLabel->setText(textMax);
326
327     if (mSquares1->GetInput())
328     {
329         mSquares1->Update();
330         mSquares2->Update();
331         mManager->Render();
332     }
333 }
334
335
336 void vvSegmentationDialog::BinariseSurface()
337 {
338     infoLabel->setText("Click erode then space on desired organ !");
339
340     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
341     int clampMin = (clipping1Slider->value() < clipping2Slider->value() ) ?
342                    clipping1Slider->value():clipping2Slider->value();
343     int clampMax = (clipping1Slider->value() > clipping2Slider->value() ) ?
344                    clipping1Slider->value():clipping2Slider->value();
345     vtkImageData* outputImage = vtkImageData::New();
346
347     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
348     {
349         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
350         int ext[6];
351         image->GetWholeExtent(ext);
352         void *in1Ptr;
353         in1Ptr = image->GetScalarPointerForExtent(ext);
354
355         switch (image->GetScalarType())
356         {
357             vtkTemplateMacro(
358                 vvImageBinarize(image, static_cast<VTK_TT *>(in1Ptr),
359                                 ext,clampMin,clampMax));
360         default:
361             std::cerr << "Error, unknown pixel format : " << image->GetScalarTypeAsString() << std::endl;
362             return;
363         }
364
365         outputImage->Initialize();
366         outputImage->SetExtent(ext);
367         outputImage->SetOrigin(image->GetOrigin());
368         outputImage->SetSpacing(image->GetSpacing());
369         outputImage->SetScalarTypeToUnsignedChar();
370         outputImage->CopyAndCastFrom(image,ext);
371         outputImage->Update();
372
373         image->DeepCopy(outputImage);
374         image->UpdateInformation();
375         image->PropagateUpdateExtent();
376
377         vtkImageData* imageBin = vtkImageData::New();
378         imageBin->DeepCopy(image);
379         imageBin->Update();
380         mBinaireImages.push_back(imageBin);
381     }
382
383     outputImage->Delete();
384     erodeButton->setEnabled(1);
385     QApplication::restoreOverrideCursor();
386     mManager->SetColorWindow(2);
387     mManager->SetColorLevel(0.5);
388     mManager->Render();
389 }
390
391 void vvSegmentationDialog::Erode()
392 {
393     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
394     vtkImageContinuousErode3D* erode = vtkImageContinuousErode3D::New();
395     erode->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
396     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
397     {
398         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
399         erode->SetInput(image);
400         erode->Update();
401         image->DeepCopy(erode->GetOutput());
402         image->Update();
403     }
404     erode->Delete();
405     dilateButton->setEnabled(1);
406     mManager->Render();
407     QApplication::restoreOverrideCursor();
408 }
409
410 void vvSegmentationDialog::Dilate()
411 {
412     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
413     vtkImageContinuousDilate3D* dilate = vtkImageContinuousDilate3D::New();
414     vtkImageLogic* And = vtkImageLogic::New();
415     And->SetOperationToAnd();
416     dilate->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
417     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
418     {
419         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
420         dilate->SetInput(image);
421         vtkImageData* mask = mBinaireImages[numImage];
422         And->SetInput1(dilate->GetOutput());
423         And->SetInput2(mask);
424         And->Update();
425         image->DeepCopy(And->GetOutput());
426         image->Update();
427     }
428     And->Delete();
429     dilate->Delete();
430     mManager->Render();
431     QApplication::restoreOverrideCursor();
432 }
433
434 void vvSegmentationDialog::InsertSeed()
435 {
436     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
437     int point4D[4];
438     point4D[0] = mManager->GetLandmarks()->GetCoordinates(
439                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[0];
440     point4D[1] = mManager->GetLandmarks()->GetCoordinates(
441                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[1];
442     point4D[2] = mManager->GetLandmarks()->GetCoordinates(
443                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[2];
444     point4D[3] = mManager->GetLandmarks()->GetCoordinates(
445                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[3];
446
447     point4D[0] = point4D[0]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[0];
448     point4D[1] = point4D[1]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[1];
449     point4D[2] = point4D[2]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[2];
450
451     vtkImageSeedConnectivity* seed = vtkImageSeedConnectivity::New();
452     seed->SetInputConnectValue(1);
453     seed->SetOutputConnectedValue(1);
454     seed->SetOutputUnconnectedValue(0);
455     seed->AddSeed(point4D[0],point4D[1],point4D[2]);
456
457     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
458     {
459         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
460         seed->SetInput(image);
461         seed->Update();
462         image->DeepCopy(seed->GetOutput());
463         image->Update();
464     }
465
466     seed->Delete();
467     QApplication::restoreOverrideCursor();
468 }
469
470 void vvSegmentationDialog::ChangeDimRendering()
471 {
472     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
473
474     if (dimButton->text() == "3D")
475     {
476         if (m3DActors.size() == 0)
477         {
478             m3DExtractor->SetValue(0,0.5);
479             for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
480             {
481                 vtkActor* actor = vtkActor::New();
482                 m3DExtractor->SetInput(mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage]);
483                 m3DExtractor->Update();
484
485                 vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
486                 mapper->SetInput(m3DExtractor->GetOutput());
487                 m3DMappers.push_back(mapper);
488
489                 actor->SetMapper(mapper);
490                 actor->GetProperty()->SetColor(1.0,0.7,0.2);
491                 actor->VisibilityOff();
492
493                 mManager->GetSlicer(0)->GetRenderer()->AddActor(actor);
494                 m3DActors.push_back(actor);
495             }
496         }
497
498         mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.5,0.6,0.9);
499         m3DActors[0]->VisibilityOn();
500
501         vtkInteractorStyleTrackballCamera* style = vtkInteractorStyleTrackballCamera::New();
502         mManager->SetInteractorStyleNavigator(0,style);
503         style->Delete();
504
505         mManager->GetSlicer(0)->GetImageActor()->VisibilityOff();
506         mSquaresActor1->VisibilityOff();
507         mSquaresActor2->VisibilityOff();
508         mManager->Render();
509         dimButton->setText("2D");
510     }
511     else
512     {
513         mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.0,0.0,0.0);
514         vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
515         mManager->SetInteractorStyleNavigator(0,style);
516         style->Delete();
517
518         mManager->GetSlicer(0)->SetSliceOrientation(2);
519         m3DActors[mManager->GetSlicer(0)->GetTSlice()]->VisibilityOff();
520
521         mManager->GetSlicer(0)->GetImageActor()->VisibilityOn();
522         mSquaresActor1->VisibilityOn();
523         mSquaresActor2->VisibilityOn();
524         dimButton->setText("3D");
525     }
526     QApplication::restoreOverrideCursor();
527 }
528
529 void vvSegmentationDialog::KernelValueChanged(int kernel)
530 {
531     mKernelValue = kernel;
532 }
533
534 void vvSegmentationDialog::Save()
535 {
536     if (dimButton->text() == "2D") //If in *3D* mode, save the mesh
537     {
538         QString fileName = QFileDialog::getSaveFileName(this,
539                 tr("Save Mesh As"),
540                 QDir::home().dirName(),
541                 "Mesh Files (*.vtk *.vtp)");
542         if (!fileName.isEmpty())
543         {
544             vtkSmartPointer<vtkPolyDataWriter> w = vtkSmartPointer<vtkPolyDataWriter>::New();
545             w->SetInput(m3DExtractor->GetOutput());
546             w->SetFileName(fileName.toStdString().c_str());
547             w->Write();
548         }
549     }
550     else {
551         QStringList OutputListeFormat;
552         OutputListeFormat.clear();
553         int dimension = mManager->GetDimension();
554         if (dimension == 1)
555         {
556             OutputListeFormat.push_back(".mhd");
557         }
558         if (dimension == 2)
559         {
560             OutputListeFormat.push_back(".bmp");
561             OutputListeFormat.push_back(".png");
562             OutputListeFormat.push_back(".jpeg");
563             OutputListeFormat.push_back(".tif");
564             OutputListeFormat.push_back(".mhd");
565             OutputListeFormat.push_back(".hdr");
566             OutputListeFormat.push_back(".vox");
567         }
568         else if (dimension == 3)
569         {
570             OutputListeFormat.push_back(".mhd");
571             OutputListeFormat.push_back(".hdr");
572             OutputListeFormat.push_back(".vox");
573         }
574         else if (dimension == 4)
575         {
576             OutputListeFormat.push_back(".mhd");
577         }
578         QString Extensions = "AllFiles(*.*)";
579         for (int i = 0; i < OutputListeFormat.count(); i++)
580         {
581             Extensions += ";;Images ( *";
582             Extensions += OutputListeFormat[i];
583             Extensions += ")";
584         }
585         QString fileName = QFileDialog::getSaveFileName(this,
586                 tr("Save As"),
587                 QDir::home().dirName(),
588                 Extensions);
589         if (!fileName.isEmpty())
590         {
591             std::string fileformat = vtksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
592             if (OutputListeFormat.contains(
593                         fileformat.c_str()))
594             {
595                 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
596                 vvProgressDialog progress("Saving "+fileName.toStdString());
597                 qApp->processEvents();
598                 vvImageWriter *writer = new vvImageWriter;
599                 writer->SetOutputFileName(fileName.toStdString());
600                 writer->SetInput(mManager->GetSlicer(0)->GetImage());
601                 writer->Update(dimension,"unsigned_char");
602                 QApplication::restoreOverrideCursor();
603                 if (writer->GetLastError().size())
604                 {
605                     QString error = "Saving did not succeed\n";
606                     error += writer->GetLastError().c_str();
607                     QMessageBox::information(this,tr("Saving Problem"),error);
608                     Save();
609                 }
610             }
611             else
612             {
613                 QString error = fileformat.c_str();
614                 if (error.isEmpty())
615                     error += "no file format specified !";
616                 else
617                     error += " format unknown !!!\n";
618                 QMessageBox::information(this,tr("Saving Problem"),error);
619                 Save();
620             }
621         }
622     }
623 }
624
625 #endif /* end #define _vvSegmentationDialog_CXX */
626