Mercurial > hg > orthanc-stone
changeset 270:2d64f4d39610 am-2
backup (work in progress)
author | am@osimis.io |
---|---|
date | Thu, 23 Aug 2018 14:45:04 +0200 |
parents | 0dfa83535cd7 |
children | 46c5296d867e |
files | Applications/Samples/SimpleViewerApplication.h Framework/Messages/MessageType.h Framework/SmartLoader.cpp Framework/SmartLoader.h Framework/Toolbox/OrthancApiClient.cpp Framework/Toolbox/OrthancApiClient.h Resources/CMake/OrthancStoneConfiguration.cmake |
diffstat | 7 files changed, 438 insertions(+), 114 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/Samples/SimpleViewerApplication.h Wed Aug 22 15:22:33 2018 +0200 +++ b/Applications/Samples/SimpleViewerApplication.h Thu Aug 23 14:45:04 2018 +0200 @@ -122,82 +122,21 @@ }; - // void OffsetSlice(int offset) - // { - // if (source_ != NULL) - // { - // int slice = static_cast<int>(slice_) + offset; - - // if (slice < 0) - // { - // slice = 0; - // } - - // if (slice >= static_cast<int>(source_->GetSliceCount())) - // { - // slice = source_->GetSliceCount() - 1; - // } - - // if (slice != static_cast<int>(slice_)) - // { - // SetSlice(slice); - // } - // } - // } - - - // void SetSlice(size_t index) - // { - // if (source_ != NULL && - // index < source_->GetSliceCount()) - // { - // slice_ = index; - - //#if 1 - // widget_->SetSlice(source_->GetSlice(slice_).GetGeometry()); - //#else - // // TEST for scene extents - Rotate the axes - // double a = 15.0 / 180.0 * M_PI; - - //#if 1 - // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); - // Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0); - //#else - // // Flip the normal - // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); - // Vector y; GeometryToolbox::AssignVector(y, sin(a), -cos(a), 0); - //#endif - - // SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y); - // widget_->SetSlice(s); - //#endif - // } - // } - - - virtual void HandleMessage(IObservable& from, const IMessage& message) { - switch (message.GetType()) { - case MessageType_Widget_GeometryChanged: - dynamic_cast<LayerWidget&>(from).SetDefaultView(); - break; - default: - VLOG("unhandled message type" << message.GetType()); - } - } - std::unique_ptr<Interactor> interactor_; LayoutWidget* mainLayout_; LayoutWidget* thumbnailsLayout_; LayerWidget* mainViewport_; std::vector<LayerWidget*> thumbnails_; std::vector<std::string> instances_; + unsigned int currentInstanceIndex_; - OrthancStone::WidgetViewport* wasmViewport1_; - OrthancStone::WidgetViewport* wasmViewport2_; + OrthancStone::WidgetViewport* wasmViewport1_; + OrthancStone::WidgetViewport* wasmViewport2_; IStatusBar* statusBar_; unsigned int slice_; std::unique_ptr<SmartLoader> smartLoader_; + std::unique_ptr<OrthancApiClient> orthancApiClient_; public: SimpleViewerApplication(MessageBroker& broker) : @@ -210,6 +149,10 @@ { DeclareIgnoredMessage(MessageType_Widget_ContentChanged); DeclareHandledMessage(MessageType_Widget_GeometryChanged); + + DeclareHandledMessage(MessageType_OrthancApi_GetStudyIds_Ready); + DeclareHandledMessage(MessageType_OrthancApi_GetStudy_Ready); + DeclareHandledMessage(MessageType_OrthancApi_GetSeries_Ready); } virtual void Finalize() {} @@ -221,10 +164,8 @@ generic.add_options() // ("study", boost::program_options::value<std::string>(), // "Orthanc ID of the study") - ("instance1", boost::program_options::value<std::string>(), - "Orthanc ID of the instances") - ("instance2", boost::program_options::value<std::string>(), - "Orthanc ID of the instances") + ("studyId", boost::program_options::value<std::string>(), + "Orthanc ID of the study") ; options.add(generic); @@ -238,58 +179,123 @@ context_ = context; statusBar_ = &statusBar; + + {// initialize viewports and layout + mainLayout_ = new LayoutWidget(); + mainLayout_->SetPadding(10); + mainLayout_->SetBackgroundCleared(true); + mainLayout_->SetBackgroundColor(0, 0, 0); + mainLayout_->SetHorizontal(); + + thumbnailsLayout_ = new LayoutWidget(); + thumbnailsLayout_->SetPadding(10); + thumbnailsLayout_->SetBackgroundCleared(true); + thumbnailsLayout_->SetBackgroundColor(50, 50, 50); + thumbnailsLayout_->SetVertical(); + + mainViewport_ = new LayerWidget(broker_); + mainViewport_->RegisterObserver(*this); + + // hierarchy + mainLayout_->AddWidget(thumbnailsLayout_); + mainLayout_->AddWidget(mainViewport_); + + // sources + smartLoader_.reset(new SmartLoader(broker_, context_->GetWebService())); + smartLoader_->SetImageQuality(SliceImageQuality_FullPam); + +// mainViewport_->AddLayer(smartLoader_->GetFrame(instances_[currentInstanceIndex_], 0)); +// thumbnails_[0]->AddLayer(smartLoader_->GetFrame(instances_[0], 0)); +// thumbnails_[1]->AddLayer(smartLoader_->GetFrame(instances_[1], 0)); + + mainLayout_->SetTransmitMouseOver(true); + interactor_.reset(new Interactor(*this)); + mainViewport_->SetInteractor(*interactor_); + } + statusBar.SetMessage("Use the key \"s\" to reinitialize the layout"); statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport"); - if (parameters.count("instance1") < 1) + orthancApiClient_.reset(new OrthancApiClient(broker_, context_->GetWebService())); + + if (parameters.count("studyId") < 1) { - LOG(ERROR) << "The instance ID is missing"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc"; + orthancApiClient_->ScheduleGetStudyIds(*this); } - if (parameters.count("instance2") < 1) + else { - LOG(ERROR) << "The instance ID is missing"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + SelectStudy(parameters["studyId"].as<std::string>()); } - instances_.push_back(parameters["instance1"].as<std::string>()); - instances_.push_back(parameters["instance2"].as<std::string>()); + } - mainLayout_ = new LayoutWidget(); - mainLayout_->SetPadding(10); - mainLayout_->SetBackgroundCleared(true); - mainLayout_->SetBackgroundColor(0, 0, 0); - mainLayout_->SetHorizontal(); - - thumbnailsLayout_ = new LayoutWidget(); - thumbnailsLayout_->SetPadding(10); - thumbnailsLayout_->SetBackgroundCleared(true); - thumbnailsLayout_->SetBackgroundColor(50, 50, 50); - thumbnailsLayout_->SetVertical(); + void OnStudyListReceived(const Json::Value& response) + { + if (response.isArray() && response.size() > 1) + { + SelectStudy(response[0].asString()); + } + } + void OnStudyReceived(const Json::Value& response) + { + if (response.isObject() && response["Series"].isArray()) + { + for (size_t i=0; i < response["Series"].size(); i++) + { + orthancApiClient_->ScheduleGetSeries(*this, response["Series"][(int)i].asString()); + } + } + } - mainViewport_ = new LayerWidget(broker_); - thumbnails_.push_back(new LayerWidget(broker_)); - thumbnails_.push_back(new LayerWidget(broker_)); - mainViewport_->RegisterObserver(*this); - thumbnails_[0]->RegisterObserver(*this); - thumbnails_[1]->RegisterObserver(*this); + void OnSeriesReceived(const Json::Value& response) + { + if (response.isObject() && response["Instances"].isArray() && response["Instances"].size() > 0) + { + LoadThumbnailForSeries(response["ID"].asString(), response["Instances"][0].asString()); + } + //TODO: create layout and start loading frames + //mainViewport_->AddLayer(smartLoader_->GetFrame(instances_[currentInstanceIndex_], 0)); + //thumbnails_[0]->AddLayer(smartLoader_->GetFrame(instances_[0], 0)); + //thumbnails_[1]->AddLayer(smartLoader_->GetFrame(instances_[1], 0)); + } + + void LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId) + { + LayerWidget* thumbnailWidget = new LayerWidget(broker_); + thumbnailWidget->RegisterObserver(*this); + thumbnailWidget->AddLayer(smartLoader_->GetFrame(instanceId, 0)); + thumbnailsLayout_->AddWidget(thumbnailWidget); + thumbnails_.push_back(thumbnailWidget); + } - // hierarchy - mainLayout_->AddWidget(thumbnailsLayout_); - mainLayout_->AddWidget(mainViewport_); - thumbnailsLayout_->AddWidget(thumbnails_[0]); - thumbnailsLayout_->AddWidget(thumbnails_[1]); + void SelectStudy(const std::string& studyId) + { + orthancApiClient_->ScheduleGetStudy(*this, studyId); + } + + void LoadSeries(const std::vector<std::string>& seriesIds) + { +// instances_.push_back(parameters["studyId"].as<std::string>()); +// instances_.push_back(parameters["instance2"].as<std::string>()); + } - // sources - smartLoader_.reset(new SmartLoader(broker_, context_->GetWebService())); - smartLoader_->SetImageQuality(SliceImageQuality_FullPam); - - mainViewport_->AddLayer(smartLoader_->GetFrame(instances_[currentInstanceIndex_], 0)); - thumbnails_[0]->AddLayer(smartLoader_->GetFrame(instances_[0], 0)); - thumbnails_[1]->AddLayer(smartLoader_->GetFrame(instances_[1], 0)); - - mainLayout_->SetTransmitMouseOver(true); - interactor_.reset(new Interactor(*this)); - mainViewport_->SetInteractor(*interactor_); + virtual void HandleMessage(IObservable& from, const IMessage& message) { + switch (message.GetType()) { + case MessageType_Widget_GeometryChanged: + dynamic_cast<LayerWidget&>(from).SetDefaultView(); + break; + case MessageType_OrthancApi_GetStudyIds_Ready: + OnStudyListReceived(dynamic_cast<const OrthancApiClient::GetJsonResponseReadyMessage&>(message).response_); + break; + case MessageType_OrthancApi_GetSeries_Ready: + OnSeriesReceived(dynamic_cast<const OrthancApiClient::GetJsonResponseReadyMessage&>(message).response_); + break; + case MessageType_OrthancApi_GetStudy_Ready: + OnStudyReceived(dynamic_cast<const OrthancApiClient::GetJsonResponseReadyMessage&>(message).response_); + break; + default: + VLOG("unhandled message type" << message.GetType()); + } } #if ORTHANC_ENABLE_SDL==0
--- a/Framework/Messages/MessageType.h Wed Aug 22 15:22:33 2018 +0200 +++ b/Framework/Messages/MessageType.h Thu Aug 23 14:45:04 2018 +0200 @@ -41,6 +41,12 @@ MessageType_HttpRequestSuccess, MessageType_HttpRequestError, + MessageType_OrthancApi_InternalGetJsonResponseReady, + MessageType_OrthancApi_InternalGetJsonResponseError, + + MessageType_OrthancApi_GetStudyIds_Ready, + MessageType_OrthancApi_GetStudy_Ready, + MessageType_OrthancApi_GetSeries_Ready, // used in unit tests only MessageType_Test1,
--- a/Framework/SmartLoader.cpp Wed Aug 22 15:22:33 2018 +0200 +++ b/Framework/SmartLoader.cpp Thu Aug 23 14:45:04 2018 +0200 @@ -29,13 +29,17 @@ IObservable(broker), IObserver(broker), imageQuality_(SliceImageQuality_FullPam), - webService_(webService) + webService_(webService), + orthancApiClient_(broker, webService) { DeclareHandledMessage(MessageType_LayerSource_GeometryReady); DeclareHandledMessage(MessageType_LayerSource_LayerReady); DeclareIgnoredMessage(MessageType_LayerSource_GeometryError); DeclareIgnoredMessage(MessageType_LayerSource_ContentChanged); DeclareIgnoredMessage(MessageType_LayerSource_SliceChanged); + +// DeclareHandledMessage(MessageType_OrthancApi_InternalGetJsonResponseReady); +// DeclareIgnoredMessage(MessageType_OrthancApi_InternalGetJsonResponseError); } void SmartLoader::HandleMessage(IObservable& from, const IMessage& message) @@ -51,6 +55,12 @@ const OrthancFrameLayerSource* layerSource=dynamic_cast<const OrthancFrameLayerSource*>(&from); // TODO keep track of objects that have been loaded already }; break; +// case MessageType_OrthancApi_GetStudyIds_Ready: +// { + +// const OrthancApiClient::GetJsonResponseReadyMessage& msg = dynamic_cast<OrthancApiClient::GetJsonResponseReadyMessage&>(message); + +// }; break; default: VLOG("unhandled message type" << message.GetType()); } @@ -75,6 +85,10 @@ return layerSource.release(); } + void SmartLoader::LoadStudyList() + { +// orthancApiClient_.ScheduleGetJsonRequest("/studies"); + } void PreloadStudy(const std::string studyId) {
--- a/Framework/SmartLoader.h Wed Aug 22 15:22:33 2018 +0200 +++ b/Framework/SmartLoader.h Thu Aug 23 14:45:04 2018 +0200 @@ -24,15 +24,17 @@ #include "Layers/ILayerSource.h" #include "Messages/IObservable.h" #include "../Platforms/Generic/OracleWebService.h" +#include "Toolbox/OrthancApiClient.h" namespace OrthancStone { class SmartLoader : public IObservable, IObserver { - SliceImageQuality imageQuality_; - IWebService& webService_; + SliceImageQuality imageQuality_; + IWebService& webService_; + OrthancApiClient orthancApiClient_; - + int studyListRequest_; public: SmartLoader(MessageBroker& broker, IWebService& webService); // TODO: add maxPreloadStorageSizeInBytes @@ -40,6 +42,7 @@ void PreloadStudy(const std::string studyId); void PreloadSeries(const std::string seriesId); + void LoadStudyList(); void SetImageQuality(SliceImageQuality imageQuality) { imageQuality_ = imageQuality; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/OrthancApiClient.cpp Thu Aug 23 14:45:04 2018 +0200 @@ -0,0 +1,204 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "OrthancApiClient.h" + +#include "MessagingToolbox.h" +#include <Core/OrthancException.h> + +namespace OrthancStone { + + struct OrthancApiClient::InternalGetJsonResponseReadyMessage : + public IMessage + { + OrthancApiClient::BaseRequest* request_; + Json::Value response_; + + InternalGetJsonResponseReadyMessage(OrthancApiClient::BaseRequest* request, + const Json::Value& response) + : IMessage(MessageType_OrthancApi_InternalGetJsonResponseReady), + request_(request), + response_(response) + { + } + + }; + + struct OrthancApiClient::InternalGetJsonResponseErrorMessage : + public IMessage + { + OrthancApiClient::BaseRequest* request_; + + InternalGetJsonResponseErrorMessage(OrthancApiClient::BaseRequest* request) + : IMessage(MessageType_OrthancApi_InternalGetJsonResponseError), + request_(request) + { + } + }; + + + // this class handles a single request to the OrthancApiClient. + // Once the response is ready, it will emit a message to the responseObserver + // the responseObserver must handle only that message (and not all messages from the OrthancApiClient) + class OrthancApiClient::BaseRequest: + public IObserver, + public IObservable, + public Orthanc::IDynamicObject + { + public: + std::string uri_; + OrthancApiClient& orthanc_; + MessageType messageToEmitWhenResponseReady_; + OrthancApiClient::Mode mode_; + + public: + BaseRequest( + OrthancApiClient& orthanc, + IObserver& responseObserver, + const std::string& uri, + MessageType messageToEmitWhenResponseReady, + OrthancApiClient::Mode mode) + : IObserver(orthanc.broker_), + IObservable(orthanc.broker_), + uri_(uri), + orthanc_(orthanc), + messageToEmitWhenResponseReady_(messageToEmitWhenResponseReady), + mode_(mode) + { + // this object will emit only a single message, the one the final responseObserver is expecting + DeclareEmittableMessage(messageToEmitWhenResponseReady); + + // this object is observing the OrthancApi so it must handle all messages + DeclareHandledMessage(MessageType_OrthancApi_InternalGetJsonResponseReady); + DeclareIgnoredMessage(MessageType_OrthancApi_InternalGetJsonResponseError); + + orthanc_.RegisterObserver(*this); + this->RegisterObserver(responseObserver); + } + virtual ~BaseRequest() {} + + // mainly maps OrthancApi internal messages to a message that is expected by the responseObserver + virtual void HandleMessage(IObservable& from, const IMessage& message) + { + switch (message.GetType()) + { + case MessageType_OrthancApi_InternalGetJsonResponseReady: + { + const OrthancApiClient::InternalGetJsonResponseReadyMessage& messageReceived = dynamic_cast<const OrthancApiClient::InternalGetJsonResponseReadyMessage&>(message); + EmitMessage(OrthancApiClient::GetJsonResponseReadyMessage(messageToEmitWhenResponseReady_, messageReceived.request_->uri_, messageReceived.response_)); + orthanc_.ReleaseRequest(messageReceived.request_); + }; break; + default: + throw MessageNotDeclaredException(message.GetType()); + } + } + + }; + + + class OrthancApiClient::WebCallback : public IWebService::ICallback + { + private: + OrthancApiClient& that_; + + public: + WebCallback(MessageBroker& broker, OrthancApiClient& that) : + IWebService::ICallback(broker), + that_(that) + { + } + + virtual void OnHttpRequestSuccess(const std::string& uri, + const void* answer, + size_t answerSize, + Orthanc::IDynamicObject* payload) + { + OrthancApiClient::BaseRequest* request = dynamic_cast<OrthancApiClient::BaseRequest*>(payload); // the BaseRequests objects belongs to the OrthancApiClient and is deleted in ReleaseRequest when it has been "consumed" + + switch (request->mode_) + { + case OrthancApiClient::Mode_GetJson: + { + Json::Value response; + if (MessagingToolbox::ParseJson(response, answer, answerSize)) + { + OrthancApiClient::InternalGetJsonResponseReadyMessage msg(request, response); + that_.EmitMessage(msg); + } + else + { + OrthancApiClient::InternalGetJsonResponseErrorMessage msg(request); + that_.EmitMessage(msg); + } + }; break; + + default: + that_.ReleaseRequest(request); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + virtual void OnHttpRequestError(const std::string& uri, + Orthanc::IDynamicObject* payload) + { + OrthancApiClient::BaseRequest* request = dynamic_cast<OrthancApiClient::BaseRequest*>(payload); // the BaseRequests objects belongs to the OrthancApiClient and is deleted in ReleaseRequest when it has been "consumed" + + switch (request->mode_) + { + case OrthancApiClient::Mode_GetJson: + { + OrthancApiClient::InternalGetJsonResponseErrorMessage msg(request); + that_.EmitMessage(msg); + }; break; + + default: + that_.ReleaseRequest(request); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + }; + + OrthancApiClient::OrthancApiClient(MessageBroker &broker, IWebService &orthanc) + : IObservable(broker), + orthanc_(orthanc), + webCallback_(new OrthancApiClient::WebCallback(broker, *this)) + { + DeclareEmittableMessage(MessageType_OrthancApi_InternalGetJsonResponseReady); + DeclareEmittableMessage(MessageType_OrthancApi_InternalGetJsonResponseError); + } + + void OrthancApiClient::ScheduleGetJsonRequest(IObserver &responseObserver, const std::string &uri, MessageType messageToEmitWhenResponseReady) + { + OrthancApiClient::BaseRequest* request = new OrthancApiClient::BaseRequest(*this, + responseObserver, + uri, + messageToEmitWhenResponseReady, + OrthancApiClient::Mode_GetJson); + orthanc_.ScheduleGetRequest(*webCallback_, uri, IWebService::Headers(), request); + requestsInProgress_.insert(request); + } + + void OrthancApiClient::ReleaseRequest(BaseRequest* request) + { + requestsInProgress_.erase(request); + delete request; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/OrthancApiClient.h Thu Aug 23 14:45:04 2018 +0200 @@ -0,0 +1,90 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <json/json.h> + +#include "IWebService.h" +#include "../Messages/IObservable.h" + + +namespace OrthancStone +{ + class OrthancApiClient: + public IObservable + { + protected: + class BaseRequest; + class GetJsonRequest; + + struct InternalGetJsonResponseReadyMessage; + struct InternalGetJsonResponseErrorMessage; + + public: + struct GetJsonResponseReadyMessage : public IMessage + { + Json::Value response_; + std::string uri_; + + GetJsonResponseReadyMessage(MessageType messageType, + const std::string& uri, + const Json::Value& response) + : IMessage(messageType), + uri_(uri), + response_(response) + { + } + }; + + public: + + enum Mode + { + Mode_GetJson + }; + + protected: + IWebService& orthanc_; + class WebCallback; + boost::shared_ptr<WebCallback> webCallback_; // This is a PImpl pattern + std::set<BaseRequest*> requestsInProgress_; + +// int ScheduleGetJsonRequest(const std::string& uri); + + void ReleaseRequest(BaseRequest* request); + + public: + OrthancApiClient(MessageBroker& broker, + IWebService& orthanc); + virtual ~OrthancApiClient() {} + + // schedule a GET request expecting a JSON request. + // once the response is ready, it will emit a OrthancApiClient::GetJsonResponseReadyMessage message whose messageType is specified in the call + void ScheduleGetJsonRequest(IObserver& responseObserver, const std::string& uri, MessageType messageToEmitWhenResponseReady); + + void ScheduleGetStudyIds(IObserver& responseObserver) {ScheduleGetJsonRequest(responseObserver, "/studies", MessageType_OrthancApi_GetStudyIds_Ready);} + void ScheduleGetStudy(IObserver& responseObserver, const std::string& studyId) {ScheduleGetJsonRequest(responseObserver, "/studies/" + studyId, MessageType_OrthancApi_GetStudy_Ready);} + void ScheduleGetSeries(IObserver& responseObserver, const std::string& seriesId) {ScheduleGetJsonRequest(responseObserver, "/series/" + seriesId, MessageType_OrthancApi_GetSeries_Ready);} + + }; +}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Wed Aug 22 15:22:33 2018 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Thu Aug 23 14:45:04 2018 +0200 @@ -209,6 +209,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Toolbox/MessagingToolbox.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrientedBoundingBox.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrthancSlicesLoader.cpp + ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrthancApiClient.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlices.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlicesCursor.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ShearWarpProjectiveTransform.cpp