# HG changeset patch # User Sebastien Jodogne # Date 1448657121 -3600 # Node ID f5b1a9267da07c8dc90a54ee5aaca85e21d017ac # Parent 46ec13a1177c3e8dd5944d3830350f76332695f9 remove unused classes diff -r 46ec13a1177c -r f5b1a9267da0 CMakeLists.txt --- a/CMakeLists.txt Fri Nov 27 21:39:41 2015 +0100 +++ b/CMakeLists.txt Fri Nov 27 21:45:21 2015 +0100 @@ -152,10 +152,7 @@ ${CMAKE_SOURCE_DIR}/Plugin/Cache/CacheManager.cpp ${CMAKE_SOURCE_DIR}/Plugin/Cache/CacheScheduler.cpp ${CMAKE_SOURCE_DIR}/Plugin/ViewerToolbox.cpp - ${CMAKE_SOURCE_DIR}/Plugin/SeriesVolumeSorter.cpp ${CMAKE_SOURCE_DIR}/Plugin/ViewerPrefetchPolicy.cpp - ${CMAKE_SOURCE_DIR}/Plugin/InstanceInformation.cpp - ${CMAKE_SOURCE_DIR}/Plugin/InstanceInformationAdapter.cpp ${CMAKE_SOURCE_DIR}/Plugin/SeriesInformationAdapter.cpp ) diff -r 46ec13a1177c -r f5b1a9267da0 NEWS --- a/NEWS Fri Nov 27 21:39:41 2015 +0100 +++ b/NEWS Fri Nov 27 21:45:21 2015 +0100 @@ -3,12 +3,12 @@ => Minimum SDK version: 0.9.5 <= +* Support of multi-frame images * The GDCM decoder replaces the built-in Orthanc decoder +TODO : ViewerPrefetchPolicy::ApplyInstance => problem in prefetching, seems down TODO : Support cine and multi-frame images TODO : Interpolation does not work, at least with Firefox -TODO : Remove CacheBundle_InstanceInformation -TODO : ViewerPrefetchPolicy::ApplyInstance => problem in prefetching, seems down Version 1.3 (2015-11-27) diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/InstanceInformation.cpp --- a/Plugin/InstanceInformation.cpp Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#include "InstanceInformation.h" - -#include "../Orthanc/Core/OrthancException.h" - -#include -#include -#include -#include -#include - - -namespace OrthancPlugins -{ - void InstanceInformation::SetPosition(const std::vector& normal, - const std::vector& position) - { - if (normal.size() != 3 || - position.size() != 3) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType); - } - - hasPosition_ = true; - memcpy(normal_, &normal[0], sizeof(float) * 3); - memcpy(position_, &position[0], sizeof(float) * 3); - } - - void InstanceInformation::SetIndexInSeries(int index) - { - hasIndex_ = true; - index_ = index; - } - - float InstanceInformation::GetPosition(size_t i) const - { - assert(hasPosition_ && i < 3); - return position_[i]; - } - - float InstanceInformation::GetNormal(size_t i) const - { - assert(hasPosition_ && i < 3); - return normal_[i]; - } - - int InstanceInformation::GetIndexInSeries() const - { - assert(hasIndex_); - return index_; - } - - void InstanceInformation::Serialize(std::string& result) const - { - Json::Value value = Json::objectValue; - - if (hasPosition_) - { - value["Normal"] = Json::arrayValue; - value["Normal"][0] = normal_[0]; - value["Normal"][1] = normal_[1]; - value["Normal"][2] = normal_[2]; - - value["Position"] = Json::arrayValue; - value["Position"][0] = position_[0]; - value["Position"][1] = position_[1]; - value["Position"][2] = position_[2]; - } - - if (hasIndex_) - { - value["Index"] = index_; - } - - Json::FastWriter writer; - result = writer.write(value); - } - - - void InstanceInformation::Deserialize(InstanceInformation& result, - const std::string& serialized) - { - result = InstanceInformation(); - - Json::Reader reader; - Json::Value value; - - if (!reader.parse(serialized, value) || - value.type() != Json::objectValue) - { - return; - } - - if (value.isMember("Normal")) - { - std::vector normal(3), position(3); - normal[0] = value["Normal"][0].asFloat(); - normal[1] = value["Normal"][1].asFloat(); - normal[2] = value["Normal"][2].asFloat(); - position[0] = value["Position"][0].asFloat(); - position[1] = value["Position"][1].asFloat(); - position[2] = value["Position"][2].asFloat(); - result.SetPosition(normal, position); - } - - if (value.isMember("Index")) - { - result.SetIndexInSeries(value["Index"].asInt()); - } - } -} diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/InstanceInformation.h --- a/Plugin/InstanceInformation.h Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#pragma once - -#include -#include - -namespace OrthancPlugins -{ - class InstanceInformation - { - private: - bool hasPosition_; - float normal_[3]; - float position_[3]; - bool hasIndex_; - int index_; - - public: - InstanceInformation() : hasPosition_(false), hasIndex_(false) - { - } - - InstanceInformation(const std::string& serialized) - { - Deserialize(*this, serialized); - } - - void SetPosition(const std::vector& normal, - const std::vector& position); - - void SetIndexInSeries(int index); - - bool HasPosition() const - { - return hasPosition_; - } - - bool HasIndexInSeries() const - { - return hasIndex_; - } - - float GetPosition(size_t i) const; - - float GetNormal(size_t i) const; - - int GetIndexInSeries() const; - - void Serialize(std::string& result) const; - - static void Deserialize(InstanceInformation& result, - const std::string& serialized); - }; -} diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/InstanceInformationAdapter.cpp --- a/Plugin/InstanceInformationAdapter.cpp Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#include "InstanceInformationAdapter.h" - -#include "ViewerToolbox.h" -#include "InstanceInformation.h" - -#include - -static const char* IMAGE_ORIENTATION_PATIENT = "ImageOrientationPatient"; -static const char* IMAGE_POSITION_PATIENT = "ImagePositionPatient"; -static const char* INDEX_IN_SERIES = "IndexInSeries"; - - -namespace OrthancPlugins -{ - bool InstanceInformationAdapter::Create(std::string& content, - const std::string& instanceId) - { - std::string message = "Creating spatial information for instance: " + instanceId; - OrthancPluginLogInfo(context_, message.c_str()); - - std::string uri = "/instances/" + instanceId; - - Json::Value instance, tags; - if (!GetJsonFromOrthanc(instance, context_, uri) || - !GetJsonFromOrthanc(tags, context_, uri + "/tags?simplify") || - instance.type() != Json::objectValue || - tags.type() != Json::objectValue) - { - return false; - } - - InstanceInformation info; - - if (tags.isMember(IMAGE_ORIENTATION_PATIENT) && - tags.isMember(IMAGE_POSITION_PATIENT) && - tags[IMAGE_ORIENTATION_PATIENT].type() == Json::stringValue && - tags[IMAGE_POSITION_PATIENT].type() == Json::stringValue) - { - std::vector cosines, position; - if (TokenizeVector(cosines, tags[IMAGE_ORIENTATION_PATIENT].asString(), 6) && - TokenizeVector(position, tags[IMAGE_POSITION_PATIENT].asString(), 3)) - { - std::vector normal(3); - normal[0] = cosines[1] * cosines[5] - cosines[2] * cosines[4]; - normal[1] = cosines[2] * cosines[3] - cosines[0] * cosines[5]; - normal[2] = cosines[0] * cosines[4] - cosines[1] * cosines[3]; - - info.SetPosition(normal, position); - } - } - - if (instance.isMember(INDEX_IN_SERIES) && - instance[INDEX_IN_SERIES].type() == Json::intValue) - { - info.SetIndexInSeries(instance[INDEX_IN_SERIES].asInt()); - } - - info.Serialize(content); - return true; - } -} diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/InstanceInformationAdapter.h --- a/Plugin/InstanceInformationAdapter.h Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#pragma once - -#include "Cache/ICacheFactory.h" - -#include - -namespace OrthancPlugins -{ - class InstanceInformationAdapter : public ICacheFactory - { - private: - OrthancPluginContext* context_; - - public: - InstanceInformationAdapter(OrthancPluginContext* context) : context_(context) - { - } - - virtual bool Create(std::string& content, - const std::string& instanceId); - }; -} diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/Plugin.cpp --- a/Plugin/Plugin.cpp Fri Nov 27 21:39:41 2015 +0100 +++ b/Plugin/Plugin.cpp Fri Nov 27 21:45:21 2015 +0100 @@ -27,7 +27,6 @@ #include "ViewerToolbox.h" #include "ViewerPrefetchPolicy.h" #include "DecodedImageAdapter.h" -#include "InstanceInformationAdapter.h" #include "SeriesInformationAdapter.h" #include "../Orthanc/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h" #include "../Orthanc/Core/Toolbox.h" @@ -76,10 +75,7 @@ { const std::string& instanceId = dynamic_cast(*obj).GetValue(); - // On the reception of a new instance, precompute its spatial position - cache->GetScheduler().Prefetch(OrthancPlugins::CacheBundle_InstanceInformation, instanceId); - - // Indalidate the parent series of the instance + // On the reception of a new instance, indalidate the parent series of the instance std::string uri = "/instances/" + std::string(instanceId); Json::Value instance; if (OrthancPlugins::GetJsonFromOrthanc(instance, context_, uri)) @@ -443,15 +439,12 @@ cache_->GetScheduler().RegisterPolicy(new ViewerPrefetchPolicy(context_)); cache_->GetScheduler().Register(CacheBundle_SeriesInformation, new SeriesInformationAdapter(context_, cache_->GetScheduler()), 1); - cache_->GetScheduler().Register(CacheBundle_InstanceInformation, - new InstanceInformationAdapter(context_), 1); cache_->GetScheduler().Register(CacheBundle_DecodedImage, new DecodedImageAdapter(context_), decodingThreads); /* Set the quotas */ cache_->GetScheduler().SetQuota(CacheBundle_SeriesInformation, 1000, 0); // Keep info about 1000 series - cache_->GetScheduler().SetQuota(CacheBundle_InstanceInformation, 10000, 0); // Keep info about 10,000 instances message = "Web viewer using a cache of " + boost::lexical_cast(cacheSize) + " MB"; OrthancPluginLogWarning(context_, message.c_str()); diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/SeriesInformationAdapter.cpp --- a/Plugin/SeriesInformationAdapter.cpp Fri Nov 27 21:39:41 2015 +0100 +++ b/Plugin/SeriesInformationAdapter.cpp Fri Nov 27 21:45:21 2015 +0100 @@ -21,9 +21,6 @@ #include "SeriesInformationAdapter.h" #include "ViewerToolbox.h" -#include "SeriesVolumeSorter.h" - -#include "../Orthanc/Core/OrthancException.h" #include @@ -70,36 +67,6 @@ } } -#if 0 - result["SortedInstances"] = Json::arrayValue; - - SeriesVolumeSorter sorter; - sorter.Reserve(series["Instances"].size()); - - for (Json::Value::ArrayIndex i = 0; i < series["Instances"].size(); i++) - { - const std::string instanceId = series["Instances"][i].asString(); - std::string tmp; - - if (!cache_.Access(tmp, CacheBundle_InstanceInformation, instanceId)) - { - OrthancPluginLogError(context_, "The cache is corrupted. Delete it to reconstruct it."); - throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); - } - - InstanceInformation instance(tmp); - sorter.AddInstance(instanceId, instance); - } - - for (size_t i = 0; i < sorter.GetSize(); i++) - { - result["SortedInstances"].append(sorter.GetInstance(i)); - } - - std::cout << result.toStyledString(); - -#endif - content = result.toStyledString(); return true; diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/SeriesVolumeSorter.cpp --- a/Plugin/SeriesVolumeSorter.cpp Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#include "SeriesVolumeSorter.h" - -#include -#include -#include -#include - -namespace OrthancPlugins -{ - SeriesVolumeSorter::SeriesVolumeSorter() : - sorted_(true), - isVolume_(true) - { - } - - - void SeriesVolumeSorter::Reserve(size_t countInstances) - { - positions_.reserve(countInstances); - indexes_.reserve(countInstances); - } - - - void SeriesVolumeSorter::AddInstance(const std::string& instanceId, - const InstanceInformation& instance) - { - if (instance.HasIndexInSeries()) - { - indexes_.push_back(std::make_pair(instanceId, instance.GetIndexInSeries())); - } - - if (!isVolume_ || - !instance.HasPosition()) - { - isVolume_ = false; - } - else - { - if (positions_.size() == 0) - { - // This is the first slice in a possible 3D volume. Remember its normal. - normal_[0] = instance.GetNormal(0); - normal_[1] = instance.GetNormal(1); - normal_[2] = instance.GetNormal(2); - } - else - { - static const float THRESHOLD = 10.0f * std::numeric_limits::epsilon(); - - // This is still a possible 3D volume. Check whether the normal - // is constant wrt. the previous slices. - if (fabs(normal_[0] - instance.GetNormal(0)) > THRESHOLD || - fabs(normal_[1] - instance.GetNormal(1)) > THRESHOLD || - fabs(normal_[2] - instance.GetNormal(2)) > THRESHOLD) - { - // The normal is not constant, not a 3D volume. - isVolume_ = false; - positions_.clear(); - } - } - - if (isVolume_) - { - float distance = (normal_[0] * instance.GetPosition(0) + - normal_[1] * instance.GetPosition(1) + - normal_[2] * instance.GetPosition(2)); - positions_.push_back(std::make_pair(instanceId, distance)); - } - } - - sorted_ = false; - } - - - std::string SeriesVolumeSorter::GetInstance(size_t index) - { - if (!sorted_) - { - if (isVolume_) - { - assert(indexes_.size() == positions_.size()); - std::sort(positions_.begin(), positions_.end(), ComparePosition); - - float a = positions_.front().second; - float b = positions_.back().second; - assert(a <= b); - - if (fabs(b - a) <= 10.0f * std::numeric_limits::epsilon()) - { - // Not enough difference between the minimum and maximum - // positions along the normal of the volume - isVolume_ = false; - } - } - - if (!isVolume_) - { - std::sort(indexes_.begin(), indexes_.end(), CompareIndex); - } - } - - if (isVolume_) - { - return positions_[index].first; - } - else - { - return indexes_[index].first; - } - } -} diff -r 46ec13a1177c -r f5b1a9267da0 Plugin/SeriesVolumeSorter.h --- a/Plugin/SeriesVolumeSorter.h Fri Nov 27 21:39:41 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 . - **/ - - -#pragma once - -#include "InstanceInformation.h" - -#include -#include - -namespace OrthancPlugins -{ - class SeriesVolumeSorter : public boost::noncopyable - { - private: - typedef std::pair InstanceWithPosition; - typedef std::pair InstanceWithIndex; - - static bool ComparePosition(const InstanceWithPosition& a, - const InstanceWithPosition& b) - { - return a.second < b.second; - } - - static bool CompareIndex(const InstanceWithIndex& a, - const InstanceWithIndex& b) - { - return a.second < b.second; - } - - bool sorted_; - bool isVolume_; - float normal_[3]; - - std::vector positions_; - std::vector indexes_; - - public: - SeriesVolumeSorter(); - - void Reserve(size_t countInstances); - - void AddInstance(const std::string& instanceId, - const InstanceInformation& instance); - - size_t GetSize() const - { - return indexes_.size(); - } - - std::string GetInstance(size_t index); - }; -}