1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageRectilinearWipe.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 "vtkImageRectilinearWipe.h"
16
17 #include "vtkImageData.h"
18 #include "vtkInformation.h"
19 #include "vtkInformationVector.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkStreamingDemandDrivenPipeline.h"
22
23 vtkStandardNewMacro(vtkImageRectilinearWipe);
24
25 //----------------------------------------------------------------------------
vtkImageRectilinearWipe()26 vtkImageRectilinearWipe::vtkImageRectilinearWipe()
27 {
28 this->Position[0] = 0;
29 this->Position[1] = 0;
30 this->Axis[0] = 0;
31 this->Axis[1] = 1;
32 this->Wipe = VTK_WIPE_QUAD;
33 this->SetNumberOfInputPorts(2);
34 }
35
36 //----------------------------------------------------------------------------
37 // This templated function executes the filter for any type of data.
38 // Handles the two input operations
39 template <class T>
vtkImageRectilinearWipeExecute2(vtkImageRectilinearWipe * self,vtkImageData * inData,T * inPtr,vtkImageData * outData,T * outPtr,int outExt[6],int id)40 void vtkImageRectilinearWipeExecute2(vtkImageRectilinearWipe *self,
41 vtkImageData *inData, T *inPtr,
42 vtkImageData *outData,
43 T *outPtr,
44 int outExt[6], int id)
45 {
46 int idxR, idxY, idxZ;
47 int maxY, maxZ;
48 vtkIdType inIncX, inIncY, inIncZ;
49 vtkIdType outIncX, outIncY, outIncZ;
50 int rowLength;
51 unsigned long count = 0;
52 unsigned long target;
53
54 // find the region to loop over
55 rowLength = (outExt[1] - outExt[0]+1)*inData->GetNumberOfScalarComponents();
56 maxY = outExt[3] - outExt[2];
57 maxZ = outExt[5] - outExt[4];
58
59 target = static_cast<unsigned long>((maxZ+1)*(maxY+1)/50.0);
60 target++;
61
62 // Get increments to march through data
63 inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
64 outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
65
66 // Loop through output pixels
67 for (idxZ = 0; idxZ <= maxZ; idxZ++)
68 {
69 for (idxY = 0; idxY <= maxY; idxY++)
70 {
71 if (!id)
72 {
73 if (!(count%target))
74 {
75 self->UpdateProgress(count/(50.0*target));
76 }
77 count++;
78 }
79 for (idxR = 0; idxR < rowLength; idxR++)
80 {
81 *outPtr = *inPtr;
82 outPtr++;
83 inPtr++;
84 }
85 outPtr += outIncY;
86 inPtr += inIncY;
87 }
88 outPtr += outIncZ;
89 inPtr += inIncZ;
90 }
91 }
92
93
94
95 //----------------------------------------------------------------------------
96 // This function adjusts the extents of the wipe to the output extents.
vtkImageRectilinearWipeClampExtents(int wipeExt[6],int outExt[6])97 static int vtkImageRectilinearWipeClampExtents(int wipeExt[6], int outExt[6])
98 {
99 int status = 1;
100
101 for (int i = 0; i < 3; i++)
102 {
103 // the lower and upper extents cannot be below the lower output extent
104 if (wipeExt[2*i] < outExt[2*i])
105 {
106 wipeExt[2*i] = outExt[2*i];
107 }
108 if (wipeExt[2*i + 1] < outExt[2*i])
109 {
110 wipeExt[2*i + 1] = outExt[2*i];
111 status = 0;
112 }
113
114 // the lower and upper extents cannot be above the upper output extent
115 if (wipeExt[2*i] > outExt[2*i + 1])
116 {
117 wipeExt[2*i] = outExt[2*i + 1];
118 status = 0;
119 }
120 if (wipeExt[2*i + 1] > outExt[2*i + 1])
121 {
122 wipeExt[2*i + 1] = outExt[2*i + 1];
123 }
124 }
125 return status;
126 }
127 //----------------------------------------------------------------------------
128 // This method is passed a input and output regions, and executes the filter
129 // algorithm to fill the output from the inputs based on the Wipe ivar.
ThreadedRequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector,vtkImageData *** inData,vtkImageData ** outData,int outExt[6],int id)130 void vtkImageRectilinearWipe::ThreadedRequestData(
131 vtkInformation * vtkNotUsed( request ),
132 vtkInformationVector ** vtkNotUsed( inputVector ),
133 vtkInformationVector * outputVector,
134 vtkImageData ***inData,
135 vtkImageData **outData,
136 int outExt[6], int id)
137 {
138 void *inPtr;
139 void *outPtr;
140 int wipeExt[6];
141 int wholeExt[6];
142 int whichInput = 0;
143
144 // Make sure the inputs/output are valid
145 if (inData[0][0] == NULL)
146 {
147 vtkErrorMacro(<< "Input " << 0 << " must be specified.");
148 return;
149 }
150
151 // this filter expects that input is the same type as output.
152 if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
153 {
154 vtkErrorMacro(<< "Execute: input ScalarType, "
155 << inData[0][0]->GetScalarType()
156 << ", must match out ScalarType "
157 << outData[0]->GetScalarType());
158 return;
159 }
160
161 if (inData[1][0] == NULL)
162 {
163 vtkErrorMacro(<< "Input " << 1 << " must be specified.");
164 return;
165 }
166
167 // this filter expects that inputs that have the same number of components
168 if (inData[0][0]->GetNumberOfScalarComponents() !=
169 inData[1][0]->GetNumberOfScalarComponents())
170 {
171 vtkErrorMacro(<< "Execute: input1 NumberOfScalarComponents, "
172 << inData[0][0]->GetNumberOfScalarComponents()
173 << ", must match out input2 NumberOfScalarComponents "
174 << inData[1][0]->GetNumberOfScalarComponents());
175 return;
176 }
177
178 // Wipe pattern depends on the whole extent.
179 outputVector->GetInformationObject(0)->Get(
180 vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExt);
181
182 // Each quadrant is processed separately
183 // lower left
184
185 memcpy (wipeExt, wholeExt, 6 * sizeof (int));
186 wipeExt[2*this->Axis[0]+1] += this->Position[0];
187 wipeExt[2*this->Axis[1]+1] += this->Position[1];
188
189 if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
190 {
191
192 outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
193
194 switch (this->Wipe)
195 {
196 case VTK_WIPE_QUAD:
197 whichInput = 0;
198 break;
199 case VTK_WIPE_HORIZONTAL:
200 whichInput = 0;
201 break;
202 case VTK_WIPE_VERTICAL:
203 whichInput = 0;
204 break;
205 case VTK_WIPE_LOWER_LEFT:
206 whichInput = 0;
207 break;
208 case VTK_WIPE_LOWER_RIGHT:
209 whichInput = 1;
210 break;
211 case VTK_WIPE_UPPER_LEFT:
212 whichInput = 1;
213 break;
214 case VTK_WIPE_UPPER_RIGHT:
215 whichInput = 1;
216 break;
217 }
218 inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
219 switch (inData[0][0]->GetScalarType())
220 {
221 vtkTemplateMacro(
222 vtkImageRectilinearWipeExecute2(this,
223 inData[whichInput][0],
224 static_cast<VTK_TT *>(inPtr),
225 outData[0],
226 static_cast<VTK_TT *>(outPtr),
227 wipeExt, id));
228 default:
229 vtkErrorMacro(<< "Execute: Unknown ScalarType");
230 return;
231 }
232 }
233
234 // lower right
235 memcpy (wipeExt, wholeExt, 6 * sizeof (int));
236 wipeExt[2*this->Axis[0]] += (this->Position[0]+1);
237 wipeExt[2*this->Axis[1]+1] =
238 wipeExt[2*this->Axis[1]] + this->Position[1];
239
240 if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
241 {
242 switch (this->Wipe)
243 {
244 case VTK_WIPE_QUAD:
245 whichInput = 1;
246 break;
247 case VTK_WIPE_HORIZONTAL:
248 whichInput = 1;
249 break;
250 case VTK_WIPE_VERTICAL:
251 whichInput = 0;
252 break;
253 case VTK_WIPE_LOWER_LEFT:
254 whichInput = 1;
255 break;
256 case VTK_WIPE_LOWER_RIGHT:
257 whichInput = 0;
258 break;
259 case VTK_WIPE_UPPER_LEFT:
260 whichInput = 1;
261 break;
262 case VTK_WIPE_UPPER_RIGHT:
263 whichInput = 1;
264 break;
265 }
266 inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
267 outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
268 switch (inData[0][0]->GetScalarType())
269 {
270 vtkTemplateMacro(
271 vtkImageRectilinearWipeExecute2(this,
272 inData[whichInput][0],
273 static_cast<VTK_TT *>(inPtr),
274 outData[0],
275 static_cast<VTK_TT *>(outPtr),
276 wipeExt, id));
277 default:
278 vtkErrorMacro(<< "Execute: Unknown ScalarType");
279 return;
280 }
281 }
282
283 // upper left
284 memcpy (wipeExt, wholeExt, 6 * sizeof (int));
285 wipeExt[2*this->Axis[0]+1] = wipeExt[2*this->Axis[0]] + this->Position[0];
286 wipeExt[2*this->Axis[1]] += (this->Position[1] + 1);
287
288 if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
289 {
290
291 switch (this->Wipe)
292 {
293 case VTK_WIPE_QUAD:
294 whichInput = 1;
295 break;
296 case VTK_WIPE_HORIZONTAL:
297 whichInput = 0;
298 break;
299 case VTK_WIPE_VERTICAL:
300 whichInput = 1;
301 break;
302 case VTK_WIPE_LOWER_LEFT:
303 whichInput = 1;
304 break;
305 case VTK_WIPE_LOWER_RIGHT:
306 whichInput = 1;
307 break;
308 case VTK_WIPE_UPPER_LEFT:
309 whichInput = 0;
310 break;
311 case VTK_WIPE_UPPER_RIGHT:
312 whichInput = 1;
313 break;
314 }
315 inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
316 outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
317 switch (inData[0][0]->GetScalarType())
318 {
319 vtkTemplateMacro(
320 vtkImageRectilinearWipeExecute2(this,
321 inData[whichInput][0],
322 static_cast<VTK_TT *>(inPtr),
323 outData[0],
324 static_cast<VTK_TT *>(outPtr),
325 wipeExt, id));
326 default:
327 vtkErrorMacro(<< "Execute: Unknown ScalarType");
328 return;
329 }
330 }
331
332 // upper right
333 memcpy (wipeExt, wholeExt, 6 * sizeof (int));
334 wipeExt[2*this->Axis[0]] += (this->Position[0] + 1);
335 wipeExt[2*this->Axis[1]] += (this->Position[1] + 1);
336
337 if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
338 {
339 switch (this->Wipe)
340 {
341 case VTK_WIPE_QUAD:
342 whichInput = 0;
343 break;
344 case VTK_WIPE_HORIZONTAL:
345 whichInput = 1;
346 break;
347 case VTK_WIPE_VERTICAL:
348 whichInput = 1;
349 break;
350 case VTK_WIPE_LOWER_LEFT:
351 whichInput = 1;
352 break;
353 case VTK_WIPE_LOWER_RIGHT:
354 whichInput = 1;
355 break;
356 case VTK_WIPE_UPPER_LEFT:
357 whichInput = 1;
358 break;
359 case VTK_WIPE_UPPER_RIGHT:
360 whichInput = 0;
361 break;
362 }
363 inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
364 outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
365 switch (inData[0][0]->GetScalarType())
366 {
367 vtkTemplateMacro(
368 vtkImageRectilinearWipeExecute2(this,
369 inData[whichInput][0],
370 static_cast<VTK_TT *>(inPtr),
371 outData[0],
372 static_cast<VTK_TT *>(outPtr),
373 wipeExt, id));
374 default:
375 vtkErrorMacro(<< "Execute: Unknown ScalarType");
376 return;
377 }
378 }
379 }
380
PrintSelf(ostream & os,vtkIndent indent)381 void vtkImageRectilinearWipe::PrintSelf(ostream& os, vtkIndent indent)
382 {
383 this->Superclass::PrintSelf(os,indent);
384 os << indent << "Position: (" << this->Position[0] << ", "
385 << this->Position[1] << ")\n";
386 os << indent << "Position: (" << this->Axis[0] << ", "
387 << this->Axis[1] << ", " << this->Axis[1] << ")\n";
388 os << indent << "Wipe: ";
389 switch (this->Wipe)
390 {
391 case VTK_WIPE_QUAD:
392 os << "Quad" << endl;
393 break;
394 case VTK_WIPE_HORIZONTAL:
395 os << "Horizontal" << endl;
396 break;
397 case VTK_WIPE_VERTICAL:
398 os << "Vertical" << endl;
399 break;
400 case VTK_WIPE_LOWER_LEFT:
401 os << "LowerLeft" << endl;
402 break;
403 case VTK_WIPE_LOWER_RIGHT:
404 os << "LowerRight" << endl;
405 break;
406 case VTK_WIPE_UPPER_LEFT:
407 os << "UpperLeft" << endl;
408 break;
409 case VTK_WIPE_UPPER_RIGHT:
410 os << "UpperRight" << endl;
411 break;
412 }
413 }
414
415