# HG changeset patch # User Sebastien Jodogne # Date 1643213977 -3600 # Node ID b3c08e607d9f20a4d4b06130a17611480890d11b # Parent 14c8f339d4807d5ceacf259f0cf3ba3b187e248d simplified signature of DicomStructureSet::ProjectStructure() diff -r 14c8f339d480 -r b3c08e607d9f Applications/Samples/Common/RtViewerApp.cpp --- a/Applications/Samples/Common/RtViewerApp.cpp Wed Jan 19 14:51:55 2022 +0100 +++ b/Applications/Samples/Common/RtViewerApp.cpp Wed Jan 26 17:19:37 2022 +0100 @@ -67,12 +67,17 @@ } } - const VolumeImageGeometry& RtViewerApp::GetMainGeometry() + VolumeImageGeometry RtViewerApp::GetMainGeometry() { ORTHANC_ASSERT(geometryProvider_.get() != NULL); - ORTHANC_ASSERT(geometryProvider_->HasGeometry()); - const VolumeImageGeometry& geometry = geometryProvider_->GetImageGeometry(); - return geometry; + if (geometryProvider_->HasGeometry()) + { + return geometryProvider_->GetImageGeometry(); + } + else + { + return VolumeImageGeometry(); + } } RtViewerApp::RtViewerApp() : diff -r 14c8f339d480 -r b3c08e607d9f Applications/Samples/Common/RtViewerApp.h --- a/Applications/Samples/Common/RtViewerApp.h Wed Jan 19 14:51:55 2022 +0100 +++ b/Applications/Samples/Common/RtViewerApp.h Wed Jan 26 17:19:37 2022 +0100 @@ -95,7 +95,7 @@ */ void SetArgument(const std::string& key, const std::string& value); - const VolumeImageGeometry& GetMainGeometry(); + VolumeImageGeometry GetMainGeometry(); static boost::shared_ptr Create(); diff -r 14c8f339d480 -r b3c08e607d9f Applications/Samples/Common/RtViewerView.cpp --- a/Applications/Samples/Common/RtViewerView.cpp Wed Jan 19 14:51:55 2022 +0100 +++ b/Applications/Samples/Common/RtViewerView.cpp Wed Jan 26 17:19:37 2022 +0100 @@ -206,7 +206,7 @@ void RtViewerView::RetrieveGeometry() { - const VolumeImageGeometry& geometry = GetApp()->GetMainGeometry(); + VolumeImageGeometry geometry = GetApp()->GetMainGeometry(); const unsigned int depth = geometry.GetProjectionDepth(projection_); currentPlane_ = depth / 2; diff -r 14c8f339d480 -r b3c08e607d9f Applications/Samples/RtViewerPlugin/Plugin.cpp --- a/Applications/Samples/RtViewerPlugin/Plugin.cpp Wed Jan 19 14:51:55 2022 +0100 +++ b/Applications/Samples/RtViewerPlugin/Plugin.cpp Wed Jan 26 17:19:37 2022 +0100 @@ -41,7 +41,7 @@ { throw Orthanc::OrthancException( Orthanc::ErrorCode_InternalError, - "The Stone MPR RT viewer requires the Web Viewer plugin to be installed"); + "The Stone MPR RT viewer requires the Orthanc Web Viewer plugin to be installed"); } } } diff -r 14c8f339d480 -r b3c08e607d9f OrthancStone/Sources/Loaders/DicomStructureSetLoader.cpp --- a/OrthancStone/Sources/Loaders/DicomStructureSetLoader.cpp Wed Jan 19 14:51:55 2022 +0100 +++ b/OrthancStone/Sources/Loaders/DicomStructureSetLoader.cpp Wed Jan 26 17:19:37 2022 +0100 @@ -366,45 +366,10 @@ for (size_t i = 0; i < content_.GetStructuresCount(); i++) { - if ((visibility_.size() == 0) || visibility_.at(i)) + if (visibility_.size() == 0 || + visibility_.at(i)) { - const Color& color = content_.GetStructureColor(i); - -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - std::vector< std::vector > polygons; - - if (content_.ProjectStructure(polygons, i, cuttingPlane)) - { - for (size_t j = 0; j < polygons.size(); j++) - { - PolylineSceneLayer::Chain chain; - chain.resize(polygons[j].size()); - - for (size_t k = 0; k < polygons[j].size(); k++) - { - chain[k] = ScenePoint2D(polygons[j][k].GetX(), polygons[j][k].GetY()); - } - - layer->AddChain(chain, true /* closed */, color); - } - } -#else - std::vector< std::pair > segments; - - if (content_.ProjectStructure(segments, i, cuttingPlane)) - { - for (size_t j = 0; j < segments.size(); j++) - { - PolylineSceneLayer::Chain chain; - chain.resize(2); - - chain[0] = ScenePoint2D(segments[j].first.GetX(), segments[j].first.GetY()); - chain[1] = ScenePoint2D(segments[j].second.GetX(), segments[j].second.GetY()); - - layer->AddChain(chain, false /* NOT closed */, color); - } - } -#endif + content_.ProjectOntoLayer(*layer, cuttingPlane, i, content_.GetStructureColor(i)); } } diff -r 14c8f339d480 -r b3c08e607d9f OrthancStone/Sources/Toolbox/DicomStructureSet.cpp --- a/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp Wed Jan 19 14:51:55 2022 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.cpp Wed Jan 26 17:19:37 2022 +0100 @@ -21,6 +21,8 @@ **/ +#define USE_BOOST_UNION_FOR_POLYGONS 1 + #include "DicomStructureSet.h" #include "DicomStructureSetUtils.h" // TODO REMOVE @@ -42,13 +44,20 @@ # include #endif +#if !defined(USE_BOOST_UNION_FOR_POLYGONS) +# error Macro USE_BOOST_UNION_FOR_POLYGONS must be defined +#endif + #include #include #include -#include -#include -#include -#include + +#if USE_BOOST_UNION_FOR_POLYGONS == 1 +# include +# include +# include +# include +#endif #if defined(_MSC_VER) # pragma warning(pop) @@ -59,11 +68,12 @@ #endif +#if USE_BOOST_UNION_FOR_POLYGONS == 1 + typedef boost::geometry::model::d2::point_xy BoostPoint; typedef boost::geometry::model::polygon BoostPolygon; typedef boost::geometry::model::multi_polygon BoostMultiPolygon; - static void Union(BoostMultiPolygon& output, std::vector& input) { @@ -94,8 +104,6 @@ } } -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - static BoostPolygon CreateRectangle(float x1, float y1, float x2, float y2) { @@ -122,12 +130,14 @@ return rect; } - bool CompareRectanglesForProjection(const std::pair& r1, const std::pair& r2) + bool CompareRectanglesForProjection(const std::pair& r1, + const std::pair& r2) { return r1.second < r2.second; } - bool CompareSlabsY(const RtStructRectanglesInSlab& r1, const RtStructRectanglesInSlab& r2) + bool CompareSlabsY(const RtStructRectanglesInSlab& r1, + const RtStructRectanglesInSlab& r2) { if ((r1.size() == 0) || (r2.size() == 0)) return false; @@ -829,22 +839,13 @@ } } - bool DicomStructureSet::ProjectStructure( -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - std::vector< std::vector >& polygons, -#else - std::vector< std::pair >& segments, -#endif - const Structure& structure, - const CoordinateSystem3D& sourceSlice) const + bool DicomStructureSet::ProjectStructure(std::vector< std::vector >& chains, + const Structure& structure, + const CoordinateSystem3D& sourceSlice) const { const CoordinateSystem3D slice = CoordinateSystem3D::NormalizeCuttingPlane(sourceSlice); -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - polygons.clear(); -#else - segments.clear(); -#endif + chains.clear(); Vector normal = GetNormal(); @@ -853,51 +854,30 @@ { // This is an axial projection + chains.reserve(structure.polygons_.size()); + for (Polygons::const_iterator polygon = structure.polygons_.begin(); polygon != structure.polygons_.end(); ++polygon) { - if (polygon->IsOnSlice(slice)) + const Points& points = polygon->GetPoints(); + + if (polygon->IsOnSlice(slice) && + !points.empty()) { -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - polygons.push_back(std::vector()); + chains.push_back(std::vector()); + chains.back().reserve(points.size() + 1); - for (Points::const_iterator p = polygon->GetPoints().begin(); - p != polygon->GetPoints().end(); ++p) + for (Points::const_iterator p = points.begin(); + p != points.end(); ++p) { double x, y; slice.ProjectPoint2(x, y, *p); - polygons.back().push_back(ScenePoint2D(x, y)); + chains.back().push_back(ScenePoint2D(x, y)); } -#else - // we need to add all the segments corresponding to this polygon - const std::vector& points3D = polygon->GetPoints(); - if (points3D.size() >= 3) - { - ScenePoint2D prev2D; - { - Vector prev = points3D[0]; - double prevX, prevY; - slice.ProjectPoint2(prevX, prevY, prev); - prev2D = ScenePoint2D(prevX, prevY); - } - size_t pointCount = points3D.size(); - for (size_t ipt = 1; ipt < pointCount; ++ipt) - { - Vector next = points3D[ipt]; - double nextX, nextY; - slice.ProjectPoint2(nextX, nextY, next); - ScenePoint2D next2D(nextX, nextY); - segments.push_back(std::pair(prev2D, next2D)); - prev2D = next2D; - } - } - else - { - LOG(ERROR) << "Contour with less than 3 points!"; - // !!! - } -#endif + double x0, y0; + slice.ProjectPoint2(x0, y0, points.front()); + chains.back().push_back(ScenePoint2D(x0, y0)); } } @@ -906,7 +886,6 @@ else if (GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisX()) || GeometryToolbox::IsParallelOrOpposite(isOpposite, normal, slice.GetAxisY())) { -#if 1 // Sagittal or coronal projection #if USE_BOOST_UNION_FOR_POLYGONS == 1 @@ -997,40 +976,33 @@ // now we need to sort the slabs in increasing Y order (see ConvertListOfSlabsToSegments) std::sort(rectanglesForEachSlab.begin(), rectanglesForEachSlab.end(), CompareSlabsY); + std::vector< std::pair > segments; ConvertListOfSlabsToSegments(segments, rectanglesForEachSlab, projected.size()); + + chains.resize(segments.size()); + for (size_t i = 0; i < segments.size(); i++) + { + chains[i].resize(2); + chains[i][0] = segments[i].first; + chains[i][1] = segments[i].second; + } + #else BoostMultiPolygon merged; Union(merged, projected); - polygons.resize(merged.size()); + chains.resize(merged.size()); for (size_t i = 0; i < merged.size(); i++) { const std::vector& outer = merged[i].outer(); - polygons[i].resize(outer.size()); + chains[i].resize(outer.size()); for (size_t j = 0; j < outer.size(); j++) { - polygons[i][j] = ScenePoint2D(outer[j].x(), outer[j].y()); + chains[i][j] = ScenePoint2D(outer[j].x(), outer[j].y()); } } #endif - -#else - for (Polygons::iterator polygon = structure.polygons_.begin(); - polygon != structure.polygons_.end(); ++polygon) - { - double x1, y1, x2, y2; - if (polygon->Project(x1, y1, x2, y2, slice)) - { - std::vector p(4); - p[0] = std::make_pair(x1, y1); - p[1] = std::make_pair(x2, y1); - p[2] = std::make_pair(x2, y2); - p[3] = std::make_pair(x1, y2); - polygons.push_back(p); - } - } -#endif return true; } @@ -1046,38 +1018,15 @@ size_t structureIndex, const Color& color) const { -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - std::vector< std::vector > polygons; - if (ProjectStructure(polygons, structureIndex, plane)) + std::vector< std::vector > chains; + + if (ProjectStructure(chains, structureIndex, plane)) { - for (size_t j = 0; j < polygons.size(); j++) + for (size_t j = 0; j < chains.size(); j++) { - std::vector chain; - chain.reserve(polygons[j].size()); - - for (size_t k = 0; k < polygons[j].size(); k++) - { - chain.push_back(ScenePoint2D(polygons[j][k].x, polygons[j][k].y)); - } - - layer.AddChain(chain, true, color.GetRed(), color.GetGreen(), color.GetBlue()); + layer.AddChain(chains[j], false, color.GetRed(), color.GetGreen(), color.GetBlue()); } } - -#else - std::vector< std::pair > segments; - - if (ProjectStructure(segments, structureIndex, plane)) - { - for (size_t j = 0; j < segments.size(); j++) - { - std::vector chain(2); - chain[0] = ScenePoint2D(segments[j].first.GetX(), segments[j].first.GetY()); - chain[1] = ScenePoint2D(segments[j].second.GetX(), segments[j].second.GetY()); - layer.AddChain(chain, false, color.GetRed(), color.GetGreen(), color.GetBlue()); - } - } -#endif } diff -r 14c8f339d480 -r b3c08e607d9f OrthancStone/Sources/Toolbox/DicomStructureSet.h --- a/OrthancStone/Sources/Toolbox/DicomStructureSet.h Wed Jan 19 14:51:55 2022 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomStructureSet.h Wed Jan 26 17:19:37 2022 +0100 @@ -40,8 +40,6 @@ # include #endif -//#define USE_BOOST_UNION_FOR_POLYGONS 1 - #include @@ -160,14 +158,9 @@ Structure& GetStructure(size_t index); - bool ProjectStructure( -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - std::vector< std::vector >& polygons, -#else - std::vector< std::pair >& segments, -#endif - const Structure& structure, - const CoordinateSystem3D& slice) const; + bool ProjectStructure(std::vector< std::vector >& chains, + const Structure& structure, + const CoordinateSystem3D& slice) const; void EstimateGeometry(); @@ -207,21 +200,12 @@ Vector GetNormal() const; -#if USE_BOOST_UNION_FOR_POLYGONS == 1 - bool ProjectStructure(std::vector< std::vector >& polygons, + bool ProjectStructure(std::vector< std::vector >& chains, size_t index, const CoordinateSystem3D& slice) const { - return ProjectStructure(polygons, GetStructure(index), slice); + return ProjectStructure(chains, GetStructure(index), slice); } -#else - bool ProjectStructure(std::vector< std::pair >& segments, - size_t index, - const CoordinateSystem3D& slice) const - { - return ProjectStructure(segments, GetStructure(index), slice); - } -#endif void ProjectOntoLayer(PolylineSceneLayer& layer, const CoordinateSystem3D& plane, diff -r 14c8f339d480 -r b3c08e607d9f OrthancStone/Sources/Toolbox/DicomStructureSetUtils.h --- a/OrthancStone/Sources/Toolbox/DicomStructureSetUtils.h Wed Jan 19 14:51:55 2022 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomStructureSetUtils.h Wed Jan 26 17:19:37 2022 +0100 @@ -49,12 +49,18 @@ #endif /** Internal */ - void ConvertListOfSlabsToSegments(std::vector< std::pair >& segments, const std::vector& slabCuts, const size_t totalRectCount); + void ConvertListOfSlabsToSegments(std::vector< std::pair >& segments, + const std::vector& slabCuts, + const size_t totalRectCount); /** Internal */ - void AddSlabBoundaries(std::vector >& boundaries, const std::vector& slabCuts, size_t iSlab); + void AddSlabBoundaries(std::vector >& boundaries, + const std::vector& slabCuts, + size_t iSlab); /** Internal */ - void ProcessBoundaryList(std::vector< std::pair >& segments, const std::vector >& boundaries, double y); + void ProcessBoundaryList(std::vector< std::pair >& segments, + const std::vector >& boundaries, + double y); }