1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageChangeInformation.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 "vtkImageChangeInformation.h"
16
17 #include "vtkImageData.h"
18 #include "vtkInformation.h"
19 #include "vtkInformationVector.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkStreamingDemandDrivenPipeline.h"
22 #include "vtkPointData.h"
23
24 vtkStandardNewMacro(vtkImageChangeInformation);
25
26 //----------------------------------------------------------------------------
vtkImageChangeInformation()27 vtkImageChangeInformation::vtkImageChangeInformation()
28 {
29 this->CenterImage = 0;
30
31 for (int i = 0; i < 3; i++)
32 {
33 this->OutputExtentStart[i] = VTK_INT_MAX;
34 this->ExtentTranslation[i] = 0;
35 this->FinalExtentTranslation[i] = VTK_INT_MAX;
36
37 this->OutputSpacing[i] = VTK_DOUBLE_MAX;
38 this->SpacingScale[i] = 1.0;
39
40 this->OutputOrigin[i] = VTK_DOUBLE_MAX;
41 this->OriginScale[i] = 1.0;
42 this->OriginTranslation[i] = 0.0;
43 }
44
45 // There is an optional second input.
46 this->SetNumberOfInputPorts(2);
47 }
48
49 // Specify a source object at a specified table location.
SetInformationInputData(vtkImageData * pd)50 void vtkImageChangeInformation::SetInformationInputData(vtkImageData *pd)
51 {
52 this->SetInputData(1, pd);
53 }
54
55 // Get a pointer to a source object at a specified table location.
GetInformationInput()56 vtkImageData *vtkImageChangeInformation::GetInformationInput()
57 {
58 if (this->GetNumberOfInputConnections(1) < 1)
59 {
60 return nullptr;
61 }
62 return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
63 }
64
65 //----------------------------------------------------------------------------
66 vtkImageChangeInformation::~vtkImageChangeInformation() = default;
67
68 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)69 void vtkImageChangeInformation::PrintSelf(ostream& os, vtkIndent indent)
70 {
71 this->Superclass::PrintSelf(os,indent);
72
73 os << indent << "CenterImage : "
74 << (this->CenterImage ? "On":"Off") << endl;
75
76 os << indent << "OutputExtentStart: ("
77 << this->OutputExtentStart[0] << ","
78 << this->OutputExtentStart[1] << ","
79 << this->OutputExtentStart[2] << ")" << endl;
80
81 os << indent << "ExtentTranslation: ("
82 << this->ExtentTranslation[0] << ","
83 << this->ExtentTranslation[1] << ","
84 << this->ExtentTranslation[2] << ")" << endl;
85
86 os << indent << "OutputSpacing: ("
87 << this->OutputSpacing[0] << ","
88 << this->OutputSpacing[1] << ","
89 << this->OutputSpacing[2] << ")" << endl;
90
91 os << indent << "SpacingScale: ("
92 << this->SpacingScale[0] << ","
93 << this->SpacingScale[1] << ","
94 << this->SpacingScale[2] << ")" << endl;
95
96 os << indent << "OutputOrigin: ("
97 << this->OutputOrigin[0] << ","
98 << this->OutputOrigin[1] << ","
99 << this->OutputOrigin[2] << ")" << endl;
100
101 os << indent << "OriginScale: ("
102 << this->OriginScale[0] << ","
103 << this->OriginScale[1] << ","
104 << this->OriginScale[2] << ")" << endl;
105
106 os << indent << "OriginTranslation: ("
107 << this->OriginTranslation[0] << ","
108 << this->OriginTranslation[1] << ","
109 << this->OriginTranslation[2] << ")" << endl;
110 }
111
112 //----------------------------------------------------------------------------
113 // Change the information
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)114 int vtkImageChangeInformation::RequestInformation (
115 vtkInformation * vtkNotUsed(request),
116 vtkInformationVector **inputVector,
117 vtkInformationVector *outputVector)
118 {
119 // get the info objects
120 vtkInformation *outInfo = outputVector->GetInformationObject(0);
121 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
122
123 int i;
124 int extent[6], inExtent[6];
125 double spacing[3], origin[3];
126
127 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),inExtent);
128
129 vtkImageData *infoInput = this->GetInformationInput();
130 if (infoInput)
131 {
132 // If there is an InformationInput, it is set as a second input
133 vtkInformation *in2Info = inputVector[1]->GetInformationObject(0);
134 infoInput->GetOrigin(origin);
135 infoInput->GetSpacing(spacing);
136 in2Info->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
137 for (i = 0; i < 3; i++)
138 {
139 extent[2*i+1] = extent[2*i] - inExtent[2*i] + inExtent[2*i+1];
140 }
141 }
142 else
143 {
144 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
145 inInfo->Get(vtkDataObject::ORIGIN(), origin);
146 inInfo->Get(vtkDataObject::SPACING(), spacing);
147 }
148
149 for (i = 0; i < 3; i++)
150 {
151 if (this->OutputSpacing[i] != VTK_DOUBLE_MAX)
152 {
153 spacing[i] = this->OutputSpacing[i];
154 }
155
156 if (this->OutputOrigin[i] != VTK_DOUBLE_MAX)
157 {
158 origin[i] = this->OutputOrigin[i];
159 }
160
161 if (this->OutputExtentStart[i] != VTK_INT_MAX)
162 {
163 extent[2*i+1] += this->OutputExtentStart[i] - extent[2*i];
164 extent[2*i] = this->OutputExtentStart[i];
165 }
166 }
167
168 if (this->CenterImage)
169 {
170 for (i = 0; i < 3; i++)
171 {
172 origin[i] = -(extent[2*i] + extent[2*i+1])*spacing[i]/2;
173 }
174 }
175
176 for (i = 0; i < 3; i++)
177 {
178 spacing[i] = spacing[i]*this->SpacingScale[i];
179 origin[i] = origin[i]*this->OriginScale[i] + this->OriginTranslation[i];
180 extent[2*i] = extent[2*i] + this->ExtentTranslation[i];
181 extent[2*i+1] = extent[2*i+1] + this->ExtentTranslation[i];
182 this->FinalExtentTranslation[i] = extent[2*i] - inExtent[2*i];
183 }
184
185 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
186 outInfo->Set(vtkDataObject::SPACING(),spacing,3);
187 outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
188
189 return 1;
190 }
191
192
193 //----------------------------------------------------------------------------
194 // This method simply copies by reference the input data to the output.
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)195 int vtkImageChangeInformation::RequestData(
196 vtkInformation *vtkNotUsed(request),
197 vtkInformationVector **inputVector,
198 vtkInformationVector *outputVector)
199 {
200 if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
201 {
202 vtkErrorMacro("Bug in code, RequestInformation was not called");
203 return 0;
204 }
205
206 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
207 vtkInformation *outInfo = outputVector->GetInformationObject(0);
208 int extent[6];
209
210 vtkImageData *inData = vtkImageData::SafeDownCast(
211 inInfo->Get(vtkDataObject::DATA_OBJECT()));
212 vtkImageData *outData = vtkImageData::SafeDownCast(
213 outInfo->Get(vtkDataObject::DATA_OBJECT()));
214
215 // since inData can be larger than update extent.
216 inData->GetExtent(extent);
217 for (int i = 0; i < 3; ++i)
218 {
219 extent[i*2] += this->FinalExtentTranslation[i];
220 extent[i*2+1] += this->FinalExtentTranslation[i];
221 }
222 outData->SetExtent(extent);
223 outData->GetPointData()->PassData(inData->GetPointData());
224
225 return 1;
226 }
227
228 //----------------------------------------------------------------------------
RequestUpdateExtent(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)229 int vtkImageChangeInformation::RequestUpdateExtent (
230 vtkInformation * vtkNotUsed(request),
231 vtkInformationVector **inputVector,
232 vtkInformationVector *outputVector)
233 {
234 // get the info objects
235 vtkInformation* outInfo = outputVector->GetInformationObject(0);
236 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
237
238 if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
239 {
240 vtkErrorMacro("Bug in code.");
241 return 0;
242 }
243
244 int inExt[6];
245 outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExt);
246
247 inExt[0] -= this->FinalExtentTranslation[0];
248 inExt[1] -= this->FinalExtentTranslation[0];
249 inExt[2] -= this->FinalExtentTranslation[1];
250 inExt[3] -= this->FinalExtentTranslation[1];
251 inExt[4] -= this->FinalExtentTranslation[2];
252 inExt[5] -= this->FinalExtentTranslation[2];
253
254 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
255
256 return 1;
257 }
258
FillInputPortInformation(int port,vtkInformation * info)259 int vtkImageChangeInformation::FillInputPortInformation(
260 int port, vtkInformation *info)
261 {
262 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
263 if (port == 1)
264 {
265 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
266 }
267
268 return 1;
269 }
270