diff OrthancStone/Sources/Toolbox/DicomStructureSet.h @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Toolbox/DicomStructureSet.h@d8af188ab545
children 94750ef63ad5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.h	Tue Jul 07 16:21:02 2020 +0200
@@ -0,0 +1,236 @@
+/**
+ * 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 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 "../OrthancStone.h"
+
+#if !defined(ORTHANC_ENABLE_DCMTK)
+#  error The macro ORTHANC_ENABLE_DCMTK must be defined
+#endif
+
+#include "DicomStructureSetUtils.h"
+#include "CoordinateSystem3D.h"
+#include "Extent2D.h"
+#include "OrthancDatasets/FullOrthancDataset.h"
+#include "../Scene2D/Color.h"
+#include "../Scene2D/PolylineSceneLayer.h"
+
+#if ORTHANC_ENABLE_DCMTK == 1
+#  include <DicomParsing/ParsedDicomFile.h>
+#endif
+
+//#define USE_BOOST_UNION_FOR_POLYGONS 1
+
+
+#include <list>
+
+namespace OrthancStone
+{
+  class DicomStructureSet : public boost::noncopyable
+  {
+  private:
+    struct ReferencedSlice
+    {
+      std::string          seriesInstanceUid_;
+      CoordinateSystem3D   geometry_;
+      double               thickness_;
+
+      ReferencedSlice()
+      {
+      }
+      
+      ReferencedSlice(const std::string& seriesInstanceUid,
+                      const CoordinateSystem3D& geometry,
+                      double thickness) :
+        seriesInstanceUid_(seriesInstanceUid),
+        geometry_(geometry),
+        thickness_(thickness)
+      {
+      }
+    };
+
+    typedef std::map<std::string, ReferencedSlice>  ReferencedSlices;
+    
+    typedef std::vector<Vector>  Points;
+
+    class Polygon
+    {
+    private:
+      std::string         sopInstanceUid_;
+      bool                hasSlice_;
+      CoordinateSystem3D  geometry_;
+      double              projectionAlongNormal_;
+      double              sliceThickness_;  // In millimeters
+      Points              points_;
+      Extent2D            extent_;
+
+      void CheckPointIsOnSlice(const Vector& v) const;
+      bool IsPointOnSliceIfAny(const Vector& v) const;
+
+    public:
+      Polygon(const std::string& sopInstanceUid) :
+        sopInstanceUid_(sopInstanceUid),
+        hasSlice_(false)
+      {
+      }
+
+      void Reserve(size_t n)
+      {
+        points_.reserve(n);
+      }
+
+      void AddPoint(const Vector& v);
+
+      bool UpdateReferencedSlice(const ReferencedSlices& slices);
+
+      bool IsOnSlice(const CoordinateSystem3D& geometry) const;
+
+      const Vector& GetGeometryOrigin() const
+      {
+        return geometry_.GetOrigin();
+      }
+
+      const std::string& GetSopInstanceUid() const
+      {
+        return sopInstanceUid_;
+      }
+
+      const Points& GetPoints() const
+      {
+        return points_;
+      }
+
+      double GetSliceThickness() const
+      {
+        return sliceThickness_;
+      }
+
+      bool Project(double& x1,
+                   double& y1,
+                   double& x2,
+                   double& y2,
+                   const CoordinateSystem3D& slice) const;
+    };
+
+    typedef std::list<Polygon>  Polygons;
+
+    struct Structure
+    {
+      std::string   name_;
+      std::string   interpretation_;
+      Polygons      polygons_;
+      uint8_t       red_;
+      uint8_t       green_;
+      uint8_t       blue_;
+    };
+
+    typedef std::vector<Structure>  Structures;
+
+    Structures        structures_;
+    ReferencedSlices  referencedSlices_;
+
+    void Setup(const IDicomDataset& dataset);
+    
+    const Structure& GetStructure(size_t index) const;
+
+    Structure& GetStructure(size_t index);
+  
+    bool ProjectStructure(
+#if USE_BOOST_UNION_FOR_POLYGONS == 1
+      std::vector< std::vector<Point2D> >& polygons,
+#else
+      std::vector< std::pair<Point2D, Point2D> >& segments,
+#endif
+      const Structure& structure,
+      const CoordinateSystem3D& slice) const;
+
+  public:
+    DicomStructureSet(const FullOrthancDataset& instance)
+    {
+      Setup(instance);
+    }
+
+#if ORTHANC_ENABLE_DCMTK == 1
+    DicomStructureSet(Orthanc::ParsedDicomFile& instance);
+#endif
+
+    size_t GetStructuresCount() const
+    {
+      return structures_.size();
+    }
+
+    Vector GetStructureCenter(size_t index) const;
+
+    const std::string& GetStructureName(size_t index) const;
+
+    const std::string& GetStructureInterpretation(size_t index) const;
+
+    Color GetStructureColor(size_t index) const;
+
+    // TODO - remove
+    void GetStructureColor(uint8_t& red,
+                           uint8_t& green,
+                           uint8_t& blue,
+                           size_t index) const;
+
+    void GetReferencedInstances(std::set<std::string>& instances);
+
+    void AddReferencedSlice(const std::string& sopInstanceUid,
+                            const std::string& seriesInstanceUid,
+                            const CoordinateSystem3D& geometry,
+                            double thickness);
+
+    void AddReferencedSlice(const Orthanc::DicomMap& dataset);
+
+    void CheckReferencedSlices();
+
+    Vector GetNormal() const;
+
+#if USE_BOOST_UNION_FOR_POLYGONS == 1
+    bool ProjectStructure(std::vector< std::vector<Point2D> >& polygons,
+                          size_t index,
+                          const CoordinateSystem3D& slice) const
+    {
+      return ProjectStructure(polygons, GetStructure(index), slice);
+    }
+#else
+    bool ProjectStructure(std::vector< std::pair<Point2D, Point2D> >& segments,
+                          size_t index,
+                          const CoordinateSystem3D& slice) const
+    {
+      return ProjectStructure(segments, GetStructure(index), slice);
+    }
+#endif
+
+    void ProjectOntoLayer(PolylineSceneLayer& layer,
+                          const CoordinateSystem3D& plane,
+                          size_t structureIndex,
+                          const Color& color) const;
+
+    void ProjectOntoLayer(PolylineSceneLayer& layer,
+                          const CoordinateSystem3D& plane,
+                          size_t structureIndex) const
+    {
+      ProjectOntoLayer(layer, plane, structureIndex, GetStructureColor(structureIndex));
+    }
+  };
+}