comparison OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp @ 1978:95449b0e064a

pixel probe is working
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 29 Oct 2022 16:56:16 +0200
parents ba971d9082d3
children b31e494e34c5
comparison
equal deleted inserted replaced
1977:ba971d9082d3 1978:95449b0e064a
26 #include "MacroSceneLayer.h" 26 #include "MacroSceneLayer.h"
27 #include "PolylineSceneLayer.h" 27 #include "PolylineSceneLayer.h"
28 #include "TextSceneLayer.h" 28 #include "TextSceneLayer.h"
29 #include "TextureBaseSceneLayer.h" // TODO REMOVE 29 #include "TextureBaseSceneLayer.h" // TODO REMOVE
30 30
31 #include <Images/ImageTraits.h>
31 #include <OrthancException.h> 32 #include <OrthancException.h>
32 33
33 #include <boost/math/constants/constants.hpp> 34 #include <boost/math/constants/constants.hpp>
34 #include <list> 35 #include <list>
35 36
953 } 954 }
954 } 955 }
955 }; 956 };
956 957
957 958
958 class AnnotationsSceneLayer::PixelProbeAnnotation : public Annotation 959 // Use this class to avoid unnecessary probing if neither the scene,
960 // nor the probe, has changed
961 class AnnotationsSceneLayer::ProbingAnnotation : public Annotation
959 { 962 {
960 private: 963 private:
961 int probedLayer_; 964 int probedLayer_;
965 bool probeChanged_;
966 uint64_t lastLayerRevision_;
967
968 protected:
969 virtual void UpdateProbeForLayer(const ISceneLayer& layer) = 0;
970
971 void TagProbeAsChanged()
972 {
973 probeChanged_ = true;
974 }
975
976 public:
977 ProbingAnnotation(AnnotationsSceneLayer& that,
978 Units units,
979 int probedLayer) :
980 Annotation(that, units),
981 probedLayer_(probedLayer),
982 probeChanged_(true),
983 lastLayerRevision_(0)
984 {
985 }
986
987 virtual void UpdateProbe(const Scene2D& scene) ORTHANC_OVERRIDE
988 {
989 if (scene.HasLayer(probedLayer_))
990 {
991 const ISceneLayer& layer = scene.GetLayer(probedLayer_);
992 if (probeChanged_ ||
993 layer.GetRevision() != lastLayerRevision_)
994 {
995 UpdateProbeForLayer(layer);
996 probeChanged_ = false;
997 lastLayerRevision_ = layer.GetRevision();
998 }
999 }
1000 }
1001 };
1002
1003
1004 class AnnotationsSceneLayer::PixelProbeAnnotation : public ProbingAnnotation
1005 {
1006 private:
962 Handle& handle_; 1007 Handle& handle_;
963 Text& label_; 1008 Text& label_;
1009
1010 protected:
1011 virtual void UpdateProbeForLayer(const ISceneLayer& layer) ORTHANC_OVERRIDE
1012 {
1013 if (layer.GetType() == ISceneLayer::Type_FloatTexture ||
1014 layer.GetType() == ISceneLayer::Type_ColorTexture)
1015 {
1016 const TextureBaseSceneLayer& texture = dynamic_cast<const TextureBaseSceneLayer&>(layer);
1017 const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(texture.GetTransform());
1018
1019 double sceneX = handle_.GetCenter().GetX();
1020 double sceneY = handle_.GetCenter().GetY();
1021 sceneToTexture.Apply(sceneX, sceneY);
1022
1023 int x = static_cast<int>(std::floor(sceneX));
1024 int y = static_cast<int>(std::floor(sceneY));
1025
1026 const Orthanc::ImageAccessor& image = texture.GetTexture();
1027
1028 if (x >= 0 &&
1029 y >= 0 &&
1030 x < static_cast<int>(image.GetWidth()) &&
1031 y < static_cast<int>(image.GetHeight()))
1032 {
1033 char buf[64];
1034
1035 switch (image.GetFormat())
1036 {
1037 case Orthanc::PixelFormat_Float32:
1038 sprintf(buf, "%.01f\n", Orthanc::ImageTraits<Orthanc::PixelFormat_Float32>::GetFloatPixel(
1039 image, static_cast<unsigned int>(x), static_cast<unsigned int>(y)));
1040 break;
1041
1042 case Orthanc::PixelFormat_RGB24:
1043 {
1044 Orthanc::PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel;
1045 Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(
1046 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_);
1048 break;
1049 }
1050
1051 default:
1052 break;
1053 }
1054
1055 label_.SetText(buf);
1056 }
1057 }
1058 }
964 1059
965 public: 1060 public:
966 PixelProbeAnnotation(AnnotationsSceneLayer& that, 1061 PixelProbeAnnotation(AnnotationsSceneLayer& that,
967 Units units, 1062 Units units,
968 const ScenePoint2D& p, 1063 const ScenePoint2D& p,
969 int probedLayer) : 1064 int probedLayer) :
970 Annotation(that, units), 1065 ProbingAnnotation(that, units, probedLayer),
971 probedLayer_(probedLayer),
972 handle_(AddTypedPrimitive<Handle>(new Handle(*this, p))), 1066 handle_(AddTypedPrimitive<Handle>(new Handle(*this, p))),
973 label_(AddTypedPrimitive<Text>(new Text(that, *this))) 1067 label_(AddTypedPrimitive<Text>(new Text(that, *this)))
974 { 1068 {
975 TextSceneLayer content; 1069 TextSceneLayer content;
976 content.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY()); 1070 content.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY());
989 1083
990 virtual void SignalMove(GeometricPrimitive& primitive, 1084 virtual void SignalMove(GeometricPrimitive& primitive,
991 const Scene2D& scene) ORTHANC_OVERRIDE 1085 const Scene2D& scene) ORTHANC_OVERRIDE
992 { 1086 {
993 label_.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY()); 1087 label_.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY());
994 } 1088 TagProbeAsChanged();
995
996 virtual void UpdateProbe(const Scene2D& scene) ORTHANC_OVERRIDE
997 {
998 if (scene.HasLayer(probedLayer_))
999 {
1000 const ISceneLayer& layer = scene.GetLayer(probedLayer_);
1001 if (layer.GetType() == ISceneLayer::Type_FloatTexture ||
1002 layer.GetType() == ISceneLayer::Type_ColorTexture)
1003 {
1004 const TextureBaseSceneLayer& texture = dynamic_cast<TextureBaseSceneLayer&>(scene.GetLayer(probedLayer_));
1005 const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(texture.GetTransform());
1006
1007 double x = handle_.GetCenter().GetX();
1008 double y = handle_.GetCenter().GetY();
1009 sceneToTexture.Apply(x, y);
1010
1011 int textureX = static_cast<int>(std::floor(x));
1012 int textureY = static_cast<int>(std::floor(y));
1013
1014 char buf[64];
1015 sprintf(buf, "Hello %d x %d / (%d,%d)\n", texture.GetTexture().GetWidth(), texture.GetTexture().GetHeight(),
1016 textureX, textureY);
1017 label_.SetText(buf);
1018 }
1019 }
1020 } 1089 }
1021 1090
1022 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE 1091 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE
1023 { 1092 {
1024 target = Json::objectValue; 1093 target = Json::objectValue;
1513 }; 1582 };
1514 1583
1515 1584
1516 class AnnotationsSceneLayer::CreatePixelProbeTracker : public IFlexiblePointerTracker 1585 class AnnotationsSceneLayer::CreatePixelProbeTracker : public IFlexiblePointerTracker
1517 { 1586 {
1518 private:
1519 AnnotationsSceneLayer& that_;
1520
1521 public: 1587 public:
1522 CreatePixelProbeTracker(AnnotationsSceneLayer& that, 1588 CreatePixelProbeTracker(AnnotationsSceneLayer& that,
1523 Units units, 1589 Units units,
1524 const ScenePoint2D& sceneClick, 1590 const ScenePoint2D& sceneClick,
1525 const Scene2D& scene, 1591 const Scene2D& scene,
1526 int probedLayer) : 1592 int probedLayer)
1527 that_(that)
1528 { 1593 {
1529 PixelProbeAnnotation* annotation = new PixelProbeAnnotation(that, units, sceneClick, probedLayer); 1594 PixelProbeAnnotation* annotation = new PixelProbeAnnotation(that, units, sceneClick, probedLayer);
1530 annotation->UpdateProbe(scene); 1595 annotation->UpdateProbe(scene);
1596 that.BroadcastMessage(AnnotationAddedMessage(that));
1531 } 1597 }
1532 1598
1533 virtual void PointerMove(const PointerEvent& event, 1599 virtual void PointerMove(const PointerEvent& event,
1534 const Scene2D& scene) ORTHANC_OVERRIDE 1600 const Scene2D& scene) ORTHANC_OVERRIDE
1535 { 1601 {
1536 } 1602 }
1537 1603
1538 virtual void PointerUp(const PointerEvent& event, 1604 virtual void PointerUp(const PointerEvent& event,
1539 const Scene2D& scene) ORTHANC_OVERRIDE 1605 const Scene2D& scene) ORTHANC_OVERRIDE
1540 { 1606 {
1541 that_.BroadcastMessage(AnnotationAddedMessage(that_));
1542 } 1607 }
1543 1608
1544 virtual void PointerDown(const PointerEvent& event, 1609 virtual void PointerDown(const PointerEvent& event,
1545 const Scene2D& scene) ORTHANC_OVERRIDE 1610 const Scene2D& scene) ORTHANC_OVERRIDE
1546 { 1611 {