Examples of writing movies with VTK?

I have a sequence of vtkXMLPolydata files that have temperature data in them. I can render them just fine, but what I’d really like to be able to do is to set up my camera to generate screenshots of the time series, or to generate a movie directly.

I have seen the example for vtkFFMPEGWriter, but it doesn’t seem to have actors, mappers, cameras … and makes me wonder what it was supposed to demo?

Any tips would be appreciated.

I guess another way of asking the question is this: Once I have an actor, how do I update the vtkPolyData that it represents, in a loop, so that I can generate a sequence of screenshots or movie frames?

Should I just remove the actor for the previous timestep and then create a new one?

Perhaps related:

In case anyone in the future needs this sort of thing:

#!/usr/bin/env python3
from os import system
from os.path import splitext
import vtkmodules.vtkRenderingOpenGL2

from glob import glob
from t01_get_value_range import get_global_max_radiance
from vtkmodules.vtkCommonCore import vtkLookupTable
from vtkmodules.vtkIOImage import vtkPNGWriter
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderWindow,
    vtkRenderer,
    vtkWindowToImageFilter)
from vtkmodules.vtkIOXML import vtkXMLPolyDataReader

MAX_TEMPERATURE = 500
TABLE_SIZE = 256
DEBUG = False

def debug_view(fname):
    r = vtkXMLPolyDataReader()
    r.SetFileName(fname)
    r.Update()

    pd = r.GetOutput()
    t = pd.GetCellData().GetArray("Temperature")
    pd.GetCellData().SetScalars(t)

    lut = vtkLookupTable()
    lut.SetNumberOfTableValues(TABLE_SIZE)
    lut.SetTableRange(0, MAX_TEMPERATURE)
    if not DEBUG:
        # Grayscale
        lut.SetHueRange(0.5, 0.5)
        lut.SetSaturationRange(0.0, 0.0)
        lut.SetValueRange(0.25, 1.0)

    m = vtkPolyDataMapper()
    m.SetInputData(pd)
    m.SetLookupTable(lut)
    m.SetScalarModeToUseCellData()
    m.SetColorModeToMapScalars()
    m.SelectColorArray("Temperature")
    m.SetScalarRange(0, MAX_TEMPERATURE)

    a = vtkActor()
    a.SetMapper(m)
    a.RotateX(-20)
    a.RotateY(50)

    ren.AddActor(a)
    ren.ResetCamera()
    renWin.Render()

    basename = splitext(fname)[0]
    save_screenshot(basename + ".png")


def save_screenshot(fname):
    w2if = vtkWindowToImageFilter()
    w2if.SetInput(renWin)
    w2if.SetInputBufferTypeToRGB()
    w2if.ReadFrontBufferOff()
    w2if.Update()

    writer = vtkPNGWriter()
    writer.SetFileName(fname)
    writer.SetInputConnection(w2if.GetOutputPort())
    writer.Write()


if __name__ == "__main__":
    # Set up basic visualization objects.
    ren = vtkRenderer()
    renWin = vtkRenderWindow()
    renWin.AddRenderer(ren)
    renWin.SetSize(300, 300)
    renWin.SetWindowName("HTV2")

    for fname in sorted(glob("surface_*.vtp")):
        logger.info(f"processing {fname}")
        debug_view(fname)

    logger.info("generating movie")
    system("ffmpeg -framerate 100 -i surface_%04d.png -pix_fmt yuv420p output.mp4")
    logger.info("cleaning up temporaries")
    system("rm *png")```