Mercurial > hg > orthanc-stone
diff OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp @ 1961:cbf54cd28d59
added CoordinateSystem3D::GetOrientationMarkers()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 27 Oct 2022 18:43:20 +0200 |
parents | 7053b8a0aaec |
children | 446e0d3e9019 |
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp Thu Oct 27 17:17:14 2022 +0200 +++ b/OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp Thu Oct 27 18:43:20 2022 +0200 @@ -381,4 +381,109 @@ return CoordinateSystem3D(a, axisX, axisY); } + + + static std::string GetOrientationString(const Vector& v) + { + /** + * This function directly comes from David Clunie: + * https://sites.google.com/site/dicomnotes/ + * + * It is also a C++ reimplementation of function + * "getOrientationString()" from Cornerstone: + * https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/local_dependencies/cornerstoneTools/cornerstoneTools.js + **/ + + const char orientationX = v[0] < 0 ? 'R' : 'L'; + const char orientationY = v[1] < 0 ? 'A' : 'P'; + const char orientationZ = v[2] < 0 ? 'F' : 'H'; + + double absX = abs(v[0]); + double absY = abs(v[1]); + double absZ = abs(v[2]); + + std::string result; + + static const double THRESHOLD = 0.0001; + + for (unsigned int i = 0; i < 3; i++) + { + if (absX > THRESHOLD && absX > absY && absX > absZ) + { + result.push_back(orientationX); + absX = 0; + } + else if (absY > THRESHOLD && absY > absX && absY > absZ) + { + result.push_back(orientationY); + absY = 0; + } + else if (absZ > THRESHOLD && absZ > absX && absZ > absY) + { + result.push_back(orientationZ); + absZ = 0; + } + else + { + break; + } + } + + return result; + } + + + static std::string InvertOrientationString(const std::string& source) + { + std::string target; + target.resize(source.length()); + + for (unsigned int i = 0; i < source.length(); i++) + { + switch (source[i]) + { + case 'H': target[i] = 'F'; break; + case 'F': target[i] = 'H'; break; + case 'R': target[i] = 'L'; break; + case 'L': target[i] = 'R'; break; + case 'A': target[i] = 'P'; break; + case 'P': target[i] = 'A'; break; + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + return target; + } + + + void CoordinateSystem3D::GetOrientationMarkers(std::string& top /* out */, + std::string& bottom /* out */, + std::string& left /* out */, + std::string& right /* out */) const + { + if (IsValid()) + { + /** + * This is a C++ reimplementation of function + * "getOrientationMarkers()" from Cornerstone: + * https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/local_dependencies/cornerstoneTools/cornerstoneTools.js + * + * ImageOrientationPatient is row cosines then column cosines + * (i.e. horizontal then vertical). + * https://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.2 + **/ + const Vector& rowCosines = axisX_; // horizontal + const Vector& columnCosines = axisY_; // vertical + + bottom = GetOrientationString(columnCosines); + right = GetOrientationString(rowCosines); + top = InvertOrientationString(bottom); + left = InvertOrientationString(right); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } }