changeset 789:c83a45f864b2

Merge
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 28 May 2019 08:15:38 +0200
parents e76c4eef1054 (current diff) 5aa728500586 (diff)
children 907189734acd 20262f5e5e88
files Samples/Sdl/Loader.cpp
diffstat 5 files changed, 131 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Toolbox/DicomStructureSet.cpp	Mon May 27 16:01:47 2019 +0200
+++ b/Framework/Toolbox/DicomStructureSet.cpp	Tue May 28 08:15:38 2019 +0200
@@ -422,24 +422,43 @@
                    << static_cast<int>(structures_[i].green_) << ","
                    << static_cast<int>(structures_[i].blue_) << ")";
 
+
+      // These temporary variables avoid allocating many vectors in the loop below
+      OrthancPlugins::DicomPath countPointsPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
+                                                DICOM_TAG_CONTOUR_SEQUENCE, 0,
+                                                DICOM_TAG_NUMBER_OF_CONTOUR_POINTS);
+
+      OrthancPlugins::DicomPath geometricTypePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
+                                                  DICOM_TAG_CONTOUR_SEQUENCE, 0,
+                                                  DICOM_TAG_CONTOUR_GEOMETRIC_TYPE);
+      
+      OrthancPlugins::DicomPath imageSequencePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
+                                                  DICOM_TAG_CONTOUR_SEQUENCE, 0,
+                                                  DICOM_TAG_CONTOUR_IMAGE_SEQUENCE);
+
+      OrthancPlugins::DicomPath referencedInstancePath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
+                                                       DICOM_TAG_CONTOUR_SEQUENCE, 0,
+                                                       DICOM_TAG_CONTOUR_IMAGE_SEQUENCE, 0,
+                                                       DICOM_TAG_REFERENCED_SOP_INSTANCE_UID);
+
+      OrthancPlugins::DicomPath contourDataPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
+                                                DICOM_TAG_CONTOUR_SEQUENCE, 0,
+                                                DICOM_TAG_CONTOUR_DATA);
+
       for (size_t j = 0; j < countSlices; j++)
       {
         unsigned int countPoints;
 
-        if (!reader.GetUnsignedIntegerValue
-            (countPoints, OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
-                                                    DICOM_TAG_CONTOUR_SEQUENCE, j,
-                                                    DICOM_TAG_NUMBER_OF_CONTOUR_POINTS)))
+        countPointsPath.SetPrefixIndex(1, j);
+        if (!reader.GetUnsignedIntegerValue(countPoints, countPointsPath))
         {
           throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
         }
             
         //LOG(INFO) << "Parsing slice containing " << countPoints << " vertices";
 
-        std::string type = reader.GetMandatoryStringValue
-          (OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
-                                     DICOM_TAG_CONTOUR_SEQUENCE, j,
-                                     DICOM_TAG_CONTOUR_GEOMETRIC_TYPE));
+        geometricTypePath.SetPrefixIndex(1, j);
+        std::string type = reader.GetMandatoryStringValue(geometricTypePath);
         if (type != "CLOSED_PLANAR")
         {
           LOG(WARNING) << "Ignoring contour with geometry type: " << type;
@@ -447,24 +466,19 @@
         }
 
         size_t size;
-        if (!tags.GetSequenceSize(size, OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
-                                                                  DICOM_TAG_CONTOUR_SEQUENCE, j,
-                                                                  DICOM_TAG_CONTOUR_IMAGE_SEQUENCE)) ||
+
+        imageSequencePath.SetPrefixIndex(1, j);
+        if (!tags.GetSequenceSize(size, imageSequencePath) ||
             size != 1)
         {
           throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);          
         }
 
