VoxelCast.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2017 Imperial College London
5  * Copyright 2013-2017 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_VoxelCast_H
21 #define MIRTK_VoxelCast_H
22 
23 #include "mirtk/Voxel.h"
24 #include "mirtk/Stream.h"
25 #include "mirtk/Math.h"
26 
27 
28 // Overloading the C++ conversion operators for vector types would be possible
29 // as well, however, this can lead to ambiguitis in mathematical expressions
30 // when a vector can be constructed from a scalar and converted to a scalar at
31 // the same time. Then it is no longer clear whether the arithmetic operation
32 // should be performed between scalars, vectors, or a mix of both. Therefore,
33 // only support the needed voxel type conversions as template specializations
34 // of our own voxel_cast template function.
35 
36 namespace mirtk {
37 
38 
39 // -----------------------------------------------------------------------------
40 /// Auxiliary template class for partial voxel_cast specialization
41 template <class TIn, class TOut>
43 {
44  /// By default, use static_cast to convert voxel value from one type to another.
45  /// If the value is out of the range which can be represented by the output
46  /// type, the minium/maximum value of the output type is returned instead.
47  static TOut Convert(const TIn &value)
48  {
49  if (static_cast<double>(value) < voxel_limits<TOut>::min()) {
50  return voxel_limits<TOut>::min_value();
51  } else if (static_cast<double>(value) > voxel_limits<TOut>::max()) {
52  return voxel_limits<TOut>::max_value();
53  }
54  return static_cast <TOut>(value);
55  }
56 };
57 
58 // -----------------------------------------------------------------------------
59 template <class T>
60 struct VoxelCaster<T, T>
61 {
62  static T Convert(const T &value)
63  {
64  return value;
65  }
66 };
67 
68 
69 // =============================================================================
70 // Scalar types
71 // =============================================================================
72 
73 // -----------------------------------------------------------------------------
74 template <>
75 struct VoxelCaster<float, float>
76 {
77  static float Convert(const float &value)
78  {
79  return value;
80  }
81 };
82 
83 // -----------------------------------------------------------------------------
84 template <>
85 struct VoxelCaster<float, double>
86 {
87  static double Convert(const float &value)
88  {
89  return static_cast<double>(value);
90  }
91 };
92 
93 // -----------------------------------------------------------------------------
94 #define _MIRTK_VOXELCAST_FLOAT_TO_INT(TOut) \
95  template <> \
96  struct VoxelCaster<float, TOut> \
97  { \
98  static TOut Convert(const float &value) \
99  { \
100  if (static_cast<double>(value) < voxel_limits<TOut>::min()) { \
101  return voxel_limits<TOut>::min_value(); \
102  } else if (static_cast<double>(value) > voxel_limits<TOut>::max()) { \
103  return voxel_limits<TOut>::max_value(); \
104  } \
105  return static_cast<TOut>(round(value)); \
106  } \
107  }
108 _MIRTK_VOXELCAST_FLOAT_TO_INT(unsigned char);
109 _MIRTK_VOXELCAST_FLOAT_TO_INT(char);
110 _MIRTK_VOXELCAST_FLOAT_TO_INT(unsigned short);
111 _MIRTK_VOXELCAST_FLOAT_TO_INT(short);
112 _MIRTK_VOXELCAST_FLOAT_TO_INT(int);
113 _MIRTK_VOXELCAST_FLOAT_TO_INT(unsigned int);
114 _MIRTK_VOXELCAST_FLOAT_TO_INT(long);
115 _MIRTK_VOXELCAST_FLOAT_TO_INT(unsigned long);
116 #undef _MIRTK_VOXELCAST_FLOAT_TO_INT
117 
118 // -----------------------------------------------------------------------------
119 template <>
120 struct VoxelCaster<double, float>
121 {
122  static float Convert(const double &value)
123  {
124  return static_cast<float>(value);
125  }
126 };
127 
128 // -----------------------------------------------------------------------------
129 template <>
130 struct VoxelCaster<double, double>
131 {
132  static double Convert(const double &value)
133  {
134  return value;
135  }
136 };
137 
138 // -----------------------------------------------------------------------------
139 #define _MIRTK_VOXELCAST_DOUBLE_TO_INT(TOut) \
140  template <> \
141  struct VoxelCaster<double, TOut> \
142  { \
143  static TOut Convert(const double &value) \
144  { \
145  if (value < voxel_limits<TOut>::min()) { \
146  return voxel_limits<TOut>::min_value(); \
147  } else if (value > voxel_limits<TOut>::max()) { \
148  return voxel_limits<TOut>::max_value(); \
149  } \
150  return static_cast<TOut>(round(value)); \
151  } \
152  }
153 _MIRTK_VOXELCAST_DOUBLE_TO_INT(unsigned char);
154 _MIRTK_VOXELCAST_DOUBLE_TO_INT(char);
155 _MIRTK_VOXELCAST_DOUBLE_TO_INT(unsigned short);
156 _MIRTK_VOXELCAST_DOUBLE_TO_INT(short);
157 _MIRTK_VOXELCAST_DOUBLE_TO_INT(int);
158 _MIRTK_VOXELCAST_DOUBLE_TO_INT(unsigned int);
159 _MIRTK_VOXELCAST_DOUBLE_TO_INT(long);
160 _MIRTK_VOXELCAST_DOUBLE_TO_INT(unsigned long);
161 #undef _MIRTK_VOXELCAST_DOUBLE_TO_INT
162 
163 // -----------------------------------------------------------------------------
164 template <class TIn>
165 struct VoxelCaster<TIn, float1>
166 {
167  static float1 Convert(const TIn &value)
168  {
169  return make_float1(value);
170  }
171 };
172 
173 // -----------------------------------------------------------------------------
174 template <class TIn>
175 struct VoxelCaster<TIn, double1>
176 {
177  static double1 Convert(const TIn &value)
178  {
179  return make_double1(static_cast<double>(value));
180  }
181 };
182 
183 // -----------------------------------------------------------------------------
184 template <class TIn>
185 struct VoxelCaster<TIn, float2>
186 {
187  static float2 Convert(const TIn &value)
188  {
189  return make_float2(static_cast<float>(value));
190  }
191 };
192 
193 // -----------------------------------------------------------------------------
194 template <class TIn>
195 struct VoxelCaster<TIn, double2>
196 {
197  static double2 Convert(const TIn &value)
198  {
199  return make_double2(value);
200  }
201 };
202 
203 // -----------------------------------------------------------------------------
204 template <class TIn>
205 struct VoxelCaster<TIn, float3>
206 {
207  static float3 Convert(const TIn &value)
208  {
209  return make_float3(static_cast<float>(value));
210  }
211 };
212 
213 // -----------------------------------------------------------------------------
214 template <class TIn>
215 struct VoxelCaster<TIn, double3>
216 {
217  static double3 Convert(const TIn &value)
218  {
219  return make_double3(static_cast<double>(value));
220  }
221 };
222 
223 // -----------------------------------------------------------------------------
224 template <class TIn>
225 struct VoxelCaster<TIn, Vector>
226 {
227  static Vector Convert(const TIn &value)
228  {
229  return Vector(1, VoxelCaster<TIn, double>::Convert(value));
230  }
231 };
232 
233 // -----------------------------------------------------------------------------
234 template <class TOut>
235 struct VoxelCaster<int, Vector3D<TOut> >
236 {
237  static Vector3D<TOut> Convert(const int &value)
238  {
240  }
241 };
242 
243 // -----------------------------------------------------------------------------
244 template <class TIn>
245 struct VoxelCaster<TIn, float4>
246 {
247  static float4 Convert(const TIn &value)
248  {
249  return make_float4(static_cast<float>(value));
250  }
251 };
252 
253 // -----------------------------------------------------------------------------
254 template <class TIn>
255 struct VoxelCaster<TIn, double4>
256 {
257  static double4 Convert(const TIn &value)
258  {
259  return make_double4(static_cast<double>(value));
260  }
261 };
262 
263 // -----------------------------------------------------------------------------
264 template <class TIn>
265 struct VoxelCaster<TIn, float3x3>
266 {
267  static float3x3 Convert(const TIn &value)
268  {
269  return make_float3x3(static_cast<float>(value));
270  }
271 };
272 
273 // -----------------------------------------------------------------------------
274 template <class TIn>
275 struct VoxelCaster<TIn, double3x3>
276 {
277  static double3x3 Convert(const TIn &value)
278  {
279  return make_double3x3(static_cast<double>(value));
280  }
281 };
282 
283 // -----------------------------------------------------------------------------
284 template <class TOut>
285 struct VoxelCaster<int, VectorND<9, TOut> >
286 {
287  static VectorND<9, TOut> Convert(const int &value)
288  {
290  }
291 };
292 
293 // -----------------------------------------------------------------------------
294 template <class TOut>
295 struct VoxelCaster<double, VectorND<9, TOut> >
296 {
297  static VectorND<9, TOut> Convert(const double &value)
298  {
300  }
301 };
302 
303 // -----------------------------------------------------------------------------
304 template <>
305 struct VoxelCaster<float, Vector>
306 {
307  static Vector Convert(const float &value)
308  {
309  return Vector(1, static_cast<double>(value));
310  }
311 };
312 
313 // -----------------------------------------------------------------------------
314 template <>
315 struct VoxelCaster<double, Vector>
316 {
317  static Vector Convert(const double &value)
318  {
319  return Vector(1, value);
320  }
321 };
322 
323 // -----------------------------------------------------------------------------
324 template <class TOut>
325 struct VoxelCaster<double, Vector3D<TOut> >
326 {
327  static Vector3D<TOut> Convert(const double &value)
328  {
330  }
331 };
332 
333 // -----------------------------------------------------------------------------
334 template <class TOut>
335 struct VoxelCaster<int, Vector4D<TOut> >
336 {
337  static Vector4D<TOut> Convert(const int &value)
338  {
340  }
341 };
342 
343 // -----------------------------------------------------------------------------
344 template <class TOut>
345 struct VoxelCaster<double, Vector4D<TOut> >
346 {
347  static Vector4D<TOut> Convert(const double &value)
348  {
350  }
351 };
352 
353 // -----------------------------------------------------------------------------
354 template <class TOut>
355 struct VoxelCaster<float1, TOut>
356 {
357  static TOut Convert(const float1 &value)
358  {
359  return VoxelCaster<float, TOut>::Convert(value.x);
360  }
361 };
362 
363 // -----------------------------------------------------------------------------
364 template <>
365 struct VoxelCaster<float1, float1>
366 {
367  static float1 Convert(const float1 &value)
368  {
369  return value;
370  }
371 };
372 
373 // -----------------------------------------------------------------------------
374 template <>
375 struct VoxelCaster<float1, double1>
376 {
377  static double1 Convert(const float1 &value)
378  {
379  return make_double1(value);
380  }
381 };
382 
383 // -----------------------------------------------------------------------------
384 template <>
385 struct VoxelCaster<float1, Vector>
386 {
387  static Vector Convert(const float1 &value)
388  {
389  Vector v(1);
390  v(0) = value.x;
391  return v;
392  }
393 };
394 
395 // -----------------------------------------------------------------------------
396 template <class TOut>
397 struct VoxelCaster<double1, TOut>
398 {
399  static TOut Convert(const double1 &value)
400  {
401  return VoxelCaster<double, TOut>::Convert(value.x);
402  }
403 };
404 
405 // -----------------------------------------------------------------------------
406 template <>
407 struct VoxelCaster<double1, float1>
408 {
409  static float1 Convert(const double1 &value)
410  {
411  return make_float1(value);
412  }
413 };
414 
415 // -----------------------------------------------------------------------------
416 template <>
417 struct VoxelCaster<double1, double1>
418 {
419  static double1 Convert(const double1 &value)
420  {
421  return value;
422  }
423 };
424 
425 // -----------------------------------------------------------------------------
426 template <>
427 struct VoxelCaster<double1, Vector>
428 {
429  static Vector Convert(const double1 &value)
430  {
431  Vector v(1);
432  v(0) = value.x;
433  return v;
434  }
435 };
436 
437 
438 // =============================================================================
439 // Vector for generic BaseImage interface
440 // =============================================================================
441 
442 // -----------------------------------------------------------------------------
443 template <class TOut>
444 struct VoxelCaster<Vector, TOut>
445 {
446  static TOut Convert(const Vector &value)
447  {
448  if (value.Rows() == 1) return VoxelCaster<double, TOut>::Convert(value(0));
449  cerr << "Can only cast vector with exactly one element to a scalar!" << endl;
450  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
451  exit(1);
452  }
453 };
454 
455 // -----------------------------------------------------------------------------
456 template <>
457 struct VoxelCaster<Vector, Vector>
458 {
459  static Vector Convert(const Vector &value)
460  {
461  return value;
462  }
463 };
464 
465 // -----------------------------------------------------------------------------
466 template <>
467 struct VoxelCaster<Vector, float1>
468 {
469  static float1 Convert(const Vector &value)
470  {
471  if (value.Rows() == 1) return make_float1(value(0));
472  cerr << "Can only cast vector with exactly one element to a 1D vector!" << endl;
473  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
474  exit(1);
475  }
476 };
477 
478 // -----------------------------------------------------------------------------
479 template <>
480 struct VoxelCaster<Vector, double1>
481 {
482  static double1 Convert(const Vector &value)
483  {
484  if (value.Rows() == 1) return make_double1(value(0));
485  cerr << "Can only cast vector with exactly one element to a 1D vector!" << endl;
486  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
487  exit(1);
488  }
489 };
490 
491 // -----------------------------------------------------------------------------
492 template <>
493 struct VoxelCaster<Vector, float2>
494 {
495  static float2 Convert(const Vector &value)
496  {
497  if (value.Rows() == 2) return make_float2(value(0), value(1));
498  cerr << "Can only cast vector with exactly two elements to a 2D vector!" << endl;
499  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
500  exit(1);
501  }
502 };
503 
504 // -----------------------------------------------------------------------------
505 template <>
506 struct VoxelCaster<Vector, double2>
507 {
508  static double2 Convert(const Vector &value)
509  {
510  if (value.Rows() == 2) return make_double2(value(0), value(1));
511  cerr << "Can only cast vector with exactly two elements to a 2D vector!" << endl;
512  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
513  exit(1);
514  }
515 };
516 
517 // -----------------------------------------------------------------------------
518 template <>
519 struct VoxelCaster<Vector, float3>
520 {
521  static float3 Convert(const Vector &value)
522  {
523  if (value.Rows() == 3) return make_float3(value(0), value(1), value(2));
524  cerr << "Can only cast vector with exactly three elements to a 3D vector!" << endl;
525  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
526  exit(1);
527  }
528 };
529 
530 // -----------------------------------------------------------------------------
531 template <>
532 struct VoxelCaster<Vector, double3>
533 {
534  static double3 Convert(const Vector &value)
535  {
536  if (value.Rows() == 3) return make_double3(value(0), value(1), value(2));
537  cerr << "Can only cast vector with exactly three elements to a 3D vector!" << endl;
538  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
539  exit(1);
540  }
541 };
542 
543 // -----------------------------------------------------------------------------
544 template <class TOut>
545 struct VoxelCaster<Vector, Vector3D<TOut> >
546 {
547  static Vector3D<TOut> Convert(const Vector &value)
548  {
549  if (value.Rows() == 3) {
553  }
554  cerr << "Can only cast vector with exactly three elements to a 3D vector!" << endl;
555  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
556  exit(1);
557  }
558 };
559 
560 // -----------------------------------------------------------------------------
561 template <>
562 struct VoxelCaster<Vector, float4>
563 {
564  static float4 Convert(const Vector &value)
565  {
566  if (value.Rows() == 4) return make_float4(value(0), value(1), value(2), value(3));
567  cerr << "Can only cast vector with exactly four elements to a 4D vector!" << endl;
568  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
569  exit(1);
570  }
571 };
572 
573 // -----------------------------------------------------------------------------
574 template <>
575 struct VoxelCaster<Vector, double4>
576 {
577  static double4 Convert(const Vector &value)
578  {
579  if (value.Rows() == 4) return make_double4(value(0), value(1), value(2), value(3));
580  cerr << "Can only cast vector with exactly four elements to a 4D vector!" << endl;
581  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
582  exit(1);
583  }
584 };
585 
586 // -----------------------------------------------------------------------------
587 template <class TOut>
588 struct VoxelCaster<Vector, Vector4D<TOut> >
589 {
590  static Vector4D<TOut> Convert(const Vector &value)
591  {
592  if (value.Rows() == 4) {
597  }
598  cerr << "Can only cast vector with exactly four elements to a 4D vector!" << endl;
599  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
600  exit(1);
601  }
602 };
603 
604 // -----------------------------------------------------------------------------
605 template <class TOut>
606 struct VoxelCaster<Vector, VectorND<9, TOut> >
607 {
608  static VectorND<9, TOut> Convert(const Vector &value)
609  {
610  if (value.Rows() == 9) {
612  for (int i = 0; i < 9; ++i) {
613  v(i) = VoxelCaster<double, TOut>::Convert(value(i));
614  }
615  return v;
616  }
617  cerr << "Can only cast vector with exactly nine elements to a 9D vector!" << endl;
618  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
619  exit(1);
620  }
621 };
622 
623 // -----------------------------------------------------------------------------
624 template <>
625 struct VoxelCaster<Vector, float3x3>
626 {
627  static float3x3 Convert(const Vector &v)
628  {
629  float3x3 m;
630  if (v.Rows() == 9) {
640  } else if (v.Rows() == 6) {
644  m.b.x = m.a.y;
647  m.c.x = m.a.z;
648  m.c.y = m.b.z;
650  } else {
651  cerr << "Can only cast vector of size 6 or 9 to a 3x3 matrix!" << endl;
652  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
653  exit(1);
654  }
655  return m;
656  }
657 };
658 
659 // -----------------------------------------------------------------------------
660 template <>
661 struct VoxelCaster<Vector, double3x3>
662 {
663  static double3x3 Convert(const Vector &v)
664  {
665  double3x3 m;
666  if (v.Rows() == 9) {
667  m.a.x = v(0);
668  m.a.y = v(1);
669  m.a.z = v(2);
670  m.b.x = v(3);
671  m.b.y = v(4);
672  m.b.z = v(5);
673  m.c.x = v(6);
674  m.c.y = v(7);
675  m.c.z = v(8);
676  } else if (v.Rows() == 6) {
677  m.a.x = v(0);
678  m.a.y = v(1);
679  m.a.z = v(2);
680  m.b.x = m.a.y;
681  m.b.y = v(3);
682  m.b.z = v(4);
683  m.c.x = m.a.z;
684  m.c.y = m.b.z;
685  m.c.z = v(5);
686  } else {
687  cerr << "Can only cast vector of size 6 or 9 to a 3x3 matrix!" << endl;
688  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
689  exit(1);
690  }
691  return m;
692  }
693 };
694 
695 
696 // =============================================================================
697 // 2D vector types
698 // =============================================================================
699 
700 // -----------------------------------------------------------------------------
701 template <class TOut>
702 struct VoxelCaster<float2, TOut>
703 {
704  static TOut Convert(const float2 &)
705  {
706  cerr << "Cannot cast 2D vector to a scalar!" << endl;
707  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
708  exit(1);
709  }
710 };
711 
712 // -----------------------------------------------------------------------------
713 template <>
714 struct VoxelCaster<float2, float2>
715 {
716  static float2 Convert(const float2 &value)
717  {
718  return value;
719  }
720 };
721 
722 // -----------------------------------------------------------------------------
723 template <>
724 struct VoxelCaster<float2, double2>
725 {
726  static double2 Convert(const float2 &value)
727  {
728  return make_double2(value);
729  }
730 };
731 
732 // -----------------------------------------------------------------------------
733 template <>
734 struct VoxelCaster<float2, Vector>
735 {
736  static Vector Convert(const float2 &value)
737  {
738  Vector v(2);
739  v(0) = value.x;
740  v(1) = value.y;
741  return v;
742  }
743 };
744 
745 // -----------------------------------------------------------------------------
746 template <class TOut>
747 struct VoxelCaster<double2, TOut>
748 {
749  static TOut Convert(const double2 &)
750  {
751  cerr << "Cannot cast 2D vector to a scalar!" << endl;
752  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
753  exit(1);
754  }
755 };
756 
757 // -----------------------------------------------------------------------------
758 template <>
759 struct VoxelCaster<double2, float2>
760 {
761  static float2 Convert(const double2 &value)
762  {
763  return make_float2(value);
764  }
765 };
766 
767 // -----------------------------------------------------------------------------
768 template <>
769 struct VoxelCaster<double2, double2>
770 {
771  static double2 Convert(const double2 &value)
772  {
773  return value;
774  }
775 };
776 
777 // -----------------------------------------------------------------------------
778 template <>
779 struct VoxelCaster<double2, Vector>
780 {
781  static Vector Convert(const double2 &value)
782  {
783  Vector v(2);
784  v(0) = value.x;
785  v(1) = value.y;
786  return v;
787  }
788 };
789 
790 
791 // =============================================================================
792 // 3D vector types
793 // =============================================================================
794 
795 // -----------------------------------------------------------------------------
796 template <class TOut>
797 struct VoxelCaster<float3, TOut>
798 {
799  static TOut Convert(const float3 &)
800  {
801  cerr << "Cannot cast 3D vector to a scalar!" << endl;
802  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
803  exit(1);
804  }
805 };
806 
807 // -----------------------------------------------------------------------------
808 template <>
809 struct VoxelCaster<float3, float3>
810 {
811  static float3 Convert(const float3 &value)
812  {
813  return value;
814  }
815 };
816 
817 // -----------------------------------------------------------------------------
818 template <>
819 struct VoxelCaster<float3, double3>
820 {
821  static double3 Convert(const float3 &value)
822  {
823  return make_double3(value);
824  }
825 };
826 
827 // -----------------------------------------------------------------------------
828 template <>
829 struct VoxelCaster<float3, Vector>
830 {
831  static Vector Convert(const float3 &value)
832  {
833  Vector v(3);
834  v(0) = value.x;
835  v(1) = value.y;
836  v(2) = value.z;
837  return v;
838  }
839 };
840 
841 // -----------------------------------------------------------------------------
842 template <class TOut>
843 struct VoxelCaster<double3, TOut>
844 {
845  static TOut Convert(const double3 &)
846  {
847  cerr << "Cannot cast 3D vector to a scalar!" << endl;
848  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
849  exit(1);
850  }
851 };
852 
853 // -----------------------------------------------------------------------------
854 template <>
855 struct VoxelCaster<double3, float3>
856 {
857  static float3 Convert(const double3 &value)
858  {
859  return make_float3(value);
860  }
861 };
862 
863 // -----------------------------------------------------------------------------
864 template <>
865 struct VoxelCaster<double3, double3>
866 {
867  static double3 Convert(const double3 &value)
868  {
869  return value;
870  }
871 };
872 
873 // -----------------------------------------------------------------------------
874 template <>
875 struct VoxelCaster<double3, Vector>
876 {
877  static Vector Convert(const double3 &value)
878  {
879  Vector v(3);
880  v(0) = value.x;
881  v(1) = value.y;
882  v(2) = value.z;
883  return v;
884  }
885 };
886 
887 // -----------------------------------------------------------------------------
888 template <class TIn>
889 struct VoxelCaster<Vector3D<TIn>, Vector>
890 {
891  static Vector Convert(const Vector3D<TIn> &value)
892  {
893  Vector v(3);
894  v.Put(value);
895  return v;
896  }
897 };
898 
899 // -----------------------------------------------------------------------------
900 template <class TIn, class TOut>
901 struct VoxelCaster<Vector3D<TIn>, TOut>
902 {
903  static TOut Convert(const Vector3D<TIn> &)
904  {
905  cerr << "Cannot cast 3D vector to a scalar!" << endl;
906  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
907  exit(1);
908  }
909 };
910 
911 // -----------------------------------------------------------------------------
912 template <class TIn, class TOut>
913 struct VoxelCaster<Vector3D<TIn>, Vector3D<TOut> >
914 {
915  static Vector3D<TOut> Convert(const Vector3D<TIn> &value)
916  {
920  }
921 };
922 
923 // -----------------------------------------------------------------------------
924 template <class T>
925 struct VoxelCaster<Vector3D<T>, Vector3D<T> >
926 {
927  static Vector3D<T> Convert(const Vector3D<T> &value)
928  {
929  return value;
930  }
931 };
932 
933 
934 // =============================================================================
935 // 4D vector types
936 // =============================================================================
937 
938 // -----------------------------------------------------------------------------
939 template <class TOut>
940 struct VoxelCaster<float4, TOut>
941 {
942  static TOut Convert(const float4 &)
943  {
944  cerr << "Cannot cast 4D vector to a scalar!" << endl;
945  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
946  exit(1);
947  }
948 };
949 
950 // -----------------------------------------------------------------------------
951 template <>
952 struct VoxelCaster<float4, float4>
953 {
954  static float4 Convert(const float4 &value)
955  {
956  return value;
957  }
958 };
959 
960 // -----------------------------------------------------------------------------
961 template <>
962 struct VoxelCaster<float4, double4>
963 {
964  static double4 Convert(const float4 &value)
965  {
966  return make_double4(value);
967  }
968 };
969 
970 // -----------------------------------------------------------------------------
971 template <>
972 struct VoxelCaster<float4, Vector>
973 {
974  static Vector Convert(const float4 &value)
975  {
976  Vector v(4);
977  v(0) = value.x;
978  v(1) = value.y;
979  v(2) = value.z;
980  v(3) = value.w;
981  return v;
982  }
983 };
984 
985 // -----------------------------------------------------------------------------
986 template <class TOut>
987 struct VoxelCaster<double4, TOut>
988 {
989  static TOut Convert(const double4 &)
990  {
991  cerr << "Cannot cast 4D vector to a scalar!" << endl;
992  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
993  exit(1);
994  }
995 };
996 
997 // -----------------------------------------------------------------------------
998 template <>
999 struct VoxelCaster<double4, float4>
1000 {
1001  static float4 Convert(const double4 &value)
1002  {
1003  return make_float4(value);
1004  }
1005 };
1006 
1007 // -----------------------------------------------------------------------------
1008 template <>
1009 struct VoxelCaster<double4, double4>
1010 {
1011  static double4 Convert(const double4 &value)
1012  {
1013  return value;
1014  }
1015 };
1016 
1017 // -----------------------------------------------------------------------------
1018 template <>
1019 struct VoxelCaster<double4, Vector>
1020 {
1021  static Vector Convert(const double4 &value)
1022  {
1023  Vector v(4);
1024  v(0) = value.x;
1025  v(1) = value.y;
1026  v(2) = value.z;
1027  v(3) = value.w;
1028  return v;
1029  }
1030 };
1031 
1032 // -----------------------------------------------------------------------------
1033 template <class TIn, class TOut>
1034 struct VoxelCaster<Vector4D<TIn>, TOut>
1035 {
1036  static TOut Convert(const Vector4D<TIn> &)
1037  {
1038  cerr << "Cannot cast 4D vector to a scalar!" << endl;
1039  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
1040  exit(1);
1041  }
1042 };
1043 
1044 // -----------------------------------------------------------------------------
1045 template <class TIn, class TOut>
1046 struct VoxelCaster<Vector4D<TIn>, Vector4D<TOut> >
1047 {
1048  static Vector4D<TOut> Convert(const Vector4D<TIn> &value)
1049  {
1054  }
1055 };
1056 
1057 // -----------------------------------------------------------------------------
1058 template <class T>
1059 struct VoxelCaster<Vector4D<T>, Vector4D<T> >
1060 {
1061  static Vector4D<T> Convert(const Vector4D<T> &value)
1062  {
1063  return value;
1064  }
1065 };
1066 
1067 // -----------------------------------------------------------------------------
1068 template <class TIn>
1069 struct VoxelCaster<Vector4D<TIn>, Vector>
1070 {
1071  static Vector Convert(const Vector4D<TIn> &value)
1072  {
1073  Vector v(4);
1074  v.Put(value);
1075  return v;
1076  }
1077 };
1078 
1079 
1080 // =============================================================================
1081 // 9D vector types
1082 // =============================================================================
1083 
1084 // -----------------------------------------------------------------------------
1085 template <class TIn, class TOut>
1086 struct VoxelCaster<VectorND<9, TIn>, TOut>
1087 {
1088  static TOut Convert(const VectorND<9, TIn> &)
1089  {
1090  cerr << "Cannot cast 9D vector to a scalar!" << endl;
1091  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
1092  exit(1);
1093  }
1094 };
1095 
1096 // -----------------------------------------------------------------------------
1097 template <class TIn, class TOut>
1098 struct VoxelCaster<VectorND<9, TIn>, VectorND<9, TOut> >
1099 {
1100  static VectorND<9, TOut> Convert(const VectorND<9, TIn> &value)
1101  {
1103  for (int i = 0; i < 9; ++i) {
1104  v(i) = VoxelCaster<TIn, TOut>::Convert(value(i));
1105  }
1106  return v;
1107  }
1108 };
1109 
1110 // -----------------------------------------------------------------------------
1111 template <class T>
1112 struct VoxelCaster<VectorND<9, T>, VectorND<9, T> >
1113 {
1114  static VectorND<9, T> Convert(const VectorND<9, T> &value)
1115  {
1116  return value;
1117  }
1118 };
1119 
1120 // -----------------------------------------------------------------------------
1121 template <class TIn>
1122 struct VoxelCaster<VectorND<9, TIn>, Vector>
1123 {
1124  static Vector Convert(const VectorND<9, TIn> &value)
1125  {
1126  Vector v(9);
1127  for (int i = 0; i < 9; ++i) {
1128  v(i) = VoxelCaster<TIn, double>::Convert(value(i));
1129  }
1130  return v;
1131  }
1132 };
1133 
1134 // -----------------------------------------------------------------------------
1135 template <class TIn>
1136 struct VoxelCaster<VectorND<9, TIn>, float3x3>
1137 {
1138  static float3x3 Convert(const VectorND<9, TIn> &v)
1139  {
1140  float3x3 m;
1141  m.a.x = VoxelCaster<TIn, float>::Convert(v(0));
1142  m.a.y = VoxelCaster<TIn, float>::Convert(v(1));
1143  m.a.z = VoxelCaster<TIn, float>::Convert(v(2));
1144  m.b.x = VoxelCaster<TIn, float>::Convert(v(3));
1145  m.b.y = VoxelCaster<TIn, float>::Convert(v(4));
1146  m.b.z = VoxelCaster<TIn, float>::Convert(v(5));
1147  m.c.x = VoxelCaster<TIn, float>::Convert(v(6));
1148  m.c.y = VoxelCaster<TIn, float>::Convert(v(7));
1149  m.c.z = VoxelCaster<TIn, float>::Convert(v(8));
1150  return m;
1151  }
1152 };
1153 
1154 // -----------------------------------------------------------------------------
1155 template <class TIn>
1156 struct VoxelCaster<VectorND<9, TIn>, double3x3>
1157 {
1158  static double3x3 Convert(const VectorND<9, TIn> &v)
1159  {
1160  double3x3 m;
1161  m.a.x = VoxelCaster<TIn, double>::Convert(v(0));
1162  m.a.y = VoxelCaster<TIn, double>::Convert(v(1));
1163  m.a.z = VoxelCaster<TIn, double>::Convert(v(2));
1164  m.b.x = VoxelCaster<TIn, double>::Convert(v(3));
1165  m.b.y = VoxelCaster<TIn, double>::Convert(v(4));
1166  m.b.z = VoxelCaster<TIn, double>::Convert(v(5));
1167  m.c.x = VoxelCaster<TIn, double>::Convert(v(6));
1168  m.c.y = VoxelCaster<TIn, double>::Convert(v(7));
1169  m.c.z = VoxelCaster<TIn, double>::Convert(v(8));
1170  return m;
1171  }
1172 };
1173 
1174 
1175 // =============================================================================
1176 // Matrix types
1177 // =============================================================================
1178 
1179 // -----------------------------------------------------------------------------
1180 template <class TOut>
1181 struct VoxelCaster<float3x3, TOut>
1182 {
1183  static TOut Convert(const float3x3 &)
1184  {
1185  cerr << "Cannot cast 3x3 matrix to a scalar!" << endl;
1186  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
1187  exit(1);
1188  }
1189 };
1190 
1191 // -----------------------------------------------------------------------------
1192 template <>
1193 struct VoxelCaster<float3x3, float3x3>
1194 {
1195  static float3x3 Convert(const float3x3 &value)
1196  {
1197  return value;
1198  }
1199 };
1200 
1201 // -----------------------------------------------------------------------------
1202 template <>
1203 struct VoxelCaster<float3x3, double3x3>
1204 {
1205  static double3x3 Convert(const float3x3 &value)
1206  {
1207  return make_double3x3(value);
1208  }
1209 };
1210 
1211 // -----------------------------------------------------------------------------
1212 template <class TOut>
1213 struct VoxelCaster<float3x3, VectorND<9, TOut> >
1214 {
1215  static VectorND<9, TOut> Convert(const float3x3 &value)
1216  {
1218  v(0) = VoxelCaster<float, TOut>::Convert(value.a.x);
1219  v(1) = VoxelCaster<float, TOut>::Convert(value.a.y);
1220  v(2) = VoxelCaster<float, TOut>::Convert(value.a.z);
1221  v(3) = VoxelCaster<float, TOut>::Convert(value.b.x);
1222  v(4) = VoxelCaster<float, TOut>::Convert(value.b.y);
1223  v(5) = VoxelCaster<float, TOut>::Convert(value.b.z);
1224  v(6) = VoxelCaster<float, TOut>::Convert(value.c.x);
1225  v(7) = VoxelCaster<float, TOut>::Convert(value.c.y);
1226  v(8) = VoxelCaster<float, TOut>::Convert(value.c.z);
1227  return v;
1228  }
1229 };
1230 
1231 // -----------------------------------------------------------------------------
1232 template <>
1233 struct VoxelCaster<float3x3, Vector>
1234 {
1235  static Vector Convert(const float3x3 &value)
1236  {
1237  Vector v(9);
1238  v(0) = value.a.x;
1239  v(1) = value.a.y;
1240  v(2) = value.a.z;
1241  v(3) = value.b.x;
1242  v(4) = value.b.y;
1243  v(5) = value.b.z;
1244  v(6) = value.c.x;
1245  v(7) = value.c.y;
1246  v(8) = value.c.z;
1247  return v;
1248  }
1249 };
1250 
1251 // -----------------------------------------------------------------------------
1252 template <class TOut>
1253 struct VoxelCaster<double3x3, TOut>
1254 {
1255  static TOut Convert(const double3x3 &)
1256  {
1257  cerr << "Cannot cast 3x3 matrix to a scalar!" << endl;
1258  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
1259  exit(1);
1260  }
1261 };
1262 
1263 // -----------------------------------------------------------------------------
1264 template <>
1265 struct VoxelCaster<double3x3, float3x3>
1266 {
1267  static float3x3 Convert(const double3x3 &value)
1268  {
1269  return make_float3x3(value);
1270  }
1271 };
1272 
1273 // -----------------------------------------------------------------------------
1274 template <>
1275 struct VoxelCaster<double3x3, double3x3>
1276 {
1277  static double3x3 Convert(const double3x3 &value)
1278  {
1279  return value;
1280  }
1281 };
1282 
1283 // -----------------------------------------------------------------------------
1284 template <class TOut>
1285 struct VoxelCaster<double3x3, VectorND<9, TOut> >
1286 {
1287  static VectorND<9, TOut> Convert(const double3x3 &value)
1288  {
1290  v(0) = VoxelCaster<double, TOut>::Convert(value.a.x);
1291  v(1) = VoxelCaster<double, TOut>::Convert(value.a.y);
1292  v(2) = VoxelCaster<double, TOut>::Convert(value.a.z);
1293  v(3) = VoxelCaster<double, TOut>::Convert(value.b.x);
1294  v(4) = VoxelCaster<double, TOut>::Convert(value.b.y);
1295  v(5) = VoxelCaster<double, TOut>::Convert(value.b.z);
1296  v(6) = VoxelCaster<double, TOut>::Convert(value.c.x);
1297  v(7) = VoxelCaster<double, TOut>::Convert(value.c.y);
1298  v(8) = VoxelCaster<double, TOut>::Convert(value.c.z);
1299  return v;
1300  }
1301 };
1302 
1303 // -----------------------------------------------------------------------------
1304 template <>
1305 struct VoxelCaster<double3x3, Vector>
1306 {
1307  static Vector Convert(const double3x3 &value)
1308  {
1309  Vector v(9);
1310  v(0) = value.a.x;
1311  v(1) = value.a.y;
1312  v(2) = value.a.z;
1313  v(3) = value.b.x;
1314  v(4) = value.b.y;
1315  v(5) = value.b.z;
1316  v(6) = value.c.x;
1317  v(7) = value.c.y;
1318  v(8) = value.c.z;
1319  return v;
1320  }
1321 };
1322 
1323 
1324 // =============================================================================
1325 // voxel_cast function
1326 // =============================================================================
1327 
1328 // -----------------------------------------------------------------------------
1329 template <class TOut, class TIn>
1330 TOut voxel_cast(const TIn &value)
1331 {
1332  return VoxelCaster<TIn, TOut>::Convert(value);
1333 }
1334 
1335 
1336 } // namespace mirtk
1337 
1338 #endif // MIRTK_VoxelCast_H
Vector & Put(const Vector3D< T > &)
Initialize from 3D vector.
Definition: Vector.h:463
static TOut Convert(const TIn &value)
Definition: VoxelCast.h:47
T _z
The z component.
Definition: Vector4D.h:45
T _t
The t component.
Definition: Vector4D.h:46
Definition: IOConfig.h:41
int Rows() const
Returns number of rows.
Definition: Vector.h:438
T _x
The x component.
Definition: Vector4D.h:43
T _z
The z component.
Definition: Vector3D.h:60
T _y
The y component.
Definition: Vector3D.h:59
T _x
The x component.
Definition: Vector3D.h:58
T _y
The y component.
Definition: Vector4D.h:44
Auxiliary template class for partial voxel_cast specialization.
Definition: VoxelCast.h:42