Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 2144:9d77c935f2c3 dicom-sr
handling of pending referenced instances when loading DICOM-SR
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 16 Aug 2024 17:24:00 +0200 |
parents | 1a02e758eaf4 |
children | 743fa9c74443 |
comparison
equal
deleted
inserted
replaced
2143:83efb01991c5 | 2144:9d77c935f2c3 |
---|---|
153 WebViewerAction_CreateRectangleProbe, // New in 2.4 | 153 WebViewerAction_CreateRectangleProbe, // New in 2.4 |
154 WebViewerAction_CreateTextAnnotation // New in 2.4 | 154 WebViewerAction_CreateTextAnnotation // New in 2.4 |
155 }; | 155 }; |
156 | 156 |
157 | 157 |
158 enum FramesCollectionType | |
159 { | |
160 FramesCollectionType_None, | |
161 FramesCollectionType_DicomSR | |
162 }; | |
163 | |
158 | 164 |
159 static OrthancStone::MouseAction ConvertWebViewerAction(int action) | 165 static OrthancStone::MouseAction ConvertWebViewerAction(int action) |
160 { | 166 { |
161 switch (action) | 167 switch (action) |
162 { | 168 { |
639 const std::string& seriesInstanceUid, | 645 const std::string& seriesInstanceUid, |
640 const std::string& pdf) = 0; | 646 const std::string& pdf) = 0; |
641 | 647 |
642 virtual void SignalVirtualSeriesThumbnailLoaded(const std::string& virtualSeriesId, | 648 virtual void SignalVirtualSeriesThumbnailLoaded(const std::string& virtualSeriesId, |
643 const std::string& jpeg) = 0; | 649 const std::string& jpeg) = 0; |
650 | |
651 virtual void SignalDicomSRLoaded(const std::string& studyInstanceUid, | |
652 const std::string& seriesInstanceUid, | |
653 const std::string& sopInstanceUid) = 0; | |
644 }; | 654 }; |
645 | 655 |
646 private: | 656 private: |
647 OrthancStone::ILoadersContext& context_; | 657 OrthancStone::ILoadersContext& context_; |
648 std::unique_ptr<IObserver> observer_; | 658 std::unique_ptr<IObserver> observer_; |
717 dicom.RemoveResource(seriesIdsToRemove[i]); | 727 dicom.RemoveResource(seriesIdsToRemove[i]); |
718 } | 728 } |
719 } | 729 } |
720 else if (payload.GetValue() == Orthanc::ResourceType_Instance) | 730 else if (payload.GetValue() == Orthanc::ResourceType_Instance) |
721 { | 731 { |
722 // This occurs if loading DICOM-SR | 732 // This occurs if loading DICOM-SR: Show the DICOM-SR once all its referenced instances are loaded |
723 | 733 |
724 // TODO - Hide/show DICOM-SR once they have been loaded | 734 for (size_t i = 0; i < dicom.GetSize(); i++) |
735 { | |
736 std::string studyInstanceUid, seriesInstanceUid, sopInstanceUid; | |
737 if (dicom.GetResource(i).LookupStringValue(studyInstanceUid, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false) && | |
738 dicom.GetResource(i).LookupStringValue(seriesInstanceUid, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false) && | |
739 dicom.GetResource(i).LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false)) | |
740 { | |
741 for (StructuredReports::const_iterator it = structuredReports_.begin(); it != structuredReports_.end(); ++it) | |
742 { | |
743 if (it->second->IsReferencedInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid)) | |
744 { | |
745 bool complete = true; | |
746 for (size_t j = 0; j < it->second->GetReferencedInstancesCount(); j++) | |
747 { | |
748 std::string referencedStudyInstanceUid, referencedSeriesInstanceUid, referencedInstanceInstanceUid, sopClassUid; | |
749 it->second->GetReferencedInstance(referencedStudyInstanceUid, referencedSeriesInstanceUid, referencedInstanceInstanceUid, sopClassUid, j); | |
750 if (!instances_->HasResource(referencedInstanceInstanceUid)) | |
751 { | |
752 complete = false; | |
753 break; | |
754 } | |
755 } | |
756 | |
757 if (complete) | |
758 { | |
759 LOG(INFO) << "Loaded all the instances referred by DICOM-SR instance: " << sopInstanceUid; | |
760 if (observer_ != NULL) | |
761 { | |
762 observer_->SignalDicomSRLoaded(it->second->GetStudyInstanceUid(), | |
763 it->second->GetSeriesInstanceUid(), | |
764 it->second->GetSopInstanceUid()); | |
765 } | |
766 } | |
767 } | |
768 } | |
769 } | |
770 } | |
725 } | 771 } |
726 | 772 |
727 if (payload.GetValue() == Orthanc::ResourceType_Study || | 773 if (payload.GetValue() == Orthanc::ResourceType_Study || |
728 payload.GetValue() == Orthanc::ResourceType_Series) | 774 payload.GetValue() == Orthanc::ResourceType_Series) |
729 { | 775 { |
1164 { | 1210 { |
1165 return false; | 1211 return false; |
1166 } | 1212 } |
1167 } | 1213 } |
1168 | 1214 |
1169 IFramesCollection* GetSeriesFrames(const std::string& seriesInstanceUid) const | 1215 IFramesCollection* GetSeriesFrames(FramesCollectionType& type, |
1170 { | 1216 const std::string& seriesInstanceUid) const |
1217 { | |
1218 type = FramesCollectionType_None; | |
1219 | |
1171 OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); | 1220 OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); |
1172 | 1221 |
1173 if (accessor.IsComplete()) | 1222 if (accessor.IsComplete()) |
1174 { | 1223 { |
1175 StructuredReports::const_iterator sr = structuredReports_.find(seriesInstanceUid); | 1224 StructuredReports::const_iterator sr = structuredReports_.find(seriesInstanceUid); |
1176 if (sr != structuredReports_.end()) | 1225 if (sr != structuredReports_.end()) |
1177 { | 1226 { |
1178 assert(sr->second != NULL); | 1227 assert(sr->second != NULL); |
1228 type = FramesCollectionType_DicomSR; | |
1179 | 1229 |
1180 try | 1230 try |
1181 { | 1231 { |
1182 return new DicomStructuredReportFrames(*sr->second, *instances_); | 1232 return new DicomStructuredReportFrames(*sr->second, *instances_); |
1183 } | 1233 } |
1184 catch (Orthanc::OrthancException&) | 1234 catch (Orthanc::OrthancException&) |
1185 { | 1235 { |
1186 // TODO | 1236 LOG(INFO) << "All the instances referenced by the DICOM-SR series \"" |
1187 LOG(ERROR) << "Instances of the DICOM-SR are not available yet"; | 1237 << seriesInstanceUid << "\" are not available yet"; |
1188 return NULL; | 1238 return NULL; |
1189 } | 1239 } |
1190 } | 1240 } |
1191 | 1241 |
1192 std::unique_ptr<OrthancStone::SortedFrames> target(new OrthancStone::SortedFrames); | 1242 std::unique_ptr<OrthancStone::SortedFrames> target(new OrthancStone::SortedFrames); |
2473 // coordinates of the current texture, with (0,0) corresponding to | 2523 // coordinates of the current texture, with (0,0) corresponding to |
2474 // the center of the top-left pixel | 2524 // the center of the top-left pixel |
2475 boost::shared_ptr<OrthancStone::AnnotationsSceneLayer> stoneAnnotations_; | 2525 boost::shared_ptr<OrthancStone::AnnotationsSceneLayer> stoneAnnotations_; |
2476 | 2526 |
2477 bool linearInterpolation_; | 2527 bool linearInterpolation_; |
2528 std::string pendingSeriesInstanceUid_; | |
2478 | 2529 |
2479 | 2530 |
2480 void ScheduleNextPrefetch() | 2531 void ScheduleNextPrefetch() |
2481 { | 2532 { |
2482 while (!prefetchQueue_.empty()) | 2533 while (!prefetchQueue_.empty()) |
3977 | 4028 |
3978 observer_->SignalSynchronizedBrowsing( | 4029 observer_->SignalSynchronizedBrowsing( |
3979 *this, current.GetOrigin() + synchronizationOffset_, current.GetNormal()); | 4030 *this, current.GetOrigin() + synchronizationOffset_, current.GetNormal()); |
3980 } | 4031 } |
3981 } | 4032 } |
4033 | |
4034 | |
4035 void SetPendingSeriesInstanceUid(const std::string& seriesInstanceUid) | |
4036 { | |
4037 pendingSeriesInstanceUid_ = seriesInstanceUid; | |
4038 } | |
4039 | |
4040 | |
4041 void ClearPendingSeriesInstanceUid() | |
4042 { | |
4043 pendingSeriesInstanceUid_.clear(); | |
4044 } | |
4045 | |
4046 | |
4047 const std::string& GetPendingSeriesInstanceUid() const | |
4048 { | |
4049 return pendingSeriesInstanceUid_; | |
4050 } | |
3982 }; | 4051 }; |
3983 | 4052 |
3984 | 4053 |
3985 | 4054 |
3986 | 4055 |
4258 pointedPosition.GetX(), | 4327 pointedPosition.GetX(), |
4259 pointedPosition.GetY(), | 4328 pointedPosition.GetY(), |
4260 labelPosition.GetX(), | 4329 labelPosition.GetX(), |
4261 labelPosition.GetY() ); | 4330 labelPosition.GetY() ); |
4262 } | 4331 } |
4332 | |
4333 virtual void SignalDicomSRLoaded(const std::string& studyInstanceUid, | |
4334 const std::string& seriesInstanceUid, | |
4335 const std::string& sopInstanceUid) ORTHANC_OVERRIDE; | |
4263 }; | 4336 }; |
4264 | 4337 |
4265 | 4338 |
4266 | 4339 |
4267 static OrthancStone::DicomSource source_; | 4340 static OrthancStone::DicomSource source_; |
4324 return viewport; | 4397 return viewport; |
4325 } | 4398 } |
4326 else | 4399 else |
4327 { | 4400 { |
4328 return found->second; | 4401 return found->second; |
4402 } | |
4403 } | |
4404 | |
4405 | |
4406 void WebAssemblyObserver::SignalDicomSRLoaded(const std::string& studyInstanceUid, | |
4407 const std::string& seriesInstanceUid, | |
4408 const std::string& sopInstanceUid) | |
4409 { | |
4410 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) | |
4411 { | |
4412 if (it->second->GetPendingSeriesInstanceUid() == seriesInstanceUid) | |
4413 { | |
4414 it->second->ClearPendingSeriesInstanceUid(); | |
4415 | |
4416 FramesCollectionType type; | |
4417 std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(type, seriesInstanceUid)); | |
4418 | |
4419 if (frames.get() != NULL) | |
4420 { | |
4421 it->second->SetFrames(frames.release()); | |
4422 } | |
4423 } | |
4329 } | 4424 } |
4330 } | 4425 } |
4331 | 4426 |
4332 | 4427 |
4333 extern "C" | 4428 extern "C" |
4622 int LoadSeriesInViewport(const char* canvas, | 4717 int LoadSeriesInViewport(const char* canvas, |
4623 const char* seriesInstanceUid) | 4718 const char* seriesInstanceUid) |
4624 { | 4719 { |
4625 try | 4720 try |
4626 { | 4721 { |
4627 std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(seriesInstanceUid)); | 4722 FramesCollectionType type; |
4723 std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(type, seriesInstanceUid)); | |
4628 | 4724 |
4629 if (frames.get() != NULL) | 4725 if (frames.get() != NULL) |
4630 { | 4726 { |
4727 GetViewport(canvas)->ClearPendingSeriesInstanceUid(); | |
4631 GetViewport(canvas)->SetFrames(frames.release()); | 4728 GetViewport(canvas)->SetFrames(frames.release()); |
4632 return 1; | 4729 return 1; |
4633 } | 4730 } |
4731 else if (type == FramesCollectionType_DicomSR) | |
4732 { | |
4733 GetViewport(canvas)->SetPendingSeriesInstanceUid(seriesInstanceUid); | |
4734 return 0; | |
4735 } | |
4634 else | 4736 else |
4635 { | 4737 { |
4738 GetViewport(canvas)->ClearPendingSeriesInstanceUid(); | |
4636 return 0; | 4739 return 0; |
4637 } | 4740 } |
4638 } | 4741 } |
4639 EXTERN_CATCH_EXCEPTIONS; | 4742 EXTERN_CATCH_EXCEPTIONS; |
4640 return 0; | 4743 return 0; |