changeset 89:f244018a4e4b wasm

BUGGY- trying to remove IVolumeSlicesObserver
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 26 May 2017 18:27:59 +0200
parents 90bf4116a23c
children 64e60018943f
files Applications/BasicApplicationContext.cpp Applications/Samples/SingleFrameApplication.h Framework/Layers/ILayerSource.h Framework/Layers/LayerSourceBase.cpp Framework/Layers/LayerSourceBase.h Framework/Layers/OrthancFrameLayerSource.cpp Framework/Layers/OrthancFrameLayerSource.h Framework/Toolbox/IVolumeSlicesObserver.h Framework/Toolbox/Slice.cpp Framework/Toolbox/Slice.h Framework/Toolbox/SliceGeometry.cpp Framework/Toolbox/SliceGeometry.h Framework/Widgets/LayerWidget.cpp Framework/Widgets/LayerWidget.h Platforms/Generic/Oracle.cpp UnitTestsSources/UnitTestsMain.cpp
diffstat 16 files changed, 139 insertions(+), 186 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/BasicApplicationContext.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Applications/BasicApplicationContext.cpp	Fri May 26 18:27:59 2017 +0200
@@ -47,6 +47,7 @@
     stopped_(true),
     updateDelay_(100)   // By default, 100ms between each refresh of the content
   {
+    srand(time(NULL)); 
   }
 
 
--- a/Applications/Samples/SingleFrameApplication.h	Fri May 26 16:11:52 2017 +0200
+++ b/Applications/Samples/SingleFrameApplication.h	Fri May 26 18:27:59 2017 +0200
@@ -34,7 +34,7 @@
   {
     class SingleFrameApplication :
       public SampleApplicationBase,
-      public IVolumeSlicesObserver
+      private ILayerSource::IObserver
     {
     private:
       class Interactor : public IWorldSceneInteractor
@@ -92,21 +92,40 @@
         }
       };
 
-      LayerWidget* widget_;
+      virtual void NotifyGeometryReady(const ILayerSource& source)
+      {
+      }
       
-    public:
-      SingleFrameApplication() : widget_(NULL)
+      virtual void NotifyGeometryError(const ILayerSource& source)
       {
       }
       
-      virtual void NotifySlicesAvailable(const ParallelSlices& slices)
+      virtual void NotifyContentChange(const ILayerSource& source)
+      {
+      }
+
+      virtual void NotifySliceChange(const ILayerSource& source,
+                                     const Slice& slice)
+      {
+      }
+ 
+      virtual void NotifyLayerReady(ILayerRenderer *layer,
+                                    const ILayerSource& source,
+                                    const Slice& slice)
       {
-        if (widget_ != NULL &&
-            slices.GetSliceCount() > 0)
-        {
-          widget_->SetSlice(slices.GetSlice(0));
-          widget_->SetDefaultView();
-        }
+      }
+
+      virtual void NotifyLayerError(const ILayerSource& source,
+                                    const SliceGeometry& slice)
+      {
+      }
+
+      LayerWidget*    widget_;
+      
+    public:
+      SingleFrameApplication() : 
+        widget_(NULL)
+      {
       }
       
       virtual void DeclareCommandLineOptions(boost::program_options::options_description& options)
@@ -146,7 +165,6 @@
 #if 1
         std::auto_ptr<OrthancFrameLayerSource> layer
           (new OrthancFrameLayerSource(context.GetWebService(), instance, frame));
-        layer->SetObserver(*this);
         widget->AddLayer(layer.release());
 
         if (parameters["smooth"].as<bool>())
@@ -157,13 +175,14 @@
         }
 #else
         // 0178023P**
-        std::auto_ptr<OrthancFrameLayerSource> layer;
-        layer.reset(new OrthancFrameLayerSource(context.GetWebService(), "c804a1a2-142545c9-33b32fe2-3df4cec0-a2bea6d6", 0));
-        //layer.reset(new OrthancFrameLayerSource(context.GetWebService(), "4bd4304f-47478948-71b24af2-51f4f1bc-275b6c1b", 0));  // BAD SLICE
-        layer->SetObserver(*this);
-        widget->AddLayer(layer.release());
+        std::auto_ptr<OrthancFrameLayerSource> ct;
+        ct.reset(new OrthancFrameLayerSource(context.GetWebService(), "c804a1a2-142545c9-33b32fe2-3df4cec0-a2bea6d6", 0));
+        //ct.reset(new OrthancFrameLayerSource(context.GetWebService(), "4bd4304f-47478948-71b24af2-51f4f1bc-275b6c1b", 0));  // BAD SLICE
+        widget->AddLayer(ct.release());
 
