vtkRenderLargeImage in Python gives wrong field of view in VTK 8.2+
Using vtkRenderLargeImage with magnification > 1 gives images where the field of view is unexpectedly cropped in VTK versions 8.2 onwards. I'm using Python, I don't know whether this is Python specific. Same hevaiour under Windows and Linux. I think this behaviour started in 8.2.0.
Here are 2 images created from the same renderer+geometry+camera using vtkRenderLargeImage in VTK 8.1.2, one with vtkRenderLargeImage.setMagnification(1) and one with vtkRenderLargeImage.setMagnification(2). As expected the sphere looks the same size in both images, but the one with magnification = 2 has twice the pixel dimensions: Here is the result of the same code using VTK 9.0.1: with mganification > 1 the image looks unexpectedly cut-off at the edges (field of view is a bit smaller):
Code to reproduce (uses matplotlib to display the results):
"""
Testing of vtkRenderLargeImage at different magnifications
with off-screen rendering.
Expected correct result:
Two images of a sphere which look identical size,
but one image has twice the pixel dimensions as the other.
"""
import vtk
from vtk.util.numpy_support import vtk_to_numpy
import matplotlib.pyplot as plt
if __name__ == '__main__':
# Set up a small off-screen render window
renderWindow = vtk.vtkRenderWindow()
renderWindow.OffScreenRenderingOn()
renderer = vtk.vtkRenderer()
renderWindow.AddRenderer(renderer)
renderWindow.SetSize(300,300)
# vtkRenderLargeImage to be tested.
vtk_win_im = vtk.vtkRenderLargeImage()
vtk_win_im.SetInput(renderer)
# Create a sphere and add it to the renderer
sphereSource = vtk.vtkSphereSource()
sphereSource.SetCenter(0.0, 0.0, 0.0)
sphereSource.SetRadius(3.0)
sphereSource.SetPhiResolution(100)
sphereSource.SetThetaResolution(100)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(sphereSource.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
renderer.AddActor(actor)
# Camera Setup so the sphere just touches the edges of the field of view
cam = renderer.GetActiveCamera()
cam.SetPosition(0.,0.,5.)
cam.SetFocalPoint(0.,0.,0.)
cam.SetViewAngle(73.74)
# Render image with magnification = 1
vtk_win_im.SetMagnification(1)
renderWindow.Render()
vtk_win_im.Update()
vtk_image = vtk_win_im.GetOutput()
vtk_array = vtk_image.GetPointData().GetScalars()
dims = vtk_image.GetDimensions()
im_mag1 = vtk_to_numpy(vtk_array).reshape(dims[1], dims[0], 3)
# Render image with magnification = 2
vtk_win_im.SetMagnification(2)
renderWindow.Render()
vtk_win_im.Update()
vtk_image = vtk_win_im.GetOutput()
vtk_array = vtk_image.GetPointData().GetScalars()
dims = vtk_image.GetDimensions()
im_mag2 = vtk_to_numpy(vtk_array).reshape(dims[1], dims[0], 3)
# Display the images; they should look the same but one at higher pixel count.
plt.subplot(121)
plt.imshow(im_mag1)
plt.title('Magnification = 1')
plt.subplot(122)
plt.imshow(im_mag2)
plt.title('Magnification = 2')
plt.suptitle('vtkRenderLargeImage test: VTK {:}'.format(vtk.vtkVersion.GetVTKVersion()))
plt.show()