vtkplotlib icon indicating copy to clipboard operation
vtkplotlib copied to clipboard

zoom_to_contents() forces a window to be displayed

Open tdeck opened this issue 9 months ago • 3 comments
trafficstars

I was working on the following code, which displays a window despite calling vpl.save_fig() with off_screen=True, when I discovered that the real culprit is the call to zoom_to_contents() displaying the window.

Looking at the code, I believe it's because of a call to screenshot_fig(). Perhaps it would be better to pass off_screen=True to this call, although I don't know if there are any implications if the plot is already on screen.

import vtkplotlib as vpl
from stl.mesh import Mesh

mesh = Mesh.from_file(vpl.data.get_rabbit_stl())
vpl.mesh_plot(mesh, color='orange')
vpl.view(up_view=(0, 0, 1), camera_position=(0, -1, 0))
vpl.reset_camera()
vpl.zoom_to_contents()
vpl.save_fig(pixels=600, off_screen=True, path='/tmp/rabbit.png')

tdeck avatar Jan 29 '25 03:01 tdeck

Calling screenshot_fig(off_screen=True) with the figure already showing causes it to close so that route is out. I keep thinking VTK would provide a way of checking if the figure is already on the screen but I can't find it.

bwoodsend avatar Feb 02 '25 21:02 bwoodsend

Thanks for taking a look at this, and for creating such a useful library!

What I'm doing now as a workaround is simply hiding all the plots I don't want to be included in the zoom, moving my camera really close to the origin at the intended angle, calling reset_camera, and then re-showing the plots. reset_camera() seems to be able to zoom out to include the figure without needing to alter the screen state. E.g.

    ...
    for pp in plane_plots:  # Here plane_plots are lines for a ground plane I don't want to zoom to
        pp.visible = False

    # Hide the plane lines during the automatic zoom out that happens, so it
    # only tries to fit the actual model in the viewport
    vpl.view(up_view=vp.up, camera_position=vp.pos)
    vpl.reset_camera()

    for pp in plane_plots:
        pp.visible = True
    ...

That won't work for everyone, but maybe sharing it here will help somebody.

tdeck avatar Feb 02 '25 23:02 tdeck

Ah, that's revealing! I was going to say that your method wouldn't be equivalent since reset_camera() leaves the camera quite zoomed out. The purpose of zoom_to_contents() is to zoom in so that there's almost no empty empty background around the objects you care about but it turns out that that zooming is broken because of a rounding error. Ho hum...

bwoodsend avatar Feb 04 '25 01:02 bwoodsend