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 }