1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
3 Main authors : XX XX XX
6 - University of LYON http://www.universite-lyon.fr/
7 - Léon Bérard cancer center http://www.centreleonberard.fr
8 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the copyright notices for more information.
14 It is distributed under dual licence
15 - BSD http://www.opensource.org/licenses/bsd-license.php
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
18 =========================================================================*/
25 #include "clitkImage2DicomRTStructFilter.h"
26 #include "clitkBinaryImageToMeshFilter.h"
27 #include "clitkImageCommon.h"
28 #include "vvFromITK.h"
31 #include <vtkPolyDataToImageStencil.h>
32 #include <vtkSmartPointer.h>
33 #include <vtkImageStencil.h>
34 #include <vtkLinearExtrusionFilter.h>
35 #include <vtkMetaImageWriter.h>
36 #include <vtkImageData.h>
39 #include "vtkPolyDataMapper.h"
40 #include "vtkPolyDataMapper2D.h"
41 #include "vtkRenderWindowInteractor.h"
42 #include "vtkPolyDataReader.h"
43 #include "vtkRenderWindow.h"
44 #include "vtkRenderer.h"
45 #include "vtkCamera.h"
46 #include "vtkProperty.h"
47 #include "vtkProperty2D.h"
48 #include <vtksys/SystemTools.hxx>
52 #include <itkVTKImageToImageFilter.h>
55 #include <vtkRTStructSetProperties.h>
56 #include <vtkGDCMPolyDataReader.h>
57 #include <vtkGDCMPolyDataWriter.h>
59 //--------------------------------------------------------------------
60 template<class PixelType>
61 clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
63 m_StructureSetFilename = "";
65 m_OutputFilename = "default-output.dcm";
66 m_ThresholdValue = 0.5;
67 m_SkipInitialStructuresFlag = false;
69 //--------------------------------------------------------------------
72 //--------------------------------------------------------------------
73 template<class PixelType>
74 clitk::Image2DicomRTStructFilter<PixelType>::~Image2DicomRTStructFilter()
77 //--------------------------------------------------------------------
80 //--------------------------------------------------------------------
81 template<class PixelType>
83 clitk::Image2DicomRTStructFilter<PixelType>::SetROIType(std::string type)
87 //--------------------------------------------------------------------
90 //--------------------------------------------------------------------
91 template<class PixelType>
92 void clitk::Image2DicomRTStructFilter<PixelType>::Update()
94 // Check this is a RT-Struct
95 gdcm::Reader gdcm_reader;
96 gdcm_reader.SetFileName(m_StructureSetFilename.c_str());
97 if (!gdcm_reader.Read()) {
98 clitkExceptionMacro("Error could not open the file '" << m_StructureSetFilename << std::endl);
100 gdcm::MediaStorage ms;
101 ms.SetFromFile(gdcm_reader.GetFile());
102 if (ms != gdcm::MediaStorage::RTStructureSetStorage) {
103 clitkExceptionMacro("File '" << m_StructureSetFilename << "' is not a DICOM-RT-Struct file." << std::endl);
107 vtkSmartPointer<vtkGDCMPolyDataReader> reader = vtkGDCMPolyDataReader::New();
108 reader->SetFileName(m_StructureSetFilename.c_str());
112 vtkRTStructSetProperties * p = reader->GetRTStructSetProperties();
113 if (GetVerboseFlag()) {
114 std::cout << "Number of structures in the dicom-rt-struct : "
115 << p->GetNumberOfStructureSetROIs() << std::endl;
118 // number of additional contours
119 int m = m_InputFilenames.size();
122 vtkGDCMPolyDataWriter * writer = vtkGDCMPolyDataWriter::New();
123 int numMasks = reader->GetNumberOfOutputPorts() + m;
125 if (m_SkipInitialStructuresFlag) {
129 writer->SetNumberOfInputPorts(numMasks);
130 writer->SetFileName(m_OutputFilename.c_str());
131 writer->SetMedicalImageProperties(reader->GetMedicalImageProperties());
133 // List of already present rois
134 vtkStringArray* roiNames = vtkStringArray::New();
135 vtkStringArray* roiAlgorithms = vtkStringArray::New();
136 vtkStringArray* roiTypes = vtkStringArray::New();
137 roiNames->SetNumberOfValues(numMasks);
138 roiAlgorithms->SetNumberOfValues(numMasks);
139 roiTypes->SetNumberOfValues(numMasks);
141 // Convert the image into a mesh
142 std::vector<vtkSmartPointer<vtkPolyData> > meshes;
143 std::vector<std::string> m_ROINames;
145 m_ROINames.resize(m);
146 for(unsigned int i=0; i<m; i++) {
149 // typedef float PixelType;
150 //typedef itk::Image<PixelType, 3> ImageType;
151 ImagePointer input = clitk::readImage<ImageType>(m_InputFilenames[i], false);
153 std::ostringstream oss;
154 oss << vtksys::SystemTools::
155 GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(m_InputFilenames[i]));
156 std::string name = oss.str();
157 m_ROINames[i] = name;
160 typedef clitk::BinaryImageToMeshFilter<ImageType> BinaryImageToMeshFilterType;
161 typename BinaryImageToMeshFilterType::Pointer convert = BinaryImageToMeshFilterType::New();
162 convert->SetThresholdValue(m_ThresholdValue);
163 convert->SetInput(input);
165 meshes[i] = convert->GetOutputMesh();
166 if (GetVerboseFlag()) {
167 std::cout << "Mesh has " << meshes[i]->GetNumberOfLines() << " lines." << std::endl;
171 // debug mesh write FIXME
172 vtkSmartPointer<vtkPolyDataWriter> wr = vtkSmartPointer<vtkPolyDataWriter>::New();
173 wr->SetInputConnection(convert->GetOutputPort()); //psurface->GetOutputPort()
174 wr->SetFileName("bidon.obj");
180 // Copy previous contours
181 for (unsigned int i = 0; i < numMasks-m; ++i) {
182 #if VTK_MAJOR_VERSION <= 5
183 writer->SetInput(i, reader->GetOutput(i));
185 writer->SetInputData(i, reader->GetOutput(i));
187 std::string theString = reader->GetRTStructSetProperties()->GetStructureSetROIName(i);
188 roiNames->InsertValue(i, theString);
189 theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i);
190 roiAlgorithms->InsertValue(i, theString);
191 theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i);
192 roiTypes->InsertValue(i, theString);
196 for (unsigned int i = numMasks-m; i < numMasks; ++i) {
197 #if VTK_MAJOR_VERSION <= 5
198 writer->SetInput(i, meshes[i-numMasks+m]);
200 writer->SetInputData(i, meshes[i-numMasks+m]);
202 roiNames->InsertValue(i, m_ROINames[i-numMasks+m]);
203 roiAlgorithms->InsertValue(i, "CLITK_CREATED");
204 roiTypes->InsertValue(i, m_ROIType);
209 vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
210 cubeMapper->SetInput( mesh );
211 cubeMapper->SetScalarRange(0,7);
212 vtkActor *cubeActor = vtkActor::New();
213 cubeActor->SetMapper(cubeMapper);
214 vtkProperty * property = cubeActor->GetProperty();
215 property->SetRepresentationToWireframe();
217 vtkRenderer *renderer = vtkRenderer::New();
218 vtkRenderWindow *renWin = vtkRenderWindow::New();
219 renWin->AddRenderer(renderer);
221 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
222 iren->SetRenderWindow(renWin);
224 renderer->AddActor(cubeActor);
225 renderer->ResetCamera();
226 renderer->SetBackground(1,1,1);
228 renWin->SetSize(300,300);
235 // Write (need to read dicom for slice id)
236 vtkRTStructSetProperties* theProperties = vtkRTStructSetProperties::New();
237 writer->SetRTStructSetProperties(theProperties);
238 if (GetVerboseFlag()) {
239 std::cout << "Looking for dicom info, study instance "
240 << p->GetStudyInstanceUID() << std::endl;
242 writer->InitializeRTStructSet(m_DicomFolder,
243 reader->GetRTStructSetProperties()->GetStructureSetLabel(),
244 reader->GetRTStructSetProperties()->GetStructureSetName(),
245 roiTypes, roiAlgorithms, roiTypes);
250 roiAlgorithms->Delete();
253 //--------------------------------------------------------------------