Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1667:9584df157a9e
clarifying variable names
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 19 Nov 2020 17:57:44 +0100 |
parents | 1e6d3289b1ad |
children | ab1bc8de1798 |
comparison
equal
deleted
inserted
replaced
1666:1e6d3289b1ad | 1667:9584df157a9e |
---|---|
897 { | 897 { |
898 assert(prefetch_.size() == framesCount_); | 898 assert(prefetch_.size() == framesCount_); |
899 return prefetch_.size(); | 899 return prefetch_.size(); |
900 } | 900 } |
901 | 901 |
902 size_t GetPrefetchFrameIndex(size_t i) const | 902 size_t GetPrefetchIndex(size_t i) const |
903 { | 903 { |
904 if (i >= prefetch_.size()) | 904 if (i >= prefetch_.size()) |
905 { | 905 { |
906 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 906 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
907 } | 907 } |
1271 | 1271 |
1272 | 1272 |
1273 class PrefetchItem | 1273 class PrefetchItem |
1274 { | 1274 { |
1275 private: | 1275 private: |
1276 size_t frameIndex_; | 1276 size_t cursorIndex_; |
1277 bool isFull_; | 1277 bool isFull_; |
1278 | 1278 |
1279 public: | 1279 public: |
1280 PrefetchItem(size_t frameIndex, | 1280 PrefetchItem(size_t cursorIndex, |
1281 bool isFull) : | 1281 bool isFull) : |
1282 frameIndex_(frameIndex), | 1282 cursorIndex_(cursorIndex), |
1283 isFull_(isFull) | 1283 isFull_(isFull) |
1284 { | 1284 { |
1285 } | 1285 } |
1286 | 1286 |
1287 size_t GetFrameIndex() const | 1287 size_t GetCursorIndex() const |
1288 { | 1288 { |
1289 return frameIndex_; | 1289 return cursorIndex_; |
1290 } | 1290 } |
1291 | 1291 |
1292 bool IsFull() const | 1292 bool IsFull() const |
1293 { | 1293 { |
1294 return isFull_; | 1294 return isFull_; |
1324 | 1324 |
1325 void ScheduleNextPrefetch() | 1325 void ScheduleNextPrefetch() |
1326 { | 1326 { |
1327 while (!prefetchQueue_.empty()) | 1327 while (!prefetchQueue_.empty()) |
1328 { | 1328 { |
1329 size_t index = prefetchQueue_.front().GetFrameIndex(); | 1329 size_t cursorIndex = prefetchQueue_.front().GetCursorIndex(); |
1330 bool isFull = prefetchQueue_.front().IsFull(); | 1330 bool isFull = prefetchQueue_.front().IsFull(); |
1331 prefetchQueue_.pop_front(); | 1331 prefetchQueue_.pop_front(); |
1332 | 1332 |
1333 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); | 1333 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid(); |
1334 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); | 1334 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); |
1335 | 1335 |
1336 { | 1336 { |
1337 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); | 1337 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); |
1338 if (!accessor.IsValid() || | 1338 if (!accessor.IsValid() || |
1339 (isFull && accessor.GetQuality() == 0)) | 1339 (isFull && accessor.GetQuality() == 0)) |
1340 { | 1340 { |
1341 if (isFull) | 1341 if (isFull) |
1342 { | 1342 { |
1343 ScheduleLoadFullDicomFrame(index, PRIORITY_NORMAL, true); | 1343 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_NORMAL, true); |
1344 } | 1344 } |
1345 else | 1345 else |
1346 { | 1346 { |
1347 ScheduleLoadRenderedFrame(index, PRIORITY_NORMAL, true); | 1347 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_NORMAL, true); |
1348 } | 1348 } |
1349 return; | 1349 return; |
1350 } | 1350 } |
1351 } | 1351 } |
1352 } | 1352 } |
1368 unsigned int frameNumber) | 1368 unsigned int frameNumber) |
1369 { | 1369 { |
1370 if (cursor_.get() != NULL && | 1370 if (cursor_.get() != NULL && |
1371 frames_.get() != NULL) | 1371 frames_.get() != NULL) |
1372 { | 1372 { |
1373 size_t index = cursor_->GetCurrentIndex(); | 1373 size_t cursorIndex = cursor_->GetCurrentIndex(); |
1374 | 1374 |
1375 if (frames_->GetInstanceOfFrame(index).GetSopInstanceUid() == sopInstanceUid && | 1375 if (frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid() == sopInstanceUid && |
1376 frames_->GetFrameNumberInInstance(index) == frameNumber) | 1376 frames_->GetFrameNumberInInstance(cursorIndex) == frameNumber) |
1377 { | 1377 { |
1378 DisplayCurrentFrame(); | 1378 DisplayCurrentFrame(); |
1379 } | 1379 } |
1380 } | 1380 } |
1381 } | 1381 } |
1386 DisplayedFrameQuality quality = DisplayedFrameQuality_None; | 1386 DisplayedFrameQuality quality = DisplayedFrameQuality_None; |
1387 | 1387 |
1388 if (cursor_.get() != NULL && | 1388 if (cursor_.get() != NULL && |
1389 frames_.get() != NULL) | 1389 frames_.get() != NULL) |
1390 { | 1390 { |
1391 const size_t index = cursor_->GetCurrentIndex(); | 1391 const size_t cursorIndex = cursor_->GetCurrentIndex(); |
1392 | 1392 |
1393 unsigned int cachedQuality; | 1393 unsigned int cachedQuality; |
1394 if (!DisplayFrame(cachedQuality, index)) | 1394 if (!DisplayFrame(cachedQuality, cursorIndex)) |
1395 { | 1395 { |
1396 // This frame is not cached yet: Load it | 1396 // This frame is not cached yet: Load it |
1397 if (source_.HasDicomWebRendered()) | 1397 if (source_.HasDicomWebRendered()) |
1398 { | 1398 { |
1399 ScheduleLoadRenderedFrame(index, PRIORITY_HIGH, false /* not a prefetch */); | 1399 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); |
1400 } | 1400 } |
1401 else | 1401 else |
1402 { | 1402 { |
1403 ScheduleLoadFullDicomFrame(index, PRIORITY_HIGH, false /* not a prefetch */); | 1403 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); |
1404 } | 1404 } |
1405 } | 1405 } |
1406 else if (cachedQuality < QUALITY_FULL) | 1406 else if (cachedQuality < QUALITY_FULL) |
1407 { | 1407 { |
1408 // This frame is only available in low-res: Download the full DICOM | 1408 // This frame is only available in low-res: Download the full DICOM |
1409 ScheduleLoadFullDicomFrame(index, PRIORITY_HIGH, false /* not a prefetch */); | 1409 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); |
1410 quality = DisplayedFrameQuality_Low; | 1410 quality = DisplayedFrameQuality_Low; |
1411 } | 1411 } |
1412 else | 1412 else |
1413 { | 1413 { |
1414 quality = DisplayedFrameQuality_High; | 1414 quality = DisplayedFrameQuality_High; |
1417 { | 1417 { |
1418 // Prepare prefetching | 1418 // Prepare prefetching |
1419 prefetchQueue_.clear(); | 1419 prefetchQueue_.clear(); |
1420 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) | 1420 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) |
1421 { | 1421 { |
1422 size_t a = cursor_->GetPrefetchFrameIndex(i); | 1422 size_t a = cursor_->GetPrefetchIndex(i); |
1423 if (a != index) | 1423 if (a != cursorIndex) |
1424 { | 1424 { |
1425 prefetchQueue_.push_back(PrefetchItem(a, i < 2)); | 1425 prefetchQueue_.push_back(PrefetchItem(a, i < 2)); |
1426 } | 1426 } |
1427 } | 1427 } |
1428 | 1428 |
1467 layer.GetWindowing(windowingCenter_, windowingWidth_); | 1467 layer.GetWindowing(windowingCenter_, windowingWidth_); |
1468 } | 1468 } |
1469 } | 1469 } |
1470 | 1470 |
1471 | 1471 |
1472 static bool IsFrameMonochrome1(const OrthancStone::SortedFrames& frames, | |
1473 size_t frameIndex) | |
1474 { | |
1475 const OrthancStone::DicomInstanceParameters& instance = frames.GetInstanceOfFrame(frameIndex); | |
1476 return (instance.GetImageInformation().GetPhotometricInterpretation() == | |
1477 Orthanc::PhotometricInterpretation_Monochrome1); | |
1478 } | |
1479 | |
1480 | |
1481 bool DisplayFrame(unsigned int& quality, | 1472 bool DisplayFrame(unsigned int& quality, |
1482 size_t index) | 1473 size_t cursorIndex) |
1483 { | 1474 { |
1484 if (frames_.get() == NULL) | 1475 if (frames_.get() == NULL) |
1485 { | 1476 { |
1486 return false; | 1477 return false; |
1487 } | 1478 } |
1488 | 1479 |
1489 const std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); | 1480 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); |
1490 size_t frameNumber = frames_->GetFrameNumberInInstance(index); | 1481 const std::string sopInstanceUid = instance.GetSopInstanceUid(); |
1482 size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); | |
1491 | 1483 |
1492 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); | 1484 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frameNumber); |
1493 if (accessor.IsValid()) | 1485 if (accessor.IsValid()) |
1494 { | 1486 { |
1495 SaveCurrentWindowing(); | 1487 SaveCurrentWindowing(); |
1496 | 1488 |
1497 quality = accessor.GetQuality(); | 1489 quality = accessor.GetQuality(); |
1498 | 1490 |
1491 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == | |
1492 Orthanc::PhotometricInterpretation_Monochrome1); | |
1493 | |
1499 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; | 1494 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; |
1500 | 1495 |
1501 switch (accessor.GetImage().GetFormat()) | 1496 switch (accessor.GetImage().GetFormat()) |
1502 { | 1497 { |
1503 case Orthanc::PixelFormat_RGB24: | 1498 case Orthanc::PixelFormat_RGB24: |
1507 case Orthanc::PixelFormat_Float32: | 1502 case Orthanc::PixelFormat_Float32: |
1508 { | 1503 { |
1509 std::unique_ptr<OrthancStone::FloatTextureSceneLayer> tmp( | 1504 std::unique_ptr<OrthancStone::FloatTextureSceneLayer> tmp( |
1510 new OrthancStone::FloatTextureSceneLayer(accessor.GetImage())); | 1505 new OrthancStone::FloatTextureSceneLayer(accessor.GetImage())); |
1511 tmp->SetCustomWindowing(windowingCenter_, windowingWidth_); | 1506 tmp->SetCustomWindowing(windowingCenter_, windowingWidth_); |
1512 tmp->SetInverted(inverted_ ^ IsFrameMonochrome1(*frames_, index)); | 1507 tmp->SetInverted(inverted_ ^ isMonochrome1); |
1513 layer.reset(tmp.release()); | 1508 layer.reset(tmp.release()); |
1514 break; | 1509 break; |
1515 } | 1510 } |
1516 | 1511 |
1517 default: | 1512 default: |
1521 layer->SetLinearInterpolation(true); | 1516 layer->SetLinearInterpolation(true); |
1522 layer->SetFlipX(flipX_); | 1517 layer->SetFlipX(flipX_); |
1523 layer->SetFlipY(flipY_); | 1518 layer->SetFlipY(flipY_); |
1524 | 1519 |
1525 double pixelSpacingX, pixelSpacingY; | 1520 double pixelSpacingX, pixelSpacingY; |
1526 OrthancStone::GeometryToolbox::GetPixelSpacing( | 1521 OrthancStone::GeometryToolbox::GetPixelSpacing(pixelSpacingX, pixelSpacingY, instance.GetTags()); |
1527 pixelSpacingX, pixelSpacingY, frames_->GetInstanceOfFrame(index).GetTags()); | |
1528 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); | 1522 layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); |
1529 | |
1530 | 1523 |
1531 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer; | 1524 std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsLayer; |
1532 | 1525 |
1533 if (annotations_ && | 1526 if (annotations_ && |
1534 cursor_.get() != NULL) | 1527 cursor_.get() != NULL) |
1592 { | 1585 { |
1593 return false; | 1586 return false; |
1594 } | 1587 } |
1595 } | 1588 } |
1596 | 1589 |
1597 void ScheduleLoadFullDicomFrame(size_t index, | 1590 void ScheduleLoadFullDicomFrame(size_t cursorIndex, |
1598 int priority, | 1591 int priority, |
1599 bool isPrefetch) | 1592 bool isPrefetch) |
1600 { | 1593 { |
1601 if (frames_.get() != NULL) | 1594 if (frames_.get() != NULL) |
1602 { | 1595 { |
1603 std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); | 1596 std::string sopInstanceUid = frames_->GetInstanceOfFrame(cursorIndex).GetSopInstanceUid(); |
1604 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); | 1597 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); |
1605 | 1598 |
1606 { | 1599 { |
1607 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); | 1600 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); |
1608 lock->Schedule( | 1601 lock->Schedule( |
1609 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create( | 1602 GetSharedObserver(), priority, OrthancStone::ParseDicomFromWadoCommand::Create( |
1613 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, isPrefetch))); | 1606 new SetFullDicomFrame(GetSharedObserver(), sopInstanceUid, frameNumber, isPrefetch))); |
1614 } | 1607 } |
1615 } | 1608 } |
1616 } | 1609 } |
1617 | 1610 |
1618 void ScheduleLoadRenderedFrame(size_t index, | 1611 void ScheduleLoadRenderedFrame(size_t cursorIndex, |
1619 int priority, | 1612 int priority, |
1620 bool isPrefetch) | 1613 bool isPrefetch) |
1621 { | 1614 { |
1622 if (!source_.HasDicomWebRendered()) | 1615 if (!source_.HasDicomWebRendered()) |
1623 { | 1616 { |
1624 ScheduleLoadFullDicomFrame(index, priority, isPrefetch); | 1617 ScheduleLoadFullDicomFrame(cursorIndex, priority, isPrefetch); |
1625 } | 1618 } |
1626 else if (frames_.get() != NULL) | 1619 else if (frames_.get() != NULL) |
1627 { | 1620 { |
1628 std::string sopInstanceUid = frames_->GetInstanceOfFrame(index).GetSopInstanceUid(); | 1621 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); |
1629 unsigned int frameNumber = frames_->GetFrameNumberInInstance(index); | 1622 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); |
1630 bool isMonochrome1 = IsFrameMonochrome1(*frames_, index); | 1623 |
1624 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == | |
1625 Orthanc::PhotometricInterpretation_Monochrome1); | |
1631 | 1626 |
1632 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() + | 1627 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() + |
1633 "/series/" + frames_->GetSeriesInstanceUid() + | 1628 "/series/" + frames_->GetSeriesInstanceUid() + |
1634 "/instances/" + sopInstanceUid + | 1629 "/instances/" + instance.GetSopInstanceUid() + |
1635 "/frames/" + boost::lexical_cast<std::string>(frameNumber + 1) + "/rendered"); | 1630 "/frames/" + boost::lexical_cast<std::string>(frameNumber + 1) + "/rendered"); |
1636 | 1631 |
1637 std::map<std::string, std::string> headers, arguments; | 1632 std::map<std::string, std::string> headers, arguments; |
1638 arguments["window"] = ( | 1633 arguments["window"] = ( |
1639 boost::lexical_cast<std::string>(windowingCenter_) + "," + | 1634 boost::lexical_cast<std::string>(windowingCenter_) + "," + |
1640 boost::lexical_cast<std::string>(windowingWidth_) + ",linear"); | 1635 boost::lexical_cast<std::string>(windowingWidth_) + ",linear"); |
1641 | 1636 |
1642 std::unique_ptr<OrthancStone::IOracleCommand> command( | 1637 std::unique_ptr<OrthancStone::IOracleCommand> command( |
1643 source_.CreateDicomWebCommand( | 1638 source_.CreateDicomWebCommand( |
1644 uri, arguments, headers, new SetLowQualityFrame( | 1639 uri, arguments, headers, new SetLowQualityFrame( |
1645 GetSharedObserver(), sopInstanceUid, frameNumber, | 1640 GetSharedObserver(), instance.GetSopInstanceUid(), frameNumber, |
1646 windowingCenter_, windowingWidth_, isMonochrome1, isPrefetch))); | 1641 windowingCenter_, windowingWidth_, isMonochrome1, isPrefetch))); |
1647 | 1642 |
1648 { | 1643 { |
1649 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); | 1644 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); |
1650 lock->Schedule(GetSharedObserver(), priority, command.release()); | 1645 lock->Schedule(GetSharedObserver(), priority, command.release()); |
1952 std::unique_ptr<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer); | 1947 std::unique_ptr<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer); |
1953 | 1948 |
1954 if (cursor_.get() != NULL && | 1949 if (cursor_.get() != NULL && |
1955 frames_.get() != NULL) | 1950 frames_.get() != NULL) |
1956 { | 1951 { |
1957 const size_t index = cursor_->GetCurrentIndex(); | 1952 const size_t cursorIndex = cursor_->GetCurrentIndex(); |
1958 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(index); | 1953 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); |
1959 const unsigned int frame = frames_->GetFrameNumberInInstance(index); | 1954 const unsigned int frame = frames_->GetFrameNumberInInstance(cursorIndex); |
1960 | 1955 |
1961 for (std::list<const ViewerViewport*>::const_iterator | 1956 for (std::list<const ViewerViewport*>::const_iterator |
1962 it = viewports.begin(); it != viewports.end(); ++it) | 1957 it = viewports.begin(); it != viewports.end(); ++it) |
1963 { | 1958 { |
1964 assert(*it != NULL); | 1959 assert(*it != NULL); |
2170 ApplyScheduledFocus(); | 2165 ApplyScheduledFocus(); |
2171 } | 2166 } |
2172 | 2167 |
2173 void ApplyScheduledFocus() | 2168 void ApplyScheduledFocus() |
2174 { | 2169 { |
2175 size_t frameIndex; | 2170 size_t cursorIndex; |
2176 | 2171 |
2177 if (hasFocusOnInstance_ && | 2172 if (hasFocusOnInstance_ && |
2178 cursor_.get() != NULL && | 2173 cursor_.get() != NULL && |
2179 frames_.get() != NULL && | 2174 frames_.get() != NULL && |
2180 frames_->LookupFrame(frameIndex, focusSopInstanceUid_, focusFrameNumber_)) | 2175 frames_->LookupFrame(cursorIndex, focusSopInstanceUid_, focusFrameNumber_)) |
2181 { | 2176 { |
2182 size_t current = cursor_->GetCurrentIndex(); | 2177 size_t current = cursor_->GetCurrentIndex(); |
2183 | 2178 |
2184 if (current != frameIndex) | 2179 if (current != cursorIndex) |
2185 { | 2180 { |
2186 cursor_->SetCurrentIndex(frameIndex); | 2181 cursor_->SetCurrentIndex(cursorIndex); |
2187 DisplayCurrentFrame(); | 2182 DisplayCurrentFrame(); |
2188 } | 2183 } |
2189 | 2184 |
2190 hasFocusOnInstance_ = false; | 2185 hasFocusOnInstance_ = false; |
2191 } | 2186 } |
2194 void FocusOnPoint(const OrthancStone::Vector& p) | 2189 void FocusOnPoint(const OrthancStone::Vector& p) |
2195 { | 2190 { |
2196 //static const double MAX_DISTANCE = 0.5; // 0.5 cm => TODO parameter? | 2191 //static const double MAX_DISTANCE = 0.5; // 0.5 cm => TODO parameter? |
2197 static const double MAX_DISTANCE = std::numeric_limits<double>::infinity(); | 2192 static const double MAX_DISTANCE = std::numeric_limits<double>::infinity(); |
2198 | 2193 |
2199 size_t frameIndex; | 2194 size_t cursorIndex; |
2200 if (cursor_.get() != NULL && | 2195 if (cursor_.get() != NULL && |
2201 frames_.get() != NULL && | 2196 frames_.get() != NULL && |
2202 frames_->FindClosestFrame(frameIndex, p, MAX_DISTANCE)) | 2197 frames_->FindClosestFrame(cursorIndex, p, MAX_DISTANCE)) |
2203 { | 2198 { |
2204 cursor_->SetCurrentIndex(frameIndex); | 2199 cursor_->SetCurrentIndex(cursorIndex); |
2205 DisplayCurrentFrame(); | 2200 DisplayCurrentFrame(); |
2206 } | 2201 } |
2207 } | 2202 } |
2208 }; | 2203 }; |
2209 | 2204 |