# HG changeset patch # User Sebastien Jodogne # Date 1574267657 -3600 # Node ID 9c8f557ea799aa42b09016d6d2f3b16f9740dd24 # Parent 177e7d431cd171a2cf0aeac1d69936035aa88805 ParsedDicomDataset to speed up loading RT-STRUCT from parsed DICOM files diff -r 177e7d431cd1 -r 9c8f557ea799 Framework/Toolbox/DicomStructureSet.cpp --- a/Framework/Toolbox/DicomStructureSet.cpp Wed Nov 20 15:24:20 2019 +0100 +++ b/Framework/Toolbox/DicomStructureSet.cpp Wed Nov 20 17:34:17 2019 +0100 @@ -27,7 +27,6 @@ #include #include #include -#include #include #if defined(_MSC_VER) @@ -46,6 +45,11 @@ # pragma warning(pop) #endif +#if ORTHANC_ENABLE_DCMTK == 1 +# include "ParsedDicomDataset.h" +#endif + + typedef boost::geometry::model::d2::point_xy BoostPoint; typedef boost::geometry::model::polygon BoostPolygon; typedef boost::geometry::model::multi_polygon BoostMultiPolygon; @@ -461,7 +465,7 @@ return structures_[index]; } - DicomStructureSet::DicomStructureSet(const OrthancPlugins::FullOrthancDataset& tags) + void DicomStructureSet::Setup(const OrthancPlugins::IDicomDataset& tags) { OrthancPlugins::DicomDatasetReader reader(tags); @@ -607,6 +611,15 @@ } +#if ORTHANC_ENABLE_DCMTK == 1 + DicomStructureSet::DicomStructureSet(Orthanc::ParsedDicomFile& instance) + { + ParsedDicomDataset dataset(instance); + Setup(dataset); + } +#endif + + Vector DicomStructureSet::GetStructureCenter(size_t index) const { const Structure& structure = GetStructure(index); diff -r 177e7d431cd1 -r 9c8f557ea799 Framework/Toolbox/DicomStructureSet.h --- a/Framework/Toolbox/DicomStructureSet.h Wed Nov 20 15:24:20 2019 +0100 +++ b/Framework/Toolbox/DicomStructureSet.h Wed Nov 20 17:34:17 2019 +0100 @@ -21,12 +21,20 @@ #pragma once +#if !defined(ORTHANC_ENABLE_DCMTK) +# error The macro ORTHANC_ENABLE_DCMTK must be defined +#endif + #include "DicomStructureSetUtils.h" #include "CoordinateSystem3D.h" #include "Extent2D.h" #include "../Scene2D/Color.h" #include "../Scene2D/PolylineSceneLayer.h" +#if ORTHANC_ENABLE_DCMTK == 1 +# include +#endif + //#define USE_BOOST_UNION_FOR_POLYGONS 1 #include @@ -138,6 +146,8 @@ Structures structures_; ReferencedSlices referencedSlices_; + void Setup(const OrthancPlugins::IDicomDataset& dataset); + const Structure& GetStructure(size_t index) const; Structure& GetStructure(size_t index); @@ -152,7 +162,14 @@ const CoordinateSystem3D& slice) const; public: - DicomStructureSet(const OrthancPlugins::FullOrthancDataset& instance); + DicomStructureSet(const OrthancPlugins::FullOrthancDataset& instance) + { + Setup(instance); + } + +#if ORTHANC_ENABLE_DCMTK == 1 + DicomStructureSet(Orthanc::ParsedDicomFile& instance); +#endif size_t GetStructuresCount() const { diff -r 177e7d431cd1 -r 9c8f557ea799 Framework/Toolbox/ParsedDicomDataset.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/ParsedDicomDataset.cpp Wed Nov 20 17:34:17 2019 +0100 @@ -0,0 +1,104 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 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 . + **/ + + +#include "ParsedDicomDataset.h" + +#include + +namespace OrthancStone +{ + static DcmItem* LookupPath(Orthanc::ParsedDicomFile& dicom, + const OrthancPlugins::DicomPath& path) + { + DcmItem* node = dicom.GetDcmtkObject().getDataset(); + + for (size_t i = 0; i < path.GetPrefixLength(); i++) + { + const OrthancPlugins::DicomTag& tmp = path.GetPrefixTag(i); + DcmTagKey tag(tmp.GetGroup(), tmp.GetElement()); + + DcmSequenceOfItems* sequence = NULL; + if (!node->findAndGetSequence(tag, sequence).good() || + sequence == NULL) + { + return NULL; + } + + unsigned long pos = path.GetPrefixIndex(i); + if (pos >= sequence->card()) + { + return NULL; + } + + node = sequence->getItem(pos); + if (node == NULL) + { + return NULL; + } + } + + return node; + } + + + bool ParsedDicomDataset::GetStringValue(std::string& result, + const OrthancPlugins::DicomPath& path) const + { + DcmItem* node = LookupPath(dicom_, path); + + if (node != NULL) + { + DcmTagKey tag(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement()); + + const char* s = NULL; + if (node->findAndGetString(tag, s).good() && + s != NULL) + { + result.assign(s); + return true; + } + } + + return false; + } + + + bool ParsedDicomDataset::GetSequenceSize(size_t& size, + const OrthancPlugins::DicomPath& path) const + { + DcmItem* node = LookupPath(dicom_, path); + + if (node != NULL) + { + DcmTagKey tag(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement()); + + DcmSequenceOfItems* s = NULL; + if (node->findAndGetSequence(tag, s).good() && + s != NULL) + { + size = s->card(); + return true; + } + } + + return false; + } +} diff -r 177e7d431cd1 -r 9c8f557ea799 Framework/Toolbox/ParsedDicomDataset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/ParsedDicomDataset.h Wed Nov 20 17:34:17 2019 +0100 @@ -0,0 +1,46 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 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 . + **/ + + +#pragma once + +#include +#include + +namespace OrthancStone +{ + class ParsedDicomDataset : public OrthancPlugins::IDicomDataset + { + private: + Orthanc::ParsedDicomFile& dicom_; + + public: + ParsedDicomDataset(Orthanc::ParsedDicomFile& dicom) : + dicom_(dicom) + { + } + + virtual bool GetStringValue(std::string& result, + const OrthancPlugins::DicomPath& path) const ORTHANC_OVERRIDE; + + virtual bool GetSequenceSize(size_t& size, + const OrthancPlugins::DicomPath& path) const ORTHANC_OVERRIDE; + }; +} diff -r 177e7d431cd1 -r 9c8f557ea799 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Wed Nov 20 15:24:20 2019 +0100 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Wed Nov 20 17:34:17 2019 +0100 @@ -409,6 +409,7 @@ list(APPEND ORTHANC_STONE_SOURCES ${ORTHANC_STONE_ROOT}/Framework/Oracle/ParseDicomSuccessMessage.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParsedDicomCache.cpp + ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParsedDicomDataset.cpp ) endif() @@ -435,6 +436,7 @@ ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp + ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomTag.cpp ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp