Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp @ 1980:0aac8f552d89
added pixel probe to the Stone Web viewer toolbar
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 30 Oct 2022 10:26:32 +0100 |
parents | b31e494e34c5 |
children | c074c75cf416 |
comparison
equal
deleted
inserted
replaced
1979:b31e494e34c5 | 1980:0aac8f552d89 |
---|---|
232 }; | 232 }; |
233 | 233 |
234 | 234 |
235 class AnnotationsSceneLayer::Handle : public GeometricPrimitive | 235 class AnnotationsSceneLayer::Handle : public GeometricPrimitive |
236 { | 236 { |
237 public: | |
238 enum Shape { | |
239 Shape_Square, | |
240 Shape_CrossedSquare | |
241 }; | |
242 | |
237 private: | 243 private: |
244 Shape shape_; | |
238 ScenePoint2D center_; | 245 ScenePoint2D center_; |
239 ScenePoint2D delta_; | 246 ScenePoint2D delta_; |
240 | 247 |
248 void AddChain(PolylineSceneLayer& polyline, | |
249 const PolylineSceneLayer::Chain& chain) const | |
250 { | |
251 if (IsHover()) | |
252 { | |
253 polyline.AddChain(chain, true /* closed */, GetHoverColor()); | |
254 } | |
255 else | |
256 { | |
257 polyline.AddChain(chain, true /* closed */, GetColor()); | |
258 } | |
259 } | |
260 | |
261 void AddRectangle(PolylineSceneLayer& polyline, | |
262 double x1, | |
263 double y1, | |
264 double x2, | |
265 double y2) | |
266 { | |
267 PolylineSceneLayer::Chain chain; | |
268 chain.resize(4); | |
269 chain[0] = ScenePoint2D(x1, y1); | |
270 chain[1] = ScenePoint2D(x2, y1); | |
271 chain[2] = ScenePoint2D(x2, y2); | |
272 chain[3] = ScenePoint2D(x1, y2); | |
273 AddChain(polyline, chain); | |
274 } | |
275 | |
276 void AddCross(PolylineSceneLayer& polyline, | |
277 double x1, | |
278 double y1, | |
279 double x2, | |
280 double y2) | |
281 { | |
282 const double halfX = (x1 + x2) / 2.0; | |
283 const double halfY = (y1 + y2) / 2.0; | |
284 | |
285 PolylineSceneLayer::Chain chain; | |
286 chain.resize(2); | |
287 | |
288 chain[0] = ScenePoint2D(x1, halfY); | |
289 chain[1] = ScenePoint2D(x2, halfY); | |
290 AddChain(polyline, chain); | |
291 | |
292 chain[0] = ScenePoint2D(halfX, y1); | |
293 chain[1] = ScenePoint2D(halfX, y2); | |
294 AddChain(polyline, chain); | |
295 } | |
296 | |
241 public: | 297 public: |
242 explicit Handle(Annotation& parentAnnotation, | 298 explicit Handle(Annotation& parentAnnotation, |
299 Shape shape, | |
243 const ScenePoint2D& center) : | 300 const ScenePoint2D& center) : |
244 GeometricPrimitive(parentAnnotation, 0), // Highest priority | 301 GeometricPrimitive(parentAnnotation, 0), // Highest priority |
302 shape_(shape), | |
245 center_(center), | 303 center_(center), |
246 delta_(0, 0) | 304 delta_(0, 0) |
247 { | 305 { |
248 } | 306 } |
249 | 307 |
270 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom(); | 328 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom(); |
271 | 329 |
272 double dx = (center_.GetX() + delta_.GetX() - p.GetX()) * zoom; | 330 double dx = (center_.GetX() + delta_.GetX() - p.GetX()) * zoom; |
273 double dy = (center_.GetY() + delta_.GetY() - p.GetY()) * zoom; | 331 double dy = (center_.GetY() + delta_.GetY() - p.GetY()) * zoom; |
274 | 332 |
275 return (std::abs(dx) <= HANDLE_SIZE / 2.0 && | 333 switch (shape_) |
276 std::abs(dy) <= HANDLE_SIZE / 2.0); | 334 { |
335 case Shape_Square: | |
336 case Shape_CrossedSquare: | |
337 return (std::abs(dx) <= HANDLE_SIZE / 2.0 && | |
338 std::abs(dy) <= HANDLE_SIZE / 2.0); | |
339 | |
340 default: | |
341 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
342 } | |
277 } | 343 } |
278 | 344 |
279 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, | 345 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, |
280 const Scene2D& scene) ORTHANC_OVERRIDE | 346 const Scene2D& scene) ORTHANC_OVERRIDE |
281 { | 347 { |
285 double x1 = center_.GetX() + delta_.GetX() - (HANDLE_SIZE / 2.0) / zoom; | 351 double x1 = center_.GetX() + delta_.GetX() - (HANDLE_SIZE / 2.0) / zoom; |
286 double y1 = center_.GetY() + delta_.GetY() - (HANDLE_SIZE / 2.0) / zoom; | 352 double y1 = center_.GetY() + delta_.GetY() - (HANDLE_SIZE / 2.0) / zoom; |
287 double x2 = center_.GetX() + delta_.GetX() + (HANDLE_SIZE / 2.0) / zoom; | 353 double x2 = center_.GetX() + delta_.GetX() + (HANDLE_SIZE / 2.0) / zoom; |
288 double y2 = center_.GetY() + delta_.GetY() + (HANDLE_SIZE / 2.0) / zoom; | 354 double y2 = center_.GetY() + delta_.GetY() + (HANDLE_SIZE / 2.0) / zoom; |
289 | 355 |
290 PolylineSceneLayer::Chain chain; | 356 switch (shape_) |
291 chain.reserve(4); | 357 { |
292 chain.push_back(ScenePoint2D(x1, y1)); | 358 case Shape_Square: |
293 chain.push_back(ScenePoint2D(x2, y1)); | 359 AddRectangle(polyline, x1, y1, x2, y2); |
294 chain.push_back(ScenePoint2D(x2, y2)); | 360 break; |
295 chain.push_back(ScenePoint2D(x1, y2)); | 361 |
296 | 362 case Shape_CrossedSquare: |
297 if (IsHover()) | 363 AddRectangle(polyline, x1, y1, x2, y2); |
298 { | 364 AddCross(polyline, x1, y1, x2, y2); |
299 polyline.AddChain(chain, true /* closed */, GetHoverColor()); | 365 break; |
300 } | 366 |
301 else | 367 default: |
302 { | 368 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
303 polyline.AddChain(chain, true /* closed */, GetColor()); | |
304 } | 369 } |
305 } | 370 } |
306 | 371 |
307 virtual void RenderOtherLayers(MacroSceneLayer& macro, | 372 virtual void RenderOtherLayers(MacroSceneLayer& macro, |
308 const Scene2D& scene) ORTHANC_OVERRIDE | 373 const Scene2D& scene) ORTHANC_OVERRIDE |
375 | 440 |
376 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, | 441 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, |
377 const Scene2D& scene) ORTHANC_OVERRIDE | 442 const Scene2D& scene) ORTHANC_OVERRIDE |
378 { | 443 { |
379 PolylineSceneLayer::Chain chain; | 444 PolylineSceneLayer::Chain chain; |
380 chain.reserve(2); | 445 chain.resize(2); |
381 chain.push_back(p1_ + delta_); | 446 chain[0] = p1_ + delta_; |
382 chain.push_back(p2_ + delta_); | 447 chain[1] = p2_ + delta_; |
383 | 448 |
384 if (IsHover()) | 449 if (IsHover()) |
385 { | 450 { |
386 polyline.AddChain(chain, false /* closed */, GetHoverColor()); | 451 polyline.AddChain(chain, false /* closed */, GetHoverColor()); |
387 } | 452 } |
478 const double radius = ScenePoint2D::DistancePtPt(middle, p1_); | 543 const double radius = ScenePoint2D::DistancePtPt(middle, p1_); |
479 | 544 |
480 double increment = 2.0 * PI / static_cast<double>(NUM_SEGMENTS - 1); | 545 double increment = 2.0 * PI / static_cast<double>(NUM_SEGMENTS - 1); |
481 | 546 |
482 PolylineSceneLayer::Chain chain; | 547 PolylineSceneLayer::Chain chain; |
483 chain.reserve(NUM_SEGMENTS); | 548 chain.resize(NUM_SEGMENTS); |
484 | 549 |
485 double theta = 0; | 550 double theta = 0; |
486 for (unsigned int i = 0; i < NUM_SEGMENTS; i++) | 551 for (unsigned int i = 0; i < NUM_SEGMENTS; i++) |
487 { | 552 { |
488 chain.push_back(ScenePoint2D(delta_.GetX() + middle.GetX() + radius * cos(theta), | 553 chain[i] = ScenePoint2D(delta_.GetX() + middle.GetX() + radius * cos(theta), |
489 delta_.GetY() + middle.GetY() + radius * sin(theta))); | 554 delta_.GetY() + middle.GetY() + radius * sin(theta)); |
490 theta += increment; | 555 theta += increment; |
491 } | 556 } |
492 | 557 |
493 if (IsHover()) | 558 if (IsHover()) |
494 { | 559 { |
615 ComputeAngles(fullAngle, startAngle, endAngle); | 680 ComputeAngles(fullAngle, startAngle, endAngle); |
616 | 681 |
617 double increment = fullAngle / static_cast<double>(NUM_SEGMENTS - 1); | 682 double increment = fullAngle / static_cast<double>(NUM_SEGMENTS - 1); |
618 | 683 |
619 PolylineSceneLayer::Chain chain; | 684 PolylineSceneLayer::Chain chain; |
620 chain.reserve(NUM_SEGMENTS); | 685 chain.resize(NUM_SEGMENTS); |
621 | 686 |
622 double theta = startAngle; | 687 double theta = startAngle; |
623 for (unsigned int i = 0; i < NUM_SEGMENTS; i++) | 688 for (unsigned int i = 0; i < NUM_SEGMENTS; i++) |
624 { | 689 { |
625 chain.push_back(ScenePoint2D(middle_.GetX() + radius * cos(theta), | 690 chain[i] = ScenePoint2D(middle_.GetX() + radius * cos(theta), |
626 middle_.GetY() + radius * sin(theta))); | 691 middle_.GetY() + radius * sin(theta)); |
627 theta += increment; | 692 theta += increment; |
628 } | 693 } |
629 | 694 |
630 if (IsHover()) | 695 if (IsHover()) |
631 { | 696 { |
879 bool showLabel, | 944 bool showLabel, |
880 const ScenePoint2D& p1, | 945 const ScenePoint2D& p1, |
881 const ScenePoint2D& p2) : | 946 const ScenePoint2D& p2) : |
882 Annotation(that, units), | 947 Annotation(that, units), |
883 showLabel_(showLabel), | 948 showLabel_(showLabel), |
884 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), | 949 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, p1))), |
885 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), | 950 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, p2))), |
886 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), | 951 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), |
887 label_(AddTypedPrimitive<Text>(new Text(that, *this))) | 952 label_(AddTypedPrimitive<Text>(new Text(that, *this))) |
888 { | 953 { |
889 label_.SetColor(COLOR_TEXT); | 954 label_.SetColor(COLOR_TEXT); |
890 UpdateLabel(); | 955 UpdateLabel(); |
1033 char buf[64]; | 1098 char buf[64]; |
1034 | 1099 |
1035 switch (image.GetFormat()) | 1100 switch (image.GetFormat()) |
1036 { | 1101 { |
1037 case Orthanc::PixelFormat_Float32: | 1102 case Orthanc::PixelFormat_Float32: |
1038 sprintf(buf, "%.01f\n", Orthanc::ImageTraits<Orthanc::PixelFormat_Float32>::GetFloatPixel( | 1103 sprintf(buf, "(%d,%d): %.01f", x, y, Orthanc::ImageTraits<Orthanc::PixelFormat_Float32>::GetFloatPixel( |
1039 image, static_cast<unsigned int>(x), static_cast<unsigned int>(y))); | 1104 image, static_cast<unsigned int>(x), static_cast<unsigned int>(y))); |
1040 break; | 1105 break; |
1041 | 1106 |
1042 case Orthanc::PixelFormat_RGB24: | 1107 case Orthanc::PixelFormat_RGB24: |
1043 { | 1108 { |
1044 Orthanc::PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel; | 1109 Orthanc::PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel; |
1045 Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel( | 1110 Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel( |
1046 pixel, image, static_cast<unsigned int>(x), static_cast<unsigned int>(y)); | 1111 pixel, image, static_cast<unsigned int>(x), static_cast<unsigned int>(y)); |
1047 sprintf(buf, "(%d,%d,%d)\n", pixel.red_, pixel.green_, pixel.blue_); | 1112 sprintf(buf, "(%d,%d): (%d,%d,%d)", x, y, pixel.red_, pixel.green_, pixel.blue_); |
1048 break; | 1113 break; |
1049 } | 1114 } |
1050 | 1115 |
1051 default: | 1116 default: |
1052 break; | 1117 break; |
1065 PixelProbeAnnotation(AnnotationsSceneLayer& that, | 1130 PixelProbeAnnotation(AnnotationsSceneLayer& that, |
1066 Units units, | 1131 Units units, |
1067 const ScenePoint2D& p, | 1132 const ScenePoint2D& p, |
1068 int probedLayer) : | 1133 int probedLayer) : |
1069 ProbingAnnotation(that, units, probedLayer), | 1134 ProbingAnnotation(that, units, probedLayer), |
1070 handle_(AddTypedPrimitive<Handle>(new Handle(*this, p))), | 1135 handle_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_CrossedSquare, p))), |
1071 label_(AddTypedPrimitive<Text>(new Text(that, *this))) | 1136 label_(AddTypedPrimitive<Text>(new Text(that, *this))) |
1072 { | 1137 { |
1073 TextSceneLayer content; | 1138 TextSceneLayer content; |
1074 content.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY()); | 1139 content.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY()); |
1075 content.SetAnchor(BitmapAnchor_CenterLeft); | 1140 content.SetAnchor(BitmapAnchor_CenterLeft); |
1168 Units units, | 1233 Units units, |
1169 const ScenePoint2D& start, | 1234 const ScenePoint2D& start, |
1170 const ScenePoint2D& middle, | 1235 const ScenePoint2D& middle, |
1171 const ScenePoint2D& end) : | 1236 const ScenePoint2D& end) : |
1172 Annotation(that, units), | 1237 Annotation(that, units), |
1173 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, start))), | 1238 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, start))), |
1174 middleHandle_(AddTypedPrimitive<Handle>(new Handle(*this, middle))), | 1239 middleHandle_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, middle))), |
1175 endHandle_(AddTypedPrimitive<Handle>(new Handle(*this, end))), | 1240 endHandle_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, end))), |
1176 segment1_(AddTypedPrimitive<Segment>(new Segment(*this, start, middle))), | 1241 segment1_(AddTypedPrimitive<Segment>(new Segment(*this, start, middle))), |
1177 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, middle, end))), | 1242 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, middle, end))), |
1178 arc_(AddTypedPrimitive<Arc>(new Arc(*this, start, middle, end))), | 1243 arc_(AddTypedPrimitive<Arc>(new Arc(*this, start, middle, end))), |
1179 label_(AddTypedPrimitive<Text>(new Text(that, *this))) | 1244 label_(AddTypedPrimitive<Text>(new Text(that, *this))) |
1180 { | 1245 { |
1338 CircleAnnotation(AnnotationsSceneLayer& that, | 1403 CircleAnnotation(AnnotationsSceneLayer& that, |
1339 Units units, | 1404 Units units, |
1340 const ScenePoint2D& p1, | 1405 const ScenePoint2D& p1, |
1341 const ScenePoint2D& p2) : | 1406 const ScenePoint2D& p2) : |
1342 Annotation(that, units), | 1407 Annotation(that, units), |
1343 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), | 1408 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, p1))), |
1344 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), | 1409 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, Handle::Shape_Square, p2))), |
1345 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), | 1410 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), |
1346 circle_(AddTypedPrimitive<Circle>(new Circle(*this, p1, p2))), | 1411 circle_(AddTypedPrimitive<Circle>(new Circle(*this, p1, p2))), |
1347 label_(AddTypedPrimitive<Text>(new Text(that, *this))) | 1412 label_(AddTypedPrimitive<Text>(new Text(that, *this))) |
1348 { | 1413 { |
1349 label_.SetColor(COLOR_TEXT); | 1414 label_.SetColor(COLOR_TEXT); |