changeset 2219:a10b7a6ec869

cached projected segments to speed up DicomStructureSet
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 22 Apr 2025 18:18:30 +0200 (6 weeks ago)
parents c098f0f16eb1
children 532764b7b57f 900fb75351cd
files OrthancStone/Sources/Toolbox/DicomStructureSet.cpp OrthancStone/Sources/Toolbox/DicomStructureSet.h
diffstat 2 files changed, 27 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp	Tue Apr 22 18:09:13 2025 +0200
+++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp	Tue Apr 22 18:18:30 2025 +0200
@@ -274,7 +274,7 @@
   void DicomStructureSet::Polygon::Project(std::list<Extent2D>& target,
                                            const CoordinateSystem3D& cuttingPlane,
                                            const Vector& estimatedNormal,
-                                           double estimatedSliceThickness) const
+                                           double estimatedSliceThickness)
   {
     CoordinateSystem3D geometry;
     double thickness = estimatedSliceThickness;
@@ -362,14 +362,33 @@
       return;  // Should never happen
     }
 
+    if (cachedProjectedSegments_.get() == NULL ||
+        !cachedGeometry_.Equals(geometry))
+    {
+      cachedGeometry_ = geometry;
+
+      cachedProjectedSegments_.reset(new std::vector<float>());
+      cachedProjectedSegments_->resize(2 * points_.size());
+
+      for (size_t i = 0; i < points_.size(); i++)
+      {
+        double x, y;
+        geometry.ProjectPoint(x, y, points_[i]);
+        (*cachedProjectedSegments_) [2 * i] = x;
+        (*cachedProjectedSegments_) [2 * i + 1] = y;
+      }
+    }
+
     std::vector<double> intersections;
     intersections.reserve(points_.size());
 
     for (size_t i = 0; i < points_.size(); i++)
     {
-      double segmentX1, segmentY1, segmentX2, segmentY2;
-      geometry.ProjectPoint(segmentX1, segmentY1, points_[i]);
-      geometry.ProjectPoint(segmentX2, segmentY2, points_[(i + 1) % points_.size()]);
+      const size_t next = (i + 1) % points_.size();
+      const double segmentX1 = (*cachedProjectedSegments_) [2 * i];
+      const double segmentY1 = (*cachedProjectedSegments_) [2 * i + 1];
+      const double segmentX2 = (*cachedProjectedSegments_) [2 * next];
+      const double segmentY2 = (*cachedProjectedSegments_) [2 * next + 1];
 
       double x, y;
       if (GeometryToolbox::IntersectLineAndSegment(x, y, cuttingX1, cuttingY1, cuttingX2, cuttingY2,
--- a/OrthancStone/Sources/Toolbox/DicomStructureSet.h	Tue Apr 22 18:09:13 2025 +0200
+++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.h	Tue Apr 22 18:18:30 2025 +0200
@@ -82,6 +82,9 @@
       double              sliceThickness_;  // In millimeters
       Points              points_;
 
+      CoordinateSystem3D                    cachedGeometry_;
+      std::unique_ptr< std::vector<float> > cachedProjectedSegments_;
+
       bool IsPointOnSliceIfAny(const Vector& v) const;
 
     public:
@@ -129,7 +132,7 @@
       void Project(std::list<Extent2D>& target,
                    const CoordinateSystem3D& cuttingPlane,
                    const Vector& estimatedNormal,
-                   double estimatedSliceThickness) const;
+                   double estimatedSliceThickness);
     };
 
     typedef std::list<Polygon*>  Polygons;