Mercurial > hg > orthanc-stone
annotate Framework/dev.h @ 254:abc1c6231947 am-2
cleanup
author | am@osimis.io |
---|---|
date | Tue, 03 Jul 2018 11:49:02 +0200 |
parents | 40b21c1f8b8d |
children | c9cf95b49a86 |
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. | |
16 * | |
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" |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
28 #include "Widgets/LayerWidget.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 |
102 | 44 class OrthancVolumeImage : |
45 public SlicedVolumeBase, | |
252 | 46 private OrthancSlicesLoader::ISliceLoaderObserver |
102 | 47 { |
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 | |
67 static bool IsCompatible(const Slice& a, | |
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 | |
101 static double GetDistance(const Slice& a, | |
102 const Slice& b) | |
103 { | |
104 return fabs(a.GetGeometry().ProjectAlongNormal(a.GetGeometry().GetOrigin()) - | |
105 a.GetGeometry().ProjectAlongNormal(b.GetGeometry().GetOrigin())); | |
106 } | |
107 | |
108 | |
252 | 109 virtual 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(); | |
154 LOG(INFO) << "Creating a volume image of size " << width << "x" << height | |
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()); |
159 image_->SetVoxelDimensions(loader.GetSlice(0).GetPixelSpacingX(), | |
160 loader.GetSlice(0).GetPixelSpacingY(), spacingZ); | |
161 image_->Clear(); | |
120
063f7f3d9f14
fix 3d locations of the doses
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
119
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 OnSliceGeometryError(const OrthancSlicesLoader& loader) |
102 | 177 { |
178 LOG(ERROR) << "Unable to download a volume image"; | |
179 SlicedVolumeBase::NotifyGeometryError(); | |
180 } | |
181 | |
252 | 182 virtual void OnSliceImageReady(const OrthancSlicesLoader& loader, |
102 | 183 unsigned int sliceIndex, |
184 const Slice& slice, | |
185 std::auto_ptr<Orthanc::ImageAccessor>& image, | |
186 SliceImageQuality quality) | |
187 { | |
188 { | |
189 ImageBuffer3D::SliceWriter writer(*image_, VolumeProjection_Axial, sliceIndex); | |
190 Orthanc::ImageProcessing::Copy(writer.GetAccessor(), *image); | |
191 } | |
192 | |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
193 SlicedVolumeBase::NotifySliceChange(sliceIndex, slice); |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
194 |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
195 if (pendingSlices_ == 1) |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
196 { |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
197 SlicedVolumeBase::NotifyVolumeReady(); |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
198 pendingSlices_ = 0; |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
199 } |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
200 else if (pendingSlices_ > 1) |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
201 { |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
202 pendingSlices_ -= 1; |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
203 } |
102 | 204 |
205 ScheduleSliceDownload(); | |
206 } | |
207 | |
252 | 208 virtual void OnSliceImageError(const OrthancSlicesLoader& loader, |
102 | 209 unsigned int sliceIndex, |
210 const Slice& slice, | |
211 SliceImageQuality quality) | |
212 { | |
213 LOG(ERROR) << "Cannot download slice " << sliceIndex << " in a volume image"; | |
214 ScheduleSliceDownload(); | |
215 } | |
216 | |
217 public: | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
218 OrthancVolumeImage(MessageBroker& broker, |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
219 IWebService& orthanc, |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
220 bool computeRange) : |
252 | 221 OrthancSlicesLoader::ISliceLoaderObserver(broker), |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
222 loader_(broker, *this, orthanc), |
136
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
223 computeRange_(computeRange), |
a06ad9d7406e
ISlicedVolume::NotifyVolumeReady
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
224 pendingSlices_(0) |
102 | 225 { |
226 } | |
227 | |
228 void ScheduleLoadSeries(const std::string& seriesId) | |
229 { | |
230 loader_.ScheduleLoadSeries(seriesId); | |
231 } | |
232 | |
117
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
233 void ScheduleLoadInstance(const std::string& instanceId) |
102 | 234 { |
117
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
235 loader_.ScheduleLoadInstance(instanceId); |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
236 } |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
237 |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
238 void ScheduleLoadFrame(const std::string& instanceId, |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
239 unsigned int frame) |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
240 { |
42c05a3baee3
loading multi-frame instances as 3D volumes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
241 loader_.ScheduleLoadFrame(instanceId, frame); |
102 | 242 } |
243 | |
244 virtual size_t GetSliceCount() const | |
245 { | |
246 return loader_.GetSliceCount(); | |
247 } | |
248 | |
249 virtual const Slice& GetSlice(size_t index) const | |
250 { | |
251 return loader_.GetSlice(index); | |
252 } | |
253 | |
254 ImageBuffer3D& GetImage() const | |
255 { | |
256 if (image_.get() == NULL) | |
257 { | |
258 // The geometry is not ready yet | |
259 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
260 } | |
261 else | |
262 { | |
263 return *image_; | |
264 } | |
265 } | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
266 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
267 bool FitWindowingToRange(RenderStyle& style, |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
268 const DicomFrameConverter& converter) const |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
269 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
270 if (image_.get() == NULL) |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
271 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
272 return false; |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
273 } |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
274 else |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
275 { |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
276 return image_->FitWindowingToRange(style, converter); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
277 } |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
278 } |
102 | 279 }; |
280 | |
281 | |
282 class VolumeImageGeometry | |
283 { | |
284 private: | |
285 unsigned int width_; | |
286 unsigned int height_; | |
287 size_t depth_; | |
288 double pixelSpacingX_; | |
289 double pixelSpacingY_; | |
290 double sliceThickness_; | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
291 CoordinateSystem3D reference_; |
102 | 292 DicomFrameConverter converter_; |
293 | |
294 double ComputeAxialThickness(const OrthancVolumeImage& volume) const | |
295 { | |
296 double thickness; | |
297 | |
298 size_t n = volume.GetSliceCount(); | |
299 if (n > 1) | |
300 { | |
301 const Slice& a = volume.GetSlice(0); | |
302 const Slice& b = volume.GetSlice(n - 1); | |
303 thickness = ((reference_.ProjectAlongNormal(b.GetGeometry().GetOrigin()) - | |
304 reference_.ProjectAlongNormal(a.GetGeometry().GetOrigin())) / | |
305 (static_cast<double>(n) - 1.0)); | |
306 } | |
307 else | |
308 { | |
309 thickness = volume.GetSlice(0).GetThickness(); | |
310 } | |
311 | |
312 if (thickness <= 0) | |
313 { | |
314 // The slices should have been sorted with increasing Z | |
315 // (along the normal) by the OrthancSlicesLoader | |
316 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
317 } | |
318 else | |
319 { | |
320 return thickness; | |
321 } | |
322 } | |
323 | |
324 void SetupAxial(const OrthancVolumeImage& volume) | |
325 { | |
326 const Slice& axial = volume.GetSlice(0); | |
327 | |
328 width_ = axial.GetWidth(); | |
329 height_ = axial.GetHeight(); | |
330 depth_ = volume.GetSliceCount(); | |
331 | |
332 pixelSpacingX_ = axial.GetPixelSpacingX(); | |
333 pixelSpacingY_ = axial.GetPixelSpacingY(); | |
334 sliceThickness_ = ComputeAxialThickness(volume); | |
335 | |
336 reference_ = axial.GetGeometry(); | |
337 } | |
338 | |
339 void SetupCoronal(const OrthancVolumeImage& volume) | |
340 { | |
341 const Slice& axial = volume.GetSlice(0); | |
342 double axialThickness = ComputeAxialThickness(volume); | |
343 | |
344 width_ = axial.GetWidth(); | |
345 height_ = volume.GetSliceCount(); | |
346 depth_ = axial.GetHeight(); | |
347 | |
348 pixelSpacingX_ = axial.GetPixelSpacingX(); | |
349 pixelSpacingY_ = axialThickness; | |
350 sliceThickness_ = axial.GetPixelSpacingY(); | |
351 | |
352 Vector origin = axial.GetGeometry().GetOrigin(); | |
353 origin += (static_cast<double>(volume.GetSliceCount() - 1) * | |
354 axialThickness * axial.GetGeometry().GetNormal()); | |
355 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
356 reference_ = CoordinateSystem3D(origin, |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
357 axial.GetGeometry().GetAxisX(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
358 -axial.GetGeometry().GetNormal()); |
102 | 359 } |
360 | |
361 void SetupSagittal(const OrthancVolumeImage& volume) | |
362 { | |
363 const Slice& axial = volume.GetSlice(0); | |
364 double axialThickness = ComputeAxialThickness(volume); | |
365 | |
366 width_ = axial.GetHeight(); | |
367 height_ = volume.GetSliceCount(); | |
368 depth_ = axial.GetWidth(); | |
369 | |
370 pixelSpacingX_ = axial.GetPixelSpacingY(); | |
371 pixelSpacingY_ = axialThickness; | |
372 sliceThickness_ = axial.GetPixelSpacingX(); | |
373 | |
374 Vector origin = axial.GetGeometry().GetOrigin(); | |
375 origin += (static_cast<double>(volume.GetSliceCount() - 1) * | |
376 axialThickness * axial.GetGeometry().GetNormal()); | |
377 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
378 reference_ = CoordinateSystem3D(origin, |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
379 axial.GetGeometry().GetAxisY(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
380 axial.GetGeometry().GetNormal()); |
102 | 381 } |
382 | |
383 public: | |
384 VolumeImageGeometry(const OrthancVolumeImage& volume, | |
385 VolumeProjection projection) | |
386 { | |
387 if (volume.GetSliceCount() == 0) | |
388 { | |
389 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
390 } | |
391 | |
392 converter_ = volume.GetSlice(0).GetConverter(); | |
393 | |
394 switch (projection) | |
395 { | |
396 case VolumeProjection_Axial: | |
397 SetupAxial(volume); | |
398 break; | |
399 | |
400 case VolumeProjection_Coronal: | |
401 SetupCoronal(volume); | |
402 break; | |
403 | |
404 case VolumeProjection_Sagittal: | |
405 SetupSagittal(volume); | |
406 break; | |
407 | |
408 default: | |
409 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
410 } | |
411 } | |
412 | |
413 size_t GetSliceCount() const | |
414 { | |
415 return depth_; | |
416 } | |
417 | |
418 const Vector& GetNormal() const | |
419 { | |
420 return reference_.GetNormal(); | |
421 } | |
422 | |
423 bool LookupSlice(size_t& index, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
424 const CoordinateSystem3D& slice) const |
102 | 425 { |
426 bool opposite; | |
427 if (!GeometryToolbox::IsParallelOrOpposite(opposite, | |
428 reference_.GetNormal(), | |
429 slice.GetNormal())) | |
430 { | |
431 return false; | |
432 } | |
433 | |
434 double z = (reference_.ProjectAlongNormal(slice.GetOrigin()) - | |
435 reference_.ProjectAlongNormal(reference_.GetOrigin())) / sliceThickness_; | |
436 | |
437 int s = static_cast<int>(boost::math::iround(z)); | |
438 | |
439 if (s < 0 || | |
440 s >= static_cast<int>(depth_)) | |
441 { | |
442 return false; | |
443 } | |
444 else | |
445 { | |
446 index = static_cast<size_t>(s); | |
447 return true; | |
448 } | |
449 } | |
450 | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
451 Slice* GetSlice(size_t slice) const |
102 | 452 { |
216 | 453 if (slice >= depth_) |
102 | 454 { |
455 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
456 } | |
457 else | |
458 { | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
459 CoordinateSystem3D origin(reference_.GetOrigin() + |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
460 static_cast<double>(slice) * sliceThickness_ * reference_.GetNormal(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
461 reference_.GetAxisX(), |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
462 reference_.GetAxisY()); |
102 | 463 |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
464 return new Slice(origin, pixelSpacingX_, pixelSpacingY_, sliceThickness_, |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
465 width_, height_, converter_); |
102 | 466 } |
467 } | |
468 }; | |
469 | |
470 | |
471 | |
472 class VolumeImageSource : | |
473 public LayerSourceBase, | |
474 private ISlicedVolume::IObserver | |
475 { | |
476 private: | |
477 OrthancVolumeImage& volume_; | |
478 std::auto_ptr<VolumeImageGeometry> axialGeometry_; | |
479 std::auto_ptr<VolumeImageGeometry> coronalGeometry_; | |
480 std::auto_ptr<VolumeImageGeometry> sagittalGeometry_; | |
481 | |
482 | |
483 bool IsGeometryReady() const | |
484 { | |
485 return axialGeometry_.get() != NULL; | |
486 } | |
487 | |
488 | |
489 virtual void NotifyGeometryReady(const ISlicedVolume& volume) | |
490 { | |
491 // These 3 values are only used to speed up the ILayerSource | |
492 axialGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Axial)); | |
493 coronalGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Coronal)); | |
494 sagittalGeometry_.reset(new VolumeImageGeometry(volume_, VolumeProjection_Sagittal)); | |
495 | |
496 LayerSourceBase::NotifyGeometryReady(); | |
497 } | |
498 | |
499 virtual void NotifyGeometryError(const ISlicedVolume& volume) | |
500 { | |
501 LayerSourceBase::NotifyGeometryError(); | |
502 } | |
503 | |
504 virtual void NotifyContentChange(const ISlicedVolume& volume) | |
505 { | |
506 LayerSourceBase::NotifyContentChange(); | |
507 } | |
508 | |
509 virtual void NotifySliceChange(const ISlicedVolume& volume, | |
510 const size_t& sliceIndex, | |
511 const Slice& slice) | |
512 { | |
513 //LayerSourceBase::NotifySliceChange(slice); | |
514 | |
515 // TODO Improve this? | |
516 LayerSourceBase::NotifyContentChange(); | |
517 } | |
518 | |
138 | 519 virtual void NotifyVolumeReady(const ISlicedVolume& volume) |
520 { | |
521 } | |
102 | 522 |
523 const VolumeImageGeometry& GetProjectionGeometry(VolumeProjection projection) | |
524 { | |
525 if (!IsGeometryReady()) | |
526 { | |
527 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
528 } | |
529 | |
530 switch (projection) | |
531 { | |
532 case VolumeProjection_Axial: | |
533 return *axialGeometry_; | |
534 | |
535 case VolumeProjection_Sagittal: | |
536 return *sagittalGeometry_; | |
537 | |
538 case VolumeProjection_Coronal: | |
539 return *coronalGeometry_; | |
540 | |
541 default: | |
542 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
543 } | |
544 } | |
545 | |
546 | |
547 bool DetectProjection(VolumeProjection& projection, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
548 const CoordinateSystem3D& viewportSlice) |
102 | 549 { |
550 bool isOpposite; // Ignored | |
551 | |
552 if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
553 viewportSlice.GetNormal(), | |
554 axialGeometry_->GetNormal())) | |
555 { | |
556 projection = VolumeProjection_Axial; | |
557 return true; | |
558 } | |
559 else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
560 viewportSlice.GetNormal(), | |
561 sagittalGeometry_->GetNormal())) | |
562 { | |
563 projection = VolumeProjection_Sagittal; | |
564 return true; | |
565 } | |
566 else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, | |
567 viewportSlice.GetNormal(), | |
568 coronalGeometry_->GetNormal())) | |
569 { | |
570 projection = VolumeProjection_Coronal; | |
571 return true; | |
572 } | |
573 else | |
574 { | |
575 return false; | |
576 } | |
577 } | |
578 | |
579 | |
580 public: | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
581 VolumeImageSource(MessageBroker& broker, OrthancVolumeImage& volume) : |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
582 LayerSourceBase(broker), |
102 | 583 volume_(volume) |
584 { | |
585 volume_.Register(*this); | |
586 } | |
587 | |
588 virtual bool GetExtent(std::vector<Vector>& points, | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
589 const CoordinateSystem3D& viewportSlice) |
102 | 590 { |
591 VolumeProjection projection; | |
592 | |
593 if (!IsGeometryReady() || | |
594 !DetectProjection(projection, viewportSlice)) | |
595 { | |
596 return false; | |
597 } | |
598 else | |
599 { | |
600 // As the slices of the volumic image are arranged in a box, | |
601 // 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
|
602 std::auto_ptr<Slice> slice(GetProjectionGeometry(projection).GetSlice(0)); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
603 slice->GetExtent(points); |
102 | 604 |
605 return true; | |
606 } | |
607 } | |
608 | |
609 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
104
diff
changeset
|
610 virtual void ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) |
102 | 611 { |
612 VolumeProjection projection; | |
613 | |
614 if (IsGeometryReady() && | |
615 DetectProjection(projection, viewportSlice)) | |
616 { | |
617 const VolumeImageGeometry& geometry = GetProjectionGeometry(projection); | |
618 | |
619 size_t closest; | |
620 | |
621 if (geometry.LookupSlice(closest, viewportSlice)) | |
622 { | |
623 bool isFullQuality = true; // TODO | |
624 | |
625 std::auto_ptr<Orthanc::Image> frame; | |
626 | |
627 { | |
628 ImageBuffer3D::SliceReader reader(volume_.GetImage(), projection, closest); | |
629 | |
630 // TODO Transfer ownership if non-axial, to avoid memcpy | |
631 frame.reset(Orthanc::Image::Clone(reader.GetAccessor())); | |
632 } | |
633 | |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
634 std::auto_ptr<Slice> slice(geometry.GetSlice(closest)); |
102 | 635 LayerSourceBase::NotifyLayerReady( |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
636 FrameRenderer::CreateRenderer(frame.release(), *slice, isFullQuality), |
102 | 637 //new SliceOutlineRenderer(slice), |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
638 slice->GetGeometry(), false); |
102 | 639 return; |
640 } | |
641 } | |
642 | |
643 // Error | |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
644 CoordinateSystem3D slice; |
102 | 645 LayerSourceBase::NotifyLayerReady(NULL, slice, true); |
646 } | |
647 }; | |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
648 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
649 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
650 class VolumeImageInteractor : |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
651 public IWorldSceneInteractor, |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
652 protected ISlicedVolume::IObserver |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
653 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
654 private: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
655 LayerWidget& widget_; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
656 VolumeProjection projection_; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
657 std::auto_ptr<VolumeImageGeometry> slices_; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
658 size_t slice_; |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
659 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
660 protected: |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
661 virtual void NotifyGeometryReady(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
662 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
663 if (slices_.get() == NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
664 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
665 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
|
666 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
667 slices_.reset(new VolumeImageGeometry(image, projection_)); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
668 SetSlice(slices_->GetSliceCount() / 2); |
120
063f7f3d9f14
fix 3d locations of the doses
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
119
diff
changeset
|
669 |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
670 widget_.SetDefaultView(); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
671 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
672 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
673 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
674 virtual void NotifyGeometryError(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
675 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
676 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
677 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
678 virtual void NotifyContentChange(const ISlicedVolume& volume) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
679 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
680 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
681 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
682 virtual void NotifySliceChange(const ISlicedVolume& volume, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
683 const size_t& sliceIndex, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
684 const Slice& slice) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
685 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
686 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
687 |
138 | 688 virtual void NotifyVolumeReady(const ISlicedVolume& volume) |
689 { | |
690 } | |
691 | |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
692 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
693 const ViewportGeometry& view, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
694 MouseButton button, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
695 double x, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
696 double y, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
697 IStatusBar* statusBar) |
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 return NULL; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
700 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
701 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
702 virtual void MouseOver(CairoContext& context, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
703 WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
704 const ViewportGeometry& view, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
705 double x, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
706 double y, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
707 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
708 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
709 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
710 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
711 virtual void MouseWheel(WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
712 MouseWheelDirection direction, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
713 KeyboardModifiers modifiers, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
714 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
715 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
716 int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
717 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
718 switch (direction) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
719 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
720 case MouseWheelDirection_Up: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
721 OffsetSlice(-scale); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
722 break; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
723 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
724 case MouseWheelDirection_Down: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
725 OffsetSlice(scale); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
726 break; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
727 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
728 default: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
729 break; |
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 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
733 virtual void KeyPressed(WorldSceneWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
734 char key, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
735 KeyboardModifiers modifiers, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
736 IStatusBar* statusBar) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
737 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
738 switch (key) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
739 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
740 case 's': |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
741 widget.SetDefaultView(); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
742 break; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
743 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
744 default: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
745 break; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
746 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
747 } |
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 public: |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
750 VolumeImageInteractor(OrthancVolumeImage& volume, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
751 LayerWidget& widget, |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
752 VolumeProjection projection) : |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
753 widget_(widget), |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
754 projection_(projection) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
755 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
756 volume.Register(*this); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
757 widget.SetInteractor(*this); |
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 bool IsGeometryReady() const |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
761 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
762 return slices_.get() != NULL; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
763 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
764 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
765 size_t GetSliceCount() const |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
766 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
767 if (slices_.get() == NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
768 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
769 return 0; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
770 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
771 else |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
772 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
773 return slices_->GetSliceCount(); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
774 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
775 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
776 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
777 void OffsetSlice(int offset) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
778 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
779 if (slices_.get() != NULL) |
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 int slice = static_cast<int>(slice_) + offset; |
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 if (slice < 0) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
784 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
785 slice = 0; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
786 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
787 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
788 if (slice >= static_cast<int>(slices_->GetSliceCount())) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
789 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
790 slice = slices_->GetSliceCount() - 1; |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
791 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
792 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
793 if (slice != static_cast<int>(slice_)) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
794 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
795 SetSlice(slice); |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
796 } |
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 } |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
799 |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
800 void SetSlice(size_t slice) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
801 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
802 if (slices_.get() != NULL) |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
803 { |
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
804 slice_ = slice; |
119
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
805 |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
806 std::auto_ptr<Slice> tmp(slices_->GetSlice(slice_)); |
ba83e38cf3ff
rendering of rt-dose
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
117
diff
changeset
|
807 widget_.SetSlice(tmp->GetGeometry()); |
104
eccd64f8e297
VolumeImageInteractor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
102
diff
changeset
|
808 } |
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 }; |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
811 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
812 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
813 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
814 class SliceLocationSource : public LayerSourceBase |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
815 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
816 private: |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
817 LayerWidget& otherPlane_; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
818 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
819 public: |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
820 SliceLocationSource(MessageBroker& broker, LayerWidget& otherPlane) : |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
216
diff
changeset
|
821 LayerSourceBase(broker), |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
822 otherPlane_(otherPlane) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
823 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
824 NotifyGeometryReady(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
825 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
826 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
827 virtual bool GetExtent(std::vector<Vector>& points, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
828 const CoordinateSystem3D& viewportSlice) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
829 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
830 return false; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
831 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
832 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
833 virtual void ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
834 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
835 Slice reference(viewportSlice, 0.001); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
836 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
837 Vector p, d; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
838 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
839 const CoordinateSystem3D& slice = otherPlane_.GetSlice(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
840 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
841 // Compute the line of intersection between the two slices |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
842 if (!GeometryToolbox::IntersectTwoPlanes(p, d, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
843 slice.GetOrigin(), slice.GetNormal(), |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
844 viewportSlice.GetOrigin(), viewportSlice.GetNormal())) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
845 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
846 // The two slice are parallel, don't try and display the intersection |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
847 NotifyLayerReady(NULL, reference.GetGeometry(), false); |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
848 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
849 else |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
850 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
851 double x1, y1, x2, y2; |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
852 viewportSlice.ProjectPoint(x1, y1, p); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
853 viewportSlice.ProjectPoint(x2, y2, p + 1000.0 * d); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
854 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
855 const Extent2D extent = otherPlane_.GetSceneExtent(); |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
856 |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
857 if (GeometryToolbox::ClipLineToRectangle(x1, y1, x2, y2, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
858 x1, y1, x2, y2, |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
859 extent.GetX1(), extent.GetY1(), |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
860 extent.GetX2(), extent.GetY2())) |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
861 { |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
862 NotifyLayerReady(new LineLayerRenderer(x1, y1, x2, y2, slice), reference.GetGeometry(), false); |
112
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 else |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
865 { |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
866 // Parallel slices |
121
e66b2c757790
displaying rt-struct
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
120
diff
changeset
|
867 NotifyLayerReady(NULL, reference.GetGeometry(), false); |
112
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
868 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
869 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
870 } |
948f86e61e83
start of SliceLocationSource
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
110
diff
changeset
|
871 }; |
102 | 872 } |