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