Mercurial > hg > orthanc-stone
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 } |