1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageResample.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkImageResample.h"
16
17 #include "vtkAlgorithmOutput.h"
18 #include "vtkImageData.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkStreamingDemandDrivenPipeline.h"
23
24 vtkStandardNewMacro(vtkImageResample);
25
26 //----------------------------------------------------------------------------
27 // Constructor: Sets default filter to be identity.
vtkImageResample()28 vtkImageResample::vtkImageResample()
29 {
30 this->MagnificationFactors[0] = 1.0;
31 this->MagnificationFactors[1] = 1.0;
32 this->MagnificationFactors[2] = 1.0;
33 this->OutputSpacing[0] = 0.0; // not specified
34 this->OutputSpacing[1] = 0.0; // not specified
35 this->OutputSpacing[2] = 0.0; // not specified
36 this->InterpolationMode = VTK_RESLICE_LINEAR;
37 this->Dimensionality = 3;
38 }
39
40 //----------------------------------------------------------------------------
SetOutputSpacing(double sx,double sy,double sz)41 void vtkImageResample::SetOutputSpacing(double sx, double sy, double sz)
42 {
43 const double spacing[3] = { sx, sy, sz };
44 bool modified = false;
45
46 for (int axis = 0; axis < 3; axis++)
47 {
48 if (this->OutputSpacing[axis] != spacing[axis])
49 {
50 this->OutputSpacing[axis] = spacing[axis];
51 if (spacing[axis] != 0.0)
52 {
53 // Delay computing the magnification factor.
54 // Input might not be set yet.
55 this->MagnificationFactors[axis] = 0.0; // Not computed yet.
56 }
57 modified = true;
58 }
59 }
60
61 if (modified)
62 {
63 this->Modified();
64 }
65 }
66
67 //----------------------------------------------------------------------------
SetAxisOutputSpacing(int axis,double s)68 void vtkImageResample::SetAxisOutputSpacing(int axis, double s)
69 {
70 if (axis < 0 || axis > 2)
71 {
72 vtkErrorMacro("Bad axis: " << axis);
73 return;
74 }
75
76 double spacing[3];
77 this->GetOutputSpacing(spacing);
78 spacing[axis] = s;
79
80 this->SetOutputSpacing(spacing);
81 }
82
83 //----------------------------------------------------------------------------
SetMagnificationFactors(double fx,double fy,double fz)84 void vtkImageResample::SetMagnificationFactors(double fx, double fy, double fz)
85 {
86 const double factors[3] = { fx, fy, fz };
87 bool modified = false;
88
89 for (int axis = 0; axis < 3; axis++)
90 {
91 if (this->MagnificationFactors[axis] != factors[axis])
92 {
93 this->MagnificationFactors[axis] = factors[axis];
94 // Spacing is no longer valid.
95 this->OutputSpacing[axis] = 0.0; // Not computed yet.
96 modified = true;
97 }
98 }
99
100 if (modified)
101 {
102 this->Modified();
103 }
104 }
105
106 //----------------------------------------------------------------------------
SetAxisMagnificationFactor(int axis,double factor)107 void vtkImageResample::SetAxisMagnificationFactor(int axis, double factor)
108 {
109 if (axis < 0 || axis > 2)
110 {
111 vtkErrorMacro("Bad axis: " << axis);
112 return;
113 }
114
115 double factors[3];
116 this->GetMagnificationFactors(factors);
117 factors[axis] = factor;
118
119 this->SetMagnificationFactors(factors);
120 }
121
122 //----------------------------------------------------------------------------
GetAxisMagnificationFactor(int axis,vtkInformation * inInfo)123 double vtkImageResample::GetAxisMagnificationFactor(int axis,
124 vtkInformation *inInfo)
125 {
126 if (axis < 0 || axis > 2)
127 {
128 vtkErrorMacro("Bad axis: " << axis);
129 return 0.0;
130 }
131
132 if (this->MagnificationFactors[axis] == 0.0)
133 {
134 double *inputSpacing;
135 if ( ! this->GetInput())
136 {
137 vtkErrorMacro("GetMagnificationFactor: Input not set.");
138 return 0.0;
139 }
140 this->GetInputConnection(0, 0)->GetProducer()->UpdateInformation();
141 if (!inInfo)
142 {
143 inInfo = this->GetExecutive()->GetInputInformation(0, 0);
144 }
145 inputSpacing = inInfo->Get(vtkDataObject::SPACING());
146 this->MagnificationFactors[axis] =
147 inputSpacing[axis] / this->OutputSpacing[axis];
148
149 }
150
151 vtkDebugMacro("Returning magnification factor "
152 << this->MagnificationFactors[axis] << " for axis "
153 << axis);
154
155 return this->MagnificationFactors[axis];
156 }
157
158
159 //----------------------------------------------------------------------------
160 // Computes any global image information associated with regions.
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)161 int vtkImageResample::RequestInformation(
162 vtkInformation *vtkNotUsed(request),
163 vtkInformationVector **inputVector,
164 vtkInformationVector *outputVector)
165 {
166 int wholeMin, wholeMax, axis, ext[6];
167 double spacing[3], factor;
168
169 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
170 vtkInformation *outInfo = outputVector->GetInformationObject(0);
171
172 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext);
173 inInfo->Get(vtkDataObject::SPACING(), spacing);
174
175 for (axis = 0; axis < 3; axis++)
176 {
177 wholeMin = ext[axis*2];
178 wholeMax = ext[axis*2+1];
179
180 // Scale the output extent
181 factor = 1.0;
182 if (axis < this->Dimensionality)
183 {
184 factor = this->GetAxisMagnificationFactor(axis, inInfo);
185 }
186
187 wholeMin = static_cast<int>(ceil(static_cast<double>(wholeMin) * factor));
188 wholeMax = static_cast<int>(floor(static_cast<double>(wholeMax) * factor));
189
190 // Change the data spacing
191 spacing[axis] /= factor;
192
193 ext[axis*2] = wholeMin;
194 ext[axis*2+1] = wholeMax;
195
196 // just in case the input spacing has changed.
197 if (this->OutputSpacing[axis] != 0.0)
198 {
199 // Cause MagnificationFactor to recompute.
200 this->MagnificationFactors[axis] = 0.0;
201 }
202 }
203
204 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext, 6);
205 outInfo->Set(vtkDataObject::SPACING(), spacing, 3);
206
207 return 1;
208 }
209
PrintSelf(ostream & os,vtkIndent indent)210 void vtkImageResample::PrintSelf(ostream& os, vtkIndent indent)
211 {
212 this->Superclass::PrintSelf(os,indent);
213 os << indent << "MagnificationFactors: " << this->MagnificationFactors[0]
214 << " " << this->MagnificationFactors[1]
215 << " " << this->MagnificationFactors[2] << "\n";
216 os << indent << "Dimensionality: " << this->Dimensionality << "\n";
217 os << indent << "Interpolate: " << (this->GetInterpolate() ? "On\n" : "Off\n");
218 }
219