-        widget->AddLayer(new OrthancFrameLayerSource(context.GetWebService(), "a1c4dc6b-255d27f0-88069875-8daed730-2f5ee5c6", 0));
+        std::auto_ptr<OrthancFrameLayerSource> pet;
+        pet.reset(new OrthancFrameLayerSource(context.GetWebService(), "a1c4dc6b-255d27f0-88069875-8daed730-2f5ee5c6", 0));
+        widget->AddLayer(pet.release());
 
         {
           RenderStyle s;
@@ -173,7 +192,7 @@
 
         {
           RenderStyle s;
-          s.drawGrid_ = true;
+          //s.drawGrid_ = true;
           s.SetColor(255, 0, 0);  // Draw missing PET layer in red
           s.alpha_ = 0.5;
           s.applyLut_ = true;
--- a/Framework/Layers/ILayerSource.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Layers/ILayerSource.h	Fri May 26 18:27:59 2017 +0200
@@ -36,19 +36,15 @@
       {
       }
 
-      // Triggered as soon as the source has enough information to
-      // answer to "GetExtent()"
-      virtual void NotifyGeometryReady(const ILayerSource& source) = 0;
-      
-      virtual void NotifyGeometryError(const ILayerSource& source) = 0;
-      
-      // Triggered if the content of the volume has changed
+      // Triggered if the content of several slices in the source
+      // volume has changed
       virtual void NotifyContentChange(const ILayerSource& source) = 0;
 
-      // Triggered if the content of some slice in the source volume has changed
+      // Triggered if the content of some individual slice in the
+      // source volume has changed
       virtual void NotifySliceChange(const ILayerSource& source,
                                      const Slice& slice) = 0;
-
+ 
       // The layer must be deleted by the observer. "layer" will never
       // be "NULL", otherwise "NotifyLayerError()" would have been
       // called.
--- a/Framework/Layers/LayerSourceBase.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Layers/LayerSourceBase.cpp	Fri May 26 18:27:59 2017 +0200
@@ -25,22 +25,6 @@
 
 namespace OrthancStone
 {
-  void LayerSourceBase::NotifyGeometryReady()
-  {
-    if (observer_ != NULL)
-    {
-      observer_->NotifyGeometryReady(*this);
-    }
-  }  
-    
-  void LayerSourceBase::NotifyGeometryError()
-  {
-    if (observer_ != NULL)
-    {
-      observer_->NotifyGeometryError(*this);
-    }
-  }  
-    
   void LayerSourceBase::NotifyContentChange()
   {
     if (observer_ != NULL)
--- a/Framework/Layers/LayerSourceBase.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Layers/LayerSourceBase.h	Fri May 26 18:27:59 2017 +0200
@@ -31,10 +31,11 @@
     IObserver*  observer_;
 
   protected:
-    void NotifyGeometryReady();
-    
-    void NotifyGeometryError();
-    
+    IObserver* GetObserver() const
+    {
+      return observer_;  // TODO REMOVE THIS, FOR TEST
+    }
+
     void NotifyContentChange();
 
     void NotifySliceChange(const Slice& slice);
--- a/Framework/Layers/OrthancFrameLayerSource.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Layers/OrthancFrameLayerSource.cpp	Fri May 26 18:27:59 2017 +0200
@@ -30,10 +30,14 @@
 #include <boost/lexical_cast.hpp>
 
 
+// TODO REMOVE THIS
+#include "../Widgets/LayerWidget.h"
+
 namespace OrthancStone
 {
   void OrthancFrameLayerSource::NotifyGeometryReady(const OrthancSlicesLoader& loader)
   {
+#if 0
     if (loader.GetSliceCount() > 0)
     {
       // Make sure all the slices are parallel. TODO Alleviate this constraint
@@ -49,23 +53,20 @@
     }
 
     LayerSourceBase::NotifyGeometryReady();
-
-    if (observer2_ != NULL)
-    {
-      ParallelSlices slices;
+#endif
 
-      for (size_t i = 0; i < loader.GetSliceCount(); i++)
-      {
-        slices.AddSlice(loader.GetSlice(i).GetGeometry());
-      }
-
-      observer2_->NotifySlicesAvailable(slices);
-    }
+    // TODO REMOVE THIS
+    /*if (GetObserver() != NULL)
+    {
+      dynamic_cast<LayerWidget*>(GetObserver())->SetSlice(loader.GetSlice(0).GetGeometry());
+      }*/
   }
 
   void OrthancFrameLayerSource::NotifyGeometryError(const OrthancSlicesLoader& loader)
   {
+#if 0
     LayerSourceBase::NotifyGeometryError();
+#endif
   }
 
   void OrthancFrameLayerSource::NotifySliceImageReady(const OrthancSlicesLoader& loader,
@@ -88,27 +89,12 @@
                                                    unsigned int frame) :
     instanceId_(instanceId),
     frame_(frame),
-    loader_(*this, orthanc),
-    observer2_(NULL)
+    loader_(*this, orthanc)
   {
     loader_.ScheduleLoadInstance(instanceId_, frame_);
   }
 
 
-  void OrthancFrameLayerSource::SetObserver(IVolumeSlicesObserver& observer)
-  {
-    if (observer2_ == NULL)
-    {
-      observer2_ = &observer;
-    }
-    else
-    {
-      // Cannot add more than one observer
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-  
   bool OrthancFrameLayerSource::GetExtent(double& x1,
                                           double& y1,
                                           double& x2,
--- a/Framework/Layers/OrthancFrameLayerSource.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Layers/OrthancFrameLayerSource.h	Fri May 26 18:27:59 2017 +0200
@@ -23,7 +23,6 @@
 
 #include "LayerSourceBase.h"
 #include "../Toolbox/IWebService.h"
-#include "../Toolbox/IVolumeSlicesObserver.h"
 #include "../Toolbox/OrthancSlicesLoader.h"
 
 namespace OrthancStone
@@ -36,7 +35,6 @@
     std::string             instanceId_;
     unsigned int            frame_;
     OrthancSlicesLoader     loader_;
-    IVolumeSlicesObserver*  observer2_;
 
     virtual void NotifyGeometryReady(const OrthancSlicesLoader& loader);
 
@@ -52,13 +50,19 @@
                                        const Slice& slice);
 
   public:
-    using LayerSourceBase::SetObserver;
-
     OrthancFrameLayerSource(IWebService& orthanc,
                             const std::string& instanceId,
                             unsigned int frame);
 
-    void SetObserver(IVolumeSlicesObserver& observer);
+    virtual size_t GetSliceCount() const
+    {
+      return loader_.GetSliceCount();
+    }
+
+    virtual const Slice& GetSlice(size_t slice) const 
+    {
+      return loader_.GetSlice(slice);
+    }
 
     virtual bool GetExtent(double& x1,
                            double& y1,
--- a/Framework/Toolbox/IVolumeSlicesObserver.h	Fri May 26 16:11:52 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017 Osimis, 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 "ParallelSlices.h"
-
-namespace OrthancStone
-{
-  class IVolumeSlicesObserver : public boost::noncopyable
-  {
-  public:
-    virtual ~IVolumeSlicesObserver()
-    {
-    }
-
-    virtual void NotifySlicesAvailable(const ParallelSlices& slices) = 0;
-  };
-}
-
--- a/Framework/Toolbox/Slice.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Toolbox/Slice.cpp	Fri May 26 18:27:59 2017 +0200
@@ -170,4 +170,18 @@
         
     return converter_;
   }
+
+
+  bool Slice::ContainsPlane(const SliceGeometry& plane) const
+  {
+    if (type_ == Type_Invalid)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+    }
+        
+    return (GeometryToolbox::IsParallel(GetGeometry().GetNormal(), plane.GetNormal()) &&
+            GeometryToolbox::IsNear(GetGeometry().ProjectAlongNormal(GetGeometry().GetOrigin()),
+                                    GetGeometry().ProjectAlongNormal(plane.GetOrigin()),
+                                    thickness_ / 2.0));
+  }
 }
--- a/Framework/Toolbox/Slice.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Toolbox/Slice.h	Fri May 26 18:27:59 2017 +0200
@@ -95,9 +95,6 @@
 
     const DicomFrameConverter& GetConverter() const;
 
-    bool ContainsPlane(const SliceGeometry& plane) const
-    {
-      return geometry_.IsSamePlane(plane, thickness_);
-    }
+    bool ContainsPlane(const SliceGeometry& plane) const;
   };
 }
--- a/Framework/Toolbox/SliceGeometry.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Toolbox/SliceGeometry.cpp	Fri May 26 18:27:59 2017 +0200
@@ -152,14 +152,4 @@
     offsetX = boost::numeric::ublas::inner_prod(axisX_, projection - origin_);
     offsetY = boost::numeric::ublas::inner_prod(axisY_, projection - origin_);
   }
-
-  
-  bool SliceGeometry::IsSamePlane(const SliceGeometry& other,
-                                  double sliceThickness) const
-  {
-    return (GeometryToolbox::IsParallel(GetNormal(), other.GetNormal()) &&
-            GeometryToolbox::IsNear(ProjectAlongNormal(other.GetOrigin()),
-                                    ProjectAlongNormal(GetOrigin()),
-                                    sliceThickness / 2.0));
-  }
 }
--- a/Framework/Toolbox/SliceGeometry.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Toolbox/SliceGeometry.h	Fri May 26 18:27:59 2017 +0200
@@ -88,8 +88,5 @@
     void ProjectPoint(double& offsetX,
                       double& offsetY,
                       const Vector& point) const;
-
-    bool IsSamePlane(const SliceGeometry& slice,
-                     double sliceThickness) const;
   };
 }
