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 }