I have a scalar array and a 3D vector array that I want to shallow copy to a vtkImageData. This way whenever data is manipulated, the change in the data is reflected in the array as well as in the vtkImageData object.
I am able to perform shallowcopy on the scalar array and when the data is changed I can see the effect on both the array and the vtkImageData. However, I failed to do the same thing for the 3D vector. The vector has 3 components.
The code below is a minimally working example that successfully shallowcopies the scalar but it crashes on imageData->GetPointData()->GetVectors()->ShallowCopy(vectorArray). Could someone help?
#include <vtkIntArray.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkSmartPointer.h>
int main() {
const int dimensions[3] = { 2, 2, 2 };
const int N = 8;
int myScalar[N] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int my3DVector[3 * N] = {
0, 1, 2, // x, y, z components of the first vector
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
18, 19, 20,
21, 22, 23 // x, y, z components of the last vector
};
// ImageData
vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
imageData->SetDimensions(dimensions);
imageData->AllocateScalars(VTK_INT, 1);
// Create a scalar point data array
vtkSmartPointer<vtkIntArray> scalarArray = vtkSmartPointer<vtkIntArray>::New();
scalarArray->SetNumberOfComponents(1);
scalarArray->SetNumberOfTuples(imageData->GetNumberOfPoints());
scalarArray->SetArray(reinterpret_cast<int*>(myScalar), N, 1);
scalarArray->SetName("MyScalar");
// Set the scalar of the imagedata
imageData->GetPointData()->GetScalars()->ShallowCopy(scalarArray);
// Changing the value of elements of myScalar should reflect on imageData
// Setting 7th element to 63.
myScalar[7] = 63;
auto value_is_63 = imageData->GetPointData()->GetScalars()->GetTuple(7);
// Changing the value of elements of imageData should reflect on myScalar
// Setting 7th element to 88.
imageData->GetPointData()->GetScalars()->SetTuple1(7, 88);
auto value_is_88 = myScalar[7];
// -----------------------------------------------------------
// I want to be able to do the same thing for my3DVector array
// -----------------------------------------------------------
// Create a vector point data array
vtkSmartPointer<vtkIntArray> vectorArray = vtkSmartPointer<vtkIntArray>::New();
vectorArray->SetNumberOfComponents(3); // 3 components
vectorArray->SetNumberOfTuples(imageData->GetNumberOfPoints());
vectorArray->SetArray(reinterpret_cast<int*>(my3DVector), 3 * N, 1);
vectorArray->SetName("MyVector");
// -----------------------------------------------------------
// It crashes on the following line
// Exception thrown: read access violation.
// __imp_vtkDataSetAttributes::GetVectors(...) returned nullptr.
// -----------------------------------------------------------
imageData->GetPointData()->GetVectors()->ShallowCopy(vectorArray);
return 0;
}