/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkImageIdealHighPass.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 "vtkImageIdealHighPass.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include vtkCxxRevisionMacro(vtkImageIdealHighPass, "$Revision: 1.22 $"); vtkStandardNewMacro(vtkImageIdealHighPass); //---------------------------------------------------------------------------- vtkImageIdealHighPass::vtkImageIdealHighPass() { this->CutOff[0] = this->CutOff[1] = this->CutOff[2] = VTK_DOUBLE_MAX; } //---------------------------------------------------------------------------- void vtkImageIdealHighPass::SetXCutOff(double cutOff) { if (cutOff == this->CutOff[0]) { return; } this->CutOff[0] = cutOff; this->Modified(); } //---------------------------------------------------------------------------- void vtkImageIdealHighPass::SetYCutOff(double cutOff) { if (cutOff == this->CutOff[1]) { return; } this->CutOff[1] = cutOff; this->Modified(); } //---------------------------------------------------------------------------- void vtkImageIdealHighPass::SetZCutOff(double cutOff) { if (cutOff == this->CutOff[2]) { return; } this->CutOff[2] = cutOff; this->Modified(); } //---------------------------------------------------------------------------- void vtkImageIdealHighPass::ThreadedRequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int ext[6], int id) { int idx0, idx1, idx2; int min0, max0; double *inPtr; double *outPtr; int wholeExtent[6]; double spacing[3]; vtkIdType inInc0, inInc1, inInc2; vtkIdType outInc0, outInc1, outInc2; double temp0, temp1, temp2, mid0, mid1, mid2; // normalization factors double norm0, norm1, norm2; double sum1, sum0; unsigned long count = 0; unsigned long target; vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); // Error checking if (inData[0][0]->GetNumberOfScalarComponents() != 2) { vtkErrorMacro("Expecting 2 components not " << inData[0][0]->GetNumberOfScalarComponents()); return; } if (inData[0][0]->GetScalarType() != VTK_DOUBLE || outData[0]->GetScalarType() != VTK_DOUBLE) { vtkErrorMacro("Expecting input and output to be of type double"); return; } inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent); inData[0][0]->GetSpacing(spacing); inPtr = (double *)(inData[0][0]->GetScalarPointerForExtent(ext)); outPtr = (double *)(outData[0]->GetScalarPointerForExtent(ext)); inData[0][0]->GetContinuousIncrements(ext, inInc0, inInc1, inInc2); outData[0]->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); min0 = ext[0]; max0 = ext[1]; mid0 = (double)(wholeExtent[0] + wholeExtent[1] + 1) / 2.0; mid1 = (double)(wholeExtent[2] + wholeExtent[3] + 1) / 2.0; mid2 = (double)(wholeExtent[4] + wholeExtent[5] + 1) / 2.0; if ( this->CutOff[0] == 0.0) { norm0 = VTK_DOUBLE_MAX; } else { norm0 = 1.0 / ((spacing[0] * 2.0 * mid0) * this->CutOff[0]); } if ( this->CutOff[1] == 0.0) { norm1 = VTK_DOUBLE_MAX; } else { norm1 = 1.0 / ((spacing[1] * 2.0 * mid1) * this->CutOff[1]); } if ( this->CutOff[2] == 0.0) { norm2 = VTK_DOUBLE_MAX; } else { norm2 = 1.0 / ((spacing[2] * 2.0 * mid2) * this->CutOff[2]); } target = (unsigned long)((ext[5]-ext[4]+1)*(ext[3]-ext[2]+1)/50.0); target++; // loop over all the pixels (keeping track of normalized distance to origin. for (idx2 = ext[4]; idx2 <= ext[5]; ++idx2) { // distance to min (this axis' contribution) temp2 = (double)idx2; // Wrap back to 0. if (temp2 > mid2) { temp2 = mid2 + mid2 - temp2; } // Convert location into normalized cycles/world unit temp2 = temp2 * norm2; for (idx1 = ext[2]; !this->AbortExecute && idx1 <= ext[3]; ++idx1) { if (!id) { if (!(count%target)) { this->UpdateProgress(count/(50.0*target)); } count++; } // distance to min (this axis' contribution) temp1 = (double)idx1; // Wrap back to 0. if (temp1 > mid1) { temp1 = mid1 + mid1 - temp1; } // Convert location into cycles / world unit temp1 = temp1 * norm1; sum1 = temp2 * temp2 + temp1 * temp1; for (idx0 = min0; idx0 <= max0; ++idx0) { // distance to min (this axis' contribution) temp0 = (double)idx0; // Wrap back to 0. if (temp0 > mid0) { temp0 = mid0 + mid0 - temp0; } // Convert location into cycles / world unit temp0 = temp0 * norm0; sum0 = sum1 + temp0 * temp0; if (sum0 > 1.0) { // real component *outPtr++ = *inPtr++; // imaginary component *outPtr++ = *inPtr++; } else { // real component *outPtr++ = 0.0; ++inPtr; // imaginary component *outPtr++ = 0.0; ++inPtr; } } inPtr += inInc1; outPtr += outInc1; } inPtr += inInc2; outPtr += outInc2; } } void vtkImageIdealHighPass::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "CutOff: ( " << this->CutOff[0] << ", " << this->CutOff[1] << ", " << this->CutOff[2] << " )\n"; }