You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
415 lines
12 KiB
C++
415 lines
12 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkImageRectilinearWipe.cxx
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkImageRectilinearWipe.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
|
|
vtkStandardNewMacro(vtkImageRectilinearWipe);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageRectilinearWipe::vtkImageRectilinearWipe()
|
|
{
|
|
this->Position[0] = 0;
|
|
this->Position[1] = 0;
|
|
this->Axis[0] = 0;
|
|
this->Axis[1] = 1;
|
|
this->Wipe = VTK_WIPE_QUAD;
|
|
this->SetNumberOfInputPorts(2);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// This templated function executes the filter for any type of data.
|
|
// Handles the two input operations
|
|
template <class T>
|
|
void vtkImageRectilinearWipeExecute2(vtkImageRectilinearWipe *self,
|
|
vtkImageData *inData, T *inPtr,
|
|
vtkImageData *outData,
|
|
T *outPtr,
|
|
int outExt[6], int id)
|
|
{
|
|
int idxR, idxY, idxZ;
|
|
int maxY, maxZ;
|
|
vtkIdType inIncX, inIncY, inIncZ;
|
|
vtkIdType outIncX, outIncY, outIncZ;
|
|
int rowLength;
|
|
unsigned long count = 0;
|
|
unsigned long target;
|
|
|
|
// find the region to loop over
|
|
rowLength = (outExt[1] - outExt[0]+1)*inData->GetNumberOfScalarComponents();
|
|
maxY = outExt[3] - outExt[2];
|
|
maxZ = outExt[5] - outExt[4];
|
|
|
|
target = static_cast<unsigned long>((maxZ+1)*(maxY+1)/50.0);
|
|
target++;
|
|
|
|
// Get increments to march through data
|
|
inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
|
|
outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
|
|
|
|
// Loop through output pixels
|
|
for (idxZ = 0; idxZ <= maxZ; idxZ++)
|
|
{
|
|
for (idxY = 0; idxY <= maxY; idxY++)
|
|
{
|
|
if (!id)
|
|
{
|
|
if (!(count%target))
|
|
{
|
|
self->UpdateProgress(count/(50.0*target));
|
|
}
|
|
count++;
|
|
}
|
|
for (idxR = 0; idxR < rowLength; idxR++)
|
|
{
|
|
*outPtr = *inPtr;
|
|
outPtr++;
|
|
inPtr++;
|
|
}
|
|
outPtr += outIncY;
|
|
inPtr += inIncY;
|
|
}
|
|
outPtr += outIncZ;
|
|
inPtr += inIncZ;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// This function adjusts the extents of the wipe to the output extents.
|
|
static int vtkImageRectilinearWipeClampExtents(int wipeExt[6], int outExt[6])
|
|
{
|
|
int status = 1;
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
// the lower and upper extents cannot be below the lower output extent
|
|
if (wipeExt[2*i] < outExt[2*i])
|
|
{
|
|
wipeExt[2*i] = outExt[2*i];
|
|
}
|
|
if (wipeExt[2*i + 1] < outExt[2*i])
|
|
{
|
|
wipeExt[2*i + 1] = outExt[2*i];
|
|
status = 0;
|
|
}
|
|
|
|
// the lower and upper extents cannot be above the upper output extent
|
|
if (wipeExt[2*i] > outExt[2*i + 1])
|
|
{
|
|
wipeExt[2*i] = outExt[2*i + 1];
|
|
status = 0;
|
|
}
|
|
if (wipeExt[2*i + 1] > outExt[2*i + 1])
|
|
{
|
|
wipeExt[2*i + 1] = outExt[2*i + 1];
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
// This method is passed a input and output regions, and executes the filter
|
|
// algorithm to fill the output from the inputs based on the Wipe ivar.
|
|
void vtkImageRectilinearWipe::ThreadedRequestData(
|
|
vtkInformation * vtkNotUsed( request ),
|
|
vtkInformationVector ** vtkNotUsed( inputVector ),
|
|
vtkInformationVector * outputVector,
|
|
vtkImageData ***inData,
|
|
vtkImageData **outData,
|
|
int outExt[6], int id)
|
|
{
|
|
void *inPtr;
|
|
void *outPtr;
|
|
int wipeExt[6];
|
|
int wholeExt[6];
|
|
int whichInput = 0;
|
|
|
|
// Make sure the inputs/output are valid
|
|
if (inData[0][0] == NULL)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 0 << " must be specified.");
|
|
return;
|
|
}
|
|
|
|
// this filter expects that input is the same type as output.
|
|
if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
|
|
{
|
|
vtkErrorMacro(<< "Execute: input ScalarType, "
|
|
<< inData[0][0]->GetScalarType()
|
|
<< ", must match out ScalarType "
|
|
<< outData[0]->GetScalarType());
|
|
return;
|
|
}
|
|
|
|
if (inData[1][0] == NULL)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 1 << " must be specified.");
|
|
return;
|
|
}
|
|
|
|
// this filter expects that inputs that have the same number of components
|
|
if (inData[0][0]->GetNumberOfScalarComponents() !=
|
|
inData[1][0]->GetNumberOfScalarComponents())
|
|
{
|
|
vtkErrorMacro(<< "Execute: input1 NumberOfScalarComponents, "
|
|
<< inData[0][0]->GetNumberOfScalarComponents()
|
|
<< ", must match out input2 NumberOfScalarComponents "
|
|
<< inData[1][0]->GetNumberOfScalarComponents());
|
|
return;
|
|
}
|
|
|
|
// Wipe pattern depends on the whole extent.
|
|
outputVector->GetInformationObject(0)->Get(
|
|
vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExt);
|
|
|
|
// Each quadrant is processed separately
|
|
// lower left
|
|
|
|
memcpy (wipeExt, wholeExt, 6 * sizeof (int));
|
|
wipeExt[2*this->Axis[0]+1] += this->Position[0];
|
|
wipeExt[2*this->Axis[1]+1] += this->Position[1];
|
|
|
|
if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
|
|
{
|
|
|
|
outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
|
|
|
|
switch (this->Wipe)
|
|
{
|
|
case VTK_WIPE_QUAD:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_HORIZONTAL:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_VERTICAL:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_LOWER_LEFT:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_LOWER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
}
|
|
inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
|
|
switch (inData[0][0]->GetScalarType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkImageRectilinearWipeExecute2(this,
|
|
inData[whichInput][0],
|
|
static_cast<VTK_TT *>(inPtr),
|
|
outData[0],
|
|
static_cast<VTK_TT *>(outPtr),
|
|
wipeExt, id));
|
|
default:
|
|
vtkErrorMacro(<< "Execute: Unknown ScalarType");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// lower right
|
|
memcpy (wipeExt, wholeExt, 6 * sizeof (int));
|
|
wipeExt[2*this->Axis[0]] += (this->Position[0]+1);
|
|
wipeExt[2*this->Axis[1]+1] =
|
|
wipeExt[2*this->Axis[1]] + this->Position[1];
|
|
|
|
if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
|
|
{
|
|
switch (this->Wipe)
|
|
{
|
|
case VTK_WIPE_QUAD:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_HORIZONTAL:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_VERTICAL:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_LOWER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_LOWER_RIGHT:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_UPPER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
}
|
|
inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
|
|
outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
|
|
switch (inData[0][0]->GetScalarType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkImageRectilinearWipeExecute2(this,
|
|
inData[whichInput][0],
|
|
static_cast<VTK_TT *>(inPtr),
|
|
outData[0],
|
|
static_cast<VTK_TT *>(outPtr),
|
|
wipeExt, id));
|
|
default:
|
|
vtkErrorMacro(<< "Execute: Unknown ScalarType");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// upper left
|
|
memcpy (wipeExt, wholeExt, 6 * sizeof (int));
|
|
wipeExt[2*this->Axis[0]+1] = wipeExt[2*this->Axis[0]] + this->Position[0];
|
|
wipeExt[2*this->Axis[1]] += (this->Position[1] + 1);
|
|
|
|
if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
|
|
{
|
|
|
|
switch (this->Wipe)
|
|
{
|
|
case VTK_WIPE_QUAD:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_HORIZONTAL:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_VERTICAL:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_LOWER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_LOWER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_LEFT:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_UPPER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
}
|
|
inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
|
|
outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
|
|
switch (inData[0][0]->GetScalarType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkImageRectilinearWipeExecute2(this,
|
|
inData[whichInput][0],
|
|
static_cast<VTK_TT *>(inPtr),
|
|
outData[0],
|
|
static_cast<VTK_TT *>(outPtr),
|
|
wipeExt, id));
|
|
default:
|
|
vtkErrorMacro(<< "Execute: Unknown ScalarType");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// upper right
|
|
memcpy (wipeExt, wholeExt, 6 * sizeof (int));
|
|
wipeExt[2*this->Axis[0]] += (this->Position[0] + 1);
|
|
wipeExt[2*this->Axis[1]] += (this->Position[1] + 1);
|
|
|
|
if (vtkImageRectilinearWipeClampExtents(wipeExt, outExt))
|
|
{
|
|
switch (this->Wipe)
|
|
{
|
|
case VTK_WIPE_QUAD:
|
|
whichInput = 0;
|
|
break;
|
|
case VTK_WIPE_HORIZONTAL:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_VERTICAL:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_LOWER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_LOWER_RIGHT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_LEFT:
|
|
whichInput = 1;
|
|
break;
|
|
case VTK_WIPE_UPPER_RIGHT:
|
|
whichInput = 0;
|
|
break;
|
|
}
|
|
inPtr = inData[whichInput][0]->GetScalarPointerForExtent(wipeExt);
|
|
outPtr = outData[0]->GetScalarPointerForExtent(wipeExt);
|
|
switch (inData[0][0]->GetScalarType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkImageRectilinearWipeExecute2(this,
|
|
inData[whichInput][0],
|
|
static_cast<VTK_TT *>(inPtr),
|
|
outData[0],
|
|
static_cast<VTK_TT *>(outPtr),
|
|
wipeExt, id));
|
|
default:
|
|
vtkErrorMacro(<< "Execute: Unknown ScalarType");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void vtkImageRectilinearWipe::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
os << indent << "Position: (" << this->Position[0] << ", "
|
|
<< this->Position[1] << ")\n";
|
|
os << indent << "Position: (" << this->Axis[0] << ", "
|
|
<< this->Axis[1] << ", " << this->Axis[1] << ")\n";
|
|
os << indent << "Wipe: ";
|
|
switch (this->Wipe)
|
|
{
|
|
case VTK_WIPE_QUAD:
|
|
os << "Quad" << endl;
|
|
break;
|
|
case VTK_WIPE_HORIZONTAL:
|
|
os << "Horizontal" << endl;
|
|
break;
|
|
case VTK_WIPE_VERTICAL:
|
|
os << "Vertical" << endl;
|
|
break;
|
|
case VTK_WIPE_LOWER_LEFT:
|
|
os << "LowerLeft" << endl;
|
|
break;
|
|
case VTK_WIPE_LOWER_RIGHT:
|
|
os << "LowerRight" << endl;
|
|
break;
|
|
case VTK_WIPE_UPPER_LEFT:
|
|
os << "UpperLeft" << endl;
|
|
break;
|
|
case VTK_WIPE_UPPER_RIGHT:
|
|
os << "UpperRight" << endl;
|
|
break;
|
|
}
|
|
}
|
|
|