Mercurial > hg > orthanc-stone
comparison Framework/Radiography/RadiographyScene.h @ 408:6834c236b36d
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 12 Nov 2018 14:52:10 +0100 |
parents | |
children | 99c9b3238008 |
comparison
equal
deleted
inserted
replaced
407:842a3c7cfdc0 | 408:6834c236b36d |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium | |
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 "../Toolbox/Extent2D.h" | |
25 #include "../Toolbox/LinearAlgebra.h" | |
26 #include "../Toolbox/OrthancApiClient.h" | |
27 #include "../Viewport/CairoContext.h" | |
28 | |
29 | |
30 namespace OrthancStone | |
31 { | |
32 class RadiographyScene : | |
33 public IObserver, | |
34 public IObservable | |
35 { | |
36 public: | |
37 typedef OriginMessage<MessageType_Widget_GeometryChanged, RadiographyScene> GeometryChangedMessage; | |
38 typedef OriginMessage<MessageType_Widget_ContentChanged, RadiographyScene> ContentChangedMessage; | |
39 | |
40 enum Corner | |
41 { | |
42 Corner_TopLeft, | |
43 Corner_TopRight, | |
44 Corner_BottomLeft, | |
45 Corner_BottomRight | |
46 }; | |
47 | |
48 class Layer : public boost::noncopyable | |
49 { | |
50 friend class RadiographyScene; | |
51 | |
52 private: | |
53 size_t index_; | |
54 bool hasSize_; | |
55 unsigned int width_; | |
56 unsigned int height_; | |
57 bool hasCrop_; | |
58 unsigned int cropX_; | |
59 unsigned int cropY_; | |
60 unsigned int cropWidth_; | |
61 unsigned int cropHeight_; | |
62 Matrix transform_; | |
63 Matrix transformInverse_; | |
64 double pixelSpacingX_; | |
65 double pixelSpacingY_; | |
66 double panX_; | |
67 double panY_; | |
68 double angle_; | |
69 bool resizeable_; | |
70 | |
71 | |
72 protected: | |
73 const Matrix& GetTransform() const | |
74 { | |
75 return transform_; | |
76 } | |
77 | |
78 | |
79 private: | |
80 void UpdateTransform(); | |
81 | |
82 void AddToExtent(Extent2D& extent, | |
83 double x, | |
84 double y) const; | |
85 | |
86 void GetCornerInternal(double& x, | |
87 double& y, | |
88 Corner corner, | |
89 unsigned int cropX, | |
90 unsigned int cropY, | |
91 unsigned int cropWidth, | |
92 unsigned int cropHeight) const; | |
93 | |
94 void SetIndex(size_t index) | |
95 { | |
96 index_ = index; | |
97 } | |
98 | |
99 bool Contains(double x, | |
100 double y) const; | |
101 | |
102 void DrawBorders(CairoContext& context, | |
103 double zoom); | |
104 | |
105 public: | |
106 Layer(); | |
107 | |
108 virtual ~Layer() | |
109 { | |
110 } | |
111 | |
112 size_t GetIndex() const | |
113 { | |
114 return index_; | |
115 } | |
116 | |
117 void ResetCrop() | |
118 { | |
119 hasCrop_ = false; | |
120 } | |
121 | |
122 void SetCrop(unsigned int x, | |
123 unsigned int y, | |
124 unsigned int width, | |
125 unsigned int height); | |
126 | |
127 void GetCrop(unsigned int& x, | |
128 unsigned int& y, | |
129 unsigned int& width, | |
130 unsigned int& height) const; | |
131 | |
132 void SetAngle(double angle); | |
133 | |
134 double GetAngle() const | |
135 { | |
136 return angle_; | |
137 } | |
138 | |
139 void SetSize(unsigned int width, | |
140 unsigned int height); | |
141 | |
142 unsigned int GetWidth() const | |
143 { | |
144 return width_; | |
145 } | |
146 | |
147 unsigned int GetHeight() const | |
148 { | |
149 return height_; | |
150 } | |
151 | |
152 Extent2D GetExtent() const; | |
153 | |
154 bool GetPixel(unsigned int& imageX, | |
155 unsigned int& imageY, | |
156 double sceneX, | |
157 double sceneY) const; | |
158 | |
159 void SetPan(double x, | |
160 double y); | |
161 | |
162 void SetPixelSpacing(double x, | |
163 double y); | |
164 | |
165 double GetPixelSpacingX() const | |
166 { | |
167 return pixelSpacingX_; | |
168 } | |
169 | |
170 double GetPixelSpacingY() const | |
171 { | |
172 return pixelSpacingY_; | |
173 } | |
174 | |
175 double GetPanX() const | |
176 { | |
177 return panX_; | |
178 } | |
179 | |
180 double GetPanY() const | |
181 { | |
182 return panY_; | |
183 } | |
184 | |
185 void GetCenter(double& centerX, | |
186 double& centerY) const; | |
187 | |
188 void GetCorner(double& x /* out */, | |
189 double& y /* out */, | |
190 Corner corner) const; | |
191 | |
192 bool LookupCorner(Corner& corner /* out */, | |
193 double x, | |
194 double y, | |
195 double zoom, | |
196 double viewportDistance) const; | |
197 | |
198 bool IsResizeable() const | |
199 { | |
200 return resizeable_; | |
201 } | |
202 | |
203 void SetResizeable(bool resizeable) | |
204 { | |
205 resizeable_ = resizeable; | |
206 } | |
207 | |
208 virtual bool GetDefaultWindowing(float& center, | |
209 float& width) const = 0; | |
210 | |
211 virtual void Render(Orthanc::ImageAccessor& buffer, | |
212 const Matrix& viewTransform, | |
213 ImageInterpolation interpolation) const = 0; | |
214 | |
215 virtual bool GetRange(float& minValue, | |
216 float& maxValue) const = 0; | |
217 }; | |
218 | |
219 | |
220 class LayerAccessor : public boost::noncopyable | |
221 { | |
222 private: | |
223 RadiographyScene& scene_; | |
224 size_t index_; | |
225 Layer* layer_; | |
226 | |
227 public: | |
228 LayerAccessor(RadiographyScene& scene, | |
229 size_t index); | |
230 | |
231 LayerAccessor(RadiographyScene& scene, | |
232 double x, | |
233 double y); | |
234 | |
235 void Invalidate() | |
236 { | |
237 layer_ = NULL; | |
238 } | |
239 | |
240 bool IsValid() const | |
241 { | |
242 return layer_ != NULL; | |
243 } | |
244 | |
245 RadiographyScene& GetScene() const; | |
246 | |
247 size_t GetIndex() const; | |
248 | |
249 Layer& GetLayer() const; | |
250 }; | |
251 | |
252 | |
253 private: | |
254 class AlphaLayer; | |
255 class DicomLayer; | |
256 | |
257 typedef std::map<size_t, Layer*> Layers; | |
258 | |
259 OrthancApiClient& orthanc_; | |
260 size_t countLayers_; | |
261 bool hasWindowing_; | |
262 float windowingCenter_; | |
263 float windowingWidth_; | |
264 Layers layers_; | |
265 | |
266 Layer& RegisterLayer(Layer* layer); | |
267 | |
268 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message); | |
269 | |
270 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message); | |
271 | |
272 void OnDicomExported(const OrthancApiClient::JsonResponseReadyMessage& message); | |
273 | |
274 public: | |
275 RadiographyScene(MessageBroker& broker, | |
276 OrthancApiClient& orthanc); | |
277 | |
278 virtual ~RadiographyScene(); | |
279 | |
280 bool GetWindowing(float& center, | |
281 float& width) const; | |
282 | |
283 void GetWindowingWithDefault(float& center, | |
284 float& width) const; | |
285 | |
286 void SetWindowing(float center, | |
287 float width); | |
288 | |
289 Layer& LoadText(const Orthanc::Font& font, | |
290 const std::string& utf8); | |
291 | |
292 Layer& LoadTestBlock(unsigned int width, | |
293 unsigned int height); | |
294 | |
295 Layer& LoadDicomFrame(const std::string& instance, | |
296 unsigned int frame, | |
297 bool httpCompression); | |
298 | |
299 Extent2D GetSceneExtent() const; | |
300 | |
301 void Render(Orthanc::ImageAccessor& buffer, | |
302 const Matrix& viewTransform, | |
303 ImageInterpolation interpolation) const; | |
304 | |
305 bool LookupLayer(size_t& index /* out */, | |
306 double x, | |
307 double y) const; | |
308 | |
309 void DrawBorder(CairoContext& context, | |
310 unsigned int layer, | |
311 double zoom); | |
312 | |
313 void GetRange(float& minValue, | |
314 float& maxValue) const; | |
315 | |
316 // Export using PAM is faster than using PNG, but requires Orthanc | |
317 // core >= 1.4.3 | |
318 void ExportDicom(const Orthanc::DicomMap& dicom, | |
319 double pixelSpacingX, | |
320 double pixelSpacingY, | |
321 bool invert, | |
322 ImageInterpolation interpolation, | |
323 bool usePam); | |
324 }; | |
325 } |