changeset 413:18b707fb8620

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 12 Nov 2018 17:17:25 +0100
parents 71c16998fcc8
children f7616c010056
files Applications/Samples/SingleFrameEditorApplication.h Framework/Radiography/RadiographySceneCommand.cpp Framework/Radiography/RadiographySceneCommand.h Framework/Radiography/RadiographyWidget.cpp Framework/Radiography/RadiographyWidget.h Resources/CMake/OrthancStoneConfiguration.cmake
diffstat 6 files changed, 475 insertions(+), 239 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/SingleFrameEditorApplication.h	Mon Nov 12 16:29:36 2018 +0100
+++ b/Applications/Samples/SingleFrameEditorApplication.h	Mon Nov 12 17:17:25 2018 +0100
@@ -24,6 +24,7 @@
 #include "SampleApplicationBase.h"
 
 #include "../../Framework/Radiography/RadiographyScene.h"
+#include "../../Framework/Radiography/RadiographyWidget.h"
 
 #include "../../Framework/Toolbox/UndoRedoStack.h"
 
@@ -51,7 +52,7 @@
 
 namespace OrthancStone
 {
-  class RadiographyLayerCommand : public UndoRedoStack::ICommand
+  class RadiographySceneCommand : public UndoRedoStack::ICommand
   {
   private:
     RadiographyScene&  scene_;
@@ -63,14 +64,14 @@
     virtual void RedoInternal(RadiographyLayer& layer) const = 0;
 
   public:
-    RadiographyLayerCommand(RadiographyScene& scene,
+    RadiographySceneCommand(RadiographyScene& scene,
                             size_t layer) :
       scene_(scene),
       layer_(layer)
     {
     }
 
-    RadiographyLayerCommand(const RadiographyScene::LayerAccessor& accessor) :
+    RadiographySceneCommand(const RadiographyScene::LayerAccessor& accessor) :
       scene_(accessor.GetScene()),
       layer_(accessor.GetIndex())
     {
@@ -131,7 +132,7 @@
     }
 
 
-    class UndoRedoCommand : public RadiographyLayerCommand
+    class UndoRedoCommand : public RadiographySceneCommand
     {
     private:
       double  sourceAngle_;
@@ -157,7 +158,7 @@
 
     public:
       UndoRedoCommand(const RadiographyLayerRotateTracker& tracker) :
-        RadiographyLayerCommand(tracker.accessor_),
+        RadiographySceneCommand(tracker.accessor_),
         sourceAngle_(tracker.originalAngle_),
         targetAngle_(tracker.accessor_.GetLayer().GetAngle())
       {
@@ -247,7 +248,7 @@
     double                           panY_;
     bool                             oneAxis_;
 
-    class UndoRedoCommand : public RadiographyLayerCommand
+    class UndoRedoCommand : public RadiographySceneCommand
     {
     private:
       double  sourceX_;
@@ -268,7 +269,7 @@
 
     public:
       UndoRedoCommand(const RadiographyLayerMoveTracker& tracker) :
-        RadiographyLayerCommand(tracker.accessor_),
+        RadiographySceneCommand(tracker.accessor_),
         sourceX_(tracker.panX_),
         sourceY_(tracker.panY_),
         targetX_(tracker.accessor_.GetLayer().GetPanX()),
@@ -358,7 +359,7 @@
     unsigned int                     cropWidth_;
     unsigned int                     cropHeight_;
 
-    class UndoRedoCommand : public RadiographyLayerCommand
+    class UndoRedoCommand : public RadiographySceneCommand
     {
     private:
       unsigned int  sourceCropX_;
@@ -383,7 +384,7 @@
 
     public:
       UndoRedoCommand(const RadiographyLayerCropTracker& tracker) :
-        RadiographyLayerCommand(tracker.accessor_),
+        RadiographySceneCommand(tracker.accessor_),
         sourceCropX_(tracker.cropX_),
         sourceCropY_(tracker.cropY_),
         sourceCropWidth_(tracker.cropWidth_),
@@ -504,7 +505,7 @@
       return sqrt(dx * dx + dy * dy);
     }
       
-    class UndoRedoCommand : public RadiographyLayerCommand
+    class UndoRedoCommand : public RadiographySceneCommand
     {
     private:
       double   sourceSpacingX_;
@@ -531,7 +532,7 @@
 
     public:
       UndoRedoCommand(const RadiographyLayerResizeTracker& tracker) :
-        RadiographyLayerCommand(tracker.accessor_),
+        RadiographySceneCommand(tracker.accessor_),
         sourceSpacingX_(tracker.originalSpacingX_),
         sourceSpacingY_(tracker.originalSpacingY_),
         sourcePanX_(tracker.originalPanX_),
@@ -849,228 +850,6 @@
   };
 
 
-  class RadiographyWidget :
-    public WorldSceneWidget,
-    public IObserver
-  {
-  private:
-    RadiographyScene&              scene_;
-    std::auto_ptr<Orthanc::Image>  floatBuffer_;
-    std::auto_ptr<CairoSurface>    cairoBuffer_;
-    bool                           invert_;
-    ImageInterpolation             interpolation_;
-    bool                           hasSelection_;
-    size_t                         selectedLayer_;
-
-    virtual bool RenderInternal(unsigned int width,
-                                unsigned int height,
-                                ImageInterpolation interpolation)
-    {
-      float windowCenter, windowWidth;
-      scene_.GetWindowingWithDefault(windowCenter, windowWidth);
-      
-      float x0 = windowCenter - windowWidth / 2.0f;
-      float x1 = windowCenter + windowWidth / 2.0f;
-
-      if (windowWidth <= 0.001f)  // Avoid division by zero at (*)
-      {
-        return false;
-      }
-      else
-      {
-        if (floatBuffer_.get() == NULL ||
-            floatBuffer_->GetWidth() != width ||
-            floatBuffer_->GetHeight() != height)
-        {
-          floatBuffer_.reset(new Orthanc::Image(Orthanc::PixelFormat_Float32, width, height, false));
-        }
-
-        if (cairoBuffer_.get() == NULL ||
-            cairoBuffer_->GetWidth() != width ||
-            cairoBuffer_->GetHeight() != height)
-        {
-          cairoBuffer_.reset(new CairoSurface(width, height));
-        }
-
-        scene_.Render(*floatBuffer_, GetView().GetMatrix(), interpolation);
-        
-        // Conversion from Float32 to BGRA32 (cairo). Very similar to
-        // GrayscaleFrameRenderer => TODO MERGE?
-
-        Orthanc::ImageAccessor target;
-        cairoBuffer_->GetWriteableAccessor(target);
-
-        float scaling = 255.0f / (x1 - x0);
-        
-        for (unsigned int y = 0; y < height; y++)
-        {
-          const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y));
-          uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-
-          for (unsigned int x = 0; x < width; x++, p++, q += 4)
-          {
-            uint8_t v = 0;
-            if (*p >= x1)
-            {
-              v = 255;
-            }
-            else if (*p <= x0)
-            {
-              v = 0;
-            }
-            else
-            {
-              // https://en.wikipedia.org/wiki/Linear_interpolation
-              v = static_cast<uint8_t>(scaling * (*p - x0));  // (*)
-            }
-
-            if (invert_)
-            {
-              v = 255 - v;
-            }
-
-            q[0] = v;
-            q[1] = v;
-            q[2] = v;
-            q[3] = 255;
-          }
-        }
-
-        return true;
-      }
-    }
-
-  protected:
-    virtual Extent2D GetSceneExtent()
-    {
-      return scene_.GetSceneExtent();
-    }
-
-    virtual bool RenderScene(CairoContext& context,
-                             const ViewportGeometry& view)
-    {
-      cairo_t* cr = context.GetObject();
-
-      if (RenderInternal(context.GetWidth(), context.GetHeight(), interpolation_))
-      {
-        // https://www.cairographics.org/FAQ/#paint_from_a_surface
-        cairo_save(cr);
-        cairo_identity_matrix(cr);
-        cairo_set_source_surface(cr, cairoBuffer_->GetObject(), 0, 0);
-        cairo_paint(cr);
-        cairo_restore(cr);
-      }
-      else
-      {
-        // https://www.cairographics.org/FAQ/#clear_a_surface
-        context.SetSourceColor(0, 0, 0);
-        cairo_paint(cr);
-      }
-
-      if (hasSelection_)
-      {
-        scene_.DrawBorder(context, selectedLayer_, view.GetZoom());
-      }
-
-      return true;
-    }
-
-  public:
-    RadiographyWidget(MessageBroker& broker,
-                      RadiographyScene& scene,
-                      const std::string& name) :
-      WorldSceneWidget(name),
-      IObserver(broker),
-      scene_(scene),
-      invert_(false),
-      interpolation_(ImageInterpolation_Nearest),
-      hasSelection_(false),
-      selectedLayer_(0)    // Dummy initialization
-    {
-      scene.RegisterObserverCallback(
-        new Callable<RadiographyWidget, RadiographyScene::GeometryChangedMessage>
-        (*this, &RadiographyWidget::OnGeometryChanged));
-
-      scene.RegisterObserverCallback(
-        new Callable<RadiographyWidget, RadiographyScene::ContentChangedMessage>
-        (*this, &RadiographyWidget::OnContentChanged));
-    }
-
-    RadiographyScene& GetScene() const
-    {
-      return scene_;
-    }
-
-    void Unselect()
-    {
-      hasSelection_ = false;
-    }
-
-    void Select(size_t layer)
-    {
-      hasSelection_ = true;
-      selectedLayer_ = layer;
-    }
-
-    bool LookupSelectedLayer(size_t& layer)
-    {
-      if (hasSelection_)
-      {
-        layer = selectedLayer_;
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-
-    void OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message)
-    {
-      LOG(INFO) << "Geometry has changed";
-      FitContent();
-    }
-
-    void OnContentChanged(const RadiographyScene::ContentChangedMessage& message)
-    {
-      LOG(INFO) << "Content has changed";
-      NotifyContentChanged();
-    }
-
-    void SetInvert(bool invert)
-    {
-      if (invert_ != invert)
-      {
-        invert_ = invert;
-        NotifyContentChanged();
-      }
-    }
-
-    void SwitchInvert()
-    {
-      invert_ = !invert_;
-      NotifyContentChanged();
-    }
-
-    bool IsInverted() const
-    {
-      return invert_;
-    }
-
-    void SetInterpolation(ImageInterpolation interpolation)
-    {
-      if (interpolation_ != interpolation)
-      {
-        interpolation_ = interpolation;
-        NotifyContentChanged();
-      }
-    }
-
-    ImageInterpolation GetInterpolation() const
-    {
-      return interpolation_;
-    }
-  };
 
   
   namespace Samples
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Radiography/RadiographySceneCommand.cpp	Mon Nov 12 17:17:25 2018 +0100
@@ -0,0 +1,62 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "RadiographySceneCommand.h"
+
+
+namespace OrthancStone
+{
+  RadiographySceneCommand::RadiographySceneCommand(RadiographyScene& scene,
+                                                   size_t layer) :
+    scene_(scene),
+    layer_(layer)
+  {
+  }
+
+  
+  RadiographySceneCommand::RadiographySceneCommand(const RadiographyScene::LayerAccessor& accessor) :
+    scene_(accessor.GetScene()),
+    layer_(accessor.GetIndex())
+  {
+  }
+
+  
+  void RadiographySceneCommand::Undo() const
+  {
+    RadiographyScene::LayerAccessor accessor(scene_, layer_);
+
+    if (accessor.IsValid())
+    {
+      UndoInternal(accessor.GetLayer());
+    }
+  }
+
+  
+  void RadiographySceneCommand::Redo() const
+  {
+    RadiographyScene::LayerAccessor accessor(scene_, layer_);
+
+    if (accessor.IsValid())
+    {
+      RedoInternal(accessor.GetLayer());
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Radiography/RadiographySceneCommand.h	Mon Nov 12 17:17:25 2018 +0100
@@ -0,0 +1,50 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../Toolbox/UndoRedoStack.h"
+#include "RadiographyScene.h"
+
+namespace OrthancStone
+{
+  class RadiographySceneCommand : public UndoRedoStack::ICommand
+  {
+  private:
+    RadiographyScene&  scene_;
+    size_t             layer_;
+
+  protected:
+    virtual void UndoInternal(RadiographyLayer& layer) const = 0;
+
+    virtual void RedoInternal(RadiographyLayer& layer) const = 0;
+
+  public:
+    RadiographySceneCommand(RadiographyScene& scene,
+                            size_t layer);
+
+    RadiographySceneCommand(const RadiographyScene::LayerAccessor& accessor);
+
+    virtual void Undo() const;
+
+    virtual void Redo() const;
+  };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Radiography/RadiographyWidget.cpp	Mon Nov 12 17:17:25 2018 +0100
@@ -0,0 +1,219 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "RadiographyWidget.h"
+
+#include <Core/Images/Image.h>
+
+
+namespace OrthancStone
+{
+  bool RadiographyWidget::RenderInternal(unsigned int width,
+                                         unsigned int height,
+                                         ImageInterpolation interpolation)
+  {
+    float windowCenter, windowWidth;
+    scene_.GetWindowingWithDefault(windowCenter, windowWidth);
+      
+    float x0 = windowCenter - windowWidth / 2.0f;
+    float x1 = windowCenter + windowWidth / 2.0f;
+
+    if (windowWidth <= 0.001f)  // Avoid division by zero at (*)
+    {
+      return false;
+    }
+    else
+    {
+      if (floatBuffer_.get() == NULL ||
+          floatBuffer_->GetWidth() != width ||
+          floatBuffer_->GetHeight() != height)
+      {
+        floatBuffer_.reset(new Orthanc::Image(Orthanc::PixelFormat_Float32, width, height, false));
+      }
+
+      if (cairoBuffer_.get() == NULL ||
+          cairoBuffer_->GetWidth() != width ||
+          cairoBuffer_->GetHeight() != height)
+      {
+        cairoBuffer_.reset(new CairoSurface(width, height));
+      }
+
+      scene_.Render(*floatBuffer_, GetView().GetMatrix(), interpolation);
+        
+      // Conversion from Float32 to BGRA32 (cairo). Very similar to
+      // GrayscaleFrameRenderer => TODO MERGE?
+
+      Orthanc::ImageAccessor target;
+      cairoBuffer_->GetWriteableAccessor(target);
+
+      float scaling = 255.0f / (x1 - x0);
+        
+      for (unsigned int y = 0; y < height; y++)
+      {
+        const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y));
+        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
+
+        for (unsigned int x = 0; x < width; x++, p++, q += 4)
+        {
+          uint8_t v = 0;
+          if (*p >= x1)
+          {
+            v = 255;
+          }
+          else if (*p <= x0)
+          {
+            v = 0;
+          }
+          else
+          {
+            // https://en.wikipedia.org/wiki/Linear_interpolation
+            v = static_cast<uint8_t>(scaling * (*p - x0));  // (*)
+          }
+
+          if (invert_)
+          {
+            v = 255 - v;
+          }
+
+          q[0] = v;
+          q[1] = v;
+          q[2] = v;
+          q[3] = 255;
+        }
+      }
+
+      return true;
+    }
+  }
+
+
+  bool RadiographyWidget::RenderScene(CairoContext& context,
+                                      const ViewportGeometry& view)
+  {
+    cairo_t* cr = context.GetObject();
+
+    if (RenderInternal(context.GetWidth(), context.GetHeight(), interpolation_))
+    {
+      // https://www.cairographics.org/FAQ/#paint_from_a_surface
+      cairo_save(cr);
+      cairo_identity_matrix(cr);
+      cairo_set_source_surface(cr, cairoBuffer_->GetObject(), 0, 0);
+      cairo_paint(cr);
+      cairo_restore(cr);
+    }
+    else
+    {
+      // https://www.cairographics.org/FAQ/#clear_a_surface
+      context.SetSourceColor(0, 0, 0);
+      cairo_paint(cr);
+    }
+
+    if (hasSelection_)
+    {
+      scene_.DrawBorder(context, selectedLayer_, view.GetZoom());
+    }
+
+    return true;
+  }
+
+
+  RadiographyWidget::RadiographyWidget(MessageBroker& broker,
+                                       RadiographyScene& scene,
+                                       const std::string& name) :
+    WorldSceneWidget(name),
+    IObserver(broker),
+    scene_(scene),
+    invert_(false),
+    interpolation_(ImageInterpolation_Nearest),
+    hasSelection_(false),
+    selectedLayer_(0)    // Dummy initialization
+  {
+    scene.RegisterObserverCallback(
+      new Callable<RadiographyWidget, RadiographyScene::GeometryChangedMessage>
+      (*this, &RadiographyWidget::OnGeometryChanged));
+
+    scene.RegisterObserverCallback(
+      new Callable<RadiographyWidget, RadiographyScene::ContentChangedMessage>
+      (*this, &RadiographyWidget::OnContentChanged));
+  }
+
+
+  void RadiographyWidget::Select(size_t layer)
+  {
+    hasSelection_ = true;
+    selectedLayer_ = layer;
+  }
+
+
+  bool RadiographyWidget::LookupSelectedLayer(size_t& layer)
+  {
+    if (hasSelection_)
+    {
+      layer = selectedLayer_;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  
+  void RadiographyWidget::OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message)
+  {
+    LOG(INFO) << "Geometry has changed";
+    FitContent();
+  }
+
+  
+  void RadiographyWidget::OnContentChanged(const RadiographyScene::ContentChangedMessage& message)
+  {
+    LOG(INFO) << "Content has changed";
+    NotifyContentChanged();
+  }
+
+  
+  void RadiographyWidget::SetInvert(bool invert)
+  {
+    if (invert_ != invert)
+    {
+      invert_ = invert;
+      NotifyContentChanged();
+    }
+  }
+
+  
+  void RadiographyWidget::SwitchInvert()
+  {
+    invert_ = !invert_;
+    NotifyContentChanged();
+  }
+
+
+  void RadiographyWidget::SetInterpolation(ImageInterpolation interpolation)
+  {
+    if (interpolation_ != interpolation)
+    {
+      interpolation_ = interpolation;
+      NotifyContentChanged();
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Radiography/RadiographyWidget.h	Mon Nov 12 17:17:25 2018 +0100
@@ -0,0 +1,95 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../Widgets/WorldSceneWidget.h"
+#include "RadiographyScene.h"
+
+
+namespace OrthancStone
+{
+  class RadiographyWidget :
+    public WorldSceneWidget,
+    public IObserver
+  {
+  private:
+    RadiographyScene&                      scene_;
+    std::auto_ptr<Orthanc::ImageAccessor>  floatBuffer_;
+    std::auto_ptr<CairoSurface>            cairoBuffer_;
+    bool                                   invert_;
+    ImageInterpolation                     interpolation_;
+    bool                                   hasSelection_;
+    size_t                                 selectedLayer_;
+
+    bool RenderInternal(unsigned int width,
+                        unsigned int height,
+                        ImageInterpolation interpolation);
+
+  protected:
+    virtual Extent2D GetSceneExtent()
+    {
+      return scene_.GetSceneExtent();
+    }
+
+    virtual bool RenderScene(CairoContext& context,
+                             const ViewportGeometry& view);
+
+  public:
+    RadiographyWidget(MessageBroker& broker,
+                      RadiographyScene& scene,
+                      const std::string& name);
+
+    RadiographyScene& GetScene() const
+    {
+      return scene_;
+    }
+
+    void Unselect()
+    {
+      hasSelection_ = false;
+    }
+
+    void Select(size_t layer);
+
+    bool LookupSelectedLayer(size_t& layer);
+
+    void OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message);
+
+    void OnContentChanged(const RadiographyScene::ContentChangedMessage& message);
+
+    void SetInvert(bool invert);
+
+    void SwitchInvert();
+
+    bool IsInverted() const
+    {
+      return invert_;
+    }
+
+    void SetInterpolation(ImageInterpolation interpolation);
+
+    ImageInterpolation GetInterpolation() const
+    {
+      return interpolation_;
+    }
+  };
+}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Mon Nov 12 16:29:36 2018 +0100
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Mon Nov 12 17:17:25 2018 +0100
@@ -247,14 +247,13 @@
   ${ORTHANC_STONE_ROOT}/Framework/Layers/RenderStyle.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Layers/SliceOutlineRenderer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyLayer.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyLayer.h
   ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyScene.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyScene.h
+  ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographySceneCommand.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/SmartLoader.cpp
   ${ORTHANC_STONE_ROOT}/Framework/StoneEnumerations.cpp
   ${ORTHANC_STONE_ROOT}/Framework/StoneException.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/AffineTransform2D.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/AffineTransform2D.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/CoordinateSystem3D.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/DicomFrameConverter.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/DicomStructureSet.cpp
@@ -263,7 +262,6 @@
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/FiniteProjectiveCamera.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/GeometryToolbox.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/IWebService.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/IWebService.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ImageGeometry.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/LinearAlgebra.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/MessagingToolbox.cpp
@@ -276,7 +274,6 @@
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/Slice.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/SlicesSorter.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ViewportGeometry.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoContext.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoSurface.cpp
@@ -304,7 +301,6 @@
   ${ORTHANC_STONE_ROOT}/Framework/Messages/ICallable.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/IMessage.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/IObservable.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Messages/IObservable.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/IObserver.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/MessageBroker.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/MessageForwarder.cpp
@@ -331,3 +327,38 @@
   ${BOOST_EXTENDED_SOURCES}
   )
 
+
+
+
+##
+## TEST - Automatically add all ".h" headers to the list of sources
+##
+
+macro(AutodetectHeaderFiles SOURCES_VAR)
+  set(TMP)
+  
+  foreach(f IN LISTS ${SOURCES_VAR})
+    get_filename_component(_base ${f} NAME_WE)
+    get_filename_component(_dir ${f} DIRECTORY)
+    get_filename_component(_extension ${f} EXT)
+    set(_header ${_dir}/${_base}.h)
+    
+    if ((_extension STREQUAL ".cpp" OR
+          _extension STREQUAL ".cc" OR
+          _extension STREQUAL ".h") AND
+        EXISTS ${_header} AND
+        NOT IS_DIRECTORY ${_header} AND
+        NOT IS_SYMLINK ${_header})
+
+      list (FIND SOURCES_VAR ${_header} _index)
+      if (${_index} EQUAL -1)
+        list(APPEND TMP ${_header})
+      endif()
+    endif()
+  endforeach()
+
+  list(APPEND ${SOURCES_VAR} ${TMP})
+endmacro()
+
+
+AutodetectHeaderFiles(ORTHANC_STONE_SOURCES)