Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1695:a691ab50d416
support of series with instances of varying resolutions - LSD-479
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 26 Nov 2020 19:46:33 +0100 |
parents | 7226b68e2742 |
children | b5a8bf32d969 |
comparison
equal
deleted
inserted
replaced
1694:7226b68e2742 | 1695:a691ab50d416 |
---|---|
103 // We are not running ParseWebAssemblyExports.py, but we're compiling the wasm | 103 // We are not running ParseWebAssemblyExports.py, but we're compiling the wasm |
104 # define STONE_WEB_VIEWER_EXPORT | 104 # define STONE_WEB_VIEWER_EXPORT |
105 #endif | 105 #endif |
106 | 106 |
107 | 107 |
108 #define FIX_LSD_479 1 | |
109 | |
110 | |
108 enum STONE_WEB_VIEWER_EXPORT ThumbnailType | 111 enum STONE_WEB_VIEWER_EXPORT ThumbnailType |
109 { | 112 { |
110 ThumbnailType_Image, | 113 ThumbnailType_Image, |
111 ThumbnailType_NoPreview, | 114 ThumbnailType_NoPreview, |
112 ThumbnailType_Pdf, | 115 ThumbnailType_Pdf, |
1404 bool fitNextContent_; | 1407 bool fitNextContent_; |
1405 std::list<PrefetchItem> prefetchQueue_; | 1408 std::list<PrefetchItem> prefetchQueue_; |
1406 bool serverSideTranscoding_; | 1409 bool serverSideTranscoding_; |
1407 OrthancStone::Vector synchronizationOffset_; | 1410 OrthancStone::Vector synchronizationOffset_; |
1408 bool synchronizationEnabled_; | 1411 bool synchronizationEnabled_; |
1409 | 1412 double centralPhysicalWidth_; // LSD-479 |
1413 double centralPhysicalHeight_; | |
1410 | 1414 |
1411 bool hasFocusOnInstance_; | 1415 bool hasFocusOnInstance_; |
1412 std::string focusSopInstanceUid_; | 1416 std::string focusSopInstanceUid_; |
1413 size_t focusFrameNumber_; | 1417 size_t focusFrameNumber_; |
1414 | 1418 |
1517 | 1521 |
1518 void RenderCurrentScene(const Orthanc::ImageAccessor& frame, | 1522 void RenderCurrentScene(const Orthanc::ImageAccessor& frame, |
1519 const OrthancStone::DicomInstanceParameters& instance, | 1523 const OrthancStone::DicomInstanceParameters& instance, |
1520 const OrthancStone::CoordinateSystem3D& plane) | 1524 const OrthancStone::CoordinateSystem3D& plane) |
1521 { | 1525 { |
1526 /** | |
1527 * IMPORTANT - DO NOT use "instance.GetWidth()" and | |
1528 * "instance.GetHeight()" in this method. Use the information from | |
1529 * "frame" instead. Indeed, the "instance" information is taken | |
1530 * from DICOMweb "/studies/.../series/.../metadata". But, | |
1531 * "SeriesMetadataExtrapolatedTags" includes the "Columns" and | |
1532 * "Rows" DICOM tags for performance, which make this information | |
1533 * unreliable if the series includes instances with varying sizes | |
1534 * (cf. LSD-479). | |
1535 **/ | |
1536 | |
1522 SaveCurrentWindowing(); | 1537 SaveCurrentWindowing(); |
1523 | 1538 |
1524 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == | 1539 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == |
1525 Orthanc::PhotometricInterpretation_Monochrome1); | 1540 Orthanc::PhotometricInterpretation_Monochrome1); |
1526 | 1541 |
1527 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; | 1542 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; |
1528 | 1543 |
1552 layer->SetFlipX(flipX_); | 1567 layer->SetFlipX(flipX_); |
1553 layer->SetFlipY(flipY_); | 1568 layer->SetFlipY(flipY_); |
1554 | 1569 |
1555 double pixelSpacingX, pixelSpacingY; | 1570 double pixelSpacingX, pixelSpacingY; |
1556 OrthancStone::GeometryToolbox::GetPixelSpacing(pixelSpacingX, pixelSpacingY, instance.GetTags()); | 1571 OrthancStone::GeometryToolbox::GetPixelSpacing(pixelSpacingX, pixelSpacingY, instance.GetTags()); |
1557 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); | 1572 |
1573 if (FIX_LSD_479) | |
1574 { | |
1575 /** | |
1576 * Some series contain a first instance (secondary capture) that | |
1577 * is completely different from others wrt. to resolution and | |
1578 * pixel spacing. We make sure to rescale each frame to fit in a | |
1579 * square that corresponds to the extent of the frame in the | |
1580 * middle of the series. | |
1581 **/ | |
1582 double physicalWidth = pixelSpacingX * static_cast<double>(frame.GetWidth()); | |
1583 double physicalHeight = pixelSpacingY * static_cast<double>(frame.GetHeight()); | |
1584 | |
1585 if (OrthancStone::LinearAlgebra::IsCloseToZero(physicalWidth) || | |
1586 OrthancStone::LinearAlgebra::IsCloseToZero(physicalHeight)) | |
1587 { | |
1588 // Numerical instability, don't try further processing | |
1589 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); | |
1590 } | |
1591 else | |
1592 { | |
1593 double scale = std::max(centralPhysicalWidth_ / physicalWidth, | |
1594 centralPhysicalHeight_ / physicalHeight); | |
1595 layer->SetPixelSpacing(pixelSpacingX * scale, pixelSpacingY * scale); | |
1596 layer->SetOrigin((centralPhysicalWidth_ - physicalWidth * scale) / 2.0, | |
1597 (centralPhysicalHeight_ - physicalHeight * scale) / 2.0); | |
1598 } | |
1599 } | |
1600 else | |
1601 { | |
1602 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); | |
1603 } | |
1558 | 1604 |
1559 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer; | 1605 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer; |
1560 | 1606 |
1561 if (annotations_) | 1607 if (annotations_) |
1562 { | 1608 { |
1791 flipX_(false), | 1837 flipX_(false), |
1792 flipY_(false), | 1838 flipY_(false), |
1793 hasFocusOnInstance_(false), | 1839 hasFocusOnInstance_(false), |
1794 focusFrameNumber_(0), | 1840 focusFrameNumber_(0), |
1795 synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), | 1841 synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), |
1796 synchronizationEnabled_(false) | 1842 synchronizationEnabled_(false), |
1843 centralPhysicalWidth_(1), | |
1844 centralPhysicalHeight_(1) | |
1797 { | 1845 { |
1798 if (!framesCache_) | 1846 if (!framesCache_) |
1799 { | 1847 { |
1800 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 1848 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
1801 } | 1849 } |
1949 if (observer_.get() != NULL) | 1997 if (observer_.get() != NULL) |
1950 { | 1998 { |
1951 observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(), | 1999 observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(), |
1952 frames_->GetFramesCount(), DisplayedFrameQuality_None); | 2000 frames_->GetFramesCount(), DisplayedFrameQuality_None); |
1953 } | 2001 } |
2002 | |
2003 centralPhysicalWidth_ = 1; | |
2004 centralPhysicalHeight_ = 1; | |
1954 | 2005 |
1955 if (frames_->GetFramesCount() != 0) | 2006 if (frames_->GetFramesCount() != 0) |
1956 { | 2007 { |
1957 const OrthancStone::DicomInstanceParameters& centralInstance = frames_->GetInstanceOfFrame(cursor_->GetCurrentIndex()); | 2008 const OrthancStone::DicomInstanceParameters& centralInstance = frames_->GetInstanceOfFrame(cursor_->GetCurrentIndex()); |
1958 | 2009 |
1975 "/instances/" + centralInstance.GetSopInstanceUid() + "/metadata"); | 2026 "/instances/" + centralInstance.GetSopInstanceUid() + "/metadata"); |
1976 | 2027 |
1977 loader_->ScheduleGetDicomWeb( | 2028 loader_->ScheduleGetDicomWeb( |
1978 boost::make_shared<OrthancStone::LoadedDicomResources>(Orthanc::DICOM_TAG_SOP_INSTANCE_UID), | 2029 boost::make_shared<OrthancStone::LoadedDicomResources>(Orthanc::DICOM_TAG_SOP_INSTANCE_UID), |
1979 0, source_, uri, new LoadSeriesDetailsFromInstance(GetSharedObserver())); | 2030 0, source_, uri, new LoadSeriesDetailsFromInstance(GetSharedObserver())); |
2031 } | |
2032 | |
2033 if (centralInstance.GetPixelSpacingX() != 0 && | |
2034 centralInstance.GetPixelSpacingY() != 0 && | |
2035 centralInstance.GetWidth() != 0 && | |
2036 centralInstance.GetHeight()) | |
2037 { | |
2038 centralPhysicalWidth_ = (centralInstance.GetPixelSpacingX() * | |
2039 static_cast<double>(centralInstance.GetWidth())); | |
2040 centralPhysicalHeight_ = (centralInstance.GetPixelSpacingY() * | |
2041 static_cast<double>(centralInstance.GetHeight())); | |
1980 } | 2042 } |
1981 } | 2043 } |
1982 | 2044 |
1983 ApplyScheduledFocus(); | 2045 ApplyScheduledFocus(); |
1984 } | 2046 } |