ShallowCopy an array into a vtkImageData

62 views Asked by At

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;
}
0

There are 0 answers