Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkVtkImageOverwrite.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 /*=========================================================================
14 
15  Program: Visualization Toolkit
16  Module: mitkVtkImageOverwrite.cpp
17 
18  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
19  All rights reserved.
20  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
21 
22  This software is distributed WITHOUT ANY WARRANTY; without even
23  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
24  PURPOSE. See the above copyright notice for more information.
25 
26 =========================================================================*/
27 #include "mitkVtkImageOverwrite.h"
28 
29 #include "vtkDataSetAttributes.h"
30 #include "vtkGarbageCollector.h"
31 #include "vtkImageData.h"
32 #include "vtkImageStencilData.h"
33 #include "vtkInformation.h"
34 #include "vtkInformationVector.h"
35 #include "vtkMath.h"
36 #include "vtkObjectFactory.h"
37 #include "vtkStreamingDemandDrivenPipeline.h"
38 #include "vtkTransform.h"
39 
40 #include "vtkTemplateAliasMacro.h"
41 // turn off 64-bit ints when templating over all types
42 #undef VTK_USE_INT64
43 #define VTK_USE_INT64 0
44 #undef VTK_USE_UINT64
45 #define VTK_USE_UINT64 0
46 
47 #include <cfloat>
48 #include <climits>
49 #include <cmath>
50 
52 
53 //--------------------------------------------------------------------------
54 // The 'floor' function on x86 and mips is many times slower than these
55 // and is used a lot in this code, optimize for different CPU architectures
56 template <class F>
57 inline int vtkResliceFloor(double x, F &f)
58 {
59 #if defined mips || defined sparc || defined __ppc__
60  x += 2147483648.0;
61  unsigned int i = static_cast<unsigned int>(x);
62  f = x - i;
63  return static_cast<int>(i - 2147483648U);
64 #elif defined i386 || defined _M_IX86
65  union {
66  double d;
67  unsigned short s[4];
68  unsigned int i[2];
69  } dual;
70  dual.d = x + 103079215104.0; // (2**(52-16))*1.5
71  f = dual.s[0] * 0.0000152587890625; // 2**(-16)
72  return static_cast<int>((dual.i[1] << 16) | ((dual.i[0]) >> 16));
73 #elif defined ia64 || defined __ia64__ || defined IA64
74  x += 103079215104.0;
75  long long i = static_cast<long long>(x);
76  f = x - i;
77  return static_cast<int>(i - 103079215104LL);
78 #else
79  double y = floor(x);
80  f = x - y;
81  return static_cast<int>(y);
82 #endif
83 }
84 
85 inline int vtkResliceRound(double x)
86 {
87 #if defined mips || defined sparc || defined __ppc__
88  return static_cast<int>(static_cast<unsigned int>(x + 2147483648.5) - 2147483648U);
89 #elif defined i386 || defined _M_IX86
90  union {
91  double d;
92  unsigned int i[2];
93  } dual;
94  dual.d = x + 103079215104.5; // (2**(52-16))*1.5
95  return static_cast<int>((dual.i[1] << 16) | ((dual.i[0]) >> 16));
96 #elif defined ia64 || defined __ia64__ || defined IA64
97  x += 103079215104.5;
98  long long i = static_cast<long long>(x);
99  return static_cast<int>(i - 103079215104LL);
100 #else
101  return static_cast<int>(floor(x + 0.5));
102 #endif
103 }
104 
105 //----------------------------------------------------------------------------
107 {
108  m_Overwrite_Mode = false;
109  this->GetOutput()->AllocateScalars(VTK_UNSIGNED_INT, 1); // VTK6_TODO where should the image be allocated?
110 }
111 
112 //----------------------------------------------------------------------------
114 {
115 }
116 
117 //----------------------------------------------------------------------------
118 // constants for different boundary-handling modes
119 
120 #define VTK_RESLICE_BACKGROUND 0 // use background if out-of-bounds
121 #define VTK_RESLICE_WRAP 1 // wrap to opposite side of image
122 #define VTK_RESLICE_MIRROR 2 // mirror off of the boundary
123 #define VTK_RESLICE_BORDER 3 // use a half-voxel border
124 #define VTK_RESLICE_nullptr 4 // do nothing to *outPtr if out-of-bounds
125 
126 //----------------------------------------------------------------------------
127 // rounding functions for each type, where 'F' is a floating-point type
128 
129 #if (VTK_USE_INT8 != 0)
130 template <class F>
131 inline void vtkResliceRound(F val, vtkTypeInt8 &rnd)
132 {
133  rnd = vtkResliceRound(val);
134 }
135 #endif
136 
137 #if (VTK_USE_UINT8 != 0)
138 template <class F>
139 inline void vtkResliceRound(F val, vtkTypeUInt8 &rnd)
140 {
141  rnd = vtkResliceRound(val);
142 }
143 #endif
144 
145 #if (VTK_USE_INT16 != 0)
146 template <class F>
147 inline void vtkResliceRound(F val, vtkTypeInt16 &rnd)
148 {
149  rnd = vtkResliceRound(val);
150 }
151 #endif
152 
153 #if (VTK_USE_UINT16 != 0)
154 template <class F>
155 inline void vtkResliceRound(F val, vtkTypeUInt16 &rnd)
156 {
157  rnd = vtkResliceRound(val);
158 }
159 #endif
160 
161 #if (VTK_USE_INT32 != 0)
162 template <class F>
163 inline void vtkResliceRound(F val, vtkTypeInt32 &rnd)
164 {
165  rnd = vtkResliceRound(val);
166 }
167 #endif
168 
169 #if (VTK_USE_UINT32 != 0)
170 template <class F>
171 inline void vtkResliceRound(F val, vtkTypeUInt32 &rnd)
172 {
173  rnd = vtkResliceRound(val);
174 }
175 #endif
176 
177 #if (VTK_USE_FLOAT32 != 0)
178 template <class F>
179 inline void vtkResliceRound(F val, vtkTypeFloat32 &rnd)
180 {
181  rnd = val;
182 }
183 #endif
184 
185 #if (VTK_USE_FLOAT64 != 0)
186 template <class F>
187 inline void vtkResliceRound(F val, vtkTypeFloat64 &rnd)
188 {
189  rnd = val;
190 }
191 #endif
192 
193 //----------------------------------------------------------------------------
194 // clamping functions for each type
195 
196 #if (VTK_USE_INT8 != 0)
197 template <class F>
198 inline void vtkResliceClamp(F val, vtkTypeInt8 &clamp)
199 {
200  if (val < -128.0)
201  {
202  val = -128.0;
203  }
204  if (val > 127.0)
205  {
206  val = 127.0;
207  }
208  vtkResliceRound(val, clamp);
209 }
210 #endif
211 
212 #if (VTK_USE_UINT8 != 0)
213 template <class F>
214 inline void vtkResliceClamp(F val, vtkTypeUInt8 &clamp)
215 {
216  if (val < 0)
217  {
218  val = 0;
219  }
220  if (val > 255.0)
221  {
222  val = 255.0;
223  }
224  vtkResliceRound(val, clamp);
225 }
226 #endif
227 
228 #if (VTK_USE_INT16 != 0)
229 template <class F>
230 inline void vtkResliceClamp(F val, vtkTypeInt16 &clamp)
231 {
232  if (val < -32768.0)
233  {
234  val = -32768.0;
235  }
236  if (val > 32767.0)
237  {
238  val = 32767.0;
239  }
240  vtkResliceRound(val, clamp);
241 }
242 #endif
243 
244 #if (VTK_USE_UINT16 != 0)
245 template <class F>
246 inline void vtkResliceClamp(F val, vtkTypeUInt16 &clamp)
247 {
248  if (val < 0)
249  {
250  val = 0;
251  }
252  if (val > 65535.0)
253  {
254  val = 65535.0;
255  }
256  vtkResliceRound(val, clamp);
257 }
258 #endif
259 
260 #if (VTK_USE_INT32 != 0)
261 template <class F>
262 inline void vtkResliceClamp(F val, vtkTypeInt32 &clamp)
263 {
264  if (val < -2147483648.0)
265  {
266  val = -2147483648.0;
267  }
268  if (val > 2147483647.0)
269  {
270  val = 2147483647.0;
271  }
272  vtkResliceRound(val, clamp);
273 }
274 #endif
275 
276 #if (VTK_USE_UINT32 != 0)
277 template <class F>
278 inline void vtkResliceClamp(F val, vtkTypeUInt32 &clamp)
279 {
280  if (val < 0)
281  {
282  val = 0;
283  }
284  if (val > 4294967295.0)
285  {
286  val = 4294967295.0;
287  }
288  vtkResliceRound(val, clamp);
289 }
290 #endif
291 
292 #if (VTK_USE_FLOAT32 != 0)
293 template <class F>
294 inline void vtkResliceClamp(F val, vtkTypeFloat32 &clamp)
295 {
296  clamp = val;
297 }
298 #endif
299 
300 #if (VTK_USE_FLOAT64 != 0)
301 template <class F>
302 inline void vtkResliceClamp(F val, vtkTypeFloat64 &clamp)
303 {
304  clamp = val;
305 }
306 #endif
307 
308 //----------------------------------------------------------------------------
309 // Perform a wrap to limit an index to [0,range).
310 // Ensures correct behaviour when the index is negative.
311 
312 inline int vtkInterpolateWrap(int num, int range)
313 {
314  if ((num %= range) < 0)
315  {
316  num += range; // required for some % implementations
317  }
318  return num;
319 }
320 
321 //----------------------------------------------------------------------------
322 // Perform a mirror to limit an index to [0,range).
323 
324 inline int vtkInterpolateMirror(int num, int range)
325 {
326  if (num < 0)
327  {
328  num = -num - 1;
329  }
330  int count = num / range;
331  num %= range;
332  if (count & 0x1)
333  {
334  num = range - num - 1;
335  }
336  return num;
337 }
338 
339 //----------------------------------------------------------------------------
340 // If the value is within one half voxel of the range [0,inExtX), then
341 // set it to "0" or "inExtX-1" as appropriate.
342 
343 inline int vtkInterpolateBorder(int &inIdX0, int &inIdX1, int inExtX, double fx)
344 {
345  if (inIdX0 >= 0 && inIdX1 < inExtX)
346  {
347  return 0;
348  }
349  if (inIdX0 == -1 && fx >= 0.5)
350  {
351  inIdX1 = inIdX0 = 0;
352  return 0;
353  }
354  if (inIdX0 == inExtX - 1 && fx < 0.5)
355  {
356  inIdX1 = inIdX0;
357  return 0;
358  }
359 
360  return 1;
361 }
362 
363 inline int vtkInterpolateBorderCheck(int inIdX0, int inIdX1, int inExtX, double fx)
364 {
365  if ((inIdX0 >= 0 && inIdX1 < inExtX) || (inIdX0 == -1 && fx >= 0.5) || (inIdX0 == inExtX - 1 && fx < 0.5))
366  {
367  return 0;
368  }
369 
370  return 1;
371 }
372 
373 //----------------------------------------------------------------------------
374 // Do nearest-neighbor interpolation of the input data 'inPtr' of extent
375 // 'inExt' at the 'point'. The result is placed at 'outPtr'.
376 // If the lookup data is beyond the extent 'inExt', set 'outPtr' to
377 // the background color 'background'.
378 // The number of scalar components in the data is 'numscalars'
379 template <class F, class T>
380 static int vtkNearestNeighborInterpolation(T *&outPtr,
381  const T *inPtr,
382  const int inExt[6],
383  const vtkIdType inInc[3],
384  int numscalars,
385  const F point[3],
386  int mode,
387  const T *background,
388  mitkVtkImageOverwrite *self)
389 {
390  int inIdX0 = vtkResliceRound(point[0]) - inExt[0];
391  int inIdY0 = vtkResliceRound(point[1]) - inExt[2];
392  int inIdZ0 = vtkResliceRound(point[2]) - inExt[4];
393 
394  int inExtX = inExt[1] - inExt[0] + 1;
395  int inExtY = inExt[3] - inExt[2] + 1;
396  int inExtZ = inExt[5] - inExt[4] + 1;
397 
398  if (inIdX0 < 0 || inIdX0 >= inExtX || inIdY0 < 0 || inIdY0 >= inExtY || inIdZ0 < 0 || inIdZ0 >= inExtZ)
399  {
400  if (mode == VTK_RESLICE_WRAP)
401  {
402  inIdX0 = vtkInterpolateWrap(inIdX0, inExtX);
403  inIdY0 = vtkInterpolateWrap(inIdY0, inExtY);
404  inIdZ0 = vtkInterpolateWrap(inIdZ0, inExtZ);
405  }
406  else if (mode == VTK_RESLICE_MIRROR)
407  {
408  inIdX0 = vtkInterpolateMirror(inIdX0, inExtX);
409  inIdY0 = vtkInterpolateMirror(inIdY0, inExtY);
410  inIdZ0 = vtkInterpolateMirror(inIdZ0, inExtZ);
411  }
412  else if (mode == VTK_RESLICE_BACKGROUND || mode == VTK_RESLICE_BORDER)
413  {
414  do
415  {
416  *outPtr++ = *background++;
417  } while (--numscalars);
418  return 0;
419  }
420  else
421  {
422  return 0;
423  }
424  }
425 
426  inPtr += inIdX0 * inInc[0] + inIdY0 * inInc[1] + inIdZ0 * inInc[2];
427 
428  do
429  {
430  if (!self->IsOverwriteMode())
431  {
432  // just copy from input to output
433  *outPtr++ = *inPtr++;
434  }
435  else
436  {
437  // copy from output to input in overwrite mode
438  *(const_cast<T *>(inPtr)) = *outPtr++;
439  inPtr++;
440  }
441  } while (--numscalars);
442 
443  return 1;
444 }
445 
446 //--------------------------------------------------------------------------
447 // get appropriate interpolation function according to scalar type
448 template <class F>
450  int (**interpolate)(void *&outPtr,
451  const void *inPtr,
452  const int inExt[6],
453  const vtkIdType inInc[3],
454  int numscalars,
455  const F point[3],
456  int mode,
457  const void *background,
458  mitkVtkImageOverwrite *self))
459 {
460  int dataType = self->GetOutput()->GetScalarType();
461 
462  switch (dataType)
463  {
464  vtkTemplateAliasMacro(*((int (**)(VTK_TT * &outPtr,
465  const VTK_TT *inPtr,
466  const int inExt[6],
467  const vtkIdType inInc[3],
468  int numscalars,
469  const F point[3],
470  int mode,
471  const VTK_TT *background,
473  default:
474  interpolate = nullptr;
475  }
476 }
477 
478 //----------------------------------------------------------------------------
479 // Some helper functions for 'RequestData'
480 //----------------------------------------------------------------------------
481 
482 //--------------------------------------------------------------------------
483 // pixel copy function, templated for different scalar types
484 template <class T>
485 struct vtkImageResliceSetPixels
486 {
487  static void Set(void *&outPtrV, const void *inPtrV, int numscalars, int n)
488  {
489  const T *inPtr = static_cast<const T *>(inPtrV);
490  T *outPtr = static_cast<T *>(outPtrV);
491  for (int i = 0; i < n; i++)
492  {
493  const T *tmpPtr = inPtr;
494  int m = numscalars;
495  do
496  {
497  *outPtr++ = *tmpPtr++;
498  } while (--m);
499  }
500  outPtrV = outPtr;
501  }
502 
503  // optimized for 1 scalar components
504  static void Set1(void *&outPtrV, const void *inPtrV, int vtkNotUsed(numscalars), int n)
505  {
506  const T *inPtr = static_cast<const T *>(inPtrV);
507  T *outPtr = static_cast<T *>(outPtrV);
508  T val = *inPtr;
509  for (int i = 0; i < n; i++)
510  {
511  *outPtr++ = val;
512  }
513  outPtrV = outPtr;
514  }
515 };
516 
517 // get a pixel copy function that is appropriate for the data type
519  void (**setpixels)(void *&out, const void *in, int numscalars, int n))
520 {
521  int dataType = self->GetOutput()->GetScalarType();
522  int numscalars = self->GetOutput()->GetNumberOfScalarComponents();
523 
524  // TODO: this switch should be examined
525  switch (numscalars)
526  {
527  case 1:
528  switch (dataType)
529  {
530  vtkTemplateAliasMacro(*setpixels = &vtkImageResliceSetPixels<VTK_TT>::Set1);
531  default:
532  setpixels = nullptr;
533  }
534  // just to make the compiler happy, TODO: check!
535  // FALLTHRU
536  default:
537  switch (dataType)
538  {
539  vtkTemplateAliasMacro(*setpixels = &vtkImageResliceSetPixels<VTK_TT>::Set);
540  default:
541  setpixels = nullptr;
542  }
543  }
544 }
545 
546 //----------------------------------------------------------------------------
547 // Convert background color from float to appropriate type
548 template <class T>
549 static void vtkAllocBackgroundPixelT(mitkVtkImageOverwrite *self, T **background_ptr, int numComponents)
550 {
551  *background_ptr = new T[numComponents];
552  T *background = *background_ptr;
553 
554  for (int i = 0; i < numComponents; i++)
555  {
556  if (i < 4)
557  {
558  vtkResliceClamp(self->GetBackgroundColor()[i], background[i]);
559  }
560  else
561  {
562  background[i] = 0;
563  }
564  }
565 }
566 
567 static void vtkAllocBackgroundPixel(mitkVtkImageOverwrite *self, void **rval, int numComponents)
568 {
569  switch (self->GetOutput()->GetScalarType())
570  {
571  vtkTemplateAliasMacro(vtkAllocBackgroundPixelT(self, (VTK_TT **)rval, numComponents));
572  }
573 }
574 
575 static void vtkFreeBackgroundPixel(mitkVtkImageOverwrite *self, void **rval)
576 {
577  switch (self->GetOutput()->GetScalarType())
578  {
579  vtkTemplateAliasMacro(delete[] * ((VTK_TT **)rval));
580  }
581 
582  *rval = nullptr;
583 }
584 
585 //----------------------------------------------------------------------------
586 // helper function for clipping of the output with a stencil
587 static int vtkResliceGetNextExtent(vtkImageStencilData *stencil,
588  int &r1,
589  int &r2,
590  int rmin,
591  int rmax,
592  int yIdx,
593  int zIdx,
594  void *&outPtr,
595  void *background,
596  int numscalars,
597  void (*setpixels)(void *&out, const void *in, int numscalars, int n),
598  int &iter)
599 {
600  // trivial case if stencil is not set
601  if (!stencil)
602  {
603  if (iter++ == 0)
604  {
605  r1 = rmin;
606  r2 = rmax;
607  return 1;
608  }
609  return 0;
610  }
611 
612  // for clearing, start at last r2 plus 1
613  int clear1 = r2 + 1;
614  if (iter == 0)
615  { // if no 'last time', start at rmin
616  clear1 = rmin;
617  }
618 
619  int rval = stencil->GetNextExtent(r1, r2, rmin, rmax, yIdx, zIdx, iter);
620  int clear2 = r1 - 1;
621  if (rval == 0)
622  {
623  clear2 = rmax;
624  }
625 
626  setpixels(outPtr, background, numscalars, clear2 - clear1 + 1);
627 
628  return rval;
629 }
630 
631 //----------------------------------------------------------------------------
632 // This function simply clears the entire output to the background color,
633 // for cases where the transformation places the output extent completely
634 // outside of the input extent.
636  mitkVtkImageOverwrite *self, vtkImageData *, void *, vtkImageData *outData, void *outPtr, int outExt[6], int id)
637 {
638  int numscalars;
639  int idY, idZ;
640  vtkIdType outIncX, outIncY, outIncZ;
641  int scalarSize;
642  unsigned long count = 0;
643  unsigned long target;
644  void *background;
645  void (*setpixels)(void *&out, const void *in, int numscalars, int n);
646 
647  // for the progress meter
648  target = static_cast<unsigned long>((outExt[5] - outExt[4] + 1) * (outExt[3] - outExt[2] + 1) / 50.0);
649  target++;
650 
651  // Get Increments to march through data
652  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
653  scalarSize = outData->GetScalarSize();
654  numscalars = outData->GetNumberOfScalarComponents();
655 
656  // allocate a voxel to copy into the background (out-of-bounds) regions
657  vtkAllocBackgroundPixel(self, &background, numscalars);
658  // get the appropriate function for pixel copying
659  vtkGetSetPixelsFunc(self, &setpixels);
660 
661  // Loop through output voxels
662  for (idZ = outExt[4]; idZ <= outExt[5]; idZ++)
663  {
664  for (idY = outExt[2]; idY <= outExt[3]; idY++)
665  {
666  if (id == 0)
667  { // update the progress if this is the main thread
668  if (!(count % target))
669  {
670  self->UpdateProgress(count / (50.0 * target));
671  }
672  count++;
673  }
674  // clear the pixels to background color and go to next row
675  setpixels(outPtr, background, numscalars, outExt[1] - outExt[0] + 1);
676  outPtr = static_cast<void *>(static_cast<char *>(outPtr) + outIncY * scalarSize);
677  }
678  outPtr = static_cast<void *>(static_cast<char *>(outPtr) + outIncZ * scalarSize);
679  }
680 
681  vtkFreeBackgroundPixel(self, &background);
682 }
683 
684 //----------------------------------------------------------------------------
685 // This function executes the filter for any type of data. It is much simpler
686 // in structure than vtkImageResliceOptimizedExecute.
688  vtkImageData *inData,
689  void *inPtr,
690  vtkImageData *outData,
691  void *outPtr,
692  int outExt[6],
693  int id)
694 {
695  int numscalars;
696  int idX, idY, idZ;
697  int idXmin, idXmax, iter;
698  vtkIdType outIncX, outIncY, outIncZ;
699  int scalarSize;
700  int inExt[6];
701  vtkIdType inInc[3];
702  unsigned long count = 0;
703  unsigned long target;
704  double point[4];
705  double f;
706  double *inSpacing, *inOrigin, *outSpacing, *outOrigin, inInvSpacing[3];
707  void *background;
708  int (*interpolate)(void *&outPtr,
709  const void *inPtr,
710  const int inExt[6],
711  const vtkIdType inInc[3],
712  int numscalars,
713  const double point[3],
714  int mode,
715  const void *background,
716  mitkVtkImageOverwrite *self) = nullptr;
717  void (*setpixels)(void *&out, const void *in, int numscalars, int n) = nullptr;
718 
719  // the 'mode' species what to do with the 'pad' (out-of-bounds) area
720  int mode = VTK_RESLICE_BACKGROUND;
721  if (self->GetMirror())
722  {
723  mode = VTK_RESLICE_MIRROR;
724  }
725  else if (self->GetWrap())
726  {
727  mode = VTK_RESLICE_WRAP;
728  }
729  else if (self->GetBorder())
730  {
731  mode = VTK_RESLICE_BORDER;
732  }
733 
734  // the transformation to apply to the data
735  vtkAbstractTransform *transform = self->GetResliceTransform();
736  vtkMatrix4x4 *matrix = self->GetResliceAxes();
737 
738  // for conversion to data coordinates
739  inOrigin = inData->GetOrigin();
740  inSpacing = inData->GetSpacing();
741  outOrigin = outData->GetOrigin();
742  outSpacing = outData->GetSpacing();
743 
744  // save effor later: invert inSpacing
745  inInvSpacing[0] = 1.0 / inSpacing[0];
746  inInvSpacing[1] = 1.0 / inSpacing[1];
747  inInvSpacing[2] = 1.0 / inSpacing[2];
748 
749  // find maximum input range
750  inData->GetExtent(inExt);
751 
752  // for the progress meter
753  target = static_cast<unsigned long>((outExt[5] - outExt[4] + 1) * (outExt[3] - outExt[2] + 1) / 50.0);
754  target++;
755 
756  // Get Increments to march through data
757  inData->GetIncrements(inInc);
758  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
759  scalarSize = outData->GetScalarSize();
760  numscalars = inData->GetNumberOfScalarComponents();
761 
762  // allocate a voxel to copy into the background (out-of-bounds) regions
763  vtkAllocBackgroundPixel(self, &background, numscalars);
764 
765  // get the appropriate functions for interpolation and pixel copying
766  vtkGetResliceInterpFunc(self, &interpolate);
767  vtkGetSetPixelsFunc(self, &setpixels);
768 
769  // get the stencil
770  vtkImageStencilData *stencil = self->GetStencil();
771 
772  // Loop through output voxels
773  for (idZ = outExt[4]; idZ <= outExt[5]; idZ++)
774  {
775  for (idY = outExt[2]; idY <= outExt[3]; idY++)
776  {
777  if (id == 0)
778  { // update the progress if this is the main thread
779  if (!(count % target))
780  {
781  self->UpdateProgress(count / (50.0 * target));
782  }
783  count++;
784  }
785 
786  iter = 0; // if there is a stencil, it is applied here
788  stencil, idXmin, idXmax, outExt[0], outExt[1], idY, idZ, outPtr, background, numscalars, setpixels, iter))
789  {
790  for (idX = idXmin; idX <= idXmax; idX++)
791  {
792  // convert to data coordinates
793  point[0] = idX * outSpacing[0] + outOrigin[0];
794  point[1] = idY * outSpacing[1] + outOrigin[1];
795  point[2] = idZ * outSpacing[2] + outOrigin[2];
796 
797  // apply ResliceAxes matrix
798  if (matrix)
799  {
800  point[3] = 1.0;
801  matrix->MultiplyPoint(point, point);
802  f = 1.0 / point[3];
803  point[0] *= f;
804  point[1] *= f;
805  point[2] *= f;
806  }
807 
808  // apply ResliceTransform
809  if (transform)
810  {
811  transform->InternalTransformPoint(point, point);
812  }
813 
814  // convert back to voxel indices
815  point[0] = (point[0] - inOrigin[0]) * inInvSpacing[0];
816  point[1] = (point[1] - inOrigin[1]) * inInvSpacing[1];
817  point[2] = (point[2] - inOrigin[2]) * inInvSpacing[2];
818 
819  // interpolate output voxel from input data set
820  interpolate(outPtr, inPtr, inExt, inInc, numscalars, point, mode, background, self);
821  }
822  }
823  outPtr = static_cast<void *>(static_cast<char *>(outPtr) + outIncY * scalarSize);
824  }
825  outPtr = static_cast<void *>(static_cast<char *>(outPtr) + outIncZ * scalarSize);
826  }
827 
828  vtkFreeBackgroundPixel(self, &background);
829 }
830 
832 {
833  m_Overwrite_Mode = b;
834 }
835 
836 void mitkVtkImageOverwrite::SetInputSlice(vtkImageData *slice)
837 {
838  // set the output as input
839  this->SetOutput(slice);
840 }
841 
842 //----------------------------------------------------------------------------
843 // This method is passed a input and output region, and executes the filter
844 // algorithm to fill the output from the input or vice versa.
845 void mitkVtkImageOverwrite::ThreadedRequestData(vtkInformation *vtkNotUsed(request),
846  vtkInformationVector **vtkNotUsed(inputVector),
847  vtkInformationVector *vtkNotUsed(outputVector),
848  vtkImageData ***inData,
849  vtkImageData **outData,
850  int outExt[6],
851  int id)
852 {
853  vtkDebugMacro(<< "Execute: inData = " << inData[0][0] << ", outData = " << outData[0]);
854  // this filter expects that input is the same type as output.
855  if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
856  {
857  vtkErrorMacro(<< "Execute: input ScalarType, " << inData[0][0]->GetScalarType() << ", must match out ScalarType "
858  << outData[0]->GetScalarType());
859  return;
860  }
861 
862  int inExt[6];
863  inData[0][0]->GetExtent(inExt);
864  // check for empty input extent
865  if (inExt[1] < inExt[0] || inExt[3] < inExt[2] || inExt[5] < inExt[4])
866  {
867  return;
868  }
869 
870  // Get the output pointer
871  void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
872 
873  if (this->HitInputExtent == 0)
874  {
875  vtkImageResliceClearExecute(this, inData[0][0], nullptr, outData[0], outPtr, outExt, id);
876  return;
877  }
878 
879  // Now that we know that we need the input, get the input pointer
880  void *inPtr = inData[0][0]->GetScalarPointerForExtent(inExt);
881 
882  vtkImageResliceExecute(this, inData[0][0], inPtr, outData[0], outPtr, outExt, id);
883 }
#define VTK_RESLICE_BACKGROUND
int vtkResliceFloor(double x, F &f)
static void vtkImageResliceClearExecute(mitkVtkImageOverwrite *self, vtkImageData *, void *, vtkImageData *outData, void *outPtr, int outExt[6], int id)
int vtkInterpolateWrap(int num, int range)
vtkStandardNewMacro(mitkVtkImageOverwrite)
static void vtkGetSetPixelsFunc(mitkVtkImageOverwrite *self, void(**setpixels)(void *&out, const void *in, int numscalars, int n))
#define VTK_RESLICE_BORDER
int vtkInterpolateBorder(int &inIdX0, int &inIdX1, int inExtX, double fx)
static int vtkNearestNeighborInterpolation(T *&outPtr, const T *inPtr, const int inExt[6], const vtkIdType inInc[3], int numscalars, const F point[3], int mode, const T *background, mitkVtkImageOverwrite *self)
static int vtkResliceGetNextExtent(vtkImageStencilData *stencil, int &r1, int &r2, int rmin, int rmax, int yIdx, int zIdx, void *&outPtr, void *background, int numscalars, void(*setpixels)(void *&out, const void *in, int numscalars, int n), int &iter)
static void vtkAllocBackgroundPixelT(mitkVtkImageOverwrite *self, T **background_ptr, int numComponents)
int vtkInterpolateMirror(int num, int range)
A vtk Filter based on vtkImageReslice with the aditional feature to write a slice into the given inpu...
static void vtkGetResliceInterpFunc(mitkVtkImageOverwrite *self, int(**interpolate)(void *&outPtr, const void *inPtr, const int inExt[6], const vtkIdType inInc[3], int numscalars, const F point[3], int mode, const void *background, mitkVtkImageOverwrite *self))
static void vtkImageResliceExecute(mitkVtkImageOverwrite *self, vtkImageData *inData, void *inPtr, vtkImageData *outData, void *outPtr, int outExt[6], int id)
static void vtkFreeBackgroundPixel(mitkVtkImageOverwrite *self, void **rval)
int vtkInterpolateBorderCheck(int inIdX0, int inIdX1, int inExtX, double fx)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
static void vtkAllocBackgroundPixel(mitkVtkImageOverwrite *self, void **rval, int numComponents)
void SetOverwriteMode(bool b)
Set the mode either to reslice (false) or to overwrite (true). Default: false.
void ThreadedRequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id) override
#define VTK_RESLICE_WRAP
int vtkResliceRound(double x)
* background
Definition: ad.h:1
void SetInputSlice(vtkImageData *slice)
Set the slice for overwrite mode. Note: It is recommend not to use this in reslice mode because other...
#define VTK_RESLICE_MIRROR