/*========================================================================= Program: Visualization Toolkit Module: TestCopyAttributeData.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. =========================================================================*/ // Test the vtkImageAlgorithm::CopyAttributeData() method, which copies // all of the attribute data arrays (PointData and CellData) that is // not usually handled by the Execute methods of the imaging filters // (Execute methods typically process only the PointData Scalars). #include "vtkImageAlgorithm.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkIntArray.h" #include "vtkFloatArray.h" #include "vtkStringArray.h" #include "vtkPointData.h" #include "vtkCellData.h" #include "vtkVariant.h" #include "vtkSmartPointer.h" #include #include // Make a dummy image filter that does nothing but call CopyAttributeData. class vtkDummyImageFilter : public vtkImageAlgorithm { public: static vtkDummyImageFilter *New(); vtkTypeMacro(vtkDummyImageFilter,vtkImageAlgorithm); protected: vtkDummyImageFilter() {}; ~vtkDummyImageFilter() override {}; int RequestData( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) override; private: vtkDummyImageFilter(const vtkDummyImageFilter&) = delete; void operator=(const vtkDummyImageFilter&) = delete; }; vtkStandardNewMacro(vtkDummyImageFilter); int vtkDummyImageFilter::RequestData( vtkInformation*, 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 extent[6]; outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent); this->AllocateOutputData(outData, outInfo, extent); // this is what we are testing this->CopyAttributeData(inData, outData, inputVector); // scalars would usually be processed here, but this is a dummy filter return 1; } int TestCopyAttributeData(int,char *[]) { int extent[6] = { 0, 6, 0, 4, 0, 2 }; int outExt[6] = { 0, 4, 2, 2, 0, 2 }; vtkSmartPointer image = vtkSmartPointer::New(); image->SetExtent(extent); image->AllocateScalars(VTK_UNSIGNED_CHAR, 1); vtkIdType numPoints = image->GetNumberOfPoints(); vtkIdType numCells = image->GetNumberOfCells(); vtkSmartPointer pointVectors = vtkSmartPointer::New(); pointVectors->SetName("ImageVectors"); pointVectors->SetNumberOfComponents(3); pointVectors->SetNumberOfTuples(numPoints); for (vtkIdType i = 0; i < numPoints; i++) { double v[3]; v[0] = sin(i*0.5); v[1] = cos(i*0.5); v[2] = sin(i*0.1); pointVectors->SetTuple(i, v); } vtkSmartPointer cellScalars = vtkSmartPointer::New(); cellScalars->SetName("CellScalars"); cellScalars->SetNumberOfValues(numCells); vtkSmartPointer cellStrings = vtkSmartPointer::New(); cellStrings->SetName("CellStrings"); cellStrings->SetNumberOfValues(numCells); for (vtkIdType j = 0; j < numCells; j++) { vtkVariant val(j); cellScalars->SetValue(j, j); cellStrings->SetValue(j, val.ToString()); } image->GetPointData()->SetVectors(pointVectors); image->GetCellData()->SetScalars(cellScalars); image->GetCellData()->AddArray(cellStrings); vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputData(image); for (int r = 0; r < 2; r++) { filter->UpdateExtent(outExt); vtkImageData *output = filter->GetOutput(); vtkDataArray *outPointVectors = output->GetPointData()->GetVectors(); vtkDataArray *outCellScalars = output->GetCellData()->GetScalars(); vtkStringArray *outCellStrings = vtkArrayDownCast( output->GetCellData()->GetAbstractArray("CellStrings")); for (int zId = outExt[4]; zId <= outExt[5]; zId++) { for (int yId = outExt[2]; yId <= outExt[3]; yId++) { for (int xId = outExt[0]; xId <= outExt[1]; xId++) { vtkIdType inIdx = (zId - extent[4])*(extent[3] - extent[2] + 1); inIdx = (inIdx + yId - extent[2])*(extent[1] - extent[0] + 1); inIdx = inIdx + xId - extent[0]; vtkIdType outIdx = (zId - outExt[4])*(outExt[3] - outExt[2] + 1); outIdx = (outIdx + yId - outExt[2])*(outExt[1] - outExt[0] + 1); outIdx = outIdx + xId - outExt[0]; double v1[3], v2[3]; pointVectors->GetTuple(inIdx, v1); outPointVectors->GetTuple(outIdx, v2); if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { cerr << "point attribute value mismatch "; return 1; } } } } for (int zId = outExt[4]; zId < outExt[5]; zId++) { int ye = (outExt[2] == outExt[3]); for (int yId = outExt[2]; yId < outExt[3] + ye; yId++) { for (int xId = outExt[0]; xId < outExt[1]; xId++) { vtkIdType inIdx = (zId - extent[4])*(extent[3] - extent[2]); inIdx = (inIdx + yId - extent[2])*(extent[1] - extent[0]); inIdx = inIdx + xId - extent[0]; vtkIdType outIdx = (zId - outExt[4])*(outExt[3] - outExt[2] + ye); outIdx = (outIdx + yId - outExt[2])*(outExt[1] - outExt[0]); outIdx = outIdx + xId - outExt[0]; double s1, s2; cellScalars->GetTuple(inIdx, &s1); outCellScalars->GetTuple(outIdx, &s2); if (s1 != s2) { cerr << "cell attribute value mismatch\n"; return 1; } if (cellStrings->GetValue(inIdx) != outCellStrings->GetValue(outIdx)) { cerr << "cell attribute string mismatch\n"; return 1; } } } } // try again with full extent to test pass data outExt[0] = extent[0]; outExt[1] = extent[1]; outExt[2] = extent[2]; outExt[3] = extent[3]; outExt[4] = extent[4]; outExt[5] = extent[5]; } return 0; }