Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Toolbox/DicomStructureSet.cpp @ 1908:affde38b84de
moved tentative bgo reimplementation of rt-struct into graveyard
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 01 Feb 2022 08:38:32 +0100 |
parents | e318b524ad3f |
children | 782ba9eb6f22 |
comparison
equal
deleted
inserted
replaced
1907:0208f99b8bde | 1908:affde38b84de |
---|---|
55 # include <boost/geometry.hpp> | 55 # include <boost/geometry.hpp> |
56 # include <boost/geometry/geometries/point_xy.hpp> | 56 # include <boost/geometry/geometries/point_xy.hpp> |
57 # include <boost/geometry/geometries/polygon.hpp> | 57 # include <boost/geometry/geometries/polygon.hpp> |
58 # include <boost/geometry/multi/geometries/multi_polygon.hpp> | 58 # include <boost/geometry/multi/geometries/multi_polygon.hpp> |
59 #else | 59 #else |
60 # include "DicomStructureSetUtils.h" // TODO REMOVE | |
61 # include "UnionOfRectangles.h" | 60 # include "UnionOfRectangles.h" |
62 #endif | 61 #endif |
63 | 62 |
64 #if defined(_MSC_VER) | 63 #if defined(_MSC_VER) |
65 # pragma warning(pop) | 64 # pragma warning(pop) |
115 boost::geometry::append(r, BoostPoint(x2, y2)); | 114 boost::geometry::append(r, BoostPoint(x2, y2)); |
116 boost::geometry::append(r, BoostPoint(x2, y1)); | 115 boost::geometry::append(r, BoostPoint(x2, y1)); |
117 return r; | 116 return r; |
118 } | 117 } |
119 | 118 |
120 #else | |
121 | |
122 namespace OrthancStone | |
123 { | |
124 static RtStructRectangleInSlab CreateRectangle(float x1, float y1, | |
125 float x2, float y2) | |
126 { | |
127 RtStructRectangleInSlab rect; | |
128 rect.xmin = std::min(x1, x2); | |
129 rect.xmax = std::max(x1, x2); | |
130 rect.ymin = std::min(y1, y2); | |
131 rect.ymax = std::max(y1, y2); | |
132 return rect; | |
133 } | |
134 | |
135 bool CompareRectanglesForProjection(const std::pair<RtStructRectangleInSlab,double>& r1, | |
136 const std::pair<RtStructRectangleInSlab, double>& r2) | |
137 { | |
138 return r1.second < r2.second; | |
139 } | |
140 | |
141 bool CompareSlabsY(const RtStructRectanglesInSlab& r1, | |
142 const RtStructRectanglesInSlab& r2) | |
143 { | |
144 if ((r1.size() == 0) || (r2.size() == 0)) | |
145 return false; | |
146 | |
147 return r1[0].ymax < r2[0].ymax; | |
148 } | |
149 } | |
150 | |
151 #endif | 119 #endif |
120 | |
152 | 121 |
153 namespace OrthancStone | 122 namespace OrthancStone |
154 { | 123 { |
155 static const Orthanc::DicomTag DICOM_TAG_CONTOUR_GEOMETRIC_TYPE(0x3006, 0x0042); | 124 static const Orthanc::DicomTag DICOM_TAG_CONTOUR_GEOMETRIC_TYPE(0x3006, 0x0042); |
156 static const Orthanc::DicomTag DICOM_TAG_CONTOUR_IMAGE_SEQUENCE(0x3006, 0x0016); | 125 static const Orthanc::DicomTag DICOM_TAG_CONTOUR_IMAGE_SEQUENCE(0x3006, 0x0016); |
919 { | 888 { |
920 chains[i][j] = ScenePoint2D(outer[j].x(), outer[j].y()); | 889 chains[i][j] = ScenePoint2D(outer[j].x(), outer[j].y()); |
921 } | 890 } |
922 } | 891 } |
923 | 892 |
924 #elif 1 | 893 #else |
925 | 894 |
926 std::list<Extent2D> rectangles; | 895 std::list<Extent2D> rectangles; |
927 | 896 |
928 for (Polygons::const_iterator polygon = structure.polygons_.begin(); | 897 for (Polygons::const_iterator polygon = structure.polygons_.begin(); |
929 polygon != structure.polygons_.end(); ++polygon) | 898 polygon != structure.polygons_.end(); ++polygon) |
946 for (Contours::const_iterator it = contours.begin(); it != contours.end(); ++it) | 915 for (Contours::const_iterator it = contours.begin(); it != contours.end(); ++it) |
947 { | 916 { |
948 chains.push_back(*it); | 917 chains.push_back(*it); |
949 } | 918 } |
950 | 919 |
951 #else | |
952 // this will contain the intersection of the polygon slab with | |
953 // the cutting plane, projected on the cutting plane coord system | |
954 // (that yields a rectangle) + the Z coordinate of the polygon | |
955 // (this is required to group polygons with the same Z later) | |
956 std::vector<std::pair<RtStructRectangleInSlab, double> > projected; | |
957 | |
958 for (Polygons::const_iterator polygon = structure.polygons_.begin(); | |
959 polygon != structure.polygons_.end(); ++polygon) | |
960 { | |
961 double x1, y1, x2, y2; | |
962 | |
963 if (polygon->Project(x1, y1, x2, y2, slice, GetEstimatedNormal(), GetEstimatedSliceThickness())) | |
964 { | |
965 double curZ = polygon->GetGeometryOrigin()[2]; | |
966 | |
967 // x1,y1 and x2,y2 are in "slice" coordinates (the cutting plane | |
968 // geometry) | |
969 projected.push_back(std::make_pair(CreateRectangle( | |
970 static_cast<float>(x1), | |
971 static_cast<float>(y1), | |
972 static_cast<float>(x2), | |
973 static_cast<float>(y2)),curZ)); | |
974 } | |
975 } | |
976 | |
977 // projected contains a set of rectangles specified by two opposite | |
978 // corners (x1,y1,x2,y2) | |
979 // we need to merge them | |
980 // each slab yields ONE polygon! | |
981 | |
982 // we need to sorted all the rectangles that originate from the same Z | |
983 // into lanes. To make sure they are grouped together in the array, we | |
984 // sort it. | |
985 std::sort(projected.begin(), projected.end(), CompareRectanglesForProjection); | |
986 | |
987 std::vector<RtStructRectanglesInSlab> rectanglesForEachSlab; | |
988 rectanglesForEachSlab.reserve(projected.size()); | |
989 | |
990 double curZ = 0; | |
991 for (size_t i = 0; i < projected.size(); ++i) | |
992 { | |
993 #if 0 | |
994 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
995 #else | |
996 if (i == 0) | |
997 { | |
998 curZ = projected[i].second; | |
999 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
1000 } | |
1001 else | |
1002 { | |
1003 // this check is needed to prevent creating a new slab if | |
1004 // the new polygon is at the same Z coord than last one | |
1005 if (!LinearAlgebra::IsNear(curZ, projected[i].second)) | |
1006 { | |
1007 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
1008 curZ = projected[i].second; | |
1009 } | |
1010 } | |
1011 #endif | 920 #endif |
1012 | 921 |
1013 rectanglesForEachSlab.back().push_back(projected[i].first); | |
1014 | |
1015 // as long as they have the same y, we should put them into the same lane | |
1016 // BUT in Sebastien's code, there is only one polygon per lane. | |
1017 | |
1018 //std::cout << "rect: xmin = " << rect.xmin << " xmax = " << rect.xmax << " ymin = " << rect.ymin << " ymax = " << rect.ymax << std::endl; | |
1019 } | |
1020 | |
1021 // now we need to sort the slabs in increasing Y order (see ConvertListOfSlabsToSegments) | |
1022 std::sort(rectanglesForEachSlab.begin(), rectanglesForEachSlab.end(), CompareSlabsY); | |
1023 | |
1024 std::vector< std::pair<ScenePoint2D, ScenePoint2D> > segments; | |
1025 ConvertListOfSlabsToSegments(segments, rectanglesForEachSlab, projected.size()); | |
1026 | |
1027 chains.resize(segments.size()); | |
1028 for (size_t i = 0; i < segments.size(); i++) | |
1029 { | |
1030 chains[i].resize(2); | |
1031 chains[i][0] = segments[i].first; | |
1032 chains[i][1] = segments[i].second; | |
1033 } | |
1034 #endif | |
1035 | |
1036 return true; | 922 return true; |
1037 } | 923 } |
1038 else | 924 else |
1039 { | 925 { |
1040 return false; | 926 return false; |