Mercurial > hg > orthanc-stone
comparison OrthancStone/Resources/Graveyard/RTStructTentativeReimplementation-BGO/DicomStructureSet-BGO.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 | |
children |
comparison
equal
deleted
inserted
replaced
1907:0208f99b8bde | 1908:affde38b84de |
---|---|
1 namespace OrthancStone | |
2 { | |
3 static RtStructRectangleInSlab CreateRectangle(float x1, float y1, | |
4 float x2, float y2) | |
5 { | |
6 RtStructRectangleInSlab rect; | |
7 rect.xmin = std::min(x1, x2); | |
8 rect.xmax = std::max(x1, x2); | |
9 rect.ymin = std::min(y1, y2); | |
10 rect.ymax = std::max(y1, y2); | |
11 return rect; | |
12 } | |
13 | |
14 bool CompareRectanglesForProjection(const std::pair<RtStructRectangleInSlab,double>& r1, | |
15 const std::pair<RtStructRectangleInSlab, double>& r2) | |
16 { | |
17 return r1.second < r2.second; | |
18 } | |
19 | |
20 bool CompareSlabsY(const RtStructRectanglesInSlab& r1, | |
21 const RtStructRectanglesInSlab& r2) | |
22 { | |
23 if ((r1.size() == 0) || (r2.size() == 0)) | |
24 return false; | |
25 | |
26 return r1[0].ymax < r2[0].ymax; | |
27 } | |
28 } | |
29 | |
30 | |
31 bool DicomStructureSet::ProjectStructure(std::vector< std::vector<ScenePoint2D> >& chains, | |
32 const Structure& structure, | |
33 const CoordinateSystem3D& sourceSlice) const | |
34 { | |
35 | |
36 // FOR SAGITTAL AND CORONAL | |
37 | |
38 | |
39 // this will contain the intersection of the polygon slab with | |
40 // the cutting plane, projected on the cutting plane coord system | |
41 // (that yields a rectangle) + the Z coordinate of the polygon | |
42 // (this is required to group polygons with the same Z later) | |
43 std::vector<std::pair<RtStructRectangleInSlab, double> > projected; | |
44 | |
45 for (Polygons::const_iterator polygon = structure.polygons_.begin(); | |
46 polygon != structure.polygons_.end(); ++polygon) | |
47 { | |
48 double x1, y1, x2, y2; | |
49 | |
50 if (polygon->Project(x1, y1, x2, y2, slice, GetEstimatedNormal(), GetEstimatedSliceThickness())) | |
51 { | |
52 double curZ = polygon->GetGeometryOrigin()[2]; | |
53 | |
54 // x1,y1 and x2,y2 are in "slice" coordinates (the cutting plane | |
55 // geometry) | |
56 projected.push_back(std::make_pair(CreateRectangle( | |
57 static_cast<float>(x1), | |
58 static_cast<float>(y1), | |
59 static_cast<float>(x2), | |
60 static_cast<float>(y2)),curZ)); | |
61 } | |
62 } | |
63 | |
64 // projected contains a set of rectangles specified by two opposite | |
65 // corners (x1,y1,x2,y2) | |
66 // we need to merge them | |
67 // each slab yields ONE polygon! | |
68 | |
69 // we need to sorted all the rectangles that originate from the same Z | |
70 // into lanes. To make sure they are grouped together in the array, we | |
71 // sort it. | |
72 std::sort(projected.begin(), projected.end(), CompareRectanglesForProjection); | |
73 | |
74 std::vector<RtStructRectanglesInSlab> rectanglesForEachSlab; | |
75 rectanglesForEachSlab.reserve(projected.size()); | |
76 | |
77 double curZ = 0; | |
78 for (size_t i = 0; i < projected.size(); ++i) | |
79 { | |
80 #if 0 | |
81 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
82 #else | |
83 if (i == 0) | |
84 { | |
85 curZ = projected[i].second; | |
86 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
87 } | |
88 else | |
89 { | |
90 // this check is needed to prevent creating a new slab if | |
91 // the new polygon is at the same Z coord than last one | |
92 if (!LinearAlgebra::IsNear(curZ, projected[i].second)) | |
93 { | |
94 rectanglesForEachSlab.push_back(RtStructRectanglesInSlab()); | |
95 curZ = projected[i].second; | |
96 } | |
97 } | |
98 #endif | |
99 | |
100 rectanglesForEachSlab.back().push_back(projected[i].first); | |
101 | |
102 // as long as they have the same y, we should put them into the same lane | |
103 // BUT in Sebastien's code, there is only one polygon per lane. | |
104 | |
105 //std::cout << "rect: xmin = " << rect.xmin << " xmax = " << rect.xmax << " ymin = " << rect.ymin << " ymax = " << rect.ymax << std::endl; | |
106 } | |
107 | |
108 // now we need to sort the slabs in increasing Y order (see ConvertListOfSlabsToSegments) | |
109 std::sort(rectanglesForEachSlab.begin(), rectanglesForEachSlab.end(), CompareSlabsY); | |
110 | |
111 std::vector< std::pair<ScenePoint2D, ScenePoint2D> > segments; | |
112 ConvertListOfSlabsToSegments(segments, rectanglesForEachSlab, projected.size()); | |
113 | |
114 chains.resize(segments.size()); | |
115 for (size_t i = 0; i < segments.size(); i++) | |
116 { | |
117 chains[i].resize(2); | |
118 chains[i][0] = segments[i].first; | |
119 chains[i][1] = segments[i].second; | |
120 } | |
121 #endif | |
122 | |
123 return true; | |
124 } |