comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1603:595c0952ef7e

focusing on osirix annotations in Stone Web viewer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 28 Oct 2020 18:49:01 +0100
parents b253b79906fa
children 2df998314507
comparison
equal deleted inserted replaced
1602:b2941196cabf 1603:595c0952ef7e
1308 std::list<PrefetchItem> prefetchQueue_; 1308 std::list<PrefetchItem> prefetchQueue_;
1309 1309
1310 1310
1311 bool hasFocusOnInstance_; 1311 bool hasFocusOnInstance_;
1312 std::string focusSopInstanceUid_; 1312 std::string focusSopInstanceUid_;
1313 size_t focusFrameNumber_;
1313 1314
1314 boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations_; 1315 boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations_;
1315 1316
1316 void ScheduleNextPrefetch() 1317 void ScheduleNextPrefetch()
1317 { 1318 {
1576 1577
1577 case Annotation::Type_Text: 1578 case Annotation::Type_Text:
1578 { 1579 {
1579 const TextAnnotation& text = dynamic_cast<const TextAnnotation&>(annotation); 1580 const TextAnnotation& text = dynamic_cast<const TextAnnotation&>(annotation);
1580 double x, y; 1581 double x, y;
1581 OrthancStone::LinearAlgebra::Print(text.GetCenter());
1582 if (GetCurrentFrameGeometry().ProjectPoint(x, y, text.GetCenter())) 1582 if (GetCurrentFrameGeometry().ProjectPoint(x, y, text.GetCenter()))
1583 { 1583 {
1584 std::unique_ptr<OrthancStone::TextSceneLayer> layer2(new OrthancStone::TextSceneLayer()); 1584 std::unique_ptr<OrthancStone::TextSceneLayer> layer2(new OrthancStone::TextSceneLayer());
1585 layer2->SetPosition(x, y); 1585 layer2->SetPosition(x, y);
1586 layer2->SetText(text.GetText()); 1586 layer2->SetText(text.GetText());
1749 cache_(cache), 1749 cache_(cache),
1750 fitNextContent_(true), 1750 fitNextContent_(true),
1751 isCtrlDown_(false), 1751 isCtrlDown_(false),
1752 flipX_(false), 1752 flipX_(false),
1753 flipY_(false), 1753 flipY_(false),
1754 hasFocusOnInstance_(false) 1754 hasFocusOnInstance_(false),
1755 focusFrameNumber_(0)
1755 { 1756 {
1756 if (!cache_) 1757 if (!cache_)
1757 { 1758 {
1758 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 1759 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
1759 } 1760 }
1855 void Handle(const OrthancStone::ParseDicomSuccessMessage& message) 1856 void Handle(const OrthancStone::ParseDicomSuccessMessage& message)
1856 { 1857 {
1857 dynamic_cast<const ICommand&>(message.GetOrigin().GetPayload()).Handle(message); 1858 dynamic_cast<const ICommand&>(message.GetOrigin().GetPayload()).Handle(message);
1858 } 1859 }
1859 1860
1860 void ApplyScheduledFocus()
1861 {
1862 size_t instanceIndex;
1863
1864 if (hasFocusOnInstance_ &&
1865 frames_.get() != NULL &&
1866 frames_->LookupSopInstanceUid(instanceIndex, focusSopInstanceUid_))
1867 {
1868 // TODO
1869
1870 hasFocusOnInstance_ = false;
1871 }
1872 }
1873
1874 public: 1861 public:
1875 static boost::shared_ptr<ViewerViewport> Create(OrthancStone::ILoadersContext::ILock& lock, 1862 static boost::shared_ptr<ViewerViewport> Create(OrthancStone::ILoadersContext::ILock& lock,
1876 const OrthancStone::DicomSource& source, 1863 const OrthancStone::DicomSource& source,
1877 const std::string& canvas, 1864 const std::string& canvas,
1878 boost::shared_ptr<FramesCache> cache, 1865 boost::shared_ptr<FramesCache> cache,
1934 loader_->ScheduleGetDicomWeb( 1921 loader_->ScheduleGetDicomWeb(
1935 boost::make_shared<OrthancStone::LoadedDicomResources>(Orthanc::DICOM_TAG_SOP_INSTANCE_UID), 1922 boost::make_shared<OrthancStone::LoadedDicomResources>(Orthanc::DICOM_TAG_SOP_INSTANCE_UID),
1936 0, source_, uri, new SetDefaultWindowingCommand(GetSharedObserver())); 1923 0, source_, uri, new SetDefaultWindowingCommand(GetSharedObserver()));
1937 } 1924 }
1938 } 1925 }
1939 } 1926
1940 1927 ApplyScheduledFocus();
1941 1928 }
1942 void UpdateCurrentFrame() 1929
1930
1931 void Redraw()
1943 { 1932 {
1944 if (cursor_.get() != NULL) 1933 if (cursor_.get() != NULL)
1945 { 1934 {
1946 unsigned int quality; 1935 unsigned int quality;
1947 DisplayFrame(quality, cursor_->GetCurrentIndex()); 1936 DisplayFrame(quality, cursor_->GetCurrentIndex());
2173 void SetAnnotations(boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations) 2162 void SetAnnotations(boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations)
2174 { 2163 {
2175 annotations_ = annotations; 2164 annotations_ = annotations;
2176 } 2165 }
2177 2166
2167 void ScheduleFrameFocus(const std::string& sopInstanceUid,
2168 unsigned int frameNumber)
2169 {
2170 hasFocusOnInstance_ = true;
2171 focusSopInstanceUid_ = sopInstanceUid;
2172 focusFrameNumber_ = frameNumber;
2173
2174 ApplyScheduledFocus();
2175 }
2176
2177 void ApplyScheduledFocus()
2178 {
2179 size_t frameIndex;
2180
2181 if (hasFocusOnInstance_ &&
2182 cursor_.get() != NULL &&
2183 frames_.get() != NULL &&
2184 frames_->LookupFrame(frameIndex, focusSopInstanceUid_, focusFrameNumber_))
2185 {
2186 size_t current = cursor_->GetCurrentIndex();
2187
2188 if (current != frameIndex)
2189 {
2190 cursor_->SetCurrentIndex(frameIndex);
2191 DisplayCurrentFrame();
2192 }
2193
2194 hasFocusOnInstance_ = false;
2195 }
2196 }
2178 }; 2197 };
2179 2198
2180 2199
2181 2200
2182 2201
2249 "seriesInstanceUid" : UTF8ToString($1) }); 2268 "seriesInstanceUid" : UTF8ToString($1) });
2250 window.dispatchEvent(customEvent); 2269 window.dispatchEvent(customEvent);
2251 }, 2270 },
2252 studyInstanceUid.c_str(), 2271 studyInstanceUid.c_str(),
2253 seriesInstanceUid.c_str()); 2272 seriesInstanceUid.c_str());
2273
2274 for (Viewports::const_iterator it = allViewports_.begin(); it != allViewports_.end(); ++it)
2275 {
2276 assert(it->second != NULL);
2277 it->second->ApplyScheduledFocus();
2278 }
2254 } 2279 }
2255 2280
2256 virtual void SignalFrameUpdated(const ViewerViewport& viewport, 2281 virtual void SignalFrameUpdated(const ViewerViewport& viewport,
2257 size_t currentFrame, 2282 size_t currentFrame,
2258 size_t countFrames, 2283 size_t countFrames,
2721 } 2746 }
2722 EXTERN_CATCH_EXCEPTIONS; 2747 EXTERN_CATCH_EXCEPTIONS;
2723 } 2748 }
2724 2749
2725 2750
2751 // Side-effect: "GetStringBuffer()" is filled with the "Series
2752 // Instance UID" of the first loaded annotation
2726 EMSCRIPTEN_KEEPALIVE 2753 EMSCRIPTEN_KEEPALIVE
2727 int LoadOsiriXAnnotations(const char* xml, 2754 int LoadOsiriXAnnotations(const char* xml,
2728 int clearPreviousAnnotations) 2755 int clearPreviousAnnotations)
2729 { 2756 {
2730 try 2757 try
2733 { 2760 {
2734 annotations_->Clear(); 2761 annotations_->Clear();
2735 } 2762 }
2736 2763
2737 annotations_->LoadXml(xml); 2764 annotations_->LoadXml(xml);
2738 2765
2766 // Force redraw, as the annotations might have changed
2739 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) 2767 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it)
2740 { 2768 {
2741 // TODO - Check if the viewport contains one of the SOP
2742 // Instance UID from the loaded annotations => focus on this
2743 // instance
2744
2745 // TODO - If no viewport contains the instance => monitor the
2746 // "ResourcesLoader" as new series get loaded
2747
2748 assert(it->second != NULL); 2769 assert(it->second != NULL);
2749 it->second->UpdateCurrentFrame(); 2770 it->second->Redraw();
2771 }
2772
2773 if (annotations_->GetSize() == 0)
2774 {
2775 stringBuffer_.clear();
2776 }
2777 else
2778 {
2779 stringBuffer_ = annotations_->GetAnnotation(0).GetSeriesInstanceUid();
2750 } 2780 }
2751 2781
2752 LOG(WARNING) << "Loaded " << annotations_->GetSize() << " annotations from OsiriX"; 2782 LOG(WARNING) << "Loaded " << annotations_->GetSize() << " annotations from OsiriX";
2753 return 1; 2783 return 1;
2754 } 2784 }
2755 EXTERN_CATCH_EXCEPTIONS; 2785 EXTERN_CATCH_EXCEPTIONS;
2756 return 0; 2786 return 0;
2757 } 2787 }
2788
2789
2790 EMSCRIPTEN_KEEPALIVE
2791 void FocusFirstOsiriXAnnotation(const char* canvas)
2792 {
2793 try
2794 {
2795 if (annotations_->GetSize() != 0)
2796 {
2797 const OrthancStone::OsiriX::Annotation& annotation = annotations_->GetAnnotation(0);
2798
2799 boost::shared_ptr<ViewerViewport> viewport = GetViewport(canvas);
2800 viewport->ScheduleFrameFocus(annotation.GetSopInstanceUid(), 0 /* focus on first frame */);
2801
2802 // Force redraw, as the annotations might already have changed
2803 viewport->Redraw();
2804 }
2805 }
2806 EXTERN_CATCH_EXCEPTIONS;
2807 }
2758 } 2808 }