# HG changeset patch # User Sebastien Jodogne # Date 1603990923 -3600 # Node ID 787db80a5a1b0755fa82d31a6dd01d0af8c6819d # Parent b7630b1a025343fc8ead9c396307812dea0c392f new class MacroLayerRenderer diff -r b7630b1a0253 -r 787db80a5a1b Applications/StoneWebViewer/WebApplication/app.js --- a/Applications/StoneWebViewer/WebApplication/app.js Thu Oct 29 17:13:13 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Thu Oct 29 18:02:03 2020 +0100 @@ -724,7 +724,12 @@ } if (e.data.type == 'show-osirix-annotations') { - app.LoadOsiriXAnnotations(e.data.xml, true /* clear previous annotations */); + var clear = true; // Whether to clear previous annotations + if ('clear' in e.data) { + clear = e.data.clear; + } + + app.LoadOsiriXAnnotations(e.data.xml, clear); } else { alert('Unknown message type: ' + e.data.type); } @@ -743,7 +748,8 @@ window.postMessage({ 'type': 'show-osirix-annotations', - 'xml': response.data + 'xml': response.data, + 'clear': true }, targetOrigin); }); } diff -r b7630b1a0253 -r 787db80a5a1b Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Oct 29 17:13:13 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Oct 29 18:02:03 2020 +0100 @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -992,8 +993,7 @@ static const int LAYER_TEXTURE = 0; static const int LAYER_REFERENCE_LINES = 1; static const int LAYER_ANNOTATIONS = 2; - static const int LAYER_TEMP = 3; // TODO - REMOVE - + class ICommand : public Orthanc::IDynamicObject { @@ -1518,11 +1518,11 @@ /**** - * BEGINNING OF EXPERIMENTAL CODE + * BEGINNING OF EXPERIMENTAL CODE => TODO => Move this to class + * "CollectionOfAnnotations"? ****/ - std::unique_ptr annotationsLayer; // TODO - Macro layer - std::unique_ptr tempLayer; // TODO - Macro layer + std::unique_ptr annotationsLayer; if (annotations_) { @@ -1530,9 +1530,10 @@ annotations_->LookupSopInstanceUid(a, sopInstanceUid); if (!a.empty()) { + annotationsLayer.reset(new OrthancStone::MacroSceneLayer); + annotationsLayer->Reserve(a.size()); + using namespace OrthancStone::OsiriX; - - std::unique_ptr layer(new OrthancStone::PolylineSceneLayer); for (std::set::const_iterator it = a.begin(); it != a.end(); ++it) { @@ -1547,6 +1548,7 @@ if (GetCurrentFrameGeometry().ProjectPoint(x1, y1, line.GetPoint1()) && GetCurrentFrameGeometry().ProjectPoint(x2, y2, line.GetPoint2())) { + std::unique_ptr layer(new OrthancStone::PolylineSceneLayer); OrthancStone::PolylineSceneLayer::Chain chain; chain.push_back(OrthancStone::ScenePoint2D(x1, y1)); chain.push_back(OrthancStone::ScenePoint2D(x2, y2)); @@ -1554,6 +1556,7 @@ // TODO - IsArrow layer->AddChain(chain, false, 0, 255, 0); + annotationsLayer->AddLayer(layer.release()); } break; } @@ -1566,11 +1569,13 @@ GetCurrentFrameGeometry().ProjectPoint(x2, y2, angle.GetCenter()) && GetCurrentFrameGeometry().ProjectPoint(x3, y3, angle.GetB())) { + std::unique_ptr layer(new OrthancStone::PolylineSceneLayer); OrthancStone::PolylineSceneLayer::Chain chain; chain.push_back(OrthancStone::ScenePoint2D(x1, y1)); chain.push_back(OrthancStone::ScenePoint2D(x2, y2)); chain.push_back(OrthancStone::ScenePoint2D(x3, y3)); layer->AddChain(chain, false, 0, 255, 0); + annotationsLayer->AddLayer(layer.release()); } break; } @@ -1581,12 +1586,12 @@ double x, y; if (GetCurrentFrameGeometry().ProjectPoint(x, y, text.GetCenter())) { - std::unique_ptr layer2(new OrthancStone::TextSceneLayer()); - layer2->SetPosition(x, y); - layer2->SetText(text.GetText()); - layer2->SetAnchor(OrthancStone::BitmapAnchor_Center); - layer2->SetColor(255, 0, 0); - tempLayer.reset(layer2.release()); + std::unique_ptr layer(new OrthancStone::TextSceneLayer()); + layer->SetPosition(x, y); + layer->SetText(text.GetText()); + layer->SetAnchor(OrthancStone::BitmapAnchor_Center); + layer->SetColor(255, 0, 0); + annotationsLayer->AddLayer(layer.release()); } break; } @@ -1595,8 +1600,6 @@ LOG(ERROR) << "Annotation type not implemented: " << annotation.GetType(); } } - - annotationsLayer.reset(layer.release()); } } @@ -1626,15 +1629,6 @@ scene.DeleteLayer(LAYER_ANNOTATIONS); } - if (tempLayer.get() != NULL) // TODO - REMOVE - { - scene.SetLayer(LAYER_TEMP, tempLayer.release()); - } - else - { - scene.DeleteLayer(LAYER_TEMP); - } - if (fitNextContent_) { lock->RefreshCanvasSize(); diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake --- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Thu Oct 29 17:13:13 2020 +0100 +++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Thu Oct 29 18:02:03 2020 +0100 @@ -315,6 +315,8 @@ ${ORTHANC_STONE_ROOT}/Scene2D/Internals/FixedPointAligner.cpp ${ORTHANC_STONE_ROOT}/Scene2D/Internals/FixedPointAligner.h ${ORTHANC_STONE_ROOT}/Scene2D/Internals/ICairoContextProvider.h + ${ORTHANC_STONE_ROOT}/Scene2D/Internals/MacroLayerRenderer.cpp + ${ORTHANC_STONE_ROOT}/Scene2D/Internals/MacroLayerRenderer.h ${ORTHANC_STONE_ROOT}/Scene2DViewport/AngleMeasureTool.cpp ${ORTHANC_STONE_ROOT}/Scene2DViewport/AngleMeasureTool.h diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/CairoCompositor.cpp --- a/OrthancStone/Sources/Scene2D/CairoCompositor.cpp Thu Oct 29 17:13:13 2020 +0100 +++ b/OrthancStone/Sources/Scene2D/CairoCompositor.cpp Thu Oct 29 18:02:03 2020 +0100 @@ -28,6 +28,7 @@ #include "Internals/CairoLookupTableTextureRenderer.h" #include "Internals/CairoPolylineRenderer.h" #include "Internals/CairoTextRenderer.h" +#include "Internals/MacroLayerRenderer.h" #include @@ -80,6 +81,9 @@ } } + case ISceneLayer::Type_Macro: + return new Internals::MacroLayerRenderer(*this, layer); + default: return NULL; } diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.cpp Thu Oct 29 18:02:03 2020 +0100 @@ -0,0 +1,68 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + **/ + + +#include "MacroLayerRenderer.h" +#include "../MacroSceneLayer.h" + +namespace OrthancStone +{ + namespace Internals + { + void MacroLayerRenderer::Clear() + { + for (size_t i = 0; i < renderers_.size(); i++) + { + assert(renderers_[i] != NULL); + delete renderers_[i]; + } + + renderers_.clear(); + } + + + void MacroLayerRenderer::Render(const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) + { + for (size_t i = 0; i < renderers_.size(); i++) + { + assert(renderers_[i] != NULL); + renderers_[i]->Render(transform, canvasWidth, canvasHeight); + } + } + + + void MacroLayerRenderer::Update(const ISceneLayer& layer) + { + const MacroSceneLayer& macro = dynamic_cast(layer); + + Clear(); + + renderers_.reserve(macro.GetSize()); + + for (size_t i = 0; i < macro.GetSize(); i++) + { + renderers_.push_back(factory_.Create(macro.GetLayer(i))); + } + } + } +} diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.h Thu Oct 29 18:02:03 2020 +0100 @@ -0,0 +1,61 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + **/ + + +#pragma once + +#include "CompositorHelper.h" + +#include + +namespace OrthancStone +{ + namespace Internals + { + class MacroLayerRenderer : public CompositorHelper::ILayerRenderer + { + private: + Internals::CompositorHelper::IRendererFactory& factory_; + std::vector renderers_; + + void Clear(); + + public: + MacroLayerRenderer(Internals::CompositorHelper::IRendererFactory& factory, + const ISceneLayer& layer) : + factory_(factory) + { + Update(layer); + } + + virtual ~MacroLayerRenderer() + { + Clear(); + } + + virtual void Render(const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) ORTHANC_OVERRIDE; + + virtual void Update(const ISceneLayer& layer) ORTHANC_OVERRIDE; + }; + } +} diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/MacroSceneLayer.cpp --- a/OrthancStone/Sources/Scene2D/MacroSceneLayer.cpp Thu Oct 29 17:13:13 2020 +0100 +++ b/OrthancStone/Sources/Scene2D/MacroSceneLayer.cpp Thu Oct 29 18:02:03 2020 +0100 @@ -53,6 +53,20 @@ } + const ISceneLayer& MacroSceneLayer::GetLayer(size_t i) const + { + if (i >= layers_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + assert(layers_[i] != NULL); + return *layers_[i]; + } + } + + ISceneLayer* MacroSceneLayer::Clone() const { std::unique_ptr copy(new MacroSceneLayer); diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/MacroSceneLayer.h --- a/OrthancStone/Sources/Scene2D/MacroSceneLayer.h Thu Oct 29 17:13:13 2020 +0100 +++ b/OrthancStone/Sources/Scene2D/MacroSceneLayer.h Thu Oct 29 18:02:03 2020 +0100 @@ -72,6 +72,8 @@ return layers_.size(); } + const ISceneLayer& GetLayer(size_t i) const; + virtual ISceneLayer* Clone() const ORTHANC_OVERRIDE; virtual Type GetType() const ORTHANC_OVERRIDE diff -r b7630b1a0253 -r 787db80a5a1b OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp --- a/OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp Thu Oct 29 17:13:13 2020 +0100 +++ b/OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp Thu Oct 29 18:02:03 2020 +0100 @@ -28,6 +28,7 @@ #include "Internals/OpenGLInfoPanelRenderer.h" #include "Internals/OpenGLLookupTableTextureRenderer.h" #include "Internals/OpenGLTextRenderer.h" +#include "Internals/MacroLayerRenderer.h" namespace OrthancStone { @@ -118,6 +119,9 @@ } } + case ISceneLayer::Type_Macro: + return new Internals::MacroLayerRenderer(*this, layer); + default: return NULL; }