Mercurial > hg > orthanc-stone
comparison Framework/Radiography/RadiographyLayer.cpp @ 430:b85f635f1eb5 am-vsol-upgrade
added serialization for RadiographyScene
author | am@osimis.io |
---|---|
date | Thu, 29 Nov 2018 15:11:19 +0100 |
parents | 6decc0ba9da5 |
children | 4eb96c6b4e96 |
comparison
equal
deleted
inserted
replaced
429:c7fb700a7d12 | 430:b85f635f1eb5 |
---|---|
30 { | 30 { |
31 return x * x; | 31 return x * x; |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 RadiographyLayer::Geometry::Geometry() : | |
36 hasCrop_(false), | |
37 panX_(0), | |
38 panY_(0), | |
39 angle_(0), | |
40 resizeable_(false), | |
41 pixelSpacingX_(1), | |
42 pixelSpacingY_(1) | |
43 { | |
44 | |
45 } | |
46 | |
47 void RadiographyLayer::Geometry::GetCrop(unsigned int &x, unsigned int &y, unsigned int &width, unsigned int &height) const | |
48 { | |
49 if (!hasCrop_) | |
50 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); // you should probably use Radiography::GetCrop() or at least call HasCrop() before | |
51 | |
52 x = cropX_; | |
53 y = cropY_; | |
54 width = cropWidth_; | |
55 height = cropHeight_; | |
56 } | |
57 | |
35 void RadiographyLayer::UpdateTransform() | 58 void RadiographyLayer::UpdateTransform() |
36 { | 59 { |
37 transform_ = AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_); | 60 transform_ = AffineTransform2D::CreateScaling(geometry_.GetPixelSpacingX(), geometry_.GetPixelSpacingY()); |
38 | 61 |
39 double centerX, centerY; | 62 double centerX, centerY; |
40 GetCenter(centerX, centerY); | 63 GetCenter(centerX, centerY); |
41 | 64 |
42 transform_ = AffineTransform2D::Combine( | 65 transform_ = AffineTransform2D::Combine( |
43 AffineTransform2D::CreateOffset(panX_ + centerX, panY_ + centerY), | 66 AffineTransform2D::CreateOffset(geometry_.GetPanX() + centerX, geometry_.GetPanY() + centerY), |
44 AffineTransform2D::CreateRotation(angle_), | 67 AffineTransform2D::CreateRotation(geometry_.GetAngle()), |
45 AffineTransform2D::CreateOffset(-centerX, -centerY), | 68 AffineTransform2D::CreateOffset(-centerX, -centerY), |
46 transform_); | 69 transform_); |
47 | 70 |
48 transformInverse_ = AffineTransform2D::Invert(transform_); | 71 transformInverse_ = AffineTransform2D::Invert(transform_); |
49 } | 72 } |
50 | 73 |
51 | 74 |
71 double dwidth = static_cast<double>(cropWidth); | 94 double dwidth = static_cast<double>(cropWidth); |
72 double dheight = static_cast<double>(cropHeight); | 95 double dheight = static_cast<double>(cropHeight); |
73 | 96 |
74 switch (corner) | 97 switch (corner) |
75 { | 98 { |
76 case Corner_TopLeft: | 99 case Corner_TopLeft: |
77 x = dx; | 100 x = dx; |
78 y = dy; | 101 y = dy; |
79 break; | 102 break; |
80 | 103 |
81 case Corner_TopRight: | 104 case Corner_TopRight: |
82 x = dx + dwidth; | 105 x = dx + dwidth; |
83 y = dy; | 106 y = dy; |
84 break; | 107 break; |
85 | 108 |
86 case Corner_BottomLeft: | 109 case Corner_BottomLeft: |
87 x = dx; | 110 x = dx; |
88 y = dy + dheight; | 111 y = dy + dheight; |
89 break; | 112 break; |
90 | 113 |
91 case Corner_BottomRight: | 114 case Corner_BottomRight: |
92 x = dx + dwidth; | 115 x = dx + dwidth; |
93 y = dy + dheight; | 116 y = dy + dheight; |
94 break; | 117 break; |
95 | 118 |
96 default: | 119 default: |
97 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 120 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
98 } | 121 } |
99 | 122 |
100 transform_.Apply(x, y); | 123 transform_.Apply(x, y); |
101 } | 124 } |
102 | 125 |
103 | 126 |
104 bool RadiographyLayer::Contains(double x, | 127 bool RadiographyLayer::Contains(double x, |
105 double y) const | 128 double y) const |
106 { | 129 { |
107 transformInverse_.Apply(x, y); | 130 transformInverse_.Apply(x, y); |
108 | 131 |
109 unsigned int cropX, cropY, cropWidth, cropHeight; | 132 unsigned int cropX, cropY, cropWidth, cropHeight; |
110 GetCrop(cropX, cropY, cropWidth, cropHeight); | 133 GetCrop(cropX, cropY, cropWidth, cropHeight); |
111 | 134 |
112 return (x >= cropX && x <= cropX + cropWidth && | 135 return (x >= cropX && x <= cropX + cropWidth && |
113 y >= cropY && y <= cropY + cropHeight); | 136 y >= cropY && y <= cropY + cropHeight); |
125 double dwidth = static_cast<double>(width); | 148 double dwidth = static_cast<double>(width); |
126 double dheight = static_cast<double>(height); | 149 double dheight = static_cast<double>(height); |
127 | 150 |
128 cairo_t* cr = context.GetObject(); | 151 cairo_t* cr = context.GetObject(); |
129 cairo_set_line_width(cr, 2.0 / zoom); | 152 cairo_set_line_width(cr, 2.0 / zoom); |
130 | 153 |
131 double x, y; | 154 double x, y; |
132 x = dx; | 155 x = dx; |
133 y = dy; | 156 y = dy; |
134 transform_.Apply(x, y); | 157 transform_.Apply(x, y); |
135 cairo_move_to(cr, x, y); | 158 cairo_move_to(cr, x, y); |
160 | 183 |
161 RadiographyLayer::RadiographyLayer() : | 184 RadiographyLayer::RadiographyLayer() : |
162 index_(0), | 185 index_(0), |
163 hasSize_(false), | 186 hasSize_(false), |
164 width_(0), | 187 width_(0), |
165 height_(0), | 188 height_(0) |
166 hasCrop_(false), | 189 { |
167 pixelSpacingX_(1), | 190 UpdateTransform(); |
168 pixelSpacingY_(1), | 191 } |
169 panX_(0), | 192 |
170 panY_(0), | 193 void RadiographyLayer::ResetCrop() |
171 angle_(0), | 194 { |
172 resizeable_(false) | 195 geometry_.ResetCrop(); |
173 { | 196 UpdateTransform(); |
174 UpdateTransform(); | 197 } |
175 } | |
176 | |
177 | 198 |
178 void RadiographyLayer::SetCrop(unsigned int x, | 199 void RadiographyLayer::SetCrop(unsigned int x, |
179 unsigned int y, | 200 unsigned int y, |
180 unsigned int width, | 201 unsigned int width, |
181 unsigned int height) | 202 unsigned int height) |
182 { | 203 { |
183 if (!hasSize_) | 204 if (!hasSize_) |
184 { | 205 { |
185 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 206 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
186 } | 207 } |
187 | 208 |
188 if (x + width > width_ || | 209 if (x + width > width_ || |
189 y + height > height_) | 210 y + height > height_) |
190 { | 211 { |
191 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 212 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
192 } | 213 } |
193 | 214 |
194 hasCrop_ = true; | 215 geometry_.SetCrop(x, y, width, height); |
195 cropX_ = x; | 216 UpdateTransform(); |
196 cropY_ = y; | 217 } |
197 cropWidth_ = width; | 218 |
198 cropHeight_ = height; | 219 void RadiographyLayer::SetGeometry(const Geometry& geometry) |
199 | 220 { |
200 UpdateTransform(); | 221 geometry_ = geometry; |
201 } | 222 |
202 | 223 if (hasSize_) |
203 | 224 { |
225 UpdateTransform(); | |
226 } | |
227 } | |
228 | |
229 | |
204 void RadiographyLayer::GetCrop(unsigned int& x, | 230 void RadiographyLayer::GetCrop(unsigned int& x, |
205 unsigned int& y, | 231 unsigned int& y, |
206 unsigned int& width, | 232 unsigned int& width, |
207 unsigned int& height) const | 233 unsigned int& height) const |
208 { | 234 { |
209 if (hasCrop_) | 235 if (GetGeometry().HasCrop()) |
210 { | 236 { |
211 x = cropX_; | 237 GetGeometry().GetCrop(x, y, width, height); |
212 y = cropY_; | |
213 width = cropWidth_; | |
214 height = cropHeight_; | |
215 } | 238 } |
216 else | 239 else |
217 { | 240 { |
218 x = 0; | 241 x = 0; |
219 y = 0; | 242 y = 0; |
220 width = width_; | 243 width = width_; |
221 height = height_; | 244 height = height_; |
222 } | 245 } |
223 } | 246 } |
224 | 247 |
225 | 248 |
226 void RadiographyLayer::SetAngle(double angle) | 249 void RadiographyLayer::SetAngle(double angle) |
227 { | 250 { |
228 angle_ = angle; | 251 geometry_.SetAngle(angle); |
229 UpdateTransform(); | 252 UpdateTransform(); |
230 } | 253 } |
231 | 254 |
232 | 255 |
233 void RadiographyLayer::SetSize(unsigned int width, | 256 void RadiographyLayer::SetSize(unsigned int width, |
237 (width != width_ || | 260 (width != width_ || |
238 height != height_)) | 261 height != height_)) |
239 { | 262 { |
240 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); | 263 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
241 } | 264 } |
242 | 265 |
243 hasSize_ = true; | 266 hasSize_ = true; |
244 width_ = width; | 267 width_ = width; |
245 height_ = height; | 268 height_ = height; |
246 | 269 |
247 UpdateTransform(); | 270 UpdateTransform(); |
249 | 272 |
250 | 273 |
251 Extent2D RadiographyLayer::GetExtent() const | 274 Extent2D RadiographyLayer::GetExtent() const |
252 { | 275 { |
253 Extent2D extent; | 276 Extent2D extent; |
254 | 277 |
255 unsigned int x, y, width, height; | 278 unsigned int x, y, width, height; |
256 GetCrop(x, y, width, height); | 279 GetCrop(x, y, width, height); |
257 | 280 |
258 double dx = static_cast<double>(x); | 281 double dx = static_cast<double>(x); |
259 double dy = static_cast<double>(y); | 282 double dy = static_cast<double>(y); |
262 | 285 |
263 AddToExtent(extent, dx, dy); | 286 AddToExtent(extent, dx, dy); |
264 AddToExtent(extent, dx + dwidth, dy); | 287 AddToExtent(extent, dx + dwidth, dy); |
265 AddToExtent(extent, dx, dy + dheight); | 288 AddToExtent(extent, dx, dy + dheight); |
266 AddToExtent(extent, dx + dwidth, dy + dheight); | 289 AddToExtent(extent, dx + dwidth, dy + dheight); |
267 | 290 |
268 return extent; | 291 return extent; |
269 } | 292 } |
270 | 293 |
271 | 294 |
272 bool RadiographyLayer::GetPixel(unsigned int& imageX, | 295 bool RadiographyLayer::GetPixel(unsigned int& imageX, |
280 return false; | 303 return false; |
281 } | 304 } |
282 else | 305 else |
283 { | 306 { |
284 transformInverse_.Apply(sceneX, sceneY); | 307 transformInverse_.Apply(sceneX, sceneY); |
285 | 308 |
286 int x = static_cast<int>(std::floor(sceneX)); | 309 int x = static_cast<int>(std::floor(sceneX)); |
287 int y = static_cast<int>(std::floor(sceneY)); | 310 int y = static_cast<int>(std::floor(sceneY)); |
288 | 311 |
289 if (x < 0) | 312 if (x < 0) |
290 { | 313 { |
318 | 341 |
319 | 342 |
320 void RadiographyLayer::SetPan(double x, | 343 void RadiographyLayer::SetPan(double x, |
321 double y) | 344 double y) |
322 { | 345 { |
323 panX_ = x; | 346 geometry_.SetPan(x, y); |
324 panY_ = y; | |
325 UpdateTransform(); | 347 UpdateTransform(); |
326 } | 348 } |
327 | 349 |
328 | 350 |
329 void RadiographyLayer::SetPixelSpacing(double x, | 351 void RadiographyLayer::SetPixelSpacing(double x, |
330 double y) | 352 double y) |
331 { | 353 { |
332 pixelSpacingX_ = x; | 354 geometry_.SetPixelSpacing(x, y); |
333 pixelSpacingY_ = y; | |
334 UpdateTransform(); | 355 UpdateTransform(); |
335 } | 356 } |
336 | 357 |
337 | 358 |
338 void RadiographyLayer::GetCenter(double& centerX, | 359 void RadiographyLayer::GetCenter(double& centerX, |
350 { | 371 { |
351 unsigned int cropX, cropY, cropWidth, cropHeight; | 372 unsigned int cropX, cropY, cropWidth, cropHeight; |
352 GetCrop(cropX, cropY, cropWidth, cropHeight); | 373 GetCrop(cropX, cropY, cropWidth, cropHeight); |
353 GetCornerInternal(x, y, corner, cropX, cropY, cropWidth, cropHeight); | 374 GetCornerInternal(x, y, corner, cropX, cropY, cropWidth, cropHeight); |
354 } | 375 } |
355 | 376 |
356 | 377 |
357 bool RadiographyLayer::LookupCorner(Corner& corner /* out */, | 378 bool RadiographyLayer::LookupCorner(Corner& corner /* out */, |
358 double x, | 379 double x, |
359 double y, | 380 double y, |
360 double zoom, | 381 double zoom, |
361 double viewportDistance) const | 382 double viewportDistance) const |
364 Corner_TopLeft, | 385 Corner_TopLeft, |
365 Corner_TopRight, | 386 Corner_TopRight, |
366 Corner_BottomLeft, | 387 Corner_BottomLeft, |
367 Corner_BottomRight | 388 Corner_BottomRight |
368 }; | 389 }; |
369 | 390 |
370 unsigned int cropX, cropY, cropWidth, cropHeight; | 391 unsigned int cropX, cropY, cropWidth, cropHeight; |
371 GetCrop(cropX, cropY, cropWidth, cropHeight); | 392 GetCrop(cropX, cropY, cropWidth, cropHeight); |
372 | 393 |
373 double threshold = Square(viewportDistance / zoom); | 394 double threshold = Square(viewportDistance / zoom); |
374 | 395 |
375 for (size_t i = 0; i < 4; i++) | 396 for (size_t i = 0; i < 4; i++) |
376 { | 397 { |
377 double cx, cy; | 398 double cx, cy; |
378 GetCornerInternal(cx, cy, CORNERS[i], cropX, cropY, cropWidth, cropHeight); | 399 GetCornerInternal(cx, cy, CORNERS[i], cropX, cropY, cropWidth, cropHeight); |
379 | 400 |
380 double d = Square(cx - x) + Square(cy - y); | 401 double d = Square(cx - x) + Square(cy - y); |
381 | 402 |
382 if (d <= threshold) | 403 if (d <= threshold) |
383 { | 404 { |
384 corner = CORNERS[i]; | 405 corner = CORNERS[i]; |
385 return true; | 406 return true; |
386 } | 407 } |
387 } | 408 } |
388 | 409 |
389 return false; | 410 return false; |
390 } | 411 } |
391 } | 412 } |