diff Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 2097:a9e23ef9ee09 dicom-sr

preparing to extract dicom-sr annotations
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 08 Nov 2023 16:31:49 +0100
parents 79e984a89a38
children 4288d635d77e
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Wed Nov 08 15:15:48 2023 +0100
+++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Wed Nov 08 16:31:49 2023 +0100
@@ -226,6 +226,13 @@
                                 const OrthancStone::Vector& point,
                                 double maximumDistance) const = 0;
 
+  virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid,
+                                                        unsigned int frameNumber,
+                                                        double originX,
+                                                        double originY,
+                                                        double pixelSpacingX,
+                                                        double pixelSpacingY) const = 0;
+
   static OrthancStone::CoordinateSystem3D GetFrameGeometry(const IFramesCollection& frames,
                                                            size_t frameIndex)
   {
@@ -279,7 +286,17 @@
                                 double maximumDistance) const ORTHANC_OVERRIDE
   {
     return frames_->FindClosestFrame(frameIndex, point, maximumDistance);
-  };
+  }
+
+  virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid,
+                                                        unsigned int frameNumber,
+                                                        double originX,
+                                                        double originY,
+                                                        double pixelSpacingX,
+                                                        double pixelSpacingY) const ORTHANC_OVERRIDE
+  {
+    return NULL;
+  }
 };
 
 
@@ -321,10 +338,9 @@
       return *parameters_;
     }
   };
-  
-  std::string         studyInstanceUid_;
-  std::string         seriesInstanceUid_;
-  std::vector<Frame*> frames_;
+
+  std::unique_ptr<OrthancStone::DicomStructuredReport>  sr_;
+  std::vector<Frame*>                                   frames_;
 
   void Finalize()
   {
@@ -353,13 +369,12 @@
   }
   
 public:
-  DicomStructuredReportFrames(OrthancStone::DicomStructuredReport& sr,
+  DicomStructuredReportFrames(const OrthancStone::DicomStructuredReport& sr,
                               const OrthancStone::LoadedDicomResources& instances) :
-    studyInstanceUid_(sr.GetStudyInstanceUid()),
-    seriesInstanceUid_(sr.GetSeriesInstanceUid())
+    sr_(new OrthancStone::DicomStructuredReport(sr))
   {
     std::list<OrthancStone::DicomStructuredReport::ReferencedFrame> tmp;
-    sr.ExportReferencedFrames(tmp);
+    sr_->ExportReferencedFrames(tmp);
 
     frames_.reserve(tmp.size());
     for (std::list<OrthancStone::DicomStructuredReport::ReferencedFrame>::const_iterator
@@ -434,6 +449,61 @@
     
     return found;
   }
+
+  virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid,
+                                                        unsigned int frameNumber,
+                                                        double originX,
+                                                        double originY,
+                                                        double pixelSpacingX,
+                                                        double pixelSpacingY) const ORTHANC_OVERRIDE
+  {
+    size_t frameIndex;
+    if (!LookupFrame(frameIndex, sopInstanceUid, frameNumber))
+    {
+      return NULL;
+    }
+
+    const OrthancStone::DicomInstanceParameters& parameters = GetInstanceOfFrame(frameIndex);
+
+    const double x = originX - pixelSpacingX / 2.0;
+    const double y = originY - pixelSpacingY / 2.0;
+    const double w = parameters.GetWidth() * pixelSpacingX;
+    const double h = parameters.GetHeight() * pixelSpacingY;
+
+    std::unique_ptr<OrthancStone::MacroSceneLayer> layer(new OrthancStone::MacroSceneLayer);
+
+    {
+      std::unique_ptr<OrthancStone::PolylineSceneLayer> polyline(new OrthancStone::PolylineSceneLayer);
+      {
+        OrthancStone::PolylineSceneLayer::Chain chain;
+        chain.push_back(OrthancStone::ScenePoint2D(x, y));
+        chain.push_back(OrthancStone::ScenePoint2D(x + pixelSpacingX, y));
+        chain.push_back(OrthancStone::ScenePoint2D(x + pixelSpacingX, y + pixelSpacingY));
+        chain.push_back(OrthancStone::ScenePoint2D(x, y + pixelSpacingY));
+
+        polyline->AddChain(chain, true, 255, 0, 0);
+      }
+
+      layer->AddLayer(polyline.release());
+    }
+
+    {
+      std::unique_ptr<OrthancStone::PolylineSceneLayer> polyline(new OrthancStone::PolylineSceneLayer);
+      {
+        OrthancStone::PolylineSceneLayer::Chain chain;
+        chain.push_back(OrthancStone::ScenePoint2D(x, y));
+        chain.push_back(OrthancStone::ScenePoint2D(x + w, y));
+        chain.push_back(OrthancStone::ScenePoint2D(x + w, y + h));
+        chain.push_back(OrthancStone::ScenePoint2D(x, y + h));
+
+        polyline->AddChain(chain, true, 255, 0, 0);
+      }
+
+      layer->AddLayer(polyline.release());
+    }
+
+    return layer.release();
+  }
 };
 
 
@@ -1966,6 +2036,7 @@
   static const int LAYER_REFERENCE_LINES = 3;
   static const int LAYER_ANNOTATIONS_OSIRIX = 4;
   static const int LAYER_ANNOTATIONS_STONE = 5;
+  static const int LAYER_STRUCTURED_REPORT = 6;
 
   
   class ICommand : public Orthanc::IDynamicObject
@@ -2650,6 +2721,16 @@
     }
 
 
+    std::unique_ptr<OrthancStone::ISceneLayer> structuredReportAnnotations;
+
+    if (frames_.get() != NULL)
+    {
+      structuredReportAnnotations.reset(frames_->ExtractAnnotations(instance.GetSopInstanceUid(), frameIndex,
+                                                                    layer->GetOriginX(), layer->GetOriginY(),
+                                                                    layer->GetPixelSpacingX(), layer->GetPixelSpacingY()));
+    }
+
+
     {
       std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
 
@@ -2684,6 +2765,24 @@
         scene.DeleteLayer(LAYER_ORIENTATION_MARKERS);
       }
 
+      if (orientationMarkers.get() != NULL)
+      {
+        scene.SetLayer(LAYER_ORIENTATION_MARKERS, orientationMarkers.release());
+      }
+      else
+      {
+        scene.DeleteLayer(LAYER_ORIENTATION_MARKERS);
+      }
+
+      if (structuredReportAnnotations.get() != NULL)
+      {
+        scene.SetLayer(LAYER_STRUCTURED_REPORT, structuredReportAnnotations.release());
+      }
+      else
+      {
+        scene.DeleteLayer(LAYER_STRUCTURED_REPORT);
+      }
+
       stoneAnnotations_->Render(scene);  // Necessary for "FitContent()" to work
 
       if (fitNextContent_)