-        std::string sopInstanceUid = reader.GetMandatoryStringValue
-          (OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
-                                     DICOM_TAG_CONTOUR_SEQUENCE, j,
-                                     DICOM_TAG_CONTOUR_IMAGE_SEQUENCE, 0,
-                                     DICOM_TAG_REFERENCED_SOP_INSTANCE_UID));
-        
-        std::string slicesData = reader.GetMandatoryStringValue
-          (OrthancPlugins::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
-                                     DICOM_TAG_CONTOUR_SEQUENCE, j,
-                                     DICOM_TAG_CONTOUR_DATA));
+        referencedInstancePath.SetPrefixIndex(1, j);
+        std::string sopInstanceUid = reader.GetMandatoryStringValue(referencedInstancePath);
+
+        contourDataPath.SetPrefixIndex(1, j);        
+        std::string slicesData = reader.GetMandatoryStringValue(contourDataPath);
 
         Vector points;
         if (!LinearAlgebra::ParseVector(points, slicesData) ||
--- a/Framework/Toolbox/DicomStructureSet.h	Mon May 27 16:01:47 2019 +0200
+++ b/Framework/Toolbox/DicomStructureSet.h	Tue May 28 08:15:38 2019 +0200
@@ -170,6 +170,7 @@
 
     Vector GetNormal() const;
 
+    // TODO - Remove
     static DicomStructureSet* SynchronousLoad(OrthancPlugins::IOrthancConnection& orthanc,
                                               const std::string& instanceId);
 
--- a/Framework/Toolbox/LinearAlgebra.cpp	Mon May 27 16:01:47 2019 +0200
+++ b/Framework/Toolbox/LinearAlgebra.cpp	Tue May 28 08:15:38 2019 +0200
@@ -63,7 +63,7 @@
                      const std::string& value)
     {
       std::vector<std::string> items;
-      Orthanc::Toolbox::TokenizeString(items, value, '\\');
+      Orthanc::Toolbox::TokenizeString(items, Orthanc::Toolbox::StripSpaces(value), '\\');
 
       target.resize(items.size());
 
@@ -71,7 +71,7 @@
       {
         try
         {
-          target[i] = boost::lexical_cast<double>(Orthanc::Toolbox::StripSpaces(items[i]));
+          target[i] = boost::lexical_cast<double>(items[i]);
         }
         catch (boost::bad_lexical_cast&)
         {
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Mon May 27 16:01:47 2019 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Tue May 28 08:15:38 2019 +0200
@@ -313,10 +313,6 @@
 
 if (ENABLE_STONE_DEPRECATED)
   list(APPEND ORTHANC_STONE_SOURCES
-    ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
-    ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp
-    ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
-    ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp
     ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Layers/CircleMeasureTracker.cpp
     ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Layers/ColorFrameRenderer.cpp
     ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.cpp
@@ -373,6 +369,11 @@
   #${ORTHANC_STONE_ROOT}/Framework/Layers/SeriesFrameRendererFactory.cpp
   #${ORTHANC_STONE_ROOT}/Framework/Layers/SingleFrameRendererFactory.cpp
 
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp
+
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/CairoCompositor.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ColorTextureSceneLayer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/FloatTextureSceneLayer.cpp
--- a/Samples/Sdl/Loader.cpp	Mon May 27 16:01:47 2019 +0200
+++ b/Samples/Sdl/Loader.cpp	Tue May 28 08:15:38 2019 +0200
@@ -37,6 +37,7 @@
 #include "../../Framework/StoneInitialization.h"
 #include "../../Framework/Toolbox/GeometryToolbox.h"
 #include "../../Framework/Toolbox/SlicesSorter.h"
+#include "../../Framework/Toolbox/DicomStructureSet.h"
 #include "../../Framework/Volumes/ImageBuffer3D.h"
 #include "../../Framework/Volumes/VolumeImageGeometry.h"
 #include "../../Framework/Volumes/VolumeReslicer.h"
@@ -1463,6 +1464,86 @@
 
 
 
+  class DicomStructureSetLoader :
+    public IObserver,
+    public IVolumeSlicer
+  {
+  private:
+    enum State
+    {
+      State_Setup,
+      State_Loading,
+      State_Ready
+    };    
+    
+    
+    std::auto_ptr<DicomStructureSet>  content_;
+    IOracle&                          oracle_;
+    State                             state_;
+    std::string                       instanceId_;
+
+    void Handle(const OrthancRestApiCommand::SuccessMessage& message)
+    {
+      if (state_ != State_Loading)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+      }
+
+      const boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
+
+      {
+        OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer());
+        content_.reset(new DicomStructureSet(dicom));
+      }
+
+      const boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
+
+      printf("LOADED: %d\n", (end - start).total_milliseconds());
+      state_ = State_Ready;
+    }
+      
+    
+  public:
+    DicomStructureSetLoader(IOracle& oracle,
+                            IObservable& oracleObservable) :
+      IObserver(oracleObservable.GetBroker()),
+      oracle_(oracle),
+      state_(State_Setup)
+    {
+      oracleObservable.RegisterObserverCallback(
+        new Callable<DicomStructureSetLoader, OrthancRestApiCommand::SuccessMessage>
+        (*this, &DicomStructureSetLoader::Handle));
+    }
+    
+    
+    void LoadInstance(const std::string& instanceId)
+    {
+      if (state_ != State_Setup)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+      }
+      else
+      {
+        state_ = State_Loading;
+        instanceId_ = instanceId;
+
+        {
+          std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
+          command->SetHttpHeader("Accept-Encoding", "gzip");
+          command->SetUri("/instances/" + instanceId + "/tags?ignore-length=3006-0050");
+          oracle_.Schedule(*this, command.release());
+        }
+      }
+    }
+
+    virtual IExtractedSlice* ExtractSlice(const CoordinateSystem3D& cuttingPlane)
+    {
+      return NULL;
+    }
+  };
+
+
+
   class VolumeSceneLayerSource : public boost::noncopyable
   {
   private:
@@ -1855,12 +1936,14 @@
   boost::shared_ptr<Toto> toto;
   boost::shared_ptr<OrthancStone::OrthancSeriesVolumeProgressiveLoader> ctLoader;
   boost::shared_ptr<OrthancStone::OrthancMultiframeVolumeLoader> doseLoader;
+  boost::shared_ptr<OrthancStone::DicomStructureSetLoader>  rtstructLoader;
 
   {
     OrthancStone::NativeApplicationContext::WriterLock lock(context);
     toto.reset(new Toto(oracle, lock.GetOracleObservable()));
     ctLoader.reset(new OrthancStone::OrthancSeriesVolumeProgressiveLoader(ct, oracle, lock.GetOracleObservable()));
     doseLoader.reset(new OrthancStone::OrthancMultiframeVolumeLoader(dose, oracle, lock.GetOracleObservable()));
+    rtstructLoader.reset(new OrthancStone::DicomStructureSetLoader(oracle, lock.GetOracleObservable()));
   }
 
 
@@ -1883,7 +1966,7 @@
     toto->SetVolume2(1, doseLoader, config.release());
   }
 
-  oracle.Schedule(*toto, new OrthancStone::SleepOracleCommand(100));
+  //oracle.Schedule(*toto, new OrthancStone::SleepOracleCommand(100));
 
   if (0)
   {
@@ -1960,9 +2043,11 @@
     }
   }
 
+  
   // 2017-11-17-Anonymized
-  ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618");  // CT
-  doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6");  // RT-DOSE
+  //ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618");  // CT
+  //doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6");  // RT-DOSE
+  rtstructLoader->LoadInstance("83d9c0c3-913a7fee-610097d7-cbf0522d-fd75bee6");  // RT-STRUCT
 
   // 2015-01-28-Multiframe
   //doseLoader->LoadInstance("88f71e2a-5fad1c61-96ed14d6-5b3d3cf7-a5825279");  // Multiframe CT