comparison 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
comparison
equal deleted inserted replaced
1960:40f8009ceb4e 1961:cbf54cd28d59
379 LinearAlgebra::CrossProduct(axisY, axisX, normal); 379 LinearAlgebra::CrossProduct(axisY, axisX, normal);
380 LinearAlgebra::NormalizeVector(axisY); 380 LinearAlgebra::NormalizeVector(axisY);
381 381
382 return CoordinateSystem3D(a, axisX, axisY); 382 return CoordinateSystem3D(a, axisX, axisY);
383 } 383 }
384
385
386 static std::string GetOrientationString(const Vector& v)
387 {
388 /**
389 * This function directly comes from David Clunie:
390 * https://sites.google.com/site/dicomnotes/
391 *
392 * It is also a C++ reimplementation of function
393 * "getOrientationString()" from Cornerstone:
394 * https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/local_dependencies/cornerstoneTools/cornerstoneTools.js
395 **/
396
397 const char orientationX = v[0] < 0 ? 'R' : 'L';
398 const char orientationY = v[1] < 0 ? 'A' : 'P';
399 const char orientationZ = v[2] < 0 ? 'F' : 'H';
400
401 double absX = abs(v[0]);
402 double absY = abs(v[1]);
403 double absZ = abs(v[2]);
404
405 std::string result;
406
407 static const double THRESHOLD = 0.0001;
408
409 for (unsigned int i = 0; i < 3; i++)
410 {
411 if (absX > THRESHOLD && absX > absY && absX > absZ)
412 {
413 result.push_back(orientationX);
414 absX = 0;
415 }
416 else if (absY > THRESHOLD && absY > absX && absY > absZ)
417 {
418 result.push_back(orientationY);
419 absY = 0;
420 }
421 else if (absZ > THRESHOLD && absZ > absX && absZ > absY)
422 {
423 result.push_back(orientationZ);
424 absZ = 0;
425 }
426 else
427 {
428 break;
429 }
430 }
431
432 return result;
433 }
434
435
436 static std::string InvertOrientationString(const std::string& source)
437 {
438 std::string target;
439 target.resize(source.length());
440
441 for (unsigned int i = 0; i < source.length(); i++)
442 {
443 switch (source[i])
444 {
445 case 'H': target[i] = 'F'; break;
446 case 'F': target[i] = 'H'; break;
447 case 'R': target[i] = 'L'; break;
448 case 'L': target[i] = 'R'; break;
449 case 'A': target[i] = 'P'; break;
450 case 'P': target[i] = 'A'; break;
451 default:
452 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
453 }
454 }
455
456 return target;
457 }
458
459
460 void CoordinateSystem3D::GetOrientationMarkers(std::string& top /* out */,
461 std::string& bottom /* out */,
462 std::string& left /* out */,
463 std::string& right /* out */) const
464 {
465 if (IsValid())
466 {
467 /**
468 * This is a C++ reimplementation of function
469 * "getOrientationMarkers()" from Cornerstone:
470 * https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/local_dependencies/cornerstoneTools/cornerstoneTools.js
471 *
472 * ImageOrientationPatient is row cosines then column cosines
473 * (i.e. horizontal then vertical).
474 * https://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.2
475 **/
476 const Vector& rowCosines = axisX_; // horizontal
477 const Vector& columnCosines = axisY_; // vertical
478
479 bottom = GetOrientationString(columnCosines);
480 right = GetOrientationString(rowCosines);
481 top = InvertOrientationString(bottom);
482 left = InvertOrientationString(right);
483 }
484 else
485 {
486 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
487 }
488 }
384 } 489 }