# HG changeset patch # User Sebastien Jodogne # Date 1654165425 -7200 # Node ID 98952be6fb97f4d6e4dca02951fe5dccc0924ef1 # Parent 3daecfa5791c3763d54da53a9aaeee28f61e3151 rendering plugin: rendering of multiple structures diff -r 3daecfa5791c -r 98952be6fb97 OrthancStone/Sources/Toolbox/DicomStructureSet.cpp --- a/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp Thu Jun 02 11:45:28 2022 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp Thu Jun 02 12:23:45 2022 +0200 @@ -401,6 +401,8 @@ } structures_.resize(count); + structureNamesIndex_.clear(); + for (size_t i = 0; i < count; i++) { structures_[i].interpretation_ = reader.GetStringValue @@ -413,6 +415,16 @@ DICOM_TAG_ROI_NAME), "No name"); + if (structureNamesIndex_.find(structures_[i].name_) == structureNamesIndex_.end()) + { + structureNamesIndex_[structures_[i].name_] = i; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, + "RT-STRUCT with twice the same name for a structure: " + structures_[i].name_); + } + Vector color; if (FastParseVector(color, tags, Orthanc::DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, DICOM_TAG_ROI_DISPLAY_COLOR)) && @@ -1018,4 +1030,21 @@ estimatedSliceThickness_ = LinearAlgebra::ComputeMedian(deltas); } } + + + bool DicomStructureSet::LookupStructureName(size_t& structureIndex /* out */, + const std::string& name) const + { + StructureNamesIndex::const_iterator found = structureNamesIndex_.find(name); + + if (found == structureNamesIndex_.end()) + { + return false; + } + else + { + structureIndex = found->second; + return true; + } + } } diff -r 3daecfa5791c -r 98952be6fb97 OrthancStone/Sources/Toolbox/DicomStructureSet.h --- a/OrthancStone/Sources/Toolbox/DicomStructureSet.h Thu Jun 02 11:45:28 2022 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.h Thu Jun 02 12:23:45 2022 +0200 @@ -148,12 +148,15 @@ uint8_t blue_; }; - typedef std::vector Structures; + typedef std::vector Structures; + typedef std::map StructureNamesIndex; Structures structures_; ReferencedSlices referencedSlices_; Vector estimatedNormal_; double estimatedSliceThickness_; + StructureNamesIndex structureNamesIndex_; + void Setup(const IDicomDataset& dataset); @@ -235,5 +238,8 @@ { return estimatedSliceThickness_; } + + bool LookupStructureName(size_t& structureIndex /* out */, + const std::string& name) const; }; } diff -r 3daecfa5791c -r 98952be6fb97 RenderingPlugin/Sources/Plugin.cpp --- a/RenderingPlugin/Sources/Plugin.cpp Thu Jun 02 11:45:28 2022 +0200 +++ b/RenderingPlugin/Sources/Plugin.cpp Thu Jun 02 12:23:45 2022 +0200 @@ -743,7 +743,7 @@ }; DataAugmentationParameters dataAugmentation; - std::string structureName; + std::vector structureNames; std::string instanceId; bool compress = false; @@ -756,7 +756,7 @@ { if (key == "structure") { - structureName = value; + Orthanc::Toolbox::TokenizeString(structureNames, value, ','); } else if (key == "instance") { @@ -773,10 +773,10 @@ } } - if (structureName.empty()) + if (structureNames.empty()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, - "Missing option \"structure\" to provide the structure name"); + "Missing option \"structure\" to provide the names of the structures of interest"); } if (instanceId.empty()) @@ -787,30 +787,28 @@ std::unique_ptr parameters(GetInstanceParameters(instanceId)); - std::list< std::vector > polygons; + typedef std::list< std::vector > Polygons; + + Polygons polygons; { DicomStructureCache::Accessor accessor(DicomStructureCache::GetSingleton(), request->groups[0]); - size_t structureIndex; - bool found = false; - for (size_t i = 0; i < accessor.GetRtStruct().GetStructuresCount(); i++) + for (size_t i = 0; i < structureNames.size(); i++) { - if (accessor.GetRtStruct().GetStructureName(i) == structureName) + size_t structureIndex; + if (accessor.GetRtStruct().LookupStructureName(structureIndex, structureNames[i])) { - structureIndex = i; - found = true; - break; + Polygons p; + accessor.GetRtStruct().GetStructurePoints(p, structureIndex, parameters->GetSopInstanceUid()); + polygons.splice(polygons.begin(), p); + } + else + { + LOG(WARNING) << "Missing structure name \"" << structureNames[i] + << "\" in RT-STRUCT: " << parameters->GetSopInstanceUid(); } } - - if (!found) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, - "Unknown structure name: " + structureName); - } - - accessor.GetRtStruct().GetStructurePoints(polygons, structureIndex, parameters->GetSopInstanceUid()); } // We use a "XOR" filler for the polygons in order to deal with holes in the RT-STRUCT