You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
7.0 KiB
230 lines
7.0 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkImageCheckerboard.cxx,v $
|
|
|
|
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 "vtkImageCheckerboard.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkObjectFactory.h"
|
|
|
|
vtkCxxRevisionMacro(vtkImageCheckerboard, "$Revision: 1.14 $");
|
|
vtkStandardNewMacro(vtkImageCheckerboard);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageCheckerboard::vtkImageCheckerboard()
|
|
{
|
|
this->NumberOfDivisions[0] = 2;
|
|
this->NumberOfDivisions[1] = 2;
|
|
this->NumberOfDivisions[2] = 2;
|
|
|
|
this->SetNumberOfInputPorts(2);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// This templated function executes the filter for any type of data.
|
|
// Handles the two input operations
|
|
template <class T>
|
|
void vtkImageCheckerboardExecute2(vtkImageCheckerboard *self,
|
|
vtkImageData *in1Data, T *in1Ptr,
|
|
vtkImageData *in2Data, T *in2Ptr,
|
|
vtkImageData *outData,
|
|
T *outPtr,
|
|
int outExt[6], int id)
|
|
{
|
|
int idxR, idxY, idxZ;
|
|
int maxY, maxZ;
|
|
int dimWholeX, dimWholeY, dimWholeZ;
|
|
int divX, divY, divZ;
|
|
int nComp;
|
|
int selectX, selectY, selectZ;
|
|
int which;
|
|
vtkIdType inIncX, inIncY, inIncZ;
|
|
vtkIdType in2IncX, in2IncY, in2IncZ;
|
|
vtkIdType outIncX, outIncY, outIncZ;
|
|
int wholeExt[6];
|
|
int rowLength;
|
|
unsigned long count = 0;
|
|
unsigned long target;
|
|
int threadOffsetX, threadOffsetY, threadOffsetZ;
|
|
int numDivX, numDivY, numDivZ;
|
|
|
|
// find the region to loop over
|
|
nComp = in1Data->GetNumberOfScalarComponents();
|
|
rowLength = (outExt[1] - outExt[0]+1)*nComp;
|
|
maxY = outExt[3] - outExt[2];
|
|
maxZ = outExt[5] - outExt[4];
|
|
|
|
outData->GetWholeExtent(wholeExt);
|
|
|
|
dimWholeX = wholeExt[1] - wholeExt[0] + 1;
|
|
dimWholeY = wholeExt[3] - wholeExt[2] + 1;
|
|
dimWholeZ = wholeExt[5] - wholeExt[4] + 1;
|
|
|
|
threadOffsetX = (outExt[0] - wholeExt[0]) * nComp;
|
|
threadOffsetY = outExt[2] - wholeExt[2];
|
|
threadOffsetZ = outExt[4] - wholeExt[4];
|
|
|
|
target = (unsigned long)((maxZ+1)*(maxY+1)/50.0);
|
|
target++;
|
|
|
|
// Get increments to march through data
|
|
in1Data->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
|
|
in2Data->GetContinuousIncrements(outExt, in2IncX, in2IncY, in2IncZ);
|
|
outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
|
|
|
|
// make sure number of divisions is not 0
|
|
numDivX = (self->GetNumberOfDivisions()[0] == 0) ? 1 : self->GetNumberOfDivisions()[0];
|
|
numDivY = (self->GetNumberOfDivisions()[1] == 0) ? 1 : self->GetNumberOfDivisions()[1];
|
|
numDivZ = (self->GetNumberOfDivisions()[2] == 0) ? 1 : self->GetNumberOfDivisions()[2];
|
|
|
|
divX = dimWholeX / numDivX * nComp;
|
|
divY = dimWholeY / numDivY;
|
|
divZ = dimWholeZ / numDivZ;
|
|
|
|
// Loop through output pixels
|
|
for (idxZ = 0; idxZ <= maxZ; idxZ++)
|
|
{
|
|
selectZ = (((idxZ + threadOffsetZ) / divZ) % 2) << 2;
|
|
for (idxY = 0; idxY <= maxY; idxY++)
|
|
{
|
|
if (!id)
|
|
{
|
|
if (!(count%target))
|
|
{
|
|
self->UpdateProgress(count/(50.0*target));
|
|
}
|
|
count++;
|
|
}
|
|
selectY = (((idxY + threadOffsetY) / divY) % 2) << 1;
|
|
for (idxR = 0; idxR < rowLength; idxR++)
|
|
{
|
|
|
|
selectX = ((idxR + threadOffsetX) / divX) % 2;
|
|
which = selectZ + selectY + selectX;
|
|
switch (which)
|
|
{
|
|
case 0:
|
|
*outPtr = *in1Ptr;
|
|
break;
|
|
case 1:
|
|
*outPtr = *in2Ptr;
|
|
break;
|
|
case 2:
|
|
*outPtr = *in2Ptr;
|
|
break;
|
|
case 3:
|
|
*outPtr = *in1Ptr;
|
|
break;
|
|
case 4:
|
|
*outPtr = *in2Ptr;
|
|
break;
|
|
case 5:
|
|
*outPtr = *in1Ptr;
|
|
break;
|
|
case 6:
|
|
*outPtr = *in1Ptr;
|
|
break;
|
|
case 7:
|
|
*outPtr = *in2Ptr;
|
|
break;
|
|
}
|
|
outPtr++;
|
|
in1Ptr++;
|
|
in2Ptr++;
|
|
}
|
|
outPtr += outIncY;
|
|
in1Ptr += inIncY;
|
|
in2Ptr += in2IncY;
|
|
}
|
|
outPtr += outIncZ;
|
|
in1Ptr += inIncZ;
|
|
in2Ptr += in2IncZ;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// This method is passed a input and output regions, and executes the filter
|
|
// algorithm to fill the output from the inputs.
|
|
void vtkImageCheckerboard::ThreadedRequestData(
|
|
vtkInformation * vtkNotUsed( request ),
|
|
vtkInformationVector ** vtkNotUsed( inputVector ),
|
|
vtkInformationVector * vtkNotUsed( outputVector ),
|
|
vtkImageData ***inData,
|
|
vtkImageData **outData,
|
|
int outExt[6], int id)
|
|
{
|
|
void *in1Ptr, *in2Ptr;
|
|
void *outPtr;
|
|
|
|
if (inData[0][0] == NULL)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 0 << " must be specified.");
|
|
return;
|
|
}
|
|
in1Ptr = inData[0][0]->GetScalarPointerForExtent(outExt);
|
|
if (!in1Ptr)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 0 << " cannot be empty.");
|
|
return;
|
|
}
|
|
|
|
outPtr = outData[0]->GetScalarPointerForExtent(outExt);
|
|
|
|
if (inData[1][0] == NULL)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 1 << " must be specified.");
|
|
return;
|
|
}
|
|
in2Ptr = inData[1][0]->GetScalarPointerForExtent(outExt);
|
|
if (!in2Ptr)
|
|
{
|
|
vtkErrorMacro(<< "Input " << 1 << " cannot be empty.");
|
|
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;
|
|
}
|
|
|
|
switch (inData[0][0]->GetScalarType())
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkImageCheckerboardExecute2(this, inData[0][0],
|
|
(VTK_TT *)(in1Ptr), inData[1][0],
|
|
(VTK_TT *)(in2Ptr),
|
|
outData[0],
|
|
(VTK_TT *)(outPtr),
|
|
outExt, id));
|
|
default:
|
|
vtkErrorMacro(<< "Execute: Unknown ScalarType");
|
|
return;
|
|
}
|
|
}
|
|
|
|
void vtkImageCheckerboard::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
os << indent << "NumberOfDivisions: (" << this->NumberOfDivisions[0] << ", "
|
|
<< this->NumberOfDivisions[1] << ", "
|
|
<< this->NumberOfDivisions[2] << ")\n";
|
|
}
|
|
|
|
|