Mercurial > hg > orthanc-stone
annotate OrthancStone/Sources/Toolbox/SlicesSorter.cpp @ 2177:4d21befb1501 default tip
clarify DICOMweb version check
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Oct 2024 19:27:56 +0200 |
parents | 16c01cc201e7 |
children |
rev | line source |
---|---|
73 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
2124
16c01cc201e7
updated copyright, as Osimis is not active on Orthanc anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2114
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
2114
c23eef785569
update year to 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2077
diff
changeset
|
6 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
73 | 7 * |
8 * This program is free software: you can redistribute it and/or | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
9 * modify it under the terms of the GNU Lesser General Public License |
73 | 10 * as published by the Free Software Foundation, either version 3 of |
11 * the License, or (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
16 * Lesser General Public License for more details. |
1596
4fb8fdf03314
removed annoying whitespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1571
diff
changeset
|
17 * |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
18 * You should have received a copy of the GNU Lesser General Public |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
19 * License along with this program. If not, see |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
20 * <http://www.gnu.org/licenses/>. |
73 | 21 **/ |
22 | |
23 | |
24 #include "SlicesSorter.h" | |
25 | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
26 #include "GeometryToolbox.h" |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
27 |
1624 | 28 #include <Logging.h> |
1455
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1300
diff
changeset
|
29 #include <OrthancException.h> |
73 | 30 |
31 namespace OrthancStone | |
32 { | |
33 class SlicesSorter::SliceWithDepth : public boost::noncopyable | |
34 { | |
35 private: | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
36 CoordinateSystem3D geometry_; |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
37 double depth_; |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
38 |
1298
8a0a62189f46
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1270
diff
changeset
|
39 std::unique_ptr<Orthanc::IDynamicObject> payload_; |
73 | 40 |
41 public: | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
42 SliceWithDepth(const CoordinateSystem3D& geometry, |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
43 Orthanc::IDynamicObject* payload) : |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
44 geometry_(geometry), |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
45 depth_(0), |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
46 payload_(payload) |
73 | 47 { |
48 } | |
49 | |
50 void SetNormal(const Vector& normal) | |
51 { | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
52 depth_ = boost::numeric::ublas::inner_prod(geometry_.GetOrigin(), normal); |
73 | 53 } |
54 | |
55 double GetDepth() const | |
56 { | |
57 return depth_; | |
58 } | |
59 | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
60 const CoordinateSystem3D& GetGeometry() const |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
61 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
62 return geometry_; |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
63 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
64 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
65 bool HasPayload() const |
73 | 66 { |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
67 return (payload_.get() != NULL); |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
68 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
69 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
70 const Orthanc::IDynamicObject& GetPayload() const |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
71 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
72 if (HasPayload()) |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
73 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
74 return *payload_; |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
75 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
76 else |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
77 { |
956
a7351ad54960
Made IsContextLost automatically set the flag by checking with the emscripten
Benjamin Golinvaux <bgo@osimis.io>
parents:
757
diff
changeset
|
78 LOG(ERROR) << "SlicesSorter::SliceWithDepth::GetPayload(): (!HasPayload())"; |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
79 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
80 } |
73 | 81 } |
82 }; | |
83 | |
84 | |
85 struct SlicesSorter::Comparator | |
86 { | |
87 bool operator() (const SliceWithDepth* const& a, | |
88 const SliceWithDepth* const& b) const | |
89 { | |
90 return a->GetDepth() < b->GetDepth(); | |
91 } | |
92 }; | |
93 | |
94 | |
95 SlicesSorter::~SlicesSorter() | |
96 { | |
97 for (size_t i = 0; i < slices_.size(); i++) | |
98 { | |
99 assert(slices_[i] != NULL); | |
100 delete slices_[i]; | |
101 } | |
102 } | |
103 | |
104 | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
105 void SlicesSorter::AddSlice(const CoordinateSystem3D& slice, |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
106 Orthanc::IDynamicObject* payload) |
73 | 107 { |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
108 slices_.push_back(new SliceWithDepth(slice, payload)); |
73 | 109 } |
110 | |
111 | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
112 const SlicesSorter::SliceWithDepth& SlicesSorter::GetSlice(size_t i) const |
73 | 113 { |
114 if (i >= slices_.size()) | |
115 { | |
116 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
117 } | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
118 else |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
119 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
120 assert(slices_[i] != NULL); |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
121 return *slices_[i]; |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
122 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
123 } |
73 | 124 |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
125 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
126 const CoordinateSystem3D& SlicesSorter::GetSliceGeometry(size_t i) const |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
127 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
128 return GetSlice(i).GetGeometry(); |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
129 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
130 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
131 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
132 bool SlicesSorter::HasSlicePayload(size_t i) const |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
133 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
134 return GetSlice(i).HasPayload(); |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
135 } |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
136 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
137 |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
138 const Orthanc::IDynamicObject& SlicesSorter::GetSlicePayload(size_t i) const |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
139 { |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
140 return GetSlice(i).GetPayload(); |
73 | 141 } |
142 | |
143 | |
144 void SlicesSorter::SetNormal(const Vector& normal) | |
145 { | |
146 for (size_t i = 0; i < slices_.size(); i++) | |
147 { | |
148 slices_[i]->SetNormal(normal); | |
149 } | |
150 | |
151 hasNormal_ = true; | |
152 } | |
153 | |
154 | |
648 | 155 void SlicesSorter::SortInternal() |
73 | 156 { |
157 if (!hasNormal_) | |
158 { | |
956
a7351ad54960
Made IsContextLost automatically set the flag by checking with the emscripten
Benjamin Golinvaux <bgo@osimis.io>
parents:
757
diff
changeset
|
159 LOG(ERROR) << "SlicesSorter::SortInternal(): (!hasNormal_)"; |
73 | 160 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
161 } | |
162 | |
163 Comparator comparator; | |
164 std::sort(slices_.begin(), slices_.end(), comparator); | |
165 } | |
166 | |
167 | |
168 void SlicesSorter::FilterNormal(const Vector& normal) | |
169 { | |
170 size_t pos = 0; | |
171 | |
172 for (size_t i = 0; i < slices_.size(); i++) | |
173 { | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
174 if (GeometryToolbox::IsParallel(normal, slices_[i]->GetGeometry().GetNormal())) |
73 | 175 { |
176 // This slice is compatible with the selected normal | |
177 slices_[pos] = slices_[i]; | |
178 pos += 1; | |
179 } | |
180 else | |
181 { | |
182 delete slices_[i]; | |
183 slices_[i] = NULL; | |
184 } | |
185 } | |
186 | |
187 slices_.resize(pos); | |
188 } | |
189 | |
190 | |
191 bool SlicesSorter::SelectNormal(Vector& normal) const | |
192 { | |
193 std::vector<Vector> normalCandidates; | |
194 std::vector<unsigned int> normalCount; | |
195 | |
196 bool found = false; | |
197 | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
198 for (size_t i = 0; !found && i < GetSlicesCount(); i++) |
73 | 199 { |
200 const Vector& normal = GetSlice(i).GetGeometry().GetNormal(); | |
201 | |
202 bool add = true; | |
203 for (size_t j = 0; add && j < normalCandidates.size(); j++) // (*) | |
204 { | |
205 if (GeometryToolbox::IsParallel(normal, normalCandidates[j])) | |
206 { | |
207 normalCount[j] += 1; | |
208 add = false; | |
209 } | |
210 } | |
211 | |
212 if (add) | |
213 { | |
214 if (normalCount.size() > 2) | |
215 { | |
216 // To get linear-time complexity in (*). This heuristics | |
217 // allows the series to have one single frame that is | |
218 // not parallel to the others (such a frame could be a | |
219 // generated preview) | |
220 found = false; | |
221 } | |
222 else | |
223 { | |
224 normalCandidates.push_back(normal); | |
225 normalCount.push_back(1); | |
226 } | |
227 } | |
228 } | |
229 | |
230 for (size_t i = 0; !found && i < normalCandidates.size(); i++) | |
231 { | |
232 unsigned int count = normalCount[i]; | |
647
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
233 if (count == GetSlicesCount() || |
6af3099ed8da
uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
234 count + 1 == GetSlicesCount()) |
73 | 235 { |
236 normal = normalCandidates[i]; | |
237 found = true; | |
238 } | |
239 } | |
240 | |
241 return found; | |
242 } | |
77 | 243 |
244 | |
648 | 245 bool SlicesSorter::Sort() |
246 { | |
247 if (GetSlicesCount() > 0) | |
248 { | |
249 Vector normal; | |
250 if (SelectNormal(normal)) | |
251 { | |
252 FilterNormal(normal); | |
253 SetNormal(normal); | |
254 SortInternal(); | |
255 return true; | |
256 } | |
257 } | |
258 | |
259 return false; | |
260 } | |
261 | |
262 | |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
263 bool SlicesSorter::ComputeSpacingBetweenSlices(double& spacing /* out */) const |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
264 { |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
265 if (GetSlicesCount() <= 1) |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
266 { |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
267 // This is a volume that is empty or that contains one single |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
268 // slice: Choose a dummy z-dimension for voxels |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
269 spacing = 1.0; |
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
270 return true; |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
271 } |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
272 |
1640
52b8b96cb55f
cleaning namespaces
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1624
diff
changeset
|
273 const CoordinateSystem3D& reference = GetSliceGeometry(0); |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
274 |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
275 double referencePosition = reference.ProjectAlongNormal(reference.GetOrigin()); |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
276 |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
277 double p = reference.ProjectAlongNormal(GetSliceGeometry(1).GetOrigin()); |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
278 spacing = p - referencePosition; |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
279 |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
280 if (spacing <= 0) |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
281 { |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
282 LOG(ERROR) << "SlicesSorter::ComputeSpacingBetweenSlices(): (spacing <= 0)"; |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
283 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls, |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
284 "Please call the Sort() method before"); |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
285 } |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
286 |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
287 for (size_t i = 1; i < GetSlicesCount(); i++) |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
288 { |
1640
52b8b96cb55f
cleaning namespaces
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1624
diff
changeset
|
289 Vector q = reference.GetOrigin() + spacing * static_cast<double>(i) * reference.GetNormal(); |
1571 | 290 double d = boost::numeric::ublas::norm_2(q - GetSliceGeometry(i).GetOrigin()); |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
291 |
1640
52b8b96cb55f
cleaning namespaces
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1624
diff
changeset
|
292 if (!LinearAlgebra::IsNear(d, 0, 0.001 /* tolerance expressed in mm */)) |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
293 { |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
294 return false; |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
295 } |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
296 } |
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
297 |
1156
34ee7204fde3
removing IGeometryProvider
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1015
diff
changeset
|
298 return true; |
667
e9339f2b5de7
refactoring of VolumeImage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
648
diff
changeset
|
299 } |
1015
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
300 |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
301 |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
302 bool SlicesSorter::AreAllSlicesDistinct() const |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
303 { |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
304 if (GetSlicesCount() <= 1) |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
305 { |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
306 return true; |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
307 } |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
308 else |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
309 { |
1640
52b8b96cb55f
cleaning namespaces
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1624
diff
changeset
|
310 const CoordinateSystem3D& reference = GetSliceGeometry(0); |
1015
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
311 double previousPosition = reference.ProjectAlongNormal(GetSliceGeometry(0).GetOrigin()); |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
312 |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
313 for (size_t i = 1; i < GetSlicesCount(); i++) |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
314 { |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
315 double position = reference.ProjectAlongNormal(GetSliceGeometry(i).GetOrigin()); |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
316 |
1640
52b8b96cb55f
cleaning namespaces
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1624
diff
changeset
|
317 if (LinearAlgebra::IsNear(position, previousPosition, 0.001 /* tolerance expressed in mm */)) |
1015
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
318 { |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
319 return false; |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
320 } |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
321 |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
322 previousPosition = position; |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
323 } |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
324 |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
325 return true; |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
326 } |
24fecc02bfb1
SlicesSorter::AreAllSlicesDistinct()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
327 } |
73 | 328 } |