# HG changeset patch # User Sebastien Jodogne # Date 1541956670 -3600 # Node ID 5d359b115b298fc5d7aec8557d44f5bbdc45c390 # Parent 3942123602bae12eb281a13875572b470ae6e1ab use of callables in OrthancVolumeImage diff -r 3942123602ba -r 5d359b115b29 Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp --- a/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp Sun Nov 11 17:50:11 2018 +0100 +++ b/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp Sun Nov 11 18:17:50 2018 +0100 @@ -170,7 +170,8 @@ void SimpleViewerApplication::OnWidgetGeometryChanged(const SliceViewerWidget::GeometryChangedMessage& message) { - message.GetOrigin().FitContent(); + // TODO: The "const_cast" could probably be replaced by "mainWidget_" + const_cast(message.GetOrigin()).FitContent(); } void SimpleViewerApplication::SelectSeriesInMainViewport(const std::string& seriesId) diff -r 3942123602ba -r 5d359b115b29 Applications/Samples/SimpleViewerApplicationSingleFile.h --- a/Applications/Samples/SimpleViewerApplicationSingleFile.h Sun Nov 11 17:50:11 2018 +0100 +++ b/Applications/Samples/SimpleViewerApplicationSingleFile.h Sun Nov 11 18:17:50 2018 +0100 @@ -407,7 +407,8 @@ void OnWidgetGeometryChanged(const SliceViewerWidget::GeometryChangedMessage& message) { - message.GetOrigin().FitContent(); + // TODO: The "const_cast" could probably be replaced by "mainWidget" + const_cast(message.GetOrigin()).FitContent(); } void SelectSeriesInMainViewport(const std::string& seriesId) diff -r 3942123602ba -r 5d359b115b29 Framework/Messages/IMessage.h --- a/Framework/Messages/IMessage.h Sun Nov 11 17:50:11 2018 +0100 +++ b/Framework/Messages/IMessage.h Sun Nov 11 18:17:50 2018 +0100 @@ -89,16 +89,16 @@ class OriginMessage : public BaseMessage { private: - TOrigin& origin_; + const TOrigin& origin_; public: - OriginMessage(TOrigin& origin) : + OriginMessage(const TOrigin& origin) : BaseMessage(), origin_(origin) { } - TOrigin& GetOrigin() const + const TOrigin& GetOrigin() const { return origin_; } diff -r 3942123602ba -r 5d359b115b29 Framework/SmartLoader.cpp --- a/Framework/SmartLoader.cpp Sun Nov 11 17:50:11 2018 +0100 +++ b/Framework/SmartLoader.cpp Sun Nov 11 18:17:50 2018 +0100 @@ -224,7 +224,8 @@ void SmartLoader::OnLayerGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message) { - DicomSeriesVolumeSlicer& source = dynamic_cast(message.GetOrigin()); + const DicomSeriesVolumeSlicer& source = + dynamic_cast(message.GetOrigin()); // save/replace the slice in cache const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() @@ -269,7 +270,9 @@ void SmartLoader::OnLayerReady(const IVolumeSlicer::LayerReadyMessage& message) { - DicomSeriesVolumeSlicer& source = dynamic_cast(message.GetOrigin()); + const DicomSeriesVolumeSlicer& source = + dynamic_cast(message.GetOrigin()); + const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ? std::string sliceKeyId = (slice.GetOrthancInstanceId() + ":" + boost::lexical_cast(slice.GetFrame())); diff -r 3942123602ba -r 5d359b115b29 Framework/Toolbox/OrthancSlicesLoader.cpp --- a/Framework/Toolbox/OrthancSlicesLoader.cpp Sun Nov 11 17:50:11 2018 +0100 +++ b/Framework/Toolbox/OrthancSlicesLoader.cpp Sun Nov 11 18:17:50 2018 +0100 @@ -175,14 +175,16 @@ void OrthancSlicesLoader::NotifySliceImageSuccess(const Operation& operation, const Orthanc::ImageAccessor& image) { - OrthancSlicesLoader::SliceImageReadyMessage msg(operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); + OrthancSlicesLoader::SliceImageReadyMessage msg + (*this, operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); EmitMessage(msg); } void OrthancSlicesLoader::NotifySliceImageError(const Operation& operation) { - OrthancSlicesLoader::SliceImageErrorMessage msg(operation.GetSliceIndex(), operation.GetSlice(), operation.GetQuality()); + OrthancSlicesLoader::SliceImageErrorMessage msg + (*this, operation.GetSliceIndex(), operation.GetSlice(), operation.GetQuality()); EmitMessage(msg); } diff -r 3942123602ba -r 5d359b115b29 Framework/Toolbox/OrthancSlicesLoader.h --- a/Framework/Toolbox/OrthancSlicesLoader.h Sun Nov 11 17:50:11 2018 +0100 +++ b/Framework/Toolbox/OrthancSlicesLoader.h Sun Nov 11 18:17:50 2018 +0100 @@ -39,7 +39,8 @@ typedef OriginMessage SliceGeometryReadyMessage; typedef OriginMessage SliceGeometryErrorMessage; - class SliceImageReadyMessage : public BaseMessage + class SliceImageReadyMessage : + public OriginMessage { private: unsigned int sliceIndex_; @@ -48,10 +49,12 @@ SliceImageQuality effectiveQuality_; public: - SliceImageReadyMessage(unsigned int sliceIndex, + SliceImageReadyMessage(const OrthancSlicesLoader& origin, + unsigned int sliceIndex, const Slice& slice, const Orthanc::ImageAccessor& image, SliceImageQuality effectiveQuality) : + OriginMessage(origin), sliceIndex_(sliceIndex), slice_(slice), image_(image), @@ -81,7 +84,8 @@ }; - class SliceImageErrorMessage : public BaseMessage + class SliceImageErrorMessage : + public OriginMessage { private: const Slice& slice_; @@ -89,9 +93,11 @@ SliceImageQuality effectiveQuality_; public: - SliceImageErrorMessage(unsigned int sliceIndex, + SliceImageErrorMessage(const OrthancSlicesLoader& origin, + unsigned int sliceIndex, const Slice& slice, SliceImageQuality effectiveQuality) : + OriginMessage(origin), slice_(slice), sliceIndex_(sliceIndex), effectiveQuality_(effectiveQuality) diff -r 3942123602ba -r 5d359b115b29 Framework/dev.h --- a/Framework/dev.h Sun Nov 11 17:50:11 2018 +0100 +++ b/Framework/dev.h Sun Nov 11 18:17:50 2018 +0100 @@ -106,18 +106,20 @@ } - void OnSliceGeometryReady(const OrthancSlicesLoader& loader) + void OnSliceGeometryReady(const OrthancSlicesLoader::SliceGeometryReadyMessage& message) { - if (loader.GetSliceCount() == 0) + assert(&message.GetOrigin() == &loader_); + + if (loader_.GetSliceCount() == 0) { LOG(ERROR) << "Empty volume image"; EmitMessage(ISlicedVolume::GeometryErrorMessage(*this)); return; } - for (size_t i = 1; i < loader.GetSliceCount(); i++) + for (size_t i = 1; i < loader_.GetSliceCount(); i++) { - if (!IsCompatible(loader.GetSlice(0), loader.GetSlice(i))) + if (!IsCompatible(loader_.GetSlice(0), loader_.GetSlice(i))) { EmitMessage(ISlicedVolume::GeometryErrorMessage(*this)); return; @@ -126,9 +128,9 @@ double spacingZ; - if (loader.GetSliceCount() > 1) + if (loader_.GetSliceCount() > 1) { - spacingZ = GetDistance(loader.GetSlice(0), loader.GetSlice(1)); + spacingZ = GetDistance(loader_.GetSlice(0), loader_.GetSlice(1)); } else { @@ -137,9 +139,9 @@ spacingZ = 1; } - for (size_t i = 1; i < loader.GetSliceCount(); i++) + for (size_t i = 1; i < loader_.GetSliceCount(); i++) { - if (!LinearAlgebra::IsNear(spacingZ, GetDistance(loader.GetSlice(i - 1), loader.GetSlice(i)), + if (!LinearAlgebra::IsNear(spacingZ, GetDistance(loader_.GetSlice(i - 1), loader_.GetSlice(i)), 0.001 /* this is expressed in mm */)) { LOG(ERROR) << "The distance between successive slices is not constant in a volume image"; @@ -148,20 +150,20 @@ } } - unsigned int width = loader.GetSlice(0).GetWidth(); - unsigned int height = loader.GetSlice(0).GetHeight(); - Orthanc::PixelFormat format = loader.GetSlice(0).GetConverter().GetExpectedPixelFormat(); + unsigned int width = loader_.GetSlice(0).GetWidth(); + unsigned int height = loader_.GetSlice(0).GetHeight(); + Orthanc::PixelFormat format = loader_.GetSlice(0).GetConverter().GetExpectedPixelFormat(); LOG(INFO) << "Creating a volume image of size " << width << "x" << height - << "x" << loader.GetSliceCount() << " in " << Orthanc::EnumerationToString(format); + << "x" << loader_.GetSliceCount() << " in " << Orthanc::EnumerationToString(format); - image_.reset(new ImageBuffer3D(format, width, height, loader.GetSliceCount(), computeRange_)); - image_->SetAxialGeometry(loader.GetSlice(0).GetGeometry()); - image_->SetVoxelDimensions(loader.GetSlice(0).GetPixelSpacingX(), - loader.GetSlice(0).GetPixelSpacingY(), spacingZ); + image_.reset(new ImageBuffer3D(format, width, height, loader_.GetSliceCount(), computeRange_)); + image_->SetAxialGeometry(loader_.GetSlice(0).GetGeometry()); + image_->SetVoxelDimensions(loader_.GetSlice(0).GetPixelSpacingX(), + loader_.GetSlice(0).GetPixelSpacingY(), spacingZ); image_->Clear(); - downloadStack_.reset(new DownloadStack(loader.GetSliceCount())); - pendingSlices_ = loader.GetSliceCount(); + downloadStack_.reset(new DownloadStack(loader_.GetSliceCount())); + pendingSlices_ = loader_.GetSliceCount(); for (unsigned int i = 0; i < 4; i++) // Limit to 4 simultaneous downloads { @@ -173,18 +175,27 @@ EmitMessage(ISlicedVolume::GeometryReadyMessage(*this)); } - void OnSliceImageReady(const OrthancSlicesLoader& loader, - unsigned int sliceIndex, - const Slice& slice, - const Orthanc::ImageAccessor& image, - SliceImageQuality quality) + + void OnSliceGeometryError(const OrthancSlicesLoader::SliceGeometryErrorMessage& message) { + assert(&message.GetOrigin() == &loader_); + + LOG(ERROR) << "Unable to download a volume image"; + EmitMessage(ISlicedVolume::GeometryErrorMessage(*this)); + } + + + void OnSliceImageReady(const OrthancSlicesLoader::SliceImageReadyMessage& message) + { + assert(&message.GetOrigin() == &loader_); + { - ImageBuffer3D::SliceWriter writer(*image_, VolumeProjection_Axial, sliceIndex); - Orthanc::ImageProcessing::Copy(writer.GetAccessor(), image); + ImageBuffer3D::SliceWriter writer(*image_, VolumeProjection_Axial, message.GetSliceIndex()); + Orthanc::ImageProcessing::Copy(writer.GetAccessor(), message.GetImage()); } - EmitMessage(ISlicedVolume::SliceContentChangedMessage(*this, sliceIndex, slice)); + EmitMessage(ISlicedVolume::SliceContentChangedMessage + (*this, message.GetSliceIndex(), message.GetSlice())); if (pendingSlices_ == 1) { @@ -199,45 +210,16 @@ ScheduleSliceDownload(); } - virtual void HandleMessage(const IObservable& from, const IMessage& message) + + void OnSliceImageError(const OrthancSlicesLoader::SliceImageErrorMessage& message) { - switch (message.GetType()) - { - case MessageType_SliceLoader_GeometryReady: - OnSliceGeometryReady(dynamic_cast(from)); - break; - - case MessageType_SliceLoader_GeometryError: - LOG(ERROR) << "Unable to download a volume image"; - EmitMessage(ISlicedVolume::GeometryErrorMessage(*this)); - break; - - case MessageType_SliceLoader_ImageReady: - { - const OrthancSlicesLoader::SliceImageReadyMessage& msg = - dynamic_cast(message); - OnSliceImageReady(dynamic_cast(from), - msg.GetSliceIndex(), - msg.GetSlice(), - msg.GetImage(), - msg.GetEffectiveQuality()); - break; - } - - case MessageType_SliceLoader_ImageError: - { - const OrthancSlicesLoader::SliceImageErrorMessage& msg = - dynamic_cast(message); - LOG(ERROR) << "Cannot download slice " << msg.GetSliceIndex() << " in a volume image"; - ScheduleSliceDownload(); - break; - } - - default: - VLOG("unhandled message type" << message.GetType()); - } + assert(&message.GetOrigin() == &loader_); + + LOG(ERROR) << "Cannot download slice " << message.GetSliceIndex() << " in a volume image"; + ScheduleSliceDownload(); } + public: OrthancVolumeImage(MessageBroker& broker, OrthancApiClient& orthanc, @@ -248,7 +230,21 @@ computeRange_(computeRange), pendingSlices_(0) { - // TODO: replace with new callables loader_.RegisterObserver(*this); + loader_.RegisterObserverCallback( + new Callable + (*this, &OrthancVolumeImage::OnSliceGeometryReady)); + + loader_.RegisterObserverCallback( + new Callable + (*this, &OrthancVolumeImage::OnSliceGeometryError)); + + loader_.RegisterObserverCallback( + new Callable + (*this, &OrthancVolumeImage::OnSliceImageReady)); + + loader_.RegisterObserverCallback( + new Callable + (*this, &OrthancVolumeImage::OnSliceImageError)); } void ScheduleLoadSeries(const std::string& seriesId) diff -r 3942123602ba -r 5d359b115b29 TODO --- a/TODO Sun Nov 11 17:50:11 2018 +0100 +++ b/TODO Sun Nov 11 18:17:50 2018 +0100 @@ -45,7 +45,6 @@ Source code cosmetics --------------------- -* Remove #include "OrthancException.h" in "ObserversRegistry.h" * Use "SampleInteractor::AddWidget()" in all samples