Mercurial > hg > orthanc-stone
annotate Framework/dev.h @ 390:0cb925325470
renamed SiblingSliceLocation as ReferenceLine
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 09 Nov 2018 17:37:34 +0100 |
parents | 20f149669c1f |
children | ed7146fa2c98 |
rev | line source |
---|---|
102 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
135
e2fe9352f240
upgrade to year 2018
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
121
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
102 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
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. | |
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 | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
16 * |
102 | 17 * You should have received a copy of the GNU Affero General Public License |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #pragma once | |
23 | |
24 #include "Layers/FrameRenderer.h" | |
25 #include "Layers/LayerSourceBase.h" | |
26 #include "Layers/SliceOutlineRenderer.h" | |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
27 #include "Layers/LineLayerRenderer.h" |
388
20f149669c1f
renamed LayerWidget as SliceViewerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
381
diff
changeset
|
28 #include "Widgets/SliceViewerWidget.h" |
102 | 29 #include "Toolbox/DownloadStack.h" |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
30 #include "Toolbox/GeometryToolbox.h" |
102 | 31 #include "Toolbox/OrthancSlicesLoader.h" |
32 #include "Volumes/ImageBuffer3D.h" | |
33 #include "Volumes/SlicedVolumeBase.h" | |
34 | |
212
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
35 #include <Core/Logging.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
36 #include <Core/Images/ImageProcessing.h> |
102 | 37 |
38 #include <boost/math/special_functions/round.hpp> | |
39 | |
40 | |
41 namespace OrthancStone | |
42 { | |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
43 // TODO: Handle errors while loading |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
44 class OrthancVolumeImage : |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
45 public SlicedVolumeBase, |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
46 public OrthancStone::IObserver |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
47 { |
102 | 48 private: |
49 OrthancSlicesLoader loader_; | |
50 std::auto_ptr<ImageBuffer3D> image_; | |
51 std::auto_ptr<DownloadStack> downloadStack_; | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
52 bool computeRange_; |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
53 size_t pendingSlices_; |
102 | 54 |
55 void ScheduleSliceDownload() | |
56 { | |
57 assert(downloadStack_.get() != NULL); | |
58 | |
59 unsigned int slice; | |
60 if (downloadStack_->Pop(slice)) | |
61 { | |
62 loader_.ScheduleLoadSliceImage(slice, SliceImageQuality_Jpeg90); | |
63 } | |
64 } | |
65 | |
66 | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
67 static bool IsCompatible(const Slice& a, |
102 | 68 const Slice& b) |
69 { | |
70 if (!GeometryToolbox::IsParallel(a.GetGeometry().GetNormal(), | |
71 b.GetGeometry().GetNormal())) | |
72 { | |
73 LOG(ERROR) << "Some slice in the volume image is not parallel to the others"; | |
74 return false; | |
75 } | |
76 | |
77 if (a.GetConverter().GetExpectedPixelFormat() != b.GetConverter().GetExpectedPixelFormat()) | |
78 { | |
79 LOG(ERROR) << "The pixel format changes across the slices of the volume image"; | |
80 return false; | |
81 } | |
82 | |
83 if (a.GetWidth() != b.GetWidth() || | |
84 a.GetHeight() != b.GetHeight()) | |
85 { | |
86 LOG(ERROR) << "The width/height of the slices change across the volume image"; | |
87 return false; | |
88 } | |
89 | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
138
diff
changeset
|
90 if (!LinearAlgebra::IsNear(a.GetPixelSpacingX(), b.GetPixelSpacingX()) || |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
138
diff
changeset
|
91 !LinearAlgebra::IsNear(a.GetPixelSpacingY(), b.GetPixelSpacingY())) |
102 | 92 { |
93 LOG(ERROR) << "The pixel spacing of the slices change across the volume image"; | |
94 return false; | |
95 } | |
96 | |
97 return true; | |
98 } | |
99 | |
100 | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
101 static double GetDistance(const Slice& a, |
102 | 102 const Slice& b) |
103 { | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
104 return fabs(a.GetGeometry().ProjectAlongNormal(a.GetGeometry().GetOrigin()) - |
102 | 105 a.GetGeometry().ProjectAlongNormal(b.GetGeometry().GetOrigin())); |
106 } | |
107 | |
108 | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
109 void OnSliceGeometryReady(const OrthancSlicesLoader& loader) |
102 | 110 { |
111 if (loader.GetSliceCount() == 0) | |
112 { | |
113 LOG(ERROR) << "Empty volume image"; | |
114 SlicedVolumeBase::NotifyGeometryError(); | |
115 return; | |
116 } | |
117 | |
118 for (size_t i = 1; i < loader.GetSliceCount(); i++) | |
119 { | |
120 if (!IsCompatible(loader.GetSlice(0), loader.GetSlice(i))) | |
121 { | |
122 SlicedVolumeBase::NotifyGeometryError(); | |
123 return; | |
124 } | |
125 } | |
126 | |
127 double spacingZ; | |
128 | |
129 if (loader.GetSliceCount() > 1) | |
130 { | |
131 spacingZ = GetDistance(loader.GetSlice(0), loader.GetSlice(1)); | |
132 } | |
133 else | |
134 { | |
135 // This is a volume with one single slice: Choose a dummy | |
136 // z-dimension for voxels | |
137 spacingZ = 1; | |
138 } | |
120
063f7f3d9f14
fix 3d locations of the doses
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
119
diff
changeset
|
139 |
102 | 140 for (size_t i = 1; i < loader.GetSliceCount(); i++) |
141 { | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
138
diff
changeset
|
142 if (!LinearAlgebra::IsNear(spacingZ, GetDistance(loader.GetSlice(i - 1), loader.GetSlice(i)), |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
138
diff
changeset
|
143 0.001 /* this is expressed in mm */)) |
102 | 144 { |
145 LOG(ERROR) << "The distance between successive slices is not constant in a volume image"; | |
146 SlicedVolumeBase::NotifyGeometryError(); | |
147 return; | |
148 } | |
149 } | |
150 | |
151 unsigned int width = loader.GetSlice(0).GetWidth(); | |
152 unsigned int height = loader.GetSlice(0).GetHeight(); | |
153 Orthanc::PixelFormat format = loader.GetSlice(0).GetConverter().GetExpectedPixelFormat(); | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
154 LOG(INFO) << "Creating a volume image of size " << width << "x" << height |
102 | 155 << "x" << loader.GetSliceCount() << " in " << Orthanc::EnumerationToString(format); |
156 | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
157 image_.reset(new ImageBuffer3D(format, width, height, loader.GetSliceCount(), computeRange_)); |
102 | 158 image_->SetAxialGeometry(loader.GetSlice(0).GetGeometry()); |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
159 image_->SetVoxelDimensions(loader.GetSlice(0).GetPixelSpacingX(), |
102 | 160 loader.GetSlice(0).GetPixelSpacingY(), spacingZ); |
161 image_->Clear(); | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
162 |
102 | 163 downloadStack_.reset(new DownloadStack(loader.GetSliceCount())); |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
164 pendingSlices_ = loader.GetSliceCount(); |
102 | 165 |
166 for (unsigned int i = 0; i < 4; i++) // Limit to 4 simultaneous downloads | |
167 { | |
168 ScheduleSliceDownload(); | |
169 } | |
170 | |
171 // TODO Check the DicomFrameConverter are constant | |
172 | |
173 SlicedVolumeBase::NotifyGeometryReady(); | |
174 } | |
175 | |
252 | 176 virtual void OnSliceImageReady(const OrthancSlicesLoader& loader, |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
177 unsigned int sliceIndex, |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
178 const Slice& slice, |
378 | 179 const Orthanc::ImageAccessor& image, |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
180 SliceImageQuality quality) |
102 | 181 { |
182 { | |
183 ImageBuffer3D::SliceWriter writer(*image_, VolumeProjection_Axial, sliceIndex); | |
378 | 184 Orthanc::ImageProcessing::Copy(writer.GetAccessor(), image); |
102 | 185 } |
186 | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
187 SlicedVolumeBase::NotifySliceChange(sliceIndex, slice); |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
188 |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
189 if (pendingSlices_ == 1) |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
190 { |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
191 SlicedVolumeBase::NotifyVolumeReady(); |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
192 pendingSlices_ = 0; |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
193 } |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
194 else if (pendingSlices_ > 1) |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
195 { |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
196 pendingSlices_ -= 1; |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
197 } |
102 | 198 |
199 ScheduleSliceDownload(); | |
200 } | |
201 | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
202 virtual void HandleMessage(const IObservable& from, const IMessage& message) |
102 | 203 { |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
204 switch (message.GetType()) |
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
205 { |
378 | 206 case MessageType_SliceLoader_GeometryReady: |
207 OnSliceGeometryReady(dynamic_cast<const OrthancSlicesLoader&>(from)); | |
208 break; | |
209 | |
210 case MessageType_SliceLoader_GeometryError: | |
211 LOG(ERROR) << "Unable to download a volume image"; | |
212 SlicedVolumeBase::NotifyGeometryError(); | |
213 break; | |
214 | |
215 case MessageType_SliceLoader_ImageReady: | |
216 { | |
217 const OrthancSlicesLoader::SliceImageReadyMessage& msg = | |
218 dynamic_cast<const OrthancSlicesLoader::SliceImageReadyMessage&>(message); | |
219 OnSliceImageReady(dynamic_cast<const OrthancSlicesLoader&>(from), | |
220 msg.GetSliceIndex(), | |
221 msg.GetSlice(), | |
222 msg.GetImage(), | |
223 msg.GetEffectiveQuality()); | |
224 break; | |
225 } | |
226 | |
227 case MessageType_SliceLoader_ImageError: | |
228 { | |
229 const OrthancSlicesLoader::SliceImageErrorMessage& msg = | |
230 dynamic_cast<const OrthancSlicesLoader::SliceImageErrorMessage&>(message); | |
231 LOG(ERROR) << "Cannot download slice " << msg.GetSliceIndex() << " in a volume image"; | |
232 ScheduleSliceDownload(); | |
233 break; | |
234 } | |
235 | |
236 default: | |
237 VLOG("unhandled message type" << message.GetType()); | |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
238 } |
102 | 239 } |
240 | |
241 public: | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
242 OrthancVolumeImage(MessageBroker& broker, |
300
b4abaeb783b1
messaging refactoring almost complete: works fine in native
am@osimis.io
parents:
299
diff
changeset
|
243 OrthancApiClient& orthanc, |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
244 bool computeRange) : |
266
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
245 OrthancStone::IObserver(broker), |
c9cf95b49a86
removed OrthancSlicesLoader::ISliceLoaderObserver; now using standard messages instead
am@osimis.io
parents:
252
diff
changeset
|
246 loader_(broker, orthanc), |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
247 computeRange_(computeRange), |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
248 pendingSlices_(0) |
102 | 249 { |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
250 // TODO: replace with new callables loader_.RegisterObserver(*this); |
102 | 251 } |
252 | |
253 void ScheduleLoadSeries(const std::string& seriesId) | |
254 { | |
255 loader_.ScheduleLoadSeries(seriesId); | |
256 } | |
257 | |
117
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
258 void ScheduleLoadInstance(const std::string& instanceId) |
102 | 259 { |
117
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
260 loader_.ScheduleLoadInstance(instanceId); |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
261 } |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
262 |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
263 void ScheduleLoadFrame(const std::string& instanceId, |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
264 unsigned int frame) |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
265 { |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
266 loader_.ScheduleLoadFrame(instanceId, frame); |
102 | 267 } |
268 | |
269 virtual size_t GetSliceCount() const | |
270 { | |
271 return loader_.GetSliceCount(); | |
272 } | |
273 | |
274 virtual const Slice& GetSlice(size_t index) const | |
275 { | |
276 return loader_.GetSlice(index); | |
277 } | |
278 | |
279 ImageBuffer3D& GetImage() const | |
280 { | |
281 if (image_.get() == NULL) | |
282 { | |
283 // The geometry is not ready yet | |
284 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
285 } | |
286 else | |
287 { | |
288 return *image_; | |
289 } | |
290 } | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
291 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
292 bool FitWindowingToRange(RenderStyle& style, |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
293 const DicomFrameConverter& converter) const |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
294 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
295 if (image_.get() == NULL) |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
296 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
297 return false; |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
298 } |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
299 else |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
300 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
301 return image_->FitWindowingToRange(style, converter); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
302 } |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
303 } |
102 | 304 }; |
305 | |
306 | |
307 class VolumeImageGeometry | |
308 { | |
309 private: | |
310 unsigned int width_; | |
311 unsigned int height_; | |
312 size_t depth_; | |
313 double pixelSpacingX_; | |
314 double pixelSpacingY_; | |
315 double sliceThickness_; | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
316 CoordinateSystem3D reference_; |
102 | 317 DicomFrameConverter converter_; |
318 | |
319 double ComputeAxialThickness(const OrthancVolumeImage& volume) const | |
320 { | |
321 double thickness; | |
322 | |
323 size_t n = volume.GetSliceCount(); | |
324 if (n > 1) | |
325 { | |
326 const Slice& a = volume.GetSlice(0); | |
327 const Slice& b = volume.GetSlice(n - 1); | |
328 thickness = ((reference_.ProjectAlongNormal(b.GetGeometry().GetOrigin()) - | |
329 reference_.ProjectAlongNormal(a.GetGeometry().GetOrigin())) / | |
330 (static_cast<double>(n) - 1.0)); | |
331 } | |
332 else | |
333 { | |
334 thickness = volume.GetSlice(0).GetThickness(); | |
335 } | |
336 | |
337 if (thickness <= 0) | |
338 { | |
339 // The slices should have been sorted with increasing Z | |
340 // (along the normal) by the OrthancSlicesLoader | |
341 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
342 } | |
343 else | |
344 { | |
345 return thickness; | |
346 } | |
347 } | |
348 | |
349 void SetupAxial(const OrthancVolumeImage& volume) | |
350 { | |
351 const Slice& axial = volume.GetSlice(0); | |
352 | |
353 width_ = axial.GetWidth(); | |
354 height_ = axial.GetHeight(); | |
355 depth_ = volume.GetSliceCount(); | |
356 | |
357 pixelSpacingX_ = axial.GetPixelSpacingX(); | |
358 pixelSpacingY_ = axial.GetPixelSpacingY(); | |
359 sliceThickness_ = ComputeAxialThickness(volume); | |
360 | |
361 reference_ = axial.GetGeometry(); | |
362 } | |
363 | |
364 void SetupCoronal(const OrthancVolumeImage& volume) | |
365 { | |
366 const Slice& axial = volume.GetSlice(0); | |
367 double axialThickness = ComputeAxialThickness(volume); | |
368 | |
369 width_ = axial.GetWidth(); | |
370 height_ = volume.GetSliceCount(); | |
371 depth_ = axial.GetHeight(); | |
372 | |
373 pixelSpacingX_ = axial.GetPixelSpacingX(); | |
374 pixelSpacingY_ = axialThickness; | |
375 sliceThickness_ = axial.GetPixelSpacingY(); | |
376 | |
377 Vector origin = axial.GetGeometry().GetOrigin(); | |
378 origin += (static_cast<double>(volume.GetSliceCount() - 1) * | |
379 axialThickness * axial.GetGeometry().GetNormal()); | |
380 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
381 reference_ = CoordinateSystem3D(origin, |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
382 axial.GetGeometry().GetAxisX(), |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
383 -axial.GetGeometry().GetNormal()); |
102 | 384 } |
385 | |
386 void SetupSagittal(const OrthancVolumeImage& volume) | |
387 { | |
388 const Slice& axial = volume.GetSlice(0); | |
389 double axialThickness = ComputeAxialThickness(volume); | |
390 | |
391 width_ = axial.GetHeight(); | |
392 height_ = volume.GetSliceCount(); | |
393 depth_ = axial.GetWidth(); | |
394 | |
395 pixelSpacingX_ = axial.GetPixelSpacingY(); | |
396 pixelSpacingY_ = axialThickness; | |
397 sliceThickness_ = axial.GetPixelSpacingX(); | |
398 | |
399 Vector origin = axial.GetGeometry().GetOrigin(); | |
400 origin += (static_cast<double>(volume.GetSliceCount() - 1) * | |
401 axialThickness * axial.GetGeometry().GetNormal()); | |
402 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
403 reference_ = CoordinateSystem3D(origin, |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
404 axial.GetGeometry().GetAxisY(), |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
405 axial.GetGeometry().GetNormal()); |
102 | 406 } |
407 | |
408 public: | |
409 VolumeImageGeometry(const OrthancVolumeImage& volume, | |
410 VolumeProjection projection) | |
411 { | |
412 if (volume.GetSliceCount() == 0) | |
413 { | |
414 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
415 } | |
416 | |
417 converter_ = volume.GetSlice(0).GetConverter(); | |
418 | |
419 switch (projection) | |
420 { | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
421 case VolumeProjection_Axial: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
422 SetupAxial(volume); |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
423 break; |
102 | 424 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
425 case VolumeProjection_Coronal: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
426 SetupCoronal(volume); |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
427 break; |
102 | 428 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
429 case VolumeProjection_Sagittal: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
430 SetupSagittal(volume); |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
431 break; |
102 | 432 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
433 default: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
434 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
102 | 435 } |
436 } | |
437 | |
438 size_t GetSliceCount() const | |
439 { | |
440 return depth_; | |
441 } | |
442 | |
443 const Vector& GetNormal() const | |
444 { | |
445 return reference_.GetNormal(); | |
446 } | |
447 | |
448 bool LookupSlice(size_t& index, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
449 const CoordinateSystem3D& slice) const |
102 | 450 { |
451 bool opposite; | |
452 if (!GeometryToolbox::IsParallelOrOpposite(opposite, | |
453 reference_.GetNormal(), | |
454 slice.GetNormal())) | |
455 { | |
456 return false; | |
457 } | |
458 | |
459 double z = (reference_.ProjectAlongNormal(slice.GetOrigin()) - | |
460 reference_.ProjectAlongNormal(reference_.GetOrigin())) / sliceThickness_; | |
461 | |
462 int s = static_cast<int>(boost::math::iround(z)); | |
463 | |
464 if (s < 0 || | |
465 s >= static_cast<int>(depth_)) | |
466 { | |
467 return false; | |
468 } | |
469 else | |
470 { | |
471 index = static_cast<size_t>(s); | |
472 return true; | |
473 } | |
474 } | |
475 | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
476 Slice* GetSlice(size_t slice) const |
102 | 477 { |
216 | 478 if (slice >= depth_) |
102 | 479 { |
480 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
481 } | |
482 else | |
483 { | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
484 CoordinateSystem3D origin(reference_.GetOrigin() + |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
485 static_cast<double>(slice) * sliceThickness_ * reference_.GetNormal(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
486 reference_.GetAxisX(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
487 reference_.GetAxisY()); |
102 | 488 |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
489 return new Slice(origin, pixelSpacingX_, pixelSpacingY_, sliceThickness_, |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
490 width_, height_, converter_); |
102 | 491 } |
492 } | |
493 }; | |
494 | |
495 | |
496 | |
497 class VolumeImageSource : | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
498 public LayerSourceBase, |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
499 private ISlicedVolume::IObserver |
102 | 500 { |
501 private: | |
381
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
502 class RendererFactory : public LayerReadyMessage::IRendererFactory |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
503 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
504 private: |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
505 const Orthanc::ImageAccessor& frame_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
506 const Slice& slice_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
507 bool isFullQuality_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
508 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
509 public: |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
510 RendererFactory(const Orthanc::ImageAccessor& frame, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
511 const Slice& slice, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
512 bool isFullQuality) : |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
513 frame_(frame), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
514 slice_(slice), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
515 isFullQuality_(isFullQuality) |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
516 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
517 } |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
518 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
519 virtual ILayerRenderer* CreateRenderer() const |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
520 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
521 return FrameRenderer::CreateRenderer(frame_, slice_, isFullQuality_); |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
522 } |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
523 }; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
524 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
525 |
102 | 526 OrthancVolumeImage& volume_; |
527 std::auto_ptr<VolumeImageGeometry> axialGeometry_; | |
528 std::auto_ptr<VolumeImageGeometry> coronalGeometry_; | |
529 std::auto_ptr<VolumeImageGeometry> sagittalGeometry_; | |
530 | |
531 | |
532 bool IsGeometryReady() const | |
533 { | |
534 return axialGeometry_.get() != NULL; | |
535 } | |
536 | |
537 | |
538 virtual void NotifyGeometryReady(const ISlicedVolume& volume) | |
539 { | |
540 // These 3 values are only used to speed up the ILayerSource | |
541 axialGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Axial)); | |
542 coronalGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Coronal)); | |
543 sagittalGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Sagittal)); | |
544 | |
545 LayerSourceBase::NotifyGeometryReady(); | |
546 } | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
547 |
102 | 548 virtual void NotifyGeometryError(const ISlicedVolume& volume) |
549 { | |
550 LayerSourceBase::NotifyGeometryError(); | |
551 } | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
552 |
102 | 553 virtual void NotifyContentChange(const ISlicedVolume& volume) |
554 { | |
555 LayerSourceBase::NotifyContentChange(); | |
556 } | |
557 | |
558 virtual void NotifySliceChange(const ISlicedVolume& volume, | |
559 const size_t& sliceIndex, | |
560 const Slice& slice) | |
561 { | |
562 //LayerSourceBase::NotifySliceChange(slice); | |
563 | |
564 // TODO Improve this? | |
565 LayerSourceBase::NotifyContentChange(); | |
566 } | |
567 | |
138 | 568 virtual void NotifyVolumeReady(const ISlicedVolume& volume) |
569 { | |
570 } | |
102 | 571 |
572 const VolumeImageGeometry& GetProjectionGeometry(VolumeProjection projection) | |
573 { | |
574 if (!IsGeometryReady()) | |
575 { | |
576 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
577 } | |
578 | |
579 switch (projection) | |
580 { | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
581 case VolumeProjection_Axial: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
582 return *axialGeometry_; |
102 | 583 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
584 case VolumeProjection_Sagittal: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
585 return *sagittalGeometry_; |
102 | 586 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
587 case VolumeProjection_Coronal: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
588 return *coronalGeometry_; |
102 | 589 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
590 default: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
591 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
102 | 592 } |
593 } | |
594 | |
595 | |
596 bool DetectProjection(VolumeProjection& projection, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
597 const CoordinateSystem3D& viewportSlice) |
102 | 598 { |
599 bool isOpposite; // Ignored | |
600 | |
601 if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
602 viewportSlice.GetNormal(), | |
603 axialGeometry_->GetNormal())) | |
604 { | |
605 projection = VolumeProjection_Axial; | |
606 return true; | |
607 } | |
608 else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
609 viewportSlice.GetNormal(), | |
610 sagittalGeometry_->GetNormal())) | |
611 { | |
612 projection = VolumeProjection_Sagittal; | |
613 return true; | |
614 } | |
615 else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
616 viewportSlice.GetNormal(), | |
617 coronalGeometry_->GetNormal())) | |
618 { | |
619 projection = VolumeProjection_Coronal; | |
620 return true; | |
621 } | |
622 else | |
623 { | |
624 return false; | |
625 } | |
626 } | |
627 | |
628 | |
629 public: | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
630 VolumeImageSource(MessageBroker& broker, OrthancVolumeImage& volume) : |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
631 LayerSourceBase(broker), |
102 | 632 volume_(volume) |
633 { | |
634 volume_.Register(*this); | |
635 } | |
636 | |
637 virtual bool GetExtent(std::vector<Vector>& points, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
638 const CoordinateSystem3D& viewportSlice) |
102 | 639 { |
640 VolumeProjection projection; | |
641 | |
642 if (!IsGeometryReady() || | |
643 !DetectProjection(projection, viewportSlice)) | |
644 { | |
645 return false; | |
646 } | |
647 else | |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
648 { |
102 | 649 // As the slices of the volumic image are arranged in a box, |
650 // we only consider one single reference slice (the one with index 0). | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
651 std::auto_ptr<Slice> slice(GetProjectionGeometry(projection).GetSlice(0)); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
652 slice->GetExtent(points); |
102 | 653 |
654 return true; | |
655 } | |
656 } | |
657 | |
658 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
659 virtual void ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) |
102 | 660 { |
661 VolumeProjection projection; | |
662 | |
663 if (IsGeometryReady() && | |
664 DetectProjection(projection, viewportSlice)) | |
665 { | |
666 const VolumeImageGeometry& geometry = GetProjectionGeometry(projection); | |
667 | |
668 size_t closest; | |
669 | |
670 if (geometry.LookupSlice(closest, viewportSlice)) | |
671 { | |
672 bool isFullQuality = true; // TODO | |
673 | |
674 std::auto_ptr<Orthanc::Image> frame; | |
675 | |
676 { | |
677 ImageBuffer3D::SliceReader reader(volume_.GetImage(), projection, closest); | |
678 | |
679 // TODO Transfer ownership if non-axial, to avoid memcpy | |
680 frame.reset(Orthanc::Image::Clone(reader.GetAccessor())); | |
681 } | |
682 | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
683 std::auto_ptr<Slice> slice(geometry.GetSlice(closest)); |
381
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
684 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
685 RendererFactory factory(*frame, *slice, isFullQuality); |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
686 LayerSourceBase::NotifyLayerReady(factory, |
378 | 687 //new SliceOutlineRenderer(slice), |
380
ba5ad93f935a
ILayerSource::LayerErrorMessage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
378
diff
changeset
|
688 slice->GetGeometry()); |
102 | 689 return; |
690 } | |
691 } | |
692 | |
693 // Error | |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
694 CoordinateSystem3D slice; |
380
ba5ad93f935a
ILayerSource::LayerErrorMessage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
378
diff
changeset
|
695 LayerSourceBase::NotifyLayerError(slice); |
102 | 696 } |
697 }; | |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
698 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
699 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
700 class VolumeImageInteractor : |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
701 public IWorldSceneInteractor, |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
702 protected ISlicedVolume::IObserver |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
703 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
704 private: |
388
20f149669c1f
renamed LayerWidget as SliceViewerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
381
diff
changeset
|
705 SliceViewerWidget& widget_; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
706 VolumeProjection projection_; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
707 std::auto_ptr<VolumeImageGeometry> slices_; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
708 size_t slice_; |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
709 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
710 protected: |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
711 virtual void NotifyGeometryReady(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
712 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
713 if (slices_.get() == NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
714 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
715 const OrthancVolumeImage& image = dynamic_cast<const OrthancVolumeImage&>(volume); |
120
063f7f3d9f14
fix 3d locations of the doses
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
119
diff
changeset
|
716 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
717 slices_.reset(new VolumeImageGeometry(image, projection_)); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
718 SetSlice(slices_->GetSliceCount() / 2); |
120
063f7f3d9f14
fix 3d locations of the doses
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
119
diff
changeset
|
719 |
330 | 720 widget_.FitContent(); |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
721 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
722 } |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
723 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
724 virtual void NotifyGeometryError(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
725 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
726 } |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
727 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
728 virtual void NotifyContentChange(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
729 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
730 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
731 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
732 virtual void NotifySliceChange(const ISlicedVolume& volume, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
733 const size_t& sliceIndex, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
734 const Slice& slice) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
735 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
736 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
737 |
138 | 738 virtual void NotifyVolumeReady(const ISlicedVolume& volume) |
739 { | |
740 } | |
741 | |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
742 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
743 const ViewportGeometry& view, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
744 MouseButton button, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
745 double x, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
746 double y, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
747 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
748 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
749 return NULL; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
750 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
751 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
752 virtual void MouseOver(CairoContext& context, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
753 WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
754 const ViewportGeometry& view, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
755 double x, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
756 double y, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
757 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
758 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
759 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
760 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
761 virtual void MouseWheel(WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
762 MouseWheelDirection direction, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
763 KeyboardModifiers modifiers, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
764 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
765 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
766 int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1); |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
767 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
768 switch (direction) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
769 { |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
770 case MouseWheelDirection_Up: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
771 OffsetSlice(-scale); |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
772 break; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
773 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
774 case MouseWheelDirection_Down: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
775 OffsetSlice(scale); |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
776 break; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
777 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
778 default: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
779 break; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
780 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
781 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
782 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
783 virtual void KeyPressed(WorldSceneWidget& widget, |
327 | 784 KeyboardKeys key, |
785 char keyChar, | |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
786 KeyboardModifiers modifiers, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
787 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
788 { |
327 | 789 switch (keyChar) |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
790 { |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
791 case 's': |
330 | 792 widget.FitContent(); |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
793 break; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
794 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
795 default: |
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
796 break; |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
797 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
798 } |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
799 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
800 public: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
801 VolumeImageInteractor(OrthancVolumeImage& volume, |
388
20f149669c1f
renamed LayerWidget as SliceViewerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
381
diff
changeset
|
802 SliceViewerWidget& widget, |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
803 VolumeProjection projection) : |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
804 widget_(widget), |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
805 projection_(projection) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
806 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
807 volume.Register(*this); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
808 widget.SetInteractor(*this); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
809 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
810 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
811 bool IsGeometryReady() const |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
812 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
813 return slices_.get() != NULL; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
814 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
815 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
816 size_t GetSliceCount() const |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
817 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
818 if (slices_.get() == NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
819 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
820 return 0; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
821 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
822 else |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
823 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
824 return slices_->GetSliceCount(); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
825 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
826 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
827 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
828 void OffsetSlice(int offset) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
829 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
830 if (slices_.get() != NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
831 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
832 int slice = static_cast<int>(slice_) + offset; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
833 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
834 if (slice < 0) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
835 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
836 slice = 0; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
837 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
838 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
839 if (slice >= static_cast<int>(slices_->GetSliceCount())) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
840 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
841 slice = slices_->GetSliceCount() - 1; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
842 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
843 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
844 if (slice != static_cast<int>(slice_)) |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
845 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
846 SetSlice(slice); |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
847 } |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
848 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
849 } |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
850 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
851 void SetSlice(size_t slice) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
852 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
853 if (slices_.get() != NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
854 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
855 slice_ = slice; |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
856 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
857 std::auto_ptr<Slice> tmp(slices_->GetSlice(slice_)); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
858 widget_.SetSlice(tmp->GetGeometry()); |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
859 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
860 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
861 }; |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
862 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
863 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
864 |
390
0cb925325470
renamed SiblingSliceLocation as ReferenceLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
388
diff
changeset
|
865 class ReferenceLineSource : public LayerSourceBase |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
866 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
867 private: |
381
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
868 class RendererFactory : public LayerReadyMessage::IRendererFactory |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
869 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
870 private: |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
871 double x1_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
872 double y1_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
873 double x2_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
874 double y2_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
875 const CoordinateSystem3D& slice_; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
876 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
877 public: |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
878 RendererFactory(double x1, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
879 double y1, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
880 double x2, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
881 double y2, |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
882 const CoordinateSystem3D& slice) : |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
883 x1_(x1), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
884 y1_(y1), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
885 x2_(x2), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
886 y2_(y2), |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
887 slice_(slice) |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
888 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
889 } |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
890 |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
891 virtual ILayerRenderer* CreateRenderer() const |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
892 { |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
893 return new LineLayerRenderer(x1_, y1_, x2_, y2_, slice_); |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
894 } |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
895 }; |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
896 |
388
20f149669c1f
renamed LayerWidget as SliceViewerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
381
diff
changeset
|
897 SliceViewerWidget& otherPlane_; |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
898 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
899 public: |
390
0cb925325470
renamed SiblingSliceLocation as ReferenceLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
388
diff
changeset
|
900 ReferenceLineSource(MessageBroker& broker, |
0cb925325470
renamed SiblingSliceLocation as ReferenceLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
388
diff
changeset
|
901 SliceViewerWidget& otherPlane) : |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
902 LayerSourceBase(broker), |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
903 otherPlane_(otherPlane) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
904 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
905 NotifyGeometryReady(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
906 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
907 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
908 virtual bool GetExtent(std::vector<Vector>& points, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
909 const CoordinateSystem3D& viewportSlice) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
910 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
911 return false; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
912 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
913 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
914 virtual void ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
915 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
916 Slice reference(viewportSlice, 0.001); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
917 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
918 Vector p, d; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
919 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
920 const CoordinateSystem3D& slice = otherPlane_.GetSlice(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
921 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
922 // Compute the line of intersection between the two slices |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
923 if (!GeometryToolbox::IntersectTwoPlanes(p, d, |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
924 slice.GetOrigin(), slice.GetNormal(), |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
925 viewportSlice.GetOrigin(), viewportSlice.GetNormal())) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
926 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
927 // The two slice are parallel, don't try and display the intersection |
380
ba5ad93f935a
ILayerSource::LayerErrorMessage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
378
diff
changeset
|
928 NotifyLayerError(reference.GetGeometry()); |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
929 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
930 else |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
931 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
932 double x1, y1, x2, y2; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
933 viewportSlice.ProjectPoint(x1, y1, p); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
934 viewportSlice.ProjectPoint(x2, y2, p + 1000.0 * d); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
935 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
936 const Extent2D extent = otherPlane_.GetSceneExtent(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
937 |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
938 if (GeometryToolbox::ClipLineToRectangle(x1, y1, x2, y2, |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
939 x1, y1, x2, y2, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
940 extent.GetX1(), extent.GetY1(), |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
941 extent.GetX2(), extent.GetY2())) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
942 { |
381
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
943 RendererFactory factory(x1, y1, x2, y2, slice); |
19bd222283ae
uncoupling LayerReadyMessage from the creation of the renderer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
380
diff
changeset
|
944 NotifyLayerReady(factory, reference.GetGeometry()); |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
945 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
946 else |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
947 { |
380
ba5ad93f935a
ILayerSource::LayerErrorMessage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
378
diff
changeset
|
948 // Error: Parallel slices |
ba5ad93f935a
ILayerSource::LayerErrorMessage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
378
diff
changeset
|
949 NotifyLayerError(reference.GetGeometry()); |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
950 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
951 } |
318
3a4ca166fafa
ImageAccessor refactoring + implemented Image Cache in SmartLoader
am@osimis.io
parents:
300
diff
changeset
|
952 } |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
953 }; |
102 | 954 } |