Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

229 lines
6.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkImageCityBlockDistance.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 "vtkImageCityBlockDistance.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkCxxRevisionMacro(vtkImageCityBlockDistance, "$Revision: 1.29 $");
vtkStandardNewMacro(vtkImageCityBlockDistance);
//----------------------------------------------------------------------------
vtkImageCityBlockDistance::vtkImageCityBlockDistance()
{
}
//----------------------------------------------------------------------------
void vtkImageCityBlockDistance::AllocateOutputScalars(vtkImageData *outData,
int* uExt,
int* wholeExtent)
{
int updateExtent[6], idx;
memcpy(updateExtent, uExt, 6*sizeof(int));
for (idx = 0; idx < this->Dimensionality; ++idx)
{
updateExtent[idx*2] = wholeExtent[idx*2];
updateExtent[idx*2+1] = wholeExtent[idx*2+1];
}
outData->SetExtent(updateExtent);
outData->AllocateScalars();
}
//----------------------------------------------------------------------------
// This method tells the superclass that the whole input array is needed
// to compute any output region.
int vtkImageCityBlockDistance::IterativeRequestUpdateExtent(
vtkInformation* input, vtkInformation* output)
{
int *outExt = output->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
int *wExt = input->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
int inExt[6];
memcpy(inExt, outExt, 6 * sizeof(int));
inExt[this->Iteration * 2] = wExt[this->Iteration * 2];
inExt[this->Iteration * 2 + 1] = wExt[this->Iteration * 2 + 1];
input->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),inExt,6);
return 1;
}
//----------------------------------------------------------------------------
// This is writen as a 1D execute method, but is called several times.
int vtkImageCityBlockDistance::IterativeRequestData(
vtkInformation* vtkNotUsed( request ),
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
vtkImageData *inData = vtkImageData::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkImageData *outData = vtkImageData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
int *uExt = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
int *wExt = outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
this->AllocateOutputScalars(outData, uExt, wExt);
short *inPtr0, *inPtr1, *inPtr2, *inPtrC;
short *outPtr0, *outPtr1, *outPtr2, *outPtrC;
vtkIdType inInc0, inInc1, inInc2;
vtkIdType outInc0, outInc1, outInc2;
int min0, max0, min1, max1, min2, max2, numberOfComponents;
int idx0, idx1, idx2, idxC;
short distP, distN;
short big = 2000;
int outExt[6];
unsigned long count = 0;
unsigned long target;
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),outExt);
// this filter expects that inputand output are short
if (inData->GetScalarType() != VTK_SHORT ||
outData->GetScalarType() != VTK_SHORT)
{
vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
<< ", and out ScalarType " << outData->GetScalarType()
<< " must be short.");
return 1;
}
// Reorder axes (the in and out extents are assumed to be the same)
// (see intercept cache update)
this->PermuteExtent(outExt, min0, max0, min1, max1, min2, max2);
this->PermuteIncrements(inData->GetIncrements(), inInc0, inInc1, inInc2);
this->PermuteIncrements(outData->GetIncrements(), outInc0, outInc1, outInc2);
numberOfComponents = inData->GetNumberOfScalarComponents();
target = (unsigned long)((max2-min2+1)*(max1-min1+1)/50.0);
target++;
// loop over all the extra axes
inPtr2 = (short *)inData->GetScalarPointerForExtent(outExt);
outPtr2 = (short *)outData->GetScalarPointerForExtent(outExt);
for (idx2 = min2; idx2 <= max2; ++idx2)
{
inPtr1 = inPtr2;
outPtr1 = outPtr2;
for (idx1 = min1; !this->AbortExecute && idx1 <= max1; ++idx1)
{
if (!(count%target))
{
this->UpdateProgress(count/(50.0*target));
}
count++;
inPtrC = inPtr1;
outPtrC = outPtr1;
for (idxC = 0; idxC < numberOfComponents; ++idxC)
{
// execute forward pass
distP = big;
distN = -big;
inPtr0 = inPtrC;
outPtr0 = outPtrC;
for (idx0 = min0; idx0 <= max0; ++idx0)
{ // preserve sign
if (*inPtr0 >= 0)
{
distN = 0;
if (distP > *inPtr0)
{
distP = *inPtr0;
}
*outPtr0 = distP;
}
if (*inPtr0 <= 0)
{
distP = 0;
if (distN < *inPtr0)
{
distN = *inPtr0;
}
*outPtr0 = distN;
}
if (distP < big)
{
++distP;
}
if (distN > -big)
{
--distN;
}
inPtr0 += inInc0;
outPtr0 += outInc0;
}
// backward pass
distP = big;
distN = -big;
// Undo the last increment to put us at the last pixel
// (input is no longer needed)
outPtr0 -= outInc0;
for (idx0 = max0; idx0 >= min0; --idx0)
{
if (*outPtr0 >= 0)
{
if (distP > *outPtr0)
{
distP = *outPtr0;
}
*outPtr0 = distP;
}
if (*outPtr0 <= 0)
{
if (distN < *outPtr0)
{
distN = *outPtr0;
}
*outPtr0 = distN;
}
if (distP < big)
{
++distP;
}
if (distN > -big)
{
--distN;
}
outPtr0 -= outInc0;
}
inPtrC += 1;
outPtrC += 1;
}
inPtr1 += inInc1;
outPtr1 += outInc1;
}
inPtr2 += inInc2;
outPtr2 += outInc2;
}
return 1;
}