Mercurial > hg > orthanc-stone
diff Framework/SmartLoader.cpp @ 421:f87f28624b96 cache-in-radiography
tentative to make SmartLoader and RadiographyScene work together (not really working)
author | am@osimis.io |
---|---|
date | Tue, 20 Nov 2018 16:35:29 +0100 |
parents | 5d359b115b29 |
children |
line wrap: on
line diff
--- a/Framework/SmartLoader.cpp Mon Nov 19 12:45:37 2018 +0100 +++ b/Framework/SmartLoader.cpp Tue Nov 20 16:35:29 2018 +0100 @@ -27,6 +27,7 @@ #include "Framework/StoneException.h" #include "Framework/Layers/FrameRenderer.h" #include "Core/Logging.h" +#include "Radiography/RadiographyScene.h" namespace OrthancStone { @@ -62,6 +63,8 @@ unsigned int sliceIndex_; std::auto_ptr<Slice> slice_; + std::auto_ptr<OrthancPlugins::FullOrthancDataset> dicomTags_; + boost::shared_ptr<Orthanc::ImageAccessor> image_; SliceImageQuality effectiveQuality_; CachedSliceStatus status_; @@ -95,6 +98,7 @@ LOG(WARNING) << "ScheduleLayerCreation for CachedSlice (image is loaded): " << slice_->GetOrthancInstanceId(); RendererFactory factory(*this); + EmitMessage(IVolumeSlicer::FrameReadyMessage(*this, image_)); EmitMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, slice_->GetGeometry())); } else @@ -127,38 +131,69 @@ { } + void SmartLoader::SetFrameInRadiographyScene(RadiographyScene& scene, const std::string& instanceId, unsigned int frame) + { + // create the frame loader + std::auto_ptr<IVolumeSlicer> layerSource(GetFrameLoader(instanceId, frame)); + IVolumeSlicer* layerSource2 = layerSource.get(); + + // make sure that the widget registers the events before we trigger them (once we start loading the frame) + scene.SetFrame(layerSource.release()); + + // start loading + LoadFrame(layerSource2, instanceId, frame); + } + + + IVolumeSlicer* SmartLoader::GetFrameLoader(const std::string &instanceId, unsigned int frame) + { + std::auto_ptr<IVolumeSlicer> layerSource; + std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame); + + + if (cachedSlices_.find(sliceKeyId) != cachedSlices_.end()) // && cachedSlices_[sliceKeyId]->status_ == CachedSliceStatus_Loaded) + { // if the image is cached, return a clone of the cached image + layerSource.reset(cachedSlices_[sliceKeyId]->Clone()); + } + else + { // return a standard frame loader + layerSource.reset(new DicomSeriesVolumeSlicer(IObserver::GetBroker(), orthancApiClient_)); + dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_); + layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::TagsReadyMessage>(*this, &SmartLoader::OnLayerTagsReady)); + layerSource->RegisterObserverCallback(new Callable<SmartLoader, DicomSeriesVolumeSlicer::FrameReadyMessage>(*this, &SmartLoader::OnFrameReady)); + layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); + } + + return layerSource.release(); + } + + void SmartLoader::LoadFrame(IVolumeSlicer *frameLoader, const std::string &instanceId, unsigned int frame) + { + SmartLoader::CachedSlice* cachedSlice = dynamic_cast<SmartLoader::CachedSlice*>(frameLoader); + + if (cachedSlice != NULL) + { + EmitMessage(IVolumeSlicer::GeometryReadyMessage(*cachedSlice)); + EmitMessage(IVolumeSlicer::TagsReadyMessage(*cachedSlice, *(cachedSlice->dicomTags_.get()))); + } + else + { + DicomSeriesVolumeSlicer* volumeLoader = dynamic_cast<DicomSeriesVolumeSlicer*>(frameLoader); + volumeLoader->LoadFrame(instanceId, frame); + } + + } + void SmartLoader::SetFrameInWidget(SliceViewerWidget& sliceViewer, size_t layerIndex, const std::string& instanceId, unsigned int frame) { - // TODO: check if this frame has already been loaded or is already being loaded. - // - if already loaded: create a "clone" that will emit the GeometryReady/ImageReady messages "immediately" - // (it can not be immediate because Observers needs to register first and this is done after this method returns) - // - if currently loading, we need to return an object that will observe the existing VolumeSlicer and forward - // the messages to its observables - // in both cases, we must be carefull about objects lifecycle !!! - - std::auto_ptr<IVolumeSlicer> layerSource; - std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame); - SmartLoader::CachedSlice* cachedSlice = NULL; + // create the frame loader + std::auto_ptr<IVolumeSlicer> layerSource(GetFrameLoader(instanceId, frame)); + IVolumeSlicer* layerSource2 = layerSource.get(); - if (cachedSlices_.find(sliceKeyId) != cachedSlices_.end()) // && cachedSlices_[sliceKeyId]->status_ == CachedSliceStatus_Loaded) - { - layerSource.reset(cachedSlices_[sliceKeyId]->Clone()); - cachedSlice = dynamic_cast<SmartLoader::CachedSlice*>(layerSource.get()); - } - else - { - layerSource.reset(new DicomSeriesVolumeSlicer(IObserver::GetBroker(), orthancApiClient_)); - dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_); - layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady)); - layerSource->RegisterObserverCallback(new Callable<SmartLoader, DicomSeriesVolumeSlicer::FrameReadyMessage>(*this, &SmartLoader::OnFrameReady)); - layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); - dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame); - } - - // make sure that the widget registers the events before we trigger them + // make sure that the widget registers the events before we trigger them (once we start loading the frame) if (sliceViewer.GetLayerCount() == layerIndex) { sliceViewer.AddLayer(layerSource.release()); @@ -172,11 +207,8 @@ throw StoneException(ErrorCode_CanOnlyAddOneLayerAtATime); } - if (cachedSlice != NULL) - { - EmitMessage(IVolumeSlicer::GeometryReadyMessage(*cachedSlice)); - } - + // start loading + LoadFrame(layerSource2, instanceId, frame); } void SmartLoader::PreloadSlice(const std::string instanceId, @@ -201,7 +233,7 @@ std::auto_ptr<IVolumeSlicer> layerSource(new DicomSeriesVolumeSlicer(IObserver::GetBroker(), orthancApiClient_)); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_); - layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady)); + layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::TagsReadyMessage>(*this, &SmartLoader::OnLayerTagsReady)); layerSource->RegisterObserverCallback(new Callable<SmartLoader, DicomSeriesVolumeSlicer::FrameReadyMessage>(*this, &SmartLoader::OnFrameReady)); layerSource->RegisterObserverCallback(new Callable<SmartLoader, IVolumeSlicer::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame); @@ -222,7 +254,7 @@ // } - void SmartLoader::OnLayerGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message) + void SmartLoader::OnLayerTagsReady(const IVolumeSlicer::TagsReadyMessage& message) { const DicomSeriesVolumeSlicer& source = dynamic_cast<const DicomSeriesVolumeSlicer&>(message.GetOrigin()); @@ -238,11 +270,12 @@ cachedSlice->slice_.reset(slice.Clone()); cachedSlice->effectiveQuality_ = source.GetImageQuality(); cachedSlice->status_ = CachedSliceStatus_GeometryLoaded; + cachedSlice->dicomTags_.reset(message.GetDicomTags().Clone()); cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice); // re-emit original Layer message to observers - EmitMessage(message); + // EmitMessage(message); } @@ -264,7 +297,7 @@ cachedSlices_[sliceKeyId] = cachedSlice; // re-emit original Layer message to observers - EmitMessage(message); +// EmitMessage(IVolumeSlicer::FrameReadyMessage(*(cachedSlice.get()), cachedSlice->image_)); } @@ -286,6 +319,6 @@ } // re-emit original Layer message to observers - EmitMessage(message); +// EmitMessage(message); } }