Mercurial > hg > orthanc-stone
diff Framework/Loaders/DicomStructureSetLoader.cpp @ 1019:29f5f2031310
Added a way to specificy which structures are to be initially displayed (the
default being ALL structures displayed) + the loader maintains a list of
structure display state, that can be modified continuously + the cache now takes
the initial list of structure into account for computing the entry + added methods
to change the loaded structure visibility + disabled the alternate loaders
(DicomStructureSetLoader2 and friends) + disabled corresponding tests
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Fri, 27 Sep 2019 13:32:05 +0200 |
parents | 4f28d9459e31 |
children | 7014c2397b45 |
line wrap: on
line diff
--- a/Framework/Loaders/DicomStructureSetLoader.cpp Thu Sep 26 09:22:27 2019 +0200 +++ b/Framework/Loaders/DicomStructureSetLoader.cpp Fri Sep 27 13:32:05 2019 +0200 @@ -24,6 +24,8 @@ #include "../Scene2D/PolylineSceneLayer.h" #include "../Toolbox/GeometryToolbox.h" +#include <algorithm> + #if 0 bool logbgo233 = false; bool logbgo115 = false; @@ -153,8 +155,7 @@ State(that) { } - - + virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) { #if 0 @@ -166,6 +167,33 @@ { OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer()); loader.content_.reset(new DicomStructureSet(dicom)); + size_t structureCount = loader.content_->GetStructuresCount(); + loader.structureVisibility_.resize(structureCount); + for (size_t i = 0; i < structureCount; ++i) + { + // if nothing is specified in the ctor, this means we want everything visible + if (loader.initiallyVisibleStructures_.size() == 0) + { + loader.structureVisibility_.at(i) = true; + } + else + { + // otherwise, we only enable visibility for those structures whose + // names are mentioned in the initiallyVisibleStructures_ array + const std::string& structureName = loader.content_->GetStructureName(i); + + std::vector<std::string>::iterator foundIt = + std::find( + loader.initiallyVisibleStructures_.begin(), + loader.initiallyVisibleStructures_.end(), + structureName); + std::vector<std::string>::iterator endIt = loader.initiallyVisibleStructures_.end(); + if (foundIt != endIt) + loader.structureVisibility_.at(i) = true; + else + loader.structureVisibility_.at(i) = false; + } + } } // Some (admittedly invalid) Dicom files have empty values in the @@ -204,14 +232,30 @@ const DicomStructureSet& content_; uint64_t revision_; bool isValid_; + std::vector<bool> visibility_; public: + /** + The visibility vector must either: + - be empty + or + - contain the same number of items as the number of structures in the + structure set. + In the first case (empty vector), all the structures are displayed. + In the second case, the visibility of each structure is defined by the + content of the vector at the corresponding index. + */ Slice(const DicomStructureSet& content, uint64_t revision, - const CoordinateSystem3D& cuttingPlane) : - content_(content), - revision_(revision) + const CoordinateSystem3D& cuttingPlane, + std::vector<bool> visibility = std::vector<bool>()) + : content_(content) + , revision_(revision) + , visibility_(visibility) { + ORTHANC_ASSERT((visibility_.size() == content_.GetStructuresCount()) + || (visibility_.size() == 0u)); + bool opposite; const Vector normal = content.GetNormal(); @@ -241,43 +285,46 @@ for (size_t i = 0; i < content_.GetStructuresCount(); i++) { - const Color& color = content_.GetStructureColor(i); + if ((visibility_.size() == 0) || visibility_.at(i)) + { + const Color& color = content_.GetStructureColor(i); #ifdef USE_BOOST_UNION_FOR_POLYGONS - std::vector< std::vector<Point2D> > polygons; - - if (content_.ProjectStructure(polygons, i, cuttingPlane)) - { - for (size_t j = 0; j < polygons.size(); j++) + std::vector< std::vector<Point2D> > polygons; + + if (content_.ProjectStructure(polygons, i, cuttingPlane)) { - PolylineSceneLayer::Chain chain; - chain.resize(polygons[j].size()); - - for (size_t k = 0; k < polygons[j].size(); k++) + for (size_t j = 0; j < polygons.size(); j++) { - chain[k] = ScenePoint2D(polygons[j][k].x, polygons[j][k].y); - } + PolylineSceneLayer::Chain chain; + chain.resize(polygons[j].size()); - layer->AddChain(chain, true /* closed */, color); - } + for (size_t k = 0; k < polygons[j].size(); k++) + { + chain[k] = ScenePoint2D(polygons[j][k].x, polygons[j][k].y); + } + + layer->AddChain(chain, true /* closed */, color); + } } #else - std::vector< std::pair<Point2D, Point2D> > segments; + std::vector< std::pair<Point2D, Point2D> > segments; - if (content_.ProjectStructure(segments, i, cuttingPlane)) - { - for (size_t j = 0; j < segments.size(); j++) + if (content_.ProjectStructure(segments, i, cuttingPlane)) { - PolylineSceneLayer::Chain chain; - chain.resize(2); + for (size_t j = 0; j < segments.size(); j++) + { + PolylineSceneLayer::Chain chain; + chain.resize(2); - chain[0] = ScenePoint2D(segments[j].first.x, segments[j].first.y); - chain[1] = ScenePoint2D(segments[j].second.x, segments[j].second.y); + chain[0] = ScenePoint2D(segments[j].first.x, segments[j].first.y); + chain[1] = ScenePoint2D(segments[j].second.x, segments[j].second.y); - layer->AddChain(chain, false /* NOT closed */, color); + layer->AddChain(chain, false /* NOT closed */, color); + } } +#endif } -#endif } return layer.release(); @@ -297,17 +344,26 @@ } + void DicomStructureSetLoader::SetStructureDisplayState(size_t structureIndex, bool display) + { + structureVisibility_.at(structureIndex) = display; + revision_++; + } + DicomStructureSetLoader::~DicomStructureSetLoader() { LOG(TRACE) << "DicomStructureSetLoader::~DicomStructureSetLoader()"; } - void DicomStructureSetLoader::LoadInstance(const std::string& instanceId) + void DicomStructureSetLoader::LoadInstance( + const std::string& instanceId, + const std::vector<std::string>& initiallyVisibleStructures) { Start(); instanceId_ = instanceId; - + initiallyVisibleStructures_ = initiallyVisibleStructures; + { std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); command->SetHttpHeader("Accept-Encoding", "gzip"); @@ -330,7 +386,7 @@ } else { - return new Slice(*content_, revision_, cuttingPlane); + return new Slice(*content_, revision_, cuttingPlane, structureVisibility_); } }