--- a/Framework/Widgets/LayerWidget.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Widgets/LayerWidget.cpp	Fri May 26 18:27:59 2017 +0200
@@ -94,6 +94,11 @@
       return countMissing_ == 0;
     }
 
+    unsigned int GetCountMissing() const
+    {
+      return countMissing_;
+    }
+
     bool RenderScene(CairoContext& context,
                      const ViewportGeometry& view)
     {
@@ -101,6 +106,11 @@
 
       for (size_t i = 0; i < renderers_.size(); i++)
       {
+        if (renderers_[i] != NULL)
+        {
+          LOG(ERROR) << "...............";
+        }
+
         if (renderers_[i] != NULL &&
             !renderers_[i]->RenderLayer(context, view, slice_))
         {
@@ -302,6 +312,7 @@
       pendingScene_->SetLayer(index, tmp.release());
 
       if (currentScene_.get() == NULL ||
+          !currentScene_->IsComplete() ||
           pendingScene_->IsComplete())
       {
         currentScene_ = pendingScene_;
@@ -340,6 +351,7 @@
     layersIndex_[layer] = index;
 
     ResetPendingScene();
+    LOG(ERROR) << "*****************************";
     layer->SetObserver(*this);
 
     return index;
@@ -373,43 +385,39 @@
 
   void LayerWidget::SetSlice(const SliceGeometry& slice)
   {
-    if (!slice_.IsSamePlane(slice, THIN_SLICE_THICKNESS))
+    if (currentScene_.get() == NULL ||
+        (pendingScene_.get() != NULL &&
+         pendingScene_->IsComplete()))
     {
-      if (currentScene_.get() == NULL ||
-          (pendingScene_.get() != NULL &&
-           pendingScene_->IsComplete()))
-      {
-        currentScene_ = pendingScene_;
-      }
-        
-      slice_ = slice;
-      ResetPendingScene();
+      currentScene_ = pendingScene_;
+    }
+
+    slice_ = slice;
+    ResetPendingScene();
+  }
 
-      for (size_t i = 0; i < layers_.size(); i++)
-      {
-        assert(layers_[i] != NULL);
-        layers_[i]->ScheduleLayerCreation(slice_);
-      }
+
+  void LayerWidget::InvalidateAllLayers()
+  {
+    for (size_t i = 0; i < layers_.size(); i++)
+    {
+      assert(layers_[i] != NULL);
+      layers_[i]->ScheduleLayerCreation(slice_);
     }
   }
 
-  
-  void LayerWidget::NotifyGeometryReady(const ILayerSource& source)
+
+  void LayerWidget::InvalidateLayer(size_t layer)
   {
-    size_t i;
-    if (LookupLayer(i, source))
+    if (layer >= layers_.size())
     {
-      LOG(INFO) << "Geometry ready for layer " << i;
-      layers_[i]->ScheduleLayerCreation(slice_);
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
     }
-  }
-  
 
-  void LayerWidget::NotifyGeometryError(const ILayerSource& source)
-  {
-    LOG(ERROR) << "Cannot get geometry";
+    assert(layers_[layer] != NULL);
+    layers_[layer]->ScheduleLayerCreation(slice_);
   }
-  
+
 
   void LayerWidget::NotifyContentChange(const ILayerSource& source)
   {
@@ -434,7 +442,7 @@
     }
   }
   
-
+  
   void LayerWidget::NotifyLayerReady(ILayerRenderer* renderer,
                                      const ILayerSource& source,
                                      const Slice& slice)
@@ -456,8 +464,10 @@
   {
     size_t index;
 
+    Slice expected(slice_, THIN_SLICE_THICKNESS);
+
     if (LookupLayer(index, source) &&
-        slice.IsSamePlane(slice_, THIN_SLICE_THICKNESS))  // Whether the slice comes from an older request
+        expected.ContainsPlane(slice))  // Whether the slice comes from an older request
     {
       LOG(INFO) << "Unable to load a slice from layer " << index;
 
--- a/Framework/Widgets/LayerWidget.h	Fri May 26 16:11:52 2017 +0200
+++ b/Framework/Widgets/LayerWidget.h	Fri May 26 18:27:59 2017 +0200
@@ -55,10 +55,6 @@
                          double& y2,
                          ILayerSource& source) const;
 
-    virtual void NotifyGeometryReady(const ILayerSource& source);
-
-    virtual void NotifyGeometryError(const ILayerSource& source);
-
     virtual void NotifyContentChange(const ILayerSource& source);
 
     virtual void NotifySliceChange(const ILayerSource& source,
@@ -86,6 +82,10 @@
     void UpdateLayer(size_t index,
                      ILayerRenderer* renderer,
                      const Slice& slice);
+
+    void InvalidateAllLayers();
+
+    void InvalidateLayer(size_t layer);
     
   public:
     LayerWidget();
@@ -94,6 +94,11 @@
 
     size_t AddLayer(ILayerSource* layer);  // Takes ownership
 
+    size_t GetLayerCount() const
+    {
+      return layers_.size();
+    }
+
     void SetLayerStyle(size_t layer,
                        const RenderStyle& style);
 
--- a/Platforms/Generic/Oracle.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/Platforms/Generic/Oracle.cpp	Fri May 26 18:27:59 2017 +0200
@@ -26,6 +26,7 @@
 #include "../../Resources/Orthanc/Core/OrthancException.h"
 
 #include <vector>
+#include <stdio.h>
 
 namespace OrthancStone
 {
@@ -67,6 +68,9 @@
           IOracleCommand& command = dynamic_cast<IOracleCommand&>(*item);
           command.Execute();
 
+          // Random sleeping to test
+          //boost::this_thread::sleep(boost::posix_time::milliseconds(50 * (1 + rand() % 10)));
+
           if (that->globalMutex_ != NULL)
           {
             boost::mutex::scoped_lock lock(*that->globalMutex_);
--- a/UnitTestsSources/UnitTestsMain.cpp	Fri May 26 16:11:52 2017 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Fri May 26 18:27:59 2017 +0200
@@ -28,7 +28,6 @@
 #include "../Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.h"
 #include "../Resources/Orthanc/Core/OrthancException.h"
 
-#include "../Framework/Toolbox/IVolumeSlicesObserver.h"
 #include "../Framework/Volumes/ImageBuffer3D.h"
 #include "../Framework/Volumes/SlicedVolumeBase.h"
 #include "../Framework/Toolbox/DownloadStack.h"
@@ -82,7 +81,6 @@
   { 
   private:
     OrthancSlicesLoader           loader_;
-    IVolumeSlicesObserver*        observer_;
     std::auto_ptr<ImageBuffer3D>  image_;
     std::auto_ptr<DownloadStack>  downloadStack_;
 
@@ -236,8 +234,7 @@
 
   public:
     OrthancVolumeImageLoader(IWebService& orthanc) : 
-      loader_(*this, orthanc),
-      observer_(NULL)
+      loader_(*this, orthanc)
     {
     }
 
@@ -261,20 +258,6 @@
     {
       return loader_.GetSlice(index);
     }
-
-    void SetObserver(IVolumeSlicesObserver& observer)
-    {
-      if (observer_ == NULL)
-      {
-        observer_ = &observer;
-      }
-      else
-      {
-        // Cannot add more than one observer
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-    }
-
   };
 }