# HG changeset patch # User Sebastien Jodogne # Date 1510154035 -3600 # Node ID 44fc253d487663c2026c53a1d3628f026a5482e9 # Parent 5099aaa53bd067c5b67200ac5a38c6230a3611c9 refactoring diff -r 5099aaa53bd0 -r 44fc253d4876 Framework/Layers/DicomStructureSetRendererFactory.cpp --- a/Framework/Layers/DicomStructureSetRendererFactory.cpp Sun Oct 08 10:52:24 2017 +0200 +++ b/Framework/Layers/DicomStructureSetRendererFactory.cpp Wed Nov 08 16:13:55 2017 +0100 @@ -49,7 +49,33 @@ if (visible_) { cairo_set_line_width(context.GetObject(), 3.0f / view.GetZoom()); - structureSet_.Render(context, slice_); + + cairo_t* cr = context.GetObject(); + + for (size_t k = 0; k < structureSet_.GetStructureCount(); k++) + { + std::vector< std::vector > polygons; + + if (structureSet_.ProjectStructure(polygons, k, slice_)) + { + uint8_t red, green, blue; + structureSet_.GetStructureColor(red, green, blue, k); + context.SetSourceColor(red, green, blue); + + for (size_t i = 0; i < polygons.size(); i++) + { + cairo_move_to(cr, polygons[i][0].first, polygons[i][0].second); + + for (size_t j = 1; j < polygons[i].size(); j++) + { + cairo_line_to(cr, polygons[i][j].first, polygons[i][j].second); + } + + cairo_line_to(cr, polygons[i][0].first, polygons[i][0].second); + cairo_stroke(cr); + } + } + } } return true; @@ -199,11 +225,7 @@ void DicomStructureSetRendererFactory::ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) { - bool isOpposite; - if (structureSet_.get() != NULL && - GeometryToolbox::IsParallelOrOpposite(isOpposite, - viewportSlice.GetNormal(), - structureSet_->GetNormal())) + if (structureSet_.get() != NULL) { NotifyLayerReady(new Renderer(*structureSet_, viewportSlice), viewportSlice, false); } diff -r 5099aaa53bd0 -r 44fc253d4876 Framework/Toolbox/DicomStructureSet.cpp --- a/Framework/Toolbox/DicomStructureSet.cpp Sun Oct 08 10:52:24 2017 +0200 +++ b/Framework/Toolbox/DicomStructureSet.cpp Wed Nov 08 16:13:55 2017 +0100 @@ -152,7 +152,18 @@ { if (index >= structures_.size()) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + return structures_[index]; + } + + + DicomStructureSet::Structure& DicomStructureSet::GetStructure(size_t index) + { + if (index >= structures_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } return structures_[index]; @@ -336,47 +347,6 @@ } - void DicomStructureSet::Render(CairoContext& context, - const CoordinateSystem3D& slice) - { - cairo_t* cr = context.GetObject(); - - for (Structures::iterator structure = structures_.begin(); - structure != structures_.end(); ++structure) - { - for (Polygons::iterator polygon = structure->polygons_.begin(); - polygon != structure->polygons_.end(); ++polygon) - { - polygon->UpdateReferencedSlice(referencedSlices_); - - if (polygon->IsOnSlice(slice)) - { - context.SetSourceColor(structure->red_, structure->green_, structure->blue_); - - Points::const_iterator p = polygon->GetPoints().begin(); - - double x, y; - slice.ProjectPoint(x, y, *p); - cairo_move_to(cr, x, y); - ++p; - - while (p != polygon->GetPoints().end()) - { - slice.ProjectPoint(x, y, *p); - cairo_line_to(cr, x, y); - ++p; - } - - slice.ProjectPoint(x, y, *polygon->GetPoints().begin()); - cairo_line_to(cr, x, y); - - cairo_stroke(cr); - } - } - } - } - - void DicomStructureSet::GetReferencedInstances(std::set& instances) { for (Structures::const_iterator structure = structures_.begin(); @@ -532,4 +502,51 @@ return result.release(); } + + bool DicomStructureSet::ProjectStructure(std::vector< std::vector >& polygons, + Structure& structure, + const CoordinateSystem3D& slice) + { + polygons.clear(); + + Vector normal = GetNormal(); + + bool isOpposite; + if (GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetNormal())) + { + // This is an axial projection + + for (Polygons::iterator polygon = structure.polygons_.begin(); + polygon != structure.polygons_.end(); ++polygon) + { + polygon->UpdateReferencedSlice(referencedSlices_); + + if (polygon->IsOnSlice(slice)) + { + polygons.push_back(std::vector()); + + for (Points::const_iterator p = polygon->GetPoints().begin(); + p != polygon->GetPoints().end(); ++p) + { + double x, y; + slice.ProjectPoint(x, y, *p); + polygons.back().push_back(std::make_pair(x, y)); + } + } + } + + return true; + } + else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisX()) || + GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisY())) + { + // Sagittal or coronal projections + + return false; + } + else + { + return false; + } + } } diff -r 5099aaa53bd0 -r 44fc253d4876 Framework/Toolbox/DicomStructureSet.h --- a/Framework/Toolbox/DicomStructureSet.h Sun Oct 08 10:52:24 2017 +0200 +++ b/Framework/Toolbox/DicomStructureSet.h Wed Nov 08 16:13:55 2017 +0100 @@ -22,7 +22,6 @@ #pragma once #include "CoordinateSystem3D.h" -#include "../Viewport/CairoContext.h" #include @@ -32,6 +31,9 @@ { class DicomStructureSet : public boost::noncopyable { + public: + typedef std::pair PolygonPoint; + private: struct ReferencedSlice { @@ -112,6 +114,12 @@ const Structure& GetStructure(size_t index) const; + Structure& GetStructure(size_t index); + + bool ProjectStructure(std::vector< std::vector >& polygons, + Structure& structure, + const CoordinateSystem3D& slice); + public: DicomStructureSet(const OrthancPlugins::FullOrthancDataset& instance); @@ -142,12 +150,16 @@ void CheckReferencedSlices(); - void Render(CairoContext& context, - const CoordinateSystem3D& slice); - Vector GetNormal() const; static DicomStructureSet* SynchronousLoad(OrthancPlugins::IOrthancConnection& orthanc, const std::string& instanceId); + + bool ProjectStructure(std::vector< std::vector >& polygons, + size_t index, + const CoordinateSystem3D& slice) + { + return ProjectStructure(polygons, GetStructure(index), slice); + } }; }