comparison Framework/Toolbox/SlicesSorter.cpp @ 647:6af3099ed8da

uncoupling OrthancStone::SlicesSorter from OrthancStone::Slice
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 13 May 2019 17:03:46 +0200
parents b70e9be013e4
children 1088d4c4d78c
comparison
equal deleted inserted replaced
646:b4fe9642e83b 647:6af3099ed8da
28 namespace OrthancStone 28 namespace OrthancStone
29 { 29 {
30 class SlicesSorter::SliceWithDepth : public boost::noncopyable 30 class SlicesSorter::SliceWithDepth : public boost::noncopyable
31 { 31 {
32 private: 32 private:
33 std::auto_ptr<Slice> slice_; 33 CoordinateSystem3D geometry_;
34 double depth_; 34 double depth_;
35
36 std::auto_ptr<Orthanc::IDynamicObject> payload_;
35 37
36 public: 38 public:
37 SliceWithDepth(Slice* slice) : 39 SliceWithDepth(const CoordinateSystem3D& geometry,
38 slice_(slice), 40 Orthanc::IDynamicObject* payload) :
39 depth_(0) 41 geometry_(geometry),
40 { 42 depth_(0),
41 if (slice == NULL) 43 payload_(payload)
42 { 44 {
43 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
44 }
45 } 45 }
46 46
47 void SetNormal(const Vector& normal) 47 void SetNormal(const Vector& normal)
48 { 48 {
49 assert(slice_.get() != NULL); 49 depth_ = boost::numeric::ublas::inner_prod(geometry_.GetOrigin(), normal);
50 depth_ = boost::numeric::ublas::inner_prod
51 (slice_->GetGeometry().GetOrigin(), normal);
52 } 50 }
53 51
54 double GetDepth() const 52 double GetDepth() const
55 { 53 {
56 return depth_; 54 return depth_;
57 } 55 }
58 56
59 const Slice& GetSlice() const 57 const CoordinateSystem3D& GetGeometry() const
60 { 58 {
61 assert(slice_.get() != NULL); 59 return geometry_;
62 return *slice_; 60 }
61
62 bool HasPayload() const
63 {
64 return (payload_.get() != NULL);
65 }
66
67 const Orthanc::IDynamicObject& GetPayload() const
68 {
69 if (HasPayload())
70 {
71 return *payload_;
72 }
73 else
74 {
75 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
76 }
63 } 77 }
64 }; 78 };
65 79
66 80
67 struct SlicesSorter::Comparator 81 struct SlicesSorter::Comparator
82 delete slices_[i]; 96 delete slices_[i];
83 } 97 }
84 } 98 }
85 99
86 100
87 void SlicesSorter::AddSlice(Slice* slice) 101 void SlicesSorter::AddSlice(const CoordinateSystem3D& slice,
88 { 102 Orthanc::IDynamicObject* payload)
89 slices_.push_back(new SliceWithDepth(slice)); 103 {
90 } 104 slices_.push_back(new SliceWithDepth(slice, payload));
91 105 }
92 106
93 const Slice& SlicesSorter::GetSlice(size_t i) const 107
108 const SlicesSorter::SliceWithDepth& SlicesSorter::GetSlice(size_t i) const
94 { 109 {
95 if (i >= slices_.size()) 110 if (i >= slices_.size())
96 { 111 {
97 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 112 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
98 } 113 }
99 114 else
100 assert(slices_[i] != NULL); 115 {
101 return slices_[i]->GetSlice(); 116 assert(slices_[i] != NULL);
117 return *slices_[i];
118 }
119 }
120
121
122 const CoordinateSystem3D& SlicesSorter::GetSliceGeometry(size_t i) const
123 {
124 return GetSlice(i).GetGeometry();
125 }
126
127
128 bool SlicesSorter::HasSlicePayload(size_t i) const
129 {
130 return GetSlice(i).HasPayload();
131 }
132
133
134 const Orthanc::IDynamicObject& SlicesSorter::GetSlicePayload(size_t i) const
135 {
136 return GetSlice(i).GetPayload();
102 } 137 }
103 138
104 139
105 void SlicesSorter::SetNormal(const Vector& normal) 140 void SlicesSorter::SetNormal(const Vector& normal)
106 { 141 {
129 { 164 {
130 size_t pos = 0; 165 size_t pos = 0;
131 166
132 for (size_t i = 0; i < slices_.size(); i++) 167 for (size_t i = 0; i < slices_.size(); i++)
133 { 168 {
134 if (GeometryToolbox::IsParallel(normal, slices_[i]->GetSlice().GetGeometry().GetNormal())) 169 if (GeometryToolbox::IsParallel(normal, slices_[i]->GetGeometry().GetNormal()))
135 { 170 {
136 // This slice is compatible with the selected normal 171 // This slice is compatible with the selected normal
137 slices_[pos] = slices_[i]; 172 slices_[pos] = slices_[i];
138 pos += 1; 173 pos += 1;
139 } 174 }
153 std::vector<Vector> normalCandidates; 188 std::vector<Vector> normalCandidates;
154 std::vector<unsigned int> normalCount; 189 std::vector<unsigned int> normalCount;
155 190
156 bool found = false; 191 bool found = false;
157 192
158 for (size_t i = 0; !found && i < GetSliceCount(); i++) 193 for (size_t i = 0; !found && i < GetSlicesCount(); i++)
159 { 194 {
160 const Vector& normal = GetSlice(i).GetGeometry().GetNormal(); 195 const Vector& normal = GetSlice(i).GetGeometry().GetNormal();
161 196
162 bool add = true; 197 bool add = true;
163 for (size_t j = 0; add && j < normalCandidates.size(); j++) // (*) 198 for (size_t j = 0; add && j < normalCandidates.size(); j++) // (*)
188 } 223 }
189 224
190 for (size_t i = 0; !found && i < normalCandidates.size(); i++) 225 for (size_t i = 0; !found && i < normalCandidates.size(); i++)
191 { 226 {
192 unsigned int count = normalCount[i]; 227 unsigned int count = normalCount[i];
193 if (count == GetSliceCount() || 228 if (count == GetSlicesCount() ||
194 count + 1 == GetSliceCount()) 229 count + 1 == GetSlicesCount())
195 { 230 {
196 normal = normalCandidates[i]; 231 normal = normalCandidates[i];
197 found = true; 232 found = true;
198 } 233 }
199 } 234 }
200 235
201 return found; 236 return found;
202 } 237 }
203 238
204 239
205 bool SlicesSorter::LookupSlice(size_t& index, 240 bool SlicesSorter::LookupClosestSlice(size_t& index,
206 const CoordinateSystem3D& slice) const 241 double& distance,
242 const CoordinateSystem3D& slice) const
207 { 243 {
208 // TODO Turn this linear-time lookup into a log-time lookup, 244 // TODO Turn this linear-time lookup into a log-time lookup,
209 // keeping track of whether the slices are sorted along the normal 245 // keeping track of whether the slices are sorted along the normal
210 246
211 for (size_t i = 0; i < slices_.size(); i++) 247 bool found = false;
212 { 248
213 if (slices_[i]->GetSlice().ContainsPlane(slice)) 249 distance = std::numeric_limits<double>::infinity();
214 { 250
215 index = i; 251 for (size_t i = 0; i < slices_.size(); i++)
216 return true; 252 {
217 } 253 assert(slices_[i] != NULL);
218 } 254
219 255 double tmp;
220 return false; 256 if (CoordinateSystem3D::GetDistance(tmp, slices_[i]->GetGeometry(), slice))
257 {
258 if (!found ||
259 tmp < distance)
260 {
261 index = i;
262 distance = tmp;
263 found = true;
264 }
265 }
266 }
267
268 return found;
221 } 269 }
222 } 270 }