2323// clitk
2424#include " clitkDicomRTStruct2ImageFilter.h"
2525#include " clitkImageCommon.h"
26+ #include " vvImageWriter.h"
2627
2728// vtk
2829#include < vtkVersion.h>
3233#include < vtkLinearExtrusionFilter.h>
3334#include < vtkMetaImageWriter.h>
3435#include < vtkXMLPolyDataWriter.h>
36+ #include < vtkTransformPolyDataFilter.h>
3537
3638
3739// --------------------------------------------------------------------
@@ -107,13 +109,19 @@ void clitk::DicomRTStruct2ImageFilter::SetImage(vvImage::Pointer image)
107109{
108110 if (image->GetNumberOfDimensions () != 3 ) {
109111 std::cerr << " Error. Please provide a 3D image." << std::endl;
110- exit (0 );
112+ exit (EXIT_FAILURE );
111113 }
112114 mSpacing .resize (3 );
113115 mOrigin .resize (3 );
114116 mSize .resize (3 );
115117 mDirection .resize (3 );
116- mTransformMatrix = image->GetTransform ()[0 ]->GetMatrix ();
118+ // mTransformMatrix = image->GetTransform()[0]->GetMatrix();
119+ mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New ();
120+ for (unsigned int i=0 ;i<4 ;i++) {
121+ for (unsigned int j=0 ;j<4 ;j++) {
122+ mTransformMatrix ->SetElement (i,j,image->GetTransform ()[0 ]->GetMatrix ()->GetElement (i,j));
123+ }
124+ }
117125 for (unsigned int i=0 ; i<3 ; i++) {
118126 mSpacing [i] = image->GetSpacing ()[i];
119127 mOrigin [i] = image->GetOrigin ()[i];
@@ -132,7 +140,7 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
132140 itk::ImageIOBase::Pointer header = clitk::readImageHeader (f);
133141 if (header->GetNumberOfDimensions () < 3 ) {
134142 std::cerr << " Error. Please provide a 3D image instead of " << f << std::endl;
135- exit (0 );
143+ exit (EXIT_FAILURE );
136144 }
137145 if (header->GetNumberOfDimensions () > 3 ) {
138146 std::cerr << " Warning dimension > 3 are ignored" << std::endl;
@@ -149,6 +157,18 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
149157 for (unsigned int j=0 ; j<3 ; j++)
150158 mDirection [i][j] = header->GetDirection (i)[j];
151159 }
160+ // cf. AddItkImage function in vvImage.txx
161+ mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New ();
162+ mTransformMatrix ->Identity ();
163+ for (unsigned int i=0 ; i<3 ; i++) {
164+ double tmp = 0 ;
165+ for (unsigned int j=0 ; j<3 ; j++) {
166+ mTransformMatrix ->SetElement (i,j,mDirection [i][j]);
167+ tmp -= mDirection [i][j] * mOrigin [j];
168+ }
169+ tmp += mOrigin [i];
170+ mTransformMatrix ->SetElement (i,3 ,tmp);
171+ }
152172}
153173// --------------------------------------------------------------------
154174
@@ -206,7 +226,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
206226
207227 // Get bounds
208228 double *bounds=mesh->GetBounds ();
209-
229+ /*
210230 //Change mOrigin, mSize and mSpacing with respect to the directions
211231 // Spacing is influenced by input direction
212232 std::vector<double> tempSpacing;
@@ -238,7 +258,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
238258 }
239259 mSize[i] = lrint(tempSize[i]);
240260 }
241-
261+ */
242262 // Compute origin
243263 std::vector<double > origin;
244264 origin.resize (3 );
@@ -259,7 +279,18 @@ void clitk::DicomRTStruct2ImageFilter::Update()
259279 extend[i] = mSize [i]-1 ;
260280 }
261281 }
262-
282+ // Apply the transform to the mesh
283+ vtkSmartPointer<vtkTransform> outputLabelmapGeometryTransform = vtkSmartPointer<vtkTransform>::New ();
284+ outputLabelmapGeometryTransform->SetMatrix (mTransformMatrix );
285+ // Apparently the inverse is wrong...
286+ // outputLabelmapGeometryTransform->Inverse();
287+ vtkSmartPointer<vtkTransformPolyDataFilter> transformPolyDataFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New ();
288+ #if VTK_MAJOR_VERSION <= 5
289+ transformPolyDataFilter->SetInput (mesh);
290+ #else
291+ transformPolyDataFilter->SetInputData (mesh);
292+ #endif
293+ transformPolyDataFilter->SetTransform (outputLabelmapGeometryTransform);
263294 // Create new output image
264295 mBinaryImage = vtkSmartPointer<vtkImageData>::New ();
265296#if VTK_MAJOR_VERSION <= 5
@@ -281,11 +312,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
281312
282313 // Extrude
283314 vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New ();
284- #if VTK_MAJOR_VERSION <= 5
285- extrude->SetInput (mesh);
286- #else
287- extrude->SetInputData (mesh);
288- #endif
315+ extrude->SetInputConnection (transformPolyDataFilter->GetOutputPort ());
289316 // /We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
290317 extrude->SetVector (0 , 0 , -mSpacing [2 ]);
291318
@@ -295,11 +322,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
295322 // http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
296323 sts->SetTolerance (0 );
297324 sts->SetInformationInput (mBinaryImage );
298- #if VTK_MAJOR_VERSION <= 5
299- sts->SetInput (extrude->GetOutput ());
300- #else
301325 sts->SetInputConnection (extrude->GetOutputPort (0 ));
302- #endif
303326 // sts->SetInput(mesh);
304327
305328 vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New ();
@@ -316,22 +339,26 @@ void clitk::DicomRTStruct2ImageFilter::Update()
316339 stencil->ReverseStencilOn ();
317340 stencil->Update ();
318341
319- /*
320- vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
321- w->SetInput(stencil->GetOutput());
322- w->SetFileName("binary2.mhd");
323- w->Write();
324- */
325-
326342 mBinaryImage ->ShallowCopy (stencil->GetOutput ());
327343
344+ vvImage::Pointer vvBinaryImage = vvImage::New ();
345+ vtkSmartPointer<vtkTransform> vvBinaryImageT = vtkSmartPointer<vtkTransform>::New ();
346+ vvBinaryImageT->SetMatrix (mTransformMatrix );
347+ vvBinaryImage->AddVtkImage (mBinaryImage , vvBinaryImageT);
348+
328349 if (mWriteOutput ) {
329- typedef itk::Image<unsigned char , 3 > ImageType;
330- typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
331- ConnectorType::Pointer connector = ConnectorType::New ();
332- connector->SetInput (GetOutput ());
333- connector->Update ();
334- clitk::writeImage<ImageType>(connector->GetOutput (), mOutputFilename );
350+ // typedef itk::Image<unsigned char, 3> ImageType;
351+ // typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
352+ // ConnectorType::Pointer connector = ConnectorType::New();
353+ // connector->SetInput(GetOutput());
354+ // connector->Update();
355+ // clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
356+ vvImageWriter::Pointer writer = vvImageWriter::New ();
357+ writer->SetInput (vvBinaryImage);
358+ if (!vvBinaryImage->GetTransform ().empty ())
359+ writer->SetSaveTransform (true );
360+ writer->SetOutputFileName (mOutputFilename );
361+ writer->Update ();
335362 }
336363}
337364// --------------------------------------------------------------------
@@ -341,7 +368,10 @@ void clitk::DicomRTStruct2ImageFilter::Update()
341368// --------------------------------------------------------------------
342369vtkImageData * clitk::DicomRTStruct2ImageFilter::GetOutput ()
343370{
344- assert (mBinaryImage );
371+ // assert(mBinaryImage);
372+ if (mBinaryImage == NULL ) {
373+ FATAL (" The binary RTStruct image is NULL" );
374+ }
345375 return mBinaryImage ;
346376}
347377// --------------------------------------------------------------------
0 commit comments