Line data Source code
1 : #include "ForbildPhantom.h"
2 :
3 : using namespace std;
4 :
5 : namespace elsa::phantoms
6 : {
7 :
8 : template <typename data_t>
9 : ForbildPhantom<data_t>::ForbildPhantom(index_t maxDimension, data_t phantomMaxSize,
10 : int maxOrderIndex)
11 : : maxDimension{maxDimension},
12 : phantomMaxSize{phantomMaxSize},
13 3 : maxOrderIndex{maxOrderIndex} {};
14 :
15 : template <typename data_t>
16 : index_t scaleForbildShift(index_t maxDimension, data_t value, data_t maxValue)
17 2725 : {
18 2725 : return std::lround((value + (maxValue / 2)) * static_cast<data_t>(maxDimension)
19 2725 : / maxValue /* cm*/);
20 2725 : }
21 :
22 : template <typename data_t>
23 : data_t scaleForbild(index_t maxDimension, data_t value, data_t maxValue)
24 1675 : {
25 1675 : return value * static_cast<data_t>(maxDimension) / maxValue /* cm*/;
26 1675 : }
27 :
28 : template <typename data_t>
29 : void ForbildPhantom<data_t>::addEllipsoids(std::vector<std::array<data_t, 11>> datas)
30 3 : {
31 159 : for (auto data : datas) {
32 159 : data_t amplit = data[0];
33 159 : Vec3X<data_t> halfAxis(3);
34 159 : halfAxis << scaleForbild(maxDimension, data[1], phantomMaxSize),
35 159 : scaleForbild(maxDimension, data[2], phantomMaxSize),
36 159 : scaleForbild(maxDimension, data[3], phantomMaxSize);
37 :
38 159 : Vec3i center(3);
39 159 : center << scaleForbildShift(maxDimension, data[4], phantomMaxSize),
40 159 : scaleForbildShift(maxDimension, data[5], phantomMaxSize),
41 159 : scaleForbildShift(maxDimension, data[6], phantomMaxSize);
42 :
43 159 : Vec3X<data_t> euler(3);
44 159 : euler << data[7], data[8], data[9];
45 :
46 159 : int order = int(data[10]);
47 :
48 159 : if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5
49 159 : || std::abs(halfAxis[2]) < 0.5 || amplit < data_t(0)) {
50 144 : Logger::get("ForbildPhantom::addEllipsoids")
51 144 : ->warn("Ellipsoid will not be rendered, because of amplitude<0 or an invalid "
52 144 : "half axis! amplitude {}, half axis ({},{},{}) ",
53 144 : amplit, halfAxis[0], halfAxis[1], halfAxis[2]);
54 144 : continue;
55 144 : }
56 :
57 15 : ellipsoids.insert_or_assign(order, Ellipsoid<data_t>{amplit, center, halfAxis, euler});
58 15 : }
59 3 : }
60 :
61 : template <typename data_t>
62 : void ForbildPhantom<data_t>::addEllipsoidsClippedX(std::vector<std::array<data_t, 12>> datas)
63 1 : {
64 1 : for (auto data : datas) {
65 1 : data_t amplit = data[0];
66 1 : Vec3X<data_t> halfAxis(3);
67 1 : halfAxis << scaleForbild(maxDimension, data[1], phantomMaxSize),
68 1 : scaleForbild(maxDimension, data[2], phantomMaxSize),
69 1 : scaleForbild(maxDimension, data[3], phantomMaxSize);
70 :
71 1 : Vec3i center(3);
72 1 : center << scaleForbildShift(maxDimension, data[4], phantomMaxSize),
73 1 : scaleForbildShift(maxDimension, data[5], phantomMaxSize),
74 1 : scaleForbildShift(maxDimension, data[6], phantomMaxSize);
75 :
76 1 : Vec3X<data_t> euler(3);
77 1 : euler << data[7], data[8], data[9];
78 :
79 1 : index_t clippedX = scaleForbildShift(maxDimension, data[10], phantomMaxSize);
80 :
81 1 : int order = int(data[11]);
82 :
83 1 : if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5
84 1 : || std::abs(halfAxis[2]) < 0.5 || amplit < data_t(0)) {
85 0 : Logger::get("ForbildPhantom::addEllipsoidsClippedX")
86 0 : ->warn("Ellipsoid will not be rendered, because of amplitude<0 or an invalid "
87 0 : "half axis! amplitude {}, half axis ({},{},{})",
88 0 : amplit, halfAxis[0], halfAxis[1], halfAxis[2]);
89 0 : continue;
90 0 : }
91 1 : auto clippX = [clippedX, center](auto minMax) {
92 : // minMax in object space
93 1 : minMax[3] = data_t(clippedX) - data_t(center[INDEX_X]);
94 1 : return minMax;
95 1 : };
96 :
97 1 : ellipsoidsClippedX.insert_or_assign(
98 1 : order, std::pair{Ellipsoid<data_t>{amplit, center, halfAxis, euler}, clippX});
99 1 : }
100 1 : }
101 :
102 : template <typename data_t>
103 : void ForbildPhantom<data_t>::addSpheres(std::vector<std::array<data_t, 6>> datas)
104 3 : {
105 409 : for (auto data : datas) {
106 409 : data_t amplit = data[0];
107 409 : Vec3i center(3);
108 409 : center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
109 409 : scaleForbildShift(maxDimension, data[2], phantomMaxSize),
110 409 : scaleForbildShift(maxDimension, data[3], phantomMaxSize);
111 :
112 409 : data_t radius = scaleForbild(maxDimension, data[4], phantomMaxSize);
113 :
114 409 : int order = int(data[5]);
115 :
116 409 : if (radius < 0.5 || amplit < data_t(0)) {
117 367 : Logger::get("ForbildPhantom::addSpheres")
118 367 : ->warn("Sphere will not be rendered, because of amplitude<0 or an invalid "
119 367 : "radius!"
120 367 : " amplitude {}, radius {} ",
121 367 : amplit, radius);
122 367 : continue;
123 367 : }
124 :
125 42 : spheres.insert_or_assign(order, Sphere<data_t>{amplit, center, radius});
126 42 : }
127 3 : }
128 :
129 : template <typename data_t>
130 : void ForbildPhantom<data_t>::addEllipCylinders(std::vector<std::array<data_t, 9>> datas)
131 3 : {
132 5 : for (auto data : datas) {
133 :
134 5 : Orientation o = static_cast<Orientation>(std::lround(data[0]));
135 5 : data_t amplit = data[1];
136 5 : data_t length = scaleForbild(maxDimension, data[2], phantomMaxSize);
137 5 : Vec3i center;
138 5 : center << scaleForbildShift(maxDimension, data[3], phantomMaxSize),
139 5 : scaleForbildShift(maxDimension, data[4], phantomMaxSize),
140 5 : scaleForbildShift(maxDimension, data[5], phantomMaxSize);
141 :
142 5 : Vec2X<data_t> halfAxis;
143 5 : halfAxis << scaleForbild(maxDimension, data[6], phantomMaxSize),
144 5 : scaleForbild(maxDimension, data[7], phantomMaxSize);
145 :
146 5 : int order = int(data[8]);
147 :
148 5 : if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5 || amplit < data_t(0)
149 5 : || length < 1.0) {
150 1 : Logger::get("ForbildPhantom::addEllipCylinders")
151 1 : ->warn("EllipCylinder will not be rendered, because of amplitude<0 or an "
152 1 : "invalid "
153 1 : "half axis! amplitude {}, half axis ({},{}), length {} ",
154 1 : amplit, halfAxis[0], halfAxis[1], length);
155 1 : continue;
156 1 : }
157 :
158 4 : ellipCylinder.insert_or_assign(
159 4 : order, EllipCylinder<data_t>{o, amplit, center, halfAxis, length});
160 4 : }
161 3 : }
162 :
163 : template <typename data_t>
164 : void ForbildPhantom<data_t>::addEllipCylindersFree(std::vector<std::array<data_t, 11>> datas)
165 3 : {
166 7 : for (auto data : datas) {
167 :
168 7 : data_t amplit = data[0];
169 7 : data_t length = scaleForbild(maxDimension, data[1], phantomMaxSize);
170 7 : Vec3i center;
171 7 : center << scaleForbildShift(maxDimension, data[2], phantomMaxSize),
172 7 : scaleForbildShift(maxDimension, data[3], phantomMaxSize),
173 7 : scaleForbildShift(maxDimension, data[4], phantomMaxSize);
174 :
175 7 : Vec2X<data_t> halfAxis;
176 7 : halfAxis << scaleForbild(maxDimension, data[5], phantomMaxSize),
177 7 : scaleForbild(maxDimension, data[6], phantomMaxSize);
178 :
179 7 : Vec3X<data_t> eulers;
180 7 : eulers << data[7], data[8], data[9];
181 :
182 7 : int order = int(data[10]);
183 :
184 7 : if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5 || amplit < data_t(0)
185 7 : || length < 1.0) {
186 2 : Logger::get("ForbildPhantom::addEllipCylindersFree")
187 2 : ->warn("EllipCylinderFree will not be rendered, because of amplitude<0 "
188 2 : "or an "
189 2 : "invalid "
190 2 : "half axis! amplitude {}, half axis ({},{}), length {}, eulers "
191 2 : "({},{},{}) ",
192 2 : amplit, halfAxis[0], halfAxis[1], length, eulers[INDEX_A],
193 2 : eulers[INDEX_B], eulers[INDEX_C]);
194 2 : continue;
195 2 : }
196 :
197 5 : ellipCylinderFree.insert_or_assign(
198 5 : order, EllipCylinderFree<data_t>{amplit, center, halfAxis, length, eulers});
199 5 : }
200 3 : }
201 :
202 : template <typename data_t>
203 : void ForbildPhantom<data_t>::addCylinders(std::vector<std::array<data_t, 8>> datas)
204 3 : {
205 44 : for (auto data : datas) {
206 :
207 44 : Orientation o = static_cast<Orientation>(std::lround(data[0]));
208 44 : data_t amplit = data[1];
209 44 : Vec3i center;
210 44 : center << scaleForbildShift(maxDimension, data[2], phantomMaxSize),
211 44 : scaleForbildShift(maxDimension, data[3], phantomMaxSize),
212 44 : scaleForbildShift(maxDimension, data[4], phantomMaxSize);
213 :
214 44 : data_t radius = scaleForbild(maxDimension, data[5], phantomMaxSize);
215 44 : data_t length = scaleForbild(maxDimension, data[6], phantomMaxSize);
216 :
217 44 : int order = int(data[7]);
218 :
219 44 : if (amplit < data_t(0) || radius < 0.5 || length < 1.0) {
220 1 : Logger::get("ForbildPhantom::addCylinders")
221 1 : ->warn("Cylinder will not be rendered, because of amplitude<0 or an "
222 1 : "invalid "
223 1 : "radius or invalid length! amplitude {}, radius {}, length {} ",
224 1 : amplit, radius, length);
225 1 : continue;
226 1 : }
227 :
228 43 : cylinders.insert_or_assign(order, Cylinder<data_t>{o, amplit, center, radius, length});
229 43 : }
230 3 : }
231 :
232 : template <typename data_t>
233 : void ForbildPhantom<data_t>::addCylindersFree(std::vector<std::array<data_t, 10>> datas)
234 3 : {
235 187 : for (auto data : datas) {
236 187 : data_t amplit = data[0];
237 187 : Vec3i center;
238 187 : center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
239 187 : scaleForbildShift(maxDimension, data[2], phantomMaxSize),
240 187 : scaleForbildShift(maxDimension, data[3], phantomMaxSize);
241 :
242 187 : data_t radius = scaleForbild(maxDimension, data[4], phantomMaxSize);
243 187 : data_t length = scaleForbild(maxDimension, data[5], phantomMaxSize);
244 :
245 187 : Vec3X<data_t> eulers;
246 187 : eulers << data[6], data[7], data[8];
247 :
248 187 : int order = int(data[9]);
249 :
250 187 : if (amplit < data_t(0) || radius < 0.5 || length < 1.0) {
251 2 : Logger::get("ForbildPhantom::addCylinders")
252 2 : ->warn("Cylinder will not be rendered, because of amplitude<0 or an "
253 2 : "invalid "
254 2 : "radius or invalid length! amplitude {}, radius {}, length {} ",
255 2 : amplit, radius, length);
256 2 : continue;
257 2 : }
258 :
259 185 : cylindersFree.insert_or_assign(
260 185 : order, CylinderFree<data_t>{amplit, center, radius, length, eulers});
261 185 : }
262 3 : }
263 :
264 : template <typename data_t>
265 : void ForbildPhantom<data_t>::addBoxes(std::vector<std::array<data_t, 8>> datas)
266 3 : {
267 96 : for (auto data : datas) {
268 :
269 96 : data_t amplit = data[0];
270 96 : Vec3i center;
271 96 : center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
272 96 : scaleForbildShift(maxDimension, data[2], phantomMaxSize),
273 96 : scaleForbildShift(maxDimension, data[3], phantomMaxSize);
274 :
275 96 : Vec3X<data_t> edgeLengths;
276 96 : edgeLengths << scaleForbild(maxDimension, data[4], phantomMaxSize),
277 96 : scaleForbild(maxDimension, data[5], phantomMaxSize),
278 96 : scaleForbild(maxDimension, data[6], phantomMaxSize);
279 :
280 96 : int order = int(data[7]);
281 :
282 96 : if (std::abs(edgeLengths[0]) < 1 || std::abs(edgeLengths[1]) < 1
283 96 : || std::abs(edgeLengths[2]) < 1 || amplit < data_t(0)) {
284 56 : Logger::get("ForbildPhantom::addBoxes")
285 56 : ->warn("Box will not be rendered, because of amplitude<0 or an invalid "
286 56 : "edge lengths! amplitude {}, edge lengths ({},{},{}) ",
287 56 : amplit, edgeLengths[0], edgeLengths[1], edgeLengths[2]);
288 56 : continue;
289 56 : }
290 :
291 40 : boxes.insert_or_assign(order, Box<data_t>{amplit, center, edgeLengths});
292 40 : }
293 3 : }
294 :
295 : // ------------------------------------------
296 : // explicit template instantiation
297 : template class ForbildPhantom<float>;
298 : template class ForbildPhantom<double>;
299 :
300 : } // namespace elsa::phantoms
|