changeset 1768:226718777702

fix DicomVolumeImageMPRSlicer::Slice::CreateSceneLayer() for opposite normals
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 11 May 2021 17:18:39 +0200
parents e7b4479dea6f
children a217140dd41a
files Applications/Samples/Common/RtViewerView.cpp OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.cpp OrthancStone/Sources/Volumes/VolumeImageGeometry.cpp
diffstat 5 files changed, 81 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/Common/RtViewerView.cpp	Tue May 11 11:42:08 2021 +0200
+++ b/Applications/Samples/Common/RtViewerView.cpp	Tue May 11 17:18:39 2021 +0200
@@ -307,7 +307,7 @@
       std::unique_ptr<LookupTableStyleConfigurator> config(new LookupTableStyleConfigurator);
       config->SetLookupTable(lut);
 
-      boost::shared_ptr<DicomVolumeImageMPRSlicer> tmp(new DicomVolumeImageMPRSlicer(doseVolume));
+      boost::shared_ptr<IVolumeSlicer> tmp(new DicomVolumeImageMPRSlicer(doseVolume));
       this->SetDoseVolumeSlicer(tmp, config.release());
     }
 
--- a/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp	Tue May 11 11:42:08 2021 +0200
+++ b/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp	Tue May 11 17:18:39 2021 +0200
@@ -51,6 +51,11 @@
     isLinearInterpolation_ = other.isLinearInterpolation_;
     flipX_ = other.flipX_;
     flipY_ = other.flipY_;
+
+    if (other.transform_.get() != NULL)
+    {
+      transform_.reset(new AffineTransform2D(*other.transform_));
+    }
   }
 
 
@@ -141,23 +146,44 @@
   }
 
   
+  void TextureBaseSceneLayer::SetTransform(const AffineTransform2D& transform)
+  {
+    transform_.reset(new AffineTransform2D(transform));
+    IncrementRevision();    
+  }
+  
+
+  void TextureBaseSceneLayer::ClearTransform()
+  {
+    transform_.reset(NULL);
+    IncrementRevision();    
+  }
+
+
   AffineTransform2D TextureBaseSceneLayer::GetTransform() const
   {
-    unsigned int width = 0;
-    unsigned int height = 0;
+    if (transform_.get() == NULL)
+    {
+      unsigned int width = 0;
+      unsigned int height = 0;
 
-    if (texture_.get() != NULL)
-    {
-      width = texture_->GetWidth();
-      height = texture_->GetHeight();
+      if (texture_.get() != NULL)
+      {
+        width = texture_->GetWidth();
+        height = texture_->GetHeight();
+      }
+    
+      return AffineTransform2D::Combine(
+        AffineTransform2D::CreateOffset(originX_, originY_),
+        AffineTransform2D::CreateRotation(angle_),
+        AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_),
+        AffineTransform2D::CreateOffset(-0.5, -0.5),
+        AffineTransform2D::CreateFlip(flipX_, flipY_, width, height));
     }
-    
-    return AffineTransform2D::Combine(
-      AffineTransform2D::CreateOffset(originX_, originY_),
-      AffineTransform2D::CreateRotation(angle_),
-      AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_),
-      AffineTransform2D::CreateOffset(-0.5, -0.5),
-      AffineTransform2D::CreateFlip(flipX_, flipY_, width, height));
+    else
+    {
+      return *transform_;
+    }
   }
 
   
--- a/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h	Tue May 11 11:42:08 2021 +0200
+++ b/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h	Tue May 11 17:18:39 2021 +0200
@@ -43,6 +43,7 @@
     bool                                   flipX_;
     bool                                   flipY_;
     uint64_t                               revision_;
+    std::unique_ptr<AffineTransform2D>     transform_;   // Manually-specified transformation
 
   protected:
     void SetTexture(Orthanc::ImageAccessor* texture);
@@ -120,6 +121,10 @@
 
     const Orthanc::ImageAccessor& GetTexture() const;
 
+    void SetTransform(const AffineTransform2D& transform);
+
+    void ClearTransform();
+
     AffineTransform2D GetTransform() const;
     
     virtual void GetBoundingBox(Extent2D& target) const ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.cpp	Tue May 11 11:42:08 2021 +0200
+++ b/OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.cpp	Tue May 11 17:18:39 2021 +0200
@@ -89,27 +89,44 @@
     }
     
     const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_);
-      
-    double x0, y0, x1, y1;
-    cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin());
-    cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX());
 
-    {
-      double xz, yz;
-      cuttingPlane.ProjectPoint(xz, yz, LinearAlgebra::CreateVector(0, 0, 0));
-      texture->SetOrigin(x0 - xz, y0 - yz);
-    }
+    /**
+     * TODO => There was a shift of (0.5, 0.5) introduced by
+     * TextureBaseSceneLayer::GetTransform(). Is it an error?
+     **/
+    
+    Vector pixelSpacing = volume_.GetGeometry().GetVoxelDimensions(projection_);
+
+    double x0, y0, x1, y1, x2, y2;
+    cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin());
+    cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX() * pixelSpacing[0]);
+    cuttingPlane.ProjectPoint(x2, y2, system.GetOrigin() + system.GetAxisY() * pixelSpacing[1]);
+
+    /**
 
-    double dx = x1 - x0;
-    double dy = y1 - y0;
-    if (!LinearAlgebra::IsCloseToZero(dx) ||
-        !LinearAlgebra::IsCloseToZero(dy))
-    {
-      texture->SetAngle(atan2(dy, dx));
-    }
+       A = [ a11 a12 ; a21 a22 ]
+       
+       (1) A * (0 ; 0) + (b1 ; b2) = (x0 ; y0)
+       (2) A * (1 ; 0) + (b1 ; b2) = (x1 ; y1)
+       (3) A * (0 ; 1) + (b1 ; b2) = (x2 ; y2)
+
+       (2-1) A * (1 ; 0) = (x1 - x0 ; y1 - y0) <=> (a11 ; a21) = (x1 - x0 ; y1 - y0)
+       (3-1) A * (0 ; 1) = (x2 - x0 ; y2 - y0) <=> (a12 ; a22) = (x2 - x0 ; y2 - y0)
+
+    **/
 
-    Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_);
-    texture->SetPixelSpacing(tmp[0], tmp[1]);
+    Matrix m(3, 3);
+    m(0, 0) = x1 - x0;  // a11
+    m(0, 1) = x2 - x0;  // a12
+    m(0, 2) = x0;       // b1
+    m(1, 0) = y1 - y0;  // a21
+    m(1, 1) = y2 - y0;  // a22
+    m(1, 2) = y0;       // b2
+    m(2, 0) = 0;
+    m(2, 1) = 0;
+    m(2, 2) = 1;
+    
+    texture->SetTransform(AffineTransform2D(m));
 
     return texture.release();
   }
--- a/OrthancStone/Sources/Volumes/VolumeImageGeometry.cpp	Tue May 11 11:42:08 2021 +0200
+++ b/OrthancStone/Sources/Volumes/VolumeImageGeometry.cpp	Tue May 11 17:18:39 2021 +0200
@@ -259,8 +259,7 @@
                                         const CoordinateSystem3D& plane) const
   {
     bool isOpposite;
-    if (!DetectProjection(projection, isOpposite, plane.GetNormal()) ||
-        isOpposite /* TODO - Error in 2021-04-27-repro-bug-HFP-HFS-cartman */)
+    if (!DetectProjection(projection, isOpposite, plane.GetNormal()))
     {
       return false;
     }