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 =========================================================================*/
20 #include "clitkDicomRT_Contour.h"
21 #include <vtkCellArray.h>
23 #if GDCM_MAJOR_VERSION >= 2
24 #include "gdcmAttribute.h"
28 //--------------------------------------------------------------------
29 clitk::DicomRT_Contour::DicomRT_Contour()
31 mMeshIsUpToDate = false;
35 //--------------------------------------------------------------------
38 //--------------------------------------------------------------------
39 clitk::DicomRT_Contour::~DicomRT_Contour()
43 //--------------------------------------------------------------------
47 //--------------------------------------------------------------------
48 void clitk::DicomRT_Contour::Print(std::ostream & os) const
50 DD("TODO : print Contours");
52 //--------------------------------------------------------------------
55 //--------------------------------------------------------------------
56 #if GDCM_MAJOR_VERSION >= 2
57 void clitk::DicomRT_Contour::UpdateDicomItem()
59 DD("DicomRT_Contour::UpdateDicomItem");
61 gdcm::DataSet & nestedds = mItem->GetNestedDataSet();
63 //NON CONSIDER CONTOUR ITEM NOT SEQ ITEM ?
65 // Contour type [Contour Geometric Type]
66 gdcm::Attribute<0x3006,0x0042> contgeotype;
67 contgeotype.SetFromDataSet( nestedds );
69 // Number of points [Number of Contour Points]
70 gdcm::Attribute<0x3006,0x0046> numcontpoints;
71 numcontpoints.SetFromDataSet( nestedds );
73 mNbOfPoints = numcontpoints.GetValue();
76 // Contour dicom values from DataPoints
77 //ComputeDataPointsFromMesh();
78 uint nb = mData->GetNumberOfPoints();
79 std::vector<double> points;
80 points.resize(mNbOfPoints*3);
81 for(unsigned int i=0; i<nb; i++) {
82 double * p = mData->GetPoint(i);
85 points[i*3+1] = p[2]-0.5;
89 gdcm::Attribute<0x3006,0x0050> at;
90 gdcm::Tag tcontourdata(0x3006,0x0050);
91 gdcm::DataElement contourdata = nestedds.GetDataElement( tcontourdata );
92 at.SetFromDataElement( contourdata );
95 at.SetValues(&points[0], points.size());
96 DD(at.GetValues()[0]);
99 nestedds.Replace(at.GetAsDataElement());
102 // Change Number of points [Number of Contour Points]
103 numcontpoints.SetValue(nb);
104 nestedds.Replace(numcontpoints.GetAsDataElement());
107 gdcm::DataElement aa = nestedds.GetDataElement( tcontourdata );
108 at.SetFromDataElement( aa );
109 const double* bb = at.GetValues();
114 //--------------------------------------------------------------------
117 //--------------------------------------------------------------------
118 #if GDCM_MAJOR_VERSION >= 2
119 bool clitk::DicomRT_Contour::Read(gdcm::Item * item)
123 const gdcm::DataSet& nestedds2 = item->GetNestedDataSet();
125 // Contour type [Contour Geometric Type]
126 gdcm::Attribute<0x3006,0x0042> contgeotype;
127 contgeotype.SetFromDataSet( nestedds2 );
129 if (contgeotype.GetValue() != "CLOSED_PLANAR " && contgeotype.GetValue() != "POINT ") { ///WARNING to the space after the name ...
130 //std::cerr << "Skip this contour : type=" << mType << std::endl;
133 if (contgeotype.GetValue() == "POINT ") {
134 std::cerr << "Warning: POINT type not fully supported. (don't use GetMesh() with this!)"
138 gdcm::Attribute<0x3006,0x0046> numcontpoints;
139 numcontpoints.SetFromDataSet( nestedds2 );
140 // Number of points [Number of Contour Points]
141 mNbOfPoints = numcontpoints.GetValue();
144 gdcm::Attribute<0x3006,0x0050> at;
145 gdcm::Tag tcontourdata(0x3006,0x0050);
146 const gdcm::DataElement & contourdata = nestedds2.GetDataElement( tcontourdata );
147 at.SetFromDataElement( contourdata );
148 const double* points = at.GetValues();
149 // unsigned int npts = at.GetNumberOfValues() / 3;
150 assert(at.GetNumberOfValues() == static_cast<unsigned int>(mNbOfPoints)*3);
153 mData = vtkSmartPointer<vtkPoints>::New();
154 mData->SetDataTypeToDouble();
155 mData->SetNumberOfPoints(mNbOfPoints);
156 for(unsigned int i=0; i<mNbOfPoints; i++) {
159 p[1] = points[i*3+1];
160 p[2] = points[i*3+2]+0.5;
161 mData->SetPoint(i, p);
162 if (mZ == -1) mZ = p[2];
163 if (std::fabs(p[2] - mZ) > mTolerance) {
167 std::cout << "ERROR ! contour not in the same slice" << std::endl;
176 bool clitk::DicomRT_Contour::Read(gdcm::SQItem * item)
179 // Contour type [Contour Geometric Type]
180 mType = item->GetEntryValue(0x3006,0x0042);
182 if (mType != "CLOSED_PLANAR " && mType != "POINT ") { ///WARNING to the space after the name ...
183 //std::cerr << "Skip this contour : type=" << mType << std::endl;
186 if (mType == "POINT ") {
187 std::cerr << "Warning: POINT type not fully supported. (don't use GetMesh() with this!)"
191 // Number of points [Number of Contour Points]
192 mNbOfPoints = parse_value<int>(item->GetEntryValue(0x3006,0x0046));
195 // Read values [Contour Data]
196 std::vector<float> points = parse_string<float>(item->GetEntryValue(0x3006,0x0050),'\\');
197 assert(points.size() == static_cast<unsigned int>(mNbOfPoints)*3);
200 mData = vtkSmartPointer<vtkPoints>::New();
201 mData->SetDataTypeToDouble();
202 mData->SetNumberOfPoints(mNbOfPoints);
203 for(unsigned int i=0; i<mNbOfPoints; i++) {
206 p[1] = points[i*3+1];
207 p[2] = points[i*3+2]+0.5;
208 mData->SetPoint(i, p);
209 if (mZ == -1) mZ = p[2];
210 if (std::fabs(p[2] - mZ) > mTolerance) {
214 std::cout << "ERROR ! contour not in the same slice" << std::endl;
222 //--------------------------------------------------------------------
225 //--------------------------------------------------------------------
226 vtkPolyData * clitk::DicomRT_Contour::GetMesh()
228 if (!mMeshIsUpToDate) {
229 ComputeMeshFromDataPoints();
233 //--------------------------------------------------------------------
236 //--------------------------------------------------------------------
237 void clitk::DicomRT_Contour::SetMesh(vtkPolyData * mesh)
241 //--------------------------------------------------------------------
244 //--------------------------------------------------------------------
245 void clitk::DicomRT_Contour::SetTransformMatrix(vtkMatrix4x4* matrix)
247 mTransformMatrix = matrix;
249 //--------------------------------------------------------------------
250 //--------------------------------------------------------------------
251 double clitk::DicomRT_Contour::GetTolerance()
255 //--------------------------------------------------------------------
256 void clitk::DicomRT_Contour::SetTolerance(double tol)
260 //--------------------------------------------------------------------
261 //--------------------------------------------------------------------
262 void clitk::DicomRT_Contour::ComputeMeshFromDataPoints()
264 // DD("ComputeMesh Contour");
265 mMesh = vtkSmartPointer<vtkPolyData>::New();
266 mMesh->Allocate(); //for cell structures
267 mPoints = vtkSmartPointer<vtkPoints>::New();
268 mMesh->SetPoints(mPoints);
270 for (unsigned int idx=0 ; idx<mNbOfPoints ; idx++) {
272 //for (unsigned int j=0 ; j<3; ++j)
273 // pointIn[j] = mData->GetPoint(idx)[j];
275 /*double pointOut[4];
276 mTransformMatrix->MultiplyPoint(pointIn, pointOut);
277 std::cout << pointOut[0] << " " << pointOut[1] << " " << pointOut[2] << " " << pointOut[3] << std::endl;
278 mMesh->GetPoints()->InsertNextPoint(pointOut[0],
281 mMesh->GetPoints()->InsertNextPoint(mData->GetPoint(idx)[0],
282 mData->GetPoint(idx)[1],
283 mData->GetPoint(idx)[2]);
284 //std::cout << mData->GetPoint(idx)[0] << " " << mData->GetPoint(idx)[1] << " " << mData->GetPoint(idx)[2] << std::endl;
286 ids[1]=(ids[0]+1) % mNbOfPoints; //0-1,1-2,...,n-1-0
287 mMesh->GetLines()->InsertNextCell(2,ids);
289 //std::cout << std::endl;
290 mMeshIsUpToDate = true;
292 //--------------------------------------------------------------------
295 //--------------------------------------------------------------------
296 void clitk::DicomRT_Contour::ComputeDataPointsFromMesh()
298 DD("ComputeDataPointsFromMesh");
303 mMesh = vtkSmartPointer<vtkPolyData>::New();
304 mMesh->Allocate(); //for cell structures
305 mPoints = vtkSmartPointer<vtkPoints>::New();
306 mMesh->SetPoints(mPoints);
308 for (unsigned int idx=0 ; idx<mNbOfPoints ; idx++) {
309 mMesh->GetPoints()->InsertNextPoint(mData->GetPoint(idx)[0],
310 mData->GetPoint(idx)[1],
311 mData->GetPoint(idx)[2]);
313 ids[1]=(ids[0]+1) % mNbOfPoints; //0-1,1-2,...,n-1-0
314 mMesh->GetLines()->InsertNextCell(2,ids);
316 mMeshIsUpToDate = true;
319 //--------------------------------------------------------------------