Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/DicomStructureSet.cpp @ 844:84cd55245e2d
Merge
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Fri, 14 Jun 2019 12:16:38 +0200 |
parents | 266e2b0b9abc |
children | 32eaf4929b08 |
rev | line source |
---|---|
0 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
47 | 8 * modify it under the terms of the GNU Affero General Public License |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
0 | 11 * |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
47 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
0 | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | |
20 | |
21 | |
22 #include "DicomStructureSet.h" | |
23 | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
24 #include "../Toolbox/GeometryToolbox.h" |
0 | 25 |
212
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
26 #include <Core/Logging.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
27 #include <Core/OrthancException.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
28 #include <Plugins/Samples/Common/FullOrthancDataset.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
29 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
113
2eca030792aa
using the Orthanc Framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
30 |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
31 #include <limits> |
0 | 32 #include <stdio.h> |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
33 #include <boost/geometry.hpp> |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
34 #include <boost/geometry/geometries/point_xy.hpp> |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
35 #include <boost/geometry/geometries/polygon.hpp> |
137 | 36 #include <boost/geometry/multi/geometries/multi_polygon.hpp> |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
37 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
38 typedef boost::geometry::model::d2::point_xy<double> BoostPoint; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
39 typedef boost::geometry::model::polygon<BoostPoint> BoostPolygon; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
40 typedef boost::geometry::model::multi_polygon<BoostPolygon> BoostMultiPolygon; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
41 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
42 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
43 static void Union(BoostMultiPolygon& output, |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
44 std::vector<BoostPolygon>& input) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
45 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
46 for (size_t i = 0; i < input.size(); i++) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
47 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
48 boost::geometry::correct(input[i]); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
49 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
50 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
51 if (input.size() == 0) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
52 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
53 output.clear(); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
54 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
55 else if (input.size() == 1) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
56 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
57 output.resize(1); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
58 output[0] = input[0]; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
59 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
60 else |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
61 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
62 boost::geometry::union_(input[0], input[1], output); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
63 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
64 for (size_t i = 0; i < input.size(); i++) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
65 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
66 BoostMultiPolygon tmp; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
67 boost::geometry::union_(output, input[i], tmp); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
68 output = tmp; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
69 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
70 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
71 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
72 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
73 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
74 static BoostPolygon CreateRectangle(float x1, float y1, |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
75 float x2, float y2) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
76 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
77 BoostPolygon r; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
78 boost::geometry::append(r, BoostPoint(x1, y1)); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
79 boost::geometry::append(r, BoostPoint(x1, y2)); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
80 boost::geometry::append(r, BoostPoint(x2, y2)); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
81 boost::geometry::append(r, BoostPoint(x2, y1)); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
82 return r; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
83 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
84 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
85 |
0 | 86 |
87 namespace OrthancStone | |
88 { | |
32 | 89 static const OrthancPlugins::DicomTag DICOM_TAG_CONTOUR_GEOMETRIC_TYPE(0x3006, 0x0042); |
90 static const OrthancPlugins::DicomTag DICOM_TAG_CONTOUR_IMAGE_SEQUENCE(0x3006, 0x0016); | |
91 static const OrthancPlugins::DicomTag DICOM_TAG_CONTOUR_SEQUENCE(0x3006, 0x0040); | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
92 static const OrthancPlugins::DicomTag DICOM_TAG_CONTOUR_DATA(0x3006, 0x0050); |
32 | 93 static const OrthancPlugins::DicomTag DICOM_TAG_NUMBER_OF_CONTOUR_POINTS(0x3006, 0x0046); |
94 static const OrthancPlugins::DicomTag DICOM_TAG_REFERENCED_SOP_INSTANCE_UID(0x0008, 0x1155); | |
95 static const OrthancPlugins::DicomTag DICOM_TAG_ROI_CONTOUR_SEQUENCE(0x3006, 0x0039); | |
96 static const OrthancPlugins::DicomTag DICOM_TAG_ROI_DISPLAY_COLOR(0x3006, 0x002a); | |
97 static const OrthancPlugins::DicomTag DICOM_TAG_ROI_NAME(0x3006, 0x0026); | |
98 static const OrthancPlugins::DicomTag DICOM_TAG_RT_ROI_INTERPRETED_TYPE(0x3006, 0x00a4); | |
99 static const OrthancPlugins::DicomTag DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE(0x3006, 0x0080); | |
100 static const OrthancPlugins::DicomTag DICOM_TAG_STRUCTURE_SET_ROI_SEQUENCE(0x3006, 0x0020); | |
0 | 101 |
102 | |
103 static uint8_t ConvertColor(double v) | |
104 { | |
105 if (v < 0) | |
106 { | |
107 return 0; | |
108 } | |
109 else if (v >= 255) | |
110 { | |
111 return 255; | |
112 } | |
113 else | |
114 { | |
115 return static_cast<uint8_t>(v); | |
116 } | |
117 } | |
118 | |
119 | |
118
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
120 static bool ParseVector(Vector& target, |
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
121 const OrthancPlugins::IDicomDataset& dataset, |
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
122 const OrthancPlugins::DicomPath& tag) |
0 | 123 { |
118
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
124 std::string value; |
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
125 return (dataset.GetStringValue(value, tag) && |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
126 LinearAlgebra::ParseVector(target, value)); |
118
a4d0b6c82b29
using Orthanc::DicomMap instead of OrthancPlugins::DicomDatasetReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
127 } |
0 | 128 |
129 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
130 void DicomStructureSet::Polygon::CheckPoint(const Vector& v) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
131 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
132 if (hasSlice_) |
0 | 133 { |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
134 if (!LinearAlgebra::IsNear(GeometryToolbox::ProjectAlongNormal(v, geometry_.GetNormal()), |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
135 projectionAlongNormal_, |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
136 sliceThickness_ / 2.0 /* in mm */)) |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
137 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
138 LOG(ERROR) << "This RT-STRUCT contains a point that is off the slice of its instance"; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
139 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
140 } |
0 | 141 } |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
142 } |
0 | 143 |
144 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
145 void DicomStructureSet::Polygon::AddPoint(const Vector& v) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
146 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
147 CheckPoint(v); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
148 points_.push_back(v); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
149 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
150 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
151 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
152 bool DicomStructureSet::Polygon::UpdateReferencedSlice(const ReferencedSlices& slices) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
153 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
154 if (hasSlice_) |
0 | 155 { |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
156 return true; |
32 | 157 } |
158 else | |
159 { | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
160 ReferencedSlices::const_iterator it = slices.find(sopInstanceUid_); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
161 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
162 if (it == slices.end()) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
163 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
164 return false; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
165 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
166 else |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
167 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
168 const CoordinateSystem3D& geometry = it->second.geometry_; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
169 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
170 hasSlice_ = true; |
131 | 171 geometry_ = geometry; |
172 projectionAlongNormal_ = GeometryToolbox::ProjectAlongNormal(geometry.GetOrigin(), geometry.GetNormal()); | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
173 sliceThickness_ = it->second.thickness_; |
0 | 174 |
131 | 175 extent_.Reset(); |
176 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
177 for (Points::const_iterator it = points_.begin(); it != points_.end(); ++it) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
178 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
179 CheckPoint(*it); |
131 | 180 |
181 double x, y; | |
182 geometry.ProjectPoint(x, y, *it); | |
183 extent_.AddPoint(x, y); | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
184 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
185 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
186 return true; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
187 } |
0 | 188 } |
189 } | |
190 | |
191 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
192 bool DicomStructureSet::Polygon::IsOnSlice(const CoordinateSystem3D& slice) const |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
193 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
194 bool isOpposite; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
195 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
196 if (points_.empty() || |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
197 !hasSlice_ || |
131 | 198 !GeometryToolbox::IsParallelOrOpposite(isOpposite, slice.GetNormal(), geometry_.GetNormal())) |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
199 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
200 return false; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
201 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
202 |
131 | 203 double d = GeometryToolbox::ProjectAlongNormal(slice.GetOrigin(), geometry_.GetNormal()); |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
204 |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
205 return (LinearAlgebra::IsNear(d, projectionAlongNormal_, |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
206 sliceThickness_ / 2.0)); |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
207 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
208 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
209 |
131 | 210 bool DicomStructureSet::Polygon::Project(double& x1, |
211 double& y1, | |
212 double& x2, | |
213 double& y2, | |
214 const CoordinateSystem3D& slice) const | |
215 { | |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
216 // TODO Optimize this method using a sweep-line algorithm for polygons |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
217 |
131 | 218 if (!hasSlice_ || |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
219 points_.size() <= 1) |
131 | 220 { |
221 return false; | |
222 } | |
223 | |
224 double x, y; | |
225 geometry_.ProjectPoint(x, y, slice.GetOrigin()); | |
226 | |
227 bool isOpposite; | |
228 if (GeometryToolbox::IsParallelOrOpposite | |
229 (isOpposite, slice.GetNormal(), geometry_.GetAxisY())) | |
230 { | |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
231 if (y < extent_.GetY1() || |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
232 y > extent_.GetY2()) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
233 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
234 // The polygon does not intersect the input slice |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
235 return false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
236 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
237 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
238 bool isFirst = true; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
239 double xmin = std::numeric_limits<double>::infinity(); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
240 double xmax = -std::numeric_limits<double>::infinity(); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
241 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
242 double prevX, prevY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
243 geometry_.ProjectPoint(prevX, prevY, points_[points_.size() - 1]); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
244 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
245 for (size_t i = 0; i < points_.size(); i++) |
131 | 246 { |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
247 // Reference: ../../Resources/Computations/IntersectSegmentAndHorizontalLine.py |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
248 double curX, curY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
249 geometry_.ProjectPoint(curX, curY, points_[i]); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
250 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
251 if ((prevY < y && curY > y) || |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
252 (prevY > y && curY < y)) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
253 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
254 double p = (curX * prevY - curY * prevX + y * (prevX - curX)) / (prevY - curY); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
255 xmin = std::min(xmin, p); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
256 xmax = std::max(xmax, p); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
257 isFirst = false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
258 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
259 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
260 prevX = curX; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
261 prevY = curY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
262 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
263 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
264 if (isFirst) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
265 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
266 return false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
267 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
268 else |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
269 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
270 Vector p1 = (geometry_.MapSliceToWorldCoordinates(xmin, y) + |
131 | 271 sliceThickness_ / 2.0 * geometry_.GetNormal()); |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
272 Vector p2 = (geometry_.MapSliceToWorldCoordinates(xmax, y) - |
131 | 273 sliceThickness_ / 2.0 * geometry_.GetNormal()); |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
274 |
131 | 275 slice.ProjectPoint(x1, y1, p1); |
276 slice.ProjectPoint(x2, y2, p2); | |
277 return true; | |
278 } | |
279 } | |
280 else if (GeometryToolbox::IsParallelOrOpposite | |
281 (isOpposite, slice.GetNormal(), geometry_.GetAxisX())) | |
282 { | |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
283 if (x < extent_.GetX1() || |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
284 x > extent_.GetX2()) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
285 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
286 return false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
287 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
288 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
289 bool isFirst = true; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
290 double ymin = std::numeric_limits<double>::infinity(); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
291 double ymax = -std::numeric_limits<double>::infinity(); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
292 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
293 double prevX, prevY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
294 geometry_.ProjectPoint(prevX, prevY, points_[points_.size() - 1]); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
295 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
296 for (size_t i = 0; i < points_.size(); i++) |
131 | 297 { |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
298 // Reference: ../../Resources/Computations/IntersectSegmentAndVerticalLine.py |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
299 double curX, curY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
300 geometry_.ProjectPoint(curX, curY, points_[i]); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
301 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
302 if ((prevX < x && curX > x) || |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
303 (prevX > x && curX < x)) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
304 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
305 double p = (curX * prevY - curY * prevX + x * (curY - prevY)) / (curX - prevX); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
306 ymin = std::min(ymin, p); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
307 ymax = std::max(ymax, p); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
308 isFirst = false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
309 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
310 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
311 prevX = curX; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
312 prevY = curY; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
313 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
314 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
315 if (isFirst) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
316 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
317 return false; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
318 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
319 else |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
320 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
321 Vector p1 = (geometry_.MapSliceToWorldCoordinates(x, ymin) + |
131 | 322 sliceThickness_ / 2.0 * geometry_.GetNormal()); |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
323 Vector p2 = (geometry_.MapSliceToWorldCoordinates(x, ymax) - |
131 | 324 sliceThickness_ / 2.0 * geometry_.GetNormal()); |
325 | |
326 slice.ProjectPoint(x1, y1, p1); | |
327 slice.ProjectPoint(x2, y2, p2); | |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
328 |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
329 // TODO WHY THIS??? |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
330 y1 = -y1; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
331 y2 = -y2; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
332 |
131 | 333 return true; |
334 } | |
335 } | |
336 else | |
337 { | |
338 // Should not happen | |
339 return false; | |
340 } | |
341 } | |
342 | |
343 | |
0 | 344 const DicomStructureSet::Structure& DicomStructureSet::GetStructure(size_t index) const |
345 { | |
346 if (index >= structures_.size()) | |
347 { | |
125 | 348 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0 | 349 } |
350 | |
351 return structures_[index]; | |
352 } | |
353 | |
354 | |
125 | 355 DicomStructureSet::Structure& DicomStructureSet::GetStructure(size_t index) |
0 | 356 { |
125 | 357 if (index >= structures_.size()) |
358 { | |
359 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
0 | 360 } |
361 | |
362 return structures_[index]; | |
363 } | |
364 | |
365 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
366 DicomStructureSet::DicomStructureSet(const OrthancPlugins::FullOrthancDataset& tags) |
0 | 367 { |
738
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
368 OrthancPlugins::DicomDatasetReader reader(tags); |
32 | 369 |
370 size_t count, tmp; | |
371 if (!tags.GetSequenceSize(count, DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE) || | |
372 !tags.GetSequenceSize(tmp, DICOM_TAG_ROI_CONTOUR_SEQUENCE) || | |
373 tmp != count || | |
374 !tags.GetSequenceSize(tmp, DICOM_TAG_STRUCTURE_SET_ROI_SEQUENCE) || | |
375 tmp != count) | |
0 | 376 { |
377 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
378 } | |
379 | |
32 | 380 structures_.resize(count); |
381 for (size_t i = 0; i < count; i++) | |
382 { | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
383 structures_[i].interpretation_ = reader.GetStringValue |
738
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
384 (OrthancPlugins::DicomPath(DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE, i, |
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
385 DICOM_TAG_RT_ROI_INTERPRETED_TYPE), |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
386 "No interpretation"); |
0 | 387 |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
388 structures_[i].name_ = reader.GetStringValue |
738
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
389 (OrthancPlugins::DicomPath(DICOM_TAG_STRUCTURE_SET_ROI_SEQUENCE, i, |
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
390 DICOM_TAG_ROI_NAME), |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
391 "No interpretation"); |
0 | 392 |
393 Vector color; | |
738
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
394 if (ParseVector(color, tags, OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
395 DICOM_TAG_ROI_DISPLAY_COLOR)) && |
32 | 396 color.size() == 3) |
0 | 397 { |
32 | 398 structures_[i].red_ = ConvertColor(color[0]); |
399 structures_[i].green_ = ConvertColor(color[1]); | |
400 structures_[i].blue_ = ConvertColor(color[2]); | |
401 } | |
402 else | |
403 { | |
404 structures_[i].red_ = 255; | |
405 structures_[i].green_ = 0; | |
406 structures_[i].blue_ = 0; | |
0 | 407 } |
408 | |
32 | 409 size_t countSlices; |
738
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
410 if (!tags.GetSequenceSize(countSlices, OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
8e31b174ab26
removing using namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
516
diff
changeset
|
411 DICOM_TAG_CONTOUR_SEQUENCE))) |
32 | 412 { |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
118
diff
changeset
|
413 countSlices = 0; |
32 | 414 } |
0 | 415 |
841
266e2b0b9abc
better error reporting in DicomStructureSetLoader + fixed POST request logic
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
416 LOG(INFO) << "New RT structure: \"" << structures_[i].name_ |
0 | 417 << "\" with interpretation \"" << structures_[i].interpretation_ |
32 | 418 << "\" containing " << countSlices << " slices (color: " |
0 | 419 << static_cast<int>(structures_[i].red_) << "," |
420 << static_cast<int>(structures_[i].green_) << "," | |
421 << static_cast<int>(structures_[i].blue_) << ")"; | |
422 | |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
423 // These temporary variables avoid allocating many vectors in the loop below |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
424 OrthancPlugins::DicomPath countPointsPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
425 DICOM_TAG_CONTOUR_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
426 DICOM_TAG_NUMBER_OF_CONTOUR_POINTS); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
427 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
428 OrthancPlugins::DicomPath geometricTypePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
429 DICOM_TAG_CONTOUR_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
430 DICOM_TAG_CONTOUR_GEOMETRIC_TYPE); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
431 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
432 OrthancPlugins::DicomPath imageSequencePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
433 DICOM_TAG_CONTOUR_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
434 DICOM_TAG_CONTOUR_IMAGE_SEQUENCE); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
435 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
436 OrthancPlugins::DicomPath referencedInstancePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
437 DICOM_TAG_CONTOUR_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
438 DICOM_TAG_CONTOUR_IMAGE_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
439 DICOM_TAG_REFERENCED_SOP_INSTANCE_UID); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
440 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
441 OrthancPlugins::DicomPath contourDataPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
442 DICOM_TAG_CONTOUR_SEQUENCE, 0, |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
443 DICOM_TAG_CONTOUR_DATA); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
444 |
32 | 445 for (size_t j = 0; j < countSlices; j++) |
0 | 446 { |
32 | 447 unsigned int countPoints; |
0 | 448 |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
449 countPointsPath.SetPrefixIndex(1, j); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
450 if (!reader.GetUnsignedIntegerValue(countPoints, countPointsPath)) |
32 | 451 { |
452 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
453 } | |
454 | |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
118
diff
changeset
|
455 //LOG(INFO) << "Parsing slice containing " << countPoints << " vertices"; |
0 | 456 |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
457 geometricTypePath.SetPrefixIndex(1, j); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
458 std::string type = reader.GetMandatoryStringValue(geometricTypePath); |
32 | 459 if (type != "CLOSED_PLANAR") |
0 | 460 { |
173
6b0411ac843a
fix captain rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
159
diff
changeset
|
461 LOG(WARNING) << "Ignoring contour with geometry type: " << type; |
6b0411ac843a
fix captain rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
159
diff
changeset
|
462 continue; |
0 | 463 } |
464 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
465 size_t size; |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
466 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
467 imageSequencePath.SetPrefixIndex(1, j); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
468 if (!tags.GetSequenceSize(size, imageSequencePath) || |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
469 size != 1) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
470 { |
0 | 471 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
472 } | |
473 | |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
474 referencedInstancePath.SetPrefixIndex(1, j); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
475 std::string sopInstanceUid = reader.GetMandatoryStringValue(referencedInstancePath); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
476 |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
477 contourDataPath.SetPrefixIndex(1, j); |
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
738
diff
changeset
|
478 std::string slicesData = reader.GetMandatoryStringValue(contourDataPath); |
0 | 479 |
480 Vector points; | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
481 if (!LinearAlgebra::ParseVector(points, slicesData) || |
32 | 482 points.size() != 3 * countPoints) |
0 | 483 { |
484 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
485 } | |
486 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
487 Polygon polygon(sopInstanceUid); |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
488 polygon.Reserve(countPoints); |
0 | 489 |
32 | 490 for (size_t k = 0; k < countPoints; k++) |
0 | 491 { |
492 Vector v(3); | |
493 v[0] = points[3 * k]; | |
494 v[1] = points[3 * k + 1]; | |
495 v[2] = points[3 * k + 2]; | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
496 polygon.AddPoint(v); |
0 | 497 } |
498 | |
499 structures_[i].polygons_.push_back(polygon); | |
500 } | |
501 } | |
502 } | |
503 | |
504 | |
505 Vector DicomStructureSet::GetStructureCenter(size_t index) const | |
506 { | |
507 const Structure& structure = GetStructure(index); | |
508 | |
509 Vector center; | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
510 LinearAlgebra::AssignVector(center, 0, 0, 0); |
0 | 511 if (structure.polygons_.empty()) |
512 { | |
513 return center; | |
514 } | |
515 | |
516 double n = static_cast<double>(structure.polygons_.size()); | |
517 | |
518 for (Polygons::const_iterator polygon = structure.polygons_.begin(); | |
519 polygon != structure.polygons_.end(); ++polygon) | |
520 { | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
521 if (!polygon->GetPoints().empty()) |
0 | 522 { |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
523 center += polygon->GetPoints().front() / n; |
0 | 524 } |
525 } | |
526 | |
527 return center; | |
528 } | |
529 | |
530 | |
531 const std::string& DicomStructureSet::GetStructureName(size_t index) const | |
532 { | |
533 return GetStructure(index).name_; | |
534 } | |
535 | |
536 | |
537 const std::string& DicomStructureSet::GetStructureInterpretation(size_t index) const | |
538 { | |
539 return GetStructure(index).interpretation_; | |
540 } | |
541 | |
542 | |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
543 Color DicomStructureSet::GetStructureColor(size_t index) const |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
544 { |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
545 const Structure& s = GetStructure(index); |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
546 return Color(s.red_, s.green_, s.blue_); |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
547 } |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
548 |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
794
diff
changeset
|
549 |
0 | 550 void DicomStructureSet::GetStructureColor(uint8_t& red, |
551 uint8_t& green, | |
552 uint8_t& blue, | |
553 size_t index) const | |
554 { | |
555 const Structure& s = GetStructure(index); | |
556 red = s.red_; | |
557 green = s.green_; | |
558 blue = s.blue_; | |
559 } | |
560 | |
561 | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
562 void DicomStructureSet::GetReferencedInstances(std::set<std::string>& instances) |
0 | 563 { |
564 for (Structures::const_iterator structure = structures_.begin(); | |
565 structure != structures_.end(); ++structure) | |
566 { | |
567 for (Polygons::const_iterator polygon = structure->polygons_.begin(); | |
568 polygon != structure->polygons_.end(); ++polygon) | |
569 { | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
570 instances.insert(polygon->GetSopInstanceUid()); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
571 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
572 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
573 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
574 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
575 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
576 void DicomStructureSet::AddReferencedSlice(const std::string& sopInstanceUid, |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
577 const std::string& seriesInstanceUid, |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
578 const CoordinateSystem3D& geometry, |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
579 double thickness) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
580 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
581 if (referencedSlices_.find(sopInstanceUid) != referencedSlices_.end()) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
582 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
583 // This geometry is already known |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
584 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
585 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
586 else |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
587 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
588 if (thickness < 0) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
589 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
590 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
591 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
592 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
593 if (!referencedSlices_.empty()) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
594 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
595 const ReferencedSlice& reference = referencedSlices_.begin()->second; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
596 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
597 if (reference.seriesInstanceUid_ != seriesInstanceUid) |
0 | 598 { |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
599 LOG(ERROR) << "This RT-STRUCT refers to several different series"; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
600 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
601 } |
0 | 602 |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
603 if (!GeometryToolbox::IsParallel(reference.geometry_.GetNormal(), geometry.GetNormal())) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
604 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
605 LOG(ERROR) << "The slices in this RT-STRUCT are not parallel"; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
606 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
607 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
608 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
609 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
610 referencedSlices_[sopInstanceUid] = ReferencedSlice(seriesInstanceUid, geometry, thickness); |
0 | 611 |
131 | 612 for (Structures::iterator structure = structures_.begin(); |
613 structure != structures_.end(); ++structure) | |
614 { | |
615 for (Polygons::iterator polygon = structure->polygons_.begin(); | |
616 polygon != structure->polygons_.end(); ++polygon) | |
617 { | |
618 polygon->UpdateReferencedSlice(referencedSlices_); | |
619 } | |
620 } | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
621 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
622 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
623 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
624 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
625 void DicomStructureSet::AddReferencedSlice(const Orthanc::DicomMap& dataset) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
626 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
627 CoordinateSystem3D slice(dataset); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
628 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
629 double thickness = 1; // 1 mm by default |
0 | 630 |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
631 std::string s; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
632 Vector v; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
633 if (dataset.CopyToString(s, Orthanc::DICOM_TAG_SLICE_THICKNESS, false) && |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
634 LinearAlgebra::ParseVector(v, s) && |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
635 v.size() > 0) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
636 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
637 thickness = v[0]; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
638 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
639 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
640 std::string instance, series; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
641 if (dataset.CopyToString(instance, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false) && |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
642 dataset.CopyToString(series, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false)) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
643 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
644 AddReferencedSlice(instance, series, slice, thickness); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
645 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
646 else |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
647 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
648 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
649 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
650 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
651 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
652 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
653 void DicomStructureSet::CheckReferencedSlices() |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
654 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
655 for (Structures::iterator structure = structures_.begin(); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
656 structure != structures_.end(); ++structure) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
657 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
658 for (Polygons::iterator polygon = structure->polygons_.begin(); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
659 polygon != structure->polygons_.end(); ++polygon) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
660 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
661 if (!polygon->UpdateReferencedSlice(referencedSlices_)) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
662 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
663 LOG(ERROR) << "Missing information about referenced instance: " |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
664 << polygon->GetSopInstanceUid(); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
665 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
0 | 666 } |
667 } | |
668 } | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
669 } |
0 | 670 |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
671 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
672 Vector DicomStructureSet::GetNormal() const |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
673 { |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
674 if (referencedSlices_.empty()) |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
675 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
676 Vector v; |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
137
diff
changeset
|
677 LinearAlgebra::AssignVector(v, 0, 0, 1); |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
678 return v; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
679 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
680 else |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
681 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
682 return referencedSlices_.begin()->second.geometry_.GetNormal(); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
683 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
684 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
685 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
686 |
125 | 687 bool DicomStructureSet::ProjectStructure(std::vector< std::vector<PolygonPoint> >& polygons, |
794 | 688 const Structure& structure, |
689 const CoordinateSystem3D& slice) const | |
125 | 690 { |
691 polygons.clear(); | |
692 | |
693 Vector normal = GetNormal(); | |
694 | |
695 bool isOpposite; | |
696 if (GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetNormal())) | |
697 { | |
698 // This is an axial projection | |
699 | |
794 | 700 for (Polygons::const_iterator polygon = structure.polygons_.begin(); |
125 | 701 polygon != structure.polygons_.end(); ++polygon) |
702 { | |
703 if (polygon->IsOnSlice(slice)) | |
704 { | |
705 polygons.push_back(std::vector<PolygonPoint>()); | |
706 | |
707 for (Points::const_iterator p = polygon->GetPoints().begin(); | |
708 p != polygon->GetPoints().end(); ++p) | |
709 { | |
710 double x, y; | |
711 slice.ProjectPoint(x, y, *p); | |
712 polygons.back().push_back(std::make_pair(x, y)); | |
713 } | |
714 } | |
715 } | |
716 | |
717 return true; | |
718 } | |
719 else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisX()) || | |
720 GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisY())) | |
721 { | |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
722 #if 1 |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
723 // Sagittal or coronal projection |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
724 std::vector<BoostPolygon> projected; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
725 |
794 | 726 for (Polygons::const_iterator polygon = structure.polygons_.begin(); |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
727 polygon != structure.polygons_.end(); ++polygon) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
728 { |
131 | 729 double x1, y1, x2, y2; |
730 if (polygon->Project(x1, y1, x2, y2, slice)) | |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
731 { |
516
11fa6f00e33c
Dummy changes (warnings, dummy dtor to check proper deletion, line wrapping) +
Benjamin Golinvaux <bgo@osimis.io>
parents:
439
diff
changeset
|
732 projected.push_back(CreateRectangle( |
11fa6f00e33c
Dummy changes (warnings, dummy dtor to check proper deletion, line wrapping) +
Benjamin Golinvaux <bgo@osimis.io>
parents:
439
diff
changeset
|
733 static_cast<float>(x1), |
11fa6f00e33c
Dummy changes (warnings, dummy dtor to check proper deletion, line wrapping) +
Benjamin Golinvaux <bgo@osimis.io>
parents:
439
diff
changeset
|
734 static_cast<float>(y1), |
11fa6f00e33c
Dummy changes (warnings, dummy dtor to check proper deletion, line wrapping) +
Benjamin Golinvaux <bgo@osimis.io>
parents:
439
diff
changeset
|
735 static_cast<float>(x2), |
11fa6f00e33c
Dummy changes (warnings, dummy dtor to check proper deletion, line wrapping) +
Benjamin Golinvaux <bgo@osimis.io>
parents:
439
diff
changeset
|
736 static_cast<float>(y2))); |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
737 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
738 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
739 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
740 BoostMultiPolygon merged; |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
741 Union(merged, projected); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
742 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
743 polygons.resize(merged.size()); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
744 for (size_t i = 0; i < merged.size(); i++) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
745 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
746 const std::vector<BoostPoint>& outer = merged[i].outer(); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
747 |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
748 polygons[i].resize(outer.size()); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
749 for (size_t j = 0; j < outer.size(); j++) |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
750 { |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
751 polygons[i][j] = std::make_pair(outer[j].x(), outer[j].y()); |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
752 } |
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
753 } |
132
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
754 #else |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
755 for (Polygons::iterator polygon = structure.polygons_.begin(); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
756 polygon != structure.polygons_.end(); ++polygon) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
757 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
758 double x1, y1, x2, y2; |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
759 if (polygon->Project(x1, y1, x2, y2, slice)) |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
760 { |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
761 std::vector<PolygonPoint> p(4); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
762 p[0] = std::make_pair(x1, y1); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
763 p[1] = std::make_pair(x2, y1); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
764 p[2] = std::make_pair(x2, y2); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
765 p[3] = std::make_pair(x1, y2); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
766 polygons.push_back(p); |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
767 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
768 } |
35c2b85836ce
fix rtstruct projections
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
131
diff
changeset
|
769 #endif |
125 | 770 |
126
c9e88e7935a4
rt-struct projection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
125
diff
changeset
|
771 return true; |
125 | 772 } |
773 else | |
774 { | |
775 return false; | |
776 } | |
0 | 777 } |
778 } |