# HG changeset patch # User Sebastien Jodogne # Date 1667055376 -7200 # Node ID 95449b0e064a1a3184b767423f4fa46145cec4ae # Parent ba971d9082d344c01f1060ccb36f9c78aa4d770c pixel probe is working diff -r ba971d9082d3 -r 95449b0e064a Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Sat Oct 29 16:31:09 2022 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Sat Oct 29 16:56:16 2022 +0200 @@ -3213,7 +3213,7 @@ break; case WebViewerAction_CreateSegment: - viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_PixelProbe); + viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Segment); break; case WebViewerAction_RemoveMeasure: diff -r ba971d9082d3 -r 95449b0e064a OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp --- a/OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp Sat Oct 29 16:31:09 2022 +0200 +++ b/OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp Sat Oct 29 16:56:16 2022 +0200 @@ -28,6 +28,7 @@ #include "TextSceneLayer.h" #include "TextureBaseSceneLayer.h" // TODO REMOVE +#include #include #include @@ -955,20 +956,113 @@ }; - class AnnotationsSceneLayer::PixelProbeAnnotation : public Annotation + // Use this class to avoid unnecessary probing if neither the scene, + // nor the probe, has changed + class AnnotationsSceneLayer::ProbingAnnotation : public Annotation { private: int probedLayer_; + bool probeChanged_; + uint64_t lastLayerRevision_; + + protected: + virtual void UpdateProbeForLayer(const ISceneLayer& layer) = 0; + + void TagProbeAsChanged() + { + probeChanged_ = true; + } + + public: + ProbingAnnotation(AnnotationsSceneLayer& that, + Units units, + int probedLayer) : + Annotation(that, units), + probedLayer_(probedLayer), + probeChanged_(true), + lastLayerRevision_(0) + { + } + + virtual void UpdateProbe(const Scene2D& scene) ORTHANC_OVERRIDE + { + if (scene.HasLayer(probedLayer_)) + { + const ISceneLayer& layer = scene.GetLayer(probedLayer_); + if (probeChanged_ || + layer.GetRevision() != lastLayerRevision_) + { + UpdateProbeForLayer(layer); + probeChanged_ = false; + lastLayerRevision_ = layer.GetRevision(); + } + } + } + }; + + + class AnnotationsSceneLayer::PixelProbeAnnotation : public ProbingAnnotation + { + private: Handle& handle_; Text& label_; + protected: + virtual void UpdateProbeForLayer(const ISceneLayer& layer) ORTHANC_OVERRIDE + { + if (layer.GetType() == ISceneLayer::Type_FloatTexture || + layer.GetType() == ISceneLayer::Type_ColorTexture) + { + const TextureBaseSceneLayer& texture = dynamic_cast(layer); + const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(texture.GetTransform()); + + double sceneX = handle_.GetCenter().GetX(); + double sceneY = handle_.GetCenter().GetY(); + sceneToTexture.Apply(sceneX, sceneY); + + int x = static_cast(std::floor(sceneX)); + int y = static_cast(std::floor(sceneY)); + + const Orthanc::ImageAccessor& image = texture.GetTexture(); + + if (x >= 0 && + y >= 0 && + x < static_cast(image.GetWidth()) && + y < static_cast(image.GetHeight())) + { + char buf[64]; + + switch (image.GetFormat()) + { + case Orthanc::PixelFormat_Float32: + sprintf(buf, "%.01f\n", Orthanc::ImageTraits::GetFloatPixel( + image, static_cast(x), static_cast(y))); + break; + + case Orthanc::PixelFormat_RGB24: + { + Orthanc::PixelTraits::PixelType pixel; + Orthanc::ImageTraits::GetPixel( + pixel, image, static_cast(x), static_cast(y)); + sprintf(buf, "(%d,%d,%d)\n", pixel.red_, pixel.green_, pixel.blue_); + break; + } + + default: + break; + } + + label_.SetText(buf); + } + } + } + public: PixelProbeAnnotation(AnnotationsSceneLayer& that, Units units, const ScenePoint2D& p, int probedLayer) : - Annotation(that, units), - probedLayer_(probedLayer), + ProbingAnnotation(that, units, probedLayer), handle_(AddTypedPrimitive(new Handle(*this, p))), label_(AddTypedPrimitive(new Text(that, *this))) { @@ -991,32 +1085,7 @@ const Scene2D& scene) ORTHANC_OVERRIDE { label_.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY()); - } - - virtual void UpdateProbe(const Scene2D& scene) ORTHANC_OVERRIDE - { - if (scene.HasLayer(probedLayer_)) - { - const ISceneLayer& layer = scene.GetLayer(probedLayer_); - if (layer.GetType() == ISceneLayer::Type_FloatTexture || - layer.GetType() == ISceneLayer::Type_ColorTexture) - { - const TextureBaseSceneLayer& texture = dynamic_cast(scene.GetLayer(probedLayer_)); - const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(texture.GetTransform()); - - double x = handle_.GetCenter().GetX(); - double y = handle_.GetCenter().GetY(); - sceneToTexture.Apply(x, y); - - int textureX = static_cast(std::floor(x)); - int textureY = static_cast(std::floor(y)); - - char buf[64]; - sprintf(buf, "Hello %d x %d / (%d,%d)\n", texture.GetTexture().GetWidth(), texture.GetTexture().GetHeight(), - textureX, textureY); - label_.SetText(buf); - } - } + TagProbeAsChanged(); } virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE @@ -1515,19 +1584,16 @@ class AnnotationsSceneLayer::CreatePixelProbeTracker : public IFlexiblePointerTracker { - private: - AnnotationsSceneLayer& that_; - public: CreatePixelProbeTracker(AnnotationsSceneLayer& that, Units units, const ScenePoint2D& sceneClick, const Scene2D& scene, - int probedLayer) : - that_(that) + int probedLayer) { PixelProbeAnnotation* annotation = new PixelProbeAnnotation(that, units, sceneClick, probedLayer); annotation->UpdateProbe(scene); + that.BroadcastMessage(AnnotationAddedMessage(that)); } virtual void PointerMove(const PointerEvent& event, @@ -1538,7 +1604,6 @@ virtual void PointerUp(const PointerEvent& event, const Scene2D& scene) ORTHANC_OVERRIDE { - that_.BroadcastMessage(AnnotationAddedMessage(that_)); } virtual void PointerDown(const PointerEvent& event, diff -r ba971d9082d3 -r 95449b0e064a OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.h --- a/OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.h Sat Oct 29 16:31:09 2022 +0200 +++ b/OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.h Sat Oct 29 16:56:16 2022 +0200 @@ -54,6 +54,7 @@ class Text; class Annotation; + class ProbingAnnotation; class PixelProbeAnnotation; class SegmentAnnotation; class AngleAnnotation;