changeset 1611:787db80a5a1b

new class MacroLayerRenderer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Oct 2020 18:02:03 +0100
parents b7630b1a0253
children 228a41233540
files Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake OrthancStone/Sources/Scene2D/CairoCompositor.cpp OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.cpp OrthancStone/Sources/Scene2D/Internals/MacroLayerRenderer.h OrthancStone/Sources/Scene2D/MacroSceneLayer.cpp OrthancStone/Sources/Scene2D/MacroSceneLayer.h OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp
diffstat 9 files changed, 181 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- 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);
       });
   }
--- 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 <Oracle/ParseDicomSuccessMessage.h>
 #include <Scene2D/ColorTextureSceneLayer.h>
 #include <Scene2D/FloatTextureSceneLayer.h>
+#include <Scene2D/MacroSceneLayer.h>
 #include <Scene2D/PolylineSceneLayer.h>
 #include <Scene2D/TextSceneLayer.h>
 #include <Scene2DViewport/ViewportController.h>
@@ -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<OrthancStone::ISceneLayer>  annotationsLayer;  // TODO - Macro layer
-      std::unique_ptr<OrthancStone::ISceneLayer>  tempLayer;  // TODO - Macro layer
+      std::unique_ptr<OrthancStone::MacroSceneLayer>  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<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer);
           
           for (std::set<size_t>::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<OrthancStone::PolylineSceneLayer> 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<OrthancStone::PolylineSceneLayer> 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<OrthancStone::TextSceneLayer> 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<OrthancStone::TextSceneLayer> 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();
--- 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
--- 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 <OrthancException.h>
 
@@ -80,6 +81,9 @@
         }
       }
 
+      case ISceneLayer::Type_Macro:
+        return new Internals::MacroLayerRenderer(*this, layer);
+
       default:
         return NULL;
     }
--- /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
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#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<const MacroSceneLayer&>(layer);
+      
+      Clear();
+
+      renderers_.reserve(macro.GetSize());
+
+      for (size_t i = 0; i < macro.GetSize(); i++)
+      {
+        renderers_.push_back(factory_.Create(macro.GetLayer(i)));
+      }
+    }
+  }
+}
--- /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
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "CompositorHelper.h"
+
+#include <Compatibility.h>
+
+namespace OrthancStone
+{
+  namespace Internals
+  {
+    class MacroLayerRenderer : public CompositorHelper::ILayerRenderer
+    {
+    private:
+      Internals::CompositorHelper::IRendererFactory&  factory_;
+      std::vector<CompositorHelper::ILayerRenderer*>  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;
+    };
+  }
+}
--- 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<MacroSceneLayer> copy(new MacroSceneLayer);
--- 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
--- 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;
       }