VTK9.1: vtkAppendPolyData::Update() takes too long

Hello,

I’m new to VTK and am trying to create a landscape of cuboids with the height of each cuboid specified in a matrix. For that I use mainly the classes vtkCubeSource and vtkAppendPolyData:

void create_preview(const Eigen::MatrixXi &heightMap, const int blockSize)
{
    // Create a renderer
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->SetBackground(1.0, 1.0, 1.0); // White background

    // Combine all cuboids into a single polydata
    vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();

    // Create a cube source for each element in the height map
    for (int x = 0; x < heightMap.rows(); x++) {
        for (int y = 0; y < heightMap.cols(); y++) {
            vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();
            cubeSource->SetXLength(blockSize);
            cubeSource->SetYLength(blockSize);
            cubeSource->SetZLength(heightMap(x, y));
            cubeSource->SetCenter(y * blockSize, (-1) * x * blockSize, heightMap(x, y) / 2.0);

            appendFilter->AddInputConnection(cubeSource->GetOutputPort());
        }
    }

    appendFilter->Update(); //Very slow for large matrices

    // Create a mapper and actor for the combined cuboids
    vtkSmartPointer<vtkPolyDataMapper> heightMapMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    heightMapMapper->SetInputConnection(appendFilter->GetOutputPort());

    vtkSmartPointer<vtkActor> heightMapActor = vtkSmartPointer<vtkActor>::New();
    heightMapActor->SetMapper(heightMapMapper);
    heightMapActor->GetProperty()->SetColor(0.0, 1.0, 0.0); // Green color

    // Add the height map actor to the renderer
    renderer->AddActor(heightMapActor);

    // Create a render window
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(1280, 720);

    // Create an interactor
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    // Set the interactor style to trackball camera
    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    renderWindowInteractor->SetInteractorStyle(style);

    // Start the interaction
    renderWindow->Render();
    renderWindowInteractor->Start();
}

The result of this code generates this kind of preview, exactly as expected:

My problem is that for bigger matrices, with shape like 560x370 values, the method vtkAppendPolyData::Update() takes a very long time to complete (on my computer about 60 seconds).
I wanted to ask if there is a way to speed things up by using a different set of classes or methods, because I couldn’t find any useful info fitting my exact use case.

Thanks in advance!

VTK’s vtkGlyph3D filter can efficiently replicate any shape at multiple positions. It’s a filter with two inputs:

  1. The main input is a point set that contains the positions at which you want to replicate the shape (e.g. the centers of the cuboids). This dataset can also contain scalar arrays that specifies scaling factors.
  2. The second input (the “Source” input) is the shape to be replicated, e.g. the output of vtkCubeSource

This would be many hundred times faster than using vtkAppendFilter in a loop. The scale would have to be a vector array: the x and y scale factors would always be 1.0, and only the z scale factor would vary point-to-point.

Note that in order for vtkGlyph3D to interpret the input vectors as scaling factors, it’s necessary to call the following method:

 glyph3D->SetScaleModeToScaleByVectorComponents()