Mercurial > hg > orthanc-stone
changeset 1812:db341679dc9f
ViewerViewport::StoneAnnotationsRegistry
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 25 May 2021 12:32:11 +0200 |
parents | fdc6a8089eb9 |
children | 53aa3f72b539 |
files | Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp |
diffstat | 2 files changed, 103 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Tue May 25 11:29:53 2021 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Tue May 25 12:32:11 2021 +0200 @@ -1175,6 +1175,8 @@ class ViewerViewport : public OrthancStone::ObserverBase<ViewerViewport> { public: + typedef std::map<std::string, boost::shared_ptr<Json::Value> > StoneAnnotationsRegistry; + class IObserver : public boost::noncopyable { public: @@ -1580,12 +1582,14 @@ size_t focusFrameNumber_; // The coordinates of OsiriX annotations are expressed in 3D world coordinates - boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations_; + boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> osiriXAnnotations_; // The coordinates of Stone annotations are expressed in 2D // coordinates of the current texture, with (0,0) corresponding to // the center of the top-left pixel - boost::shared_ptr<OrthancStone::AnnotationsSceneLayer> annotationsStone_; + boost::shared_ptr<OrthancStone::AnnotationsSceneLayer> stoneAnnotations_; + boost::shared_ptr<StoneAnnotationsRegistry> stoneAnnotationsRegistry_; + void ScheduleNextPrefetch() { @@ -1761,10 +1765,10 @@ std::unique_ptr<OrthancStone::MacroSceneLayer> annotationsOsiriX; - if (annotations_) + if (osiriXAnnotations_) { std::set<size_t> a; - annotations_->LookupSopInstanceUid(a, instance.GetSopInstanceUid()); + osiriXAnnotations_->LookupSopInstanceUid(a, instance.GetSopInstanceUid()); if (plane.IsValid() && !a.empty()) { @@ -1776,12 +1780,29 @@ for (std::set<size_t>::const_iterator it = a.begin(); it != a.end(); ++it) { - const OrthancStone::OsiriX::Annotation& annotation = annotations_->GetAnnotation(*it); + const OrthancStone::OsiriX::Annotation& annotation = osiriXAnnotations_->GetAnnotation(*it); annotationsOsiriX->AddLayer(factory.Create(annotation, plane)); } } } + if (stoneAnnotationsRegistry_.get() == NULL) + { + stoneAnnotations_->Clear(); + } + else + { + StoneAnnotationsRegistry::const_iterator found = stoneAnnotationsRegistry_->find(instance.GetSopInstanceUid()); + if (found == stoneAnnotationsRegistry_->end()) + { + stoneAnnotations_->Clear(); + } + else + { + stoneAnnotations_->Unserialize(*found->second); + } + } + { std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); @@ -1805,7 +1826,7 @@ fitNextContent_ = false; } - annotationsStone_->Render(scene); + stoneAnnotations_->Render(scene); //lock->GetCompositor().Refresh(scene); lock->Invalidate(); @@ -2010,7 +2031,8 @@ synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), synchronizationEnabled_(false), centralPhysicalWidth_(1), - centralPhysicalHeight_(1) + centralPhysicalHeight_(1), + stoneAnnotationsRegistry_(NULL) { if (!framesCache_) { @@ -2039,17 +2061,7 @@ SetWindowingPreset(); - { - annotationsStone_.reset(new OrthancStone::AnnotationsSceneLayer(LAYER_ANNOTATIONS_STONE)); - annotationsStone_->AddSegmentAnnotation(OrthancStone::ScenePoint2D(0, 0), - OrthancStone::ScenePoint2D(100, 100)); - annotationsStone_->AddAngleAnnotation(OrthancStone::ScenePoint2D(100, 50), - OrthancStone::ScenePoint2D(150, 40), - OrthancStone::ScenePoint2D(200, 50)); - annotationsStone_->AddCircleAnnotation(OrthancStone::ScenePoint2D(50, 200), - OrthancStone::ScenePoint2D(100, 250)); - annotationsStone_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Edit); - } + stoneAnnotations_.reset(new OrthancStone::AnnotationsSceneLayer(LAYER_ANNOTATIONS_STONE)); } @@ -2130,33 +2142,47 @@ } - void RefreshAnnotations() + void RefreshAnnotations(bool save) { - std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); - annotationsStone_->Render(lock->GetController().GetScene()); - lock->Invalidate(); + { + std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); + stoneAnnotations_->Render(lock->GetController().GetScene()); + lock->Invalidate(); + } + + if (save) + { + if (cursor_.get() != NULL && + frames_.get() != NULL) + { + const size_t cursorIndex = cursor_->GetCurrentIndex(); + const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); + + boost::shared_ptr<Json::Value> v(new Json::Value); + stoneAnnotations_->Serialize(*v); + (*stoneAnnotationsRegistry_) [instance.GetSopInstanceUid()] = v; + } + } } void Handle(const OrthancStone::ViewportController::SceneTransformChanged& message) { - RefreshAnnotations(); + RefreshAnnotations(false /* don't save */); } void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationChangedMessage& message) { - RefreshAnnotations(); + RefreshAnnotations(true /* save */); } void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationAddedMessage& message) { - RefreshAnnotations(); - LOG(WARNING) << "annotation added"; + RefreshAnnotations(true /* save */); } void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationRemovedMessage& message) { - RefreshAnnotations(); - LOG(WARNING) << "annotation removed"; + RefreshAnnotations(true /* save */); } public: @@ -2191,13 +2217,13 @@ lock->GetOracleObservable(), &ViewerViewport::Handle); viewport->Register<OrthancStone::AnnotationsSceneLayer::AnnotationChangedMessage>( - *viewport->annotationsStone_, &ViewerViewport::Handle); + *viewport->stoneAnnotations_, &ViewerViewport::Handle); viewport->Register<OrthancStone::AnnotationsSceneLayer::AnnotationAddedMessage>( - *viewport->annotationsStone_, &ViewerViewport::Handle); + *viewport->stoneAnnotations_, &ViewerViewport::Handle); viewport->Register<OrthancStone::AnnotationsSceneLayer::AnnotationRemovedMessage>( - *viewport->annotationsStone_, &ViewerViewport::Handle); + *viewport->stoneAnnotations_, &ViewerViewport::Handle); } { @@ -2297,7 +2323,8 @@ lock->GetCompositor().FitContent(lock->GetController().GetScene()); } - annotationsStone_->Render(lock->GetController().GetScene()); + stoneAnnotations_->ClearHover(); + stoneAnnotations_->Render(lock->GetController().GetScene()); lock->Invalidate(); } @@ -2639,7 +2666,7 @@ std::unique_ptr<OrthancStone::IViewport::ILock> lock2(lock1->Lock()); std::unique_ptr<OrthancStone::IFlexiblePointerTracker> t; - t.reset(viewer_.annotationsStone_->CreateTracker(event.GetMainPosition(), lock2->GetController().GetScene())); + t.reset(viewer_.stoneAnnotations_->CreateTracker(event.GetMainPosition(), lock2->GetController().GetScene())); if (t.get() != NULL) { @@ -2662,9 +2689,9 @@ { std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport.Lock()); - if (viewer_.annotationsStone_->SetMouseHover(event.GetMainPosition(), lock->GetController().GetScene())) + if (viewer_.stoneAnnotations_->SetMouseHover(event.GetMainPosition(), lock->GetController().GetScene())) { - viewer_.annotationsStone_->Render(lock->GetController().GetScene()); + viewer_.stoneAnnotations_->Render(lock->GetController().GetScene()); lock->Invalidate(); } } @@ -2684,9 +2711,9 @@ viewport_->FitForPrint(); } - void SetAnnotations(boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations) + void SetOsiriXAnnotations(boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations) { - annotations_ = annotations; + osiriXAnnotations_ = annotations; } void ScheduleFrameFocus(const std::string& sopInstanceUid, @@ -2775,6 +2802,12 @@ OrthancStone::LinearAlgebra::AssignVector(synchronizationOffset_, 0, 0, 0); synchronizationEnabled_ = enabled; } + + + void SetStoneAnnotationsRegistry(boost::shared_ptr<ViewerViewport::StoneAnnotationsRegistry>& registry) + { + stoneAnnotationsRegistry_ = registry; + } }; @@ -2782,9 +2815,11 @@ typedef std::map<std::string, boost::shared_ptr<ViewerViewport> > Viewports; + static Viewports allViewports_; static bool showReferenceLines_ = true; -static boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> annotations_; +static boost::shared_ptr<OrthancStone::OsiriX::CollectionOfAnnotations> osiriXAnnotations_; +static boost::shared_ptr<ViewerViewport::StoneAnnotationsRegistry> stoneAnnotationsRegistry_; static void UpdateReferenceLines() @@ -3047,7 +3082,8 @@ ViewerViewport::Create(*context_, source_, canvas, framesCache_, softwareRendering_)); viewport->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_); viewport->AcquireObserver(new WebAssemblyObserver); - viewport->SetAnnotations(annotations_); + viewport->SetOsiriXAnnotations(osiriXAnnotations_); + viewport->SetStoneAnnotationsRegistry(stoneAnnotationsRegistry_); allViewports_[canvas] = viewport; return viewport; } @@ -3071,7 +3107,25 @@ context_->SetDicomCacheSize(128 * 1024 * 1024); // 128MB framesCache_.reset(new FramesCache); - annotations_.reset(new OrthancStone::OsiriX::CollectionOfAnnotations); + osiriXAnnotations_.reset(new OrthancStone::OsiriX::CollectionOfAnnotations); + stoneAnnotationsRegistry_.reset(new ViewerViewport::StoneAnnotationsRegistry); + + { + // TODO - TEST + OrthancStone::AnnotationsSceneLayer l(0); + l.AddSegmentAnnotation(OrthancStone::ScenePoint2D(0, 0), + OrthancStone::ScenePoint2D(100, 100)); + l.AddAngleAnnotation(OrthancStone::ScenePoint2D(100, 50), + OrthancStone::ScenePoint2D(150, 40), + OrthancStone::ScenePoint2D(200, 50)); + l.AddCircleAnnotation(OrthancStone::ScenePoint2D(50, 200), + OrthancStone::ScenePoint2D(100, 250)); + l.SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Edit); + boost::shared_ptr<Json::Value> s(new Json::Value); + l.Serialize(*s); + (*stoneAnnotationsRegistry_) ["1.2.840.113543.6.6.4.7.64234348190163144631511103849051737563212"] = s; + } + DISPATCH_JAVASCRIPT_EVENT("StoneInitialized"); } @@ -3531,10 +3585,10 @@ { if (clearPreviousAnnotations) { - annotations_->Clear(); + osiriXAnnotations_->Clear(); } - annotations_->LoadXml(xml); + osiriXAnnotations_->LoadXml(xml); // Force redraw, as the annotations might have changed for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) @@ -3543,16 +3597,16 @@ it->second->Redraw(); } - if (annotations_->GetSize() == 0) + if (osiriXAnnotations_->GetSize() == 0) { stringBuffer_.clear(); } else { - stringBuffer_ = annotations_->GetAnnotation(0).GetSeriesInstanceUid(); + stringBuffer_ = osiriXAnnotations_->GetAnnotation(0).GetSeriesInstanceUid(); } - LOG(WARNING) << "Loaded " << annotations_->GetSize() << " annotations from OsiriX"; + LOG(WARNING) << "Loaded " << osiriXAnnotations_->GetSize() << " annotations from OsiriX"; return 1; } EXTERN_CATCH_EXCEPTIONS; @@ -3565,9 +3619,9 @@ { try { - if (annotations_->GetSize() != 0) + if (osiriXAnnotations_->GetSize() != 0) { - const OrthancStone::OsiriX::Annotation& annotation = annotations_->GetAnnotation(0); + const OrthancStone::OsiriX::Annotation& annotation = osiriXAnnotations_->GetAnnotation(0); boost::shared_ptr<ViewerViewport> viewport = GetViewport(canvas); viewport->ScheduleFrameFocus(annotation.GetSopInstanceUid(), 0 /* focus on first frame */);