在 pyvista 中保存屏幕截图,包括交互/旋转
Save screen capture in pyvista including interaction / rotation
我正在寻找一种在 pyvista
中 交互 期间有效捕获帧缓冲区的方法,以便我可以在模型移动之后制作视频屏幕。
我遇到的问题是,当我单击屏幕与 viewer/plotter 交互时,按下鼠标按钮时没有写入任何帧,模型正在移动到下一个位置。这导致视频中有 'jerky' 个动作。
有没有办法绕过这种行为,即使在被操纵时也能有效地执行绘图仪 window 的屏幕截图之类的操作?也许通过直接访问帧缓冲区或类似的东西?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyvista as pv
import numpy as np
from pyvista import examples
import matplotlib as mpl
import matplotlib.pyplot as plt
px = int(round(1920*0.4))
py = int(round(1000*0.4))
mesh = examples.download_st_helens().warp_by_scalar()
p = pv.Plotter()
p.set_background(color='k')
cmap = mpl.cm.get_cmap('viridis')
p.add_mesh(mesh, lighting=True, texture=False, cmap=cmap, smooth_shading=True)
p.show_grid()
p.show(window_size=[px,py], auto_close=False, interactive_update=True)
p.render()
p.open_movie('anim.mp4',framerate=60)
i=0
while (i<100):
i+=1
p.write_frame()
print(i)
p.close()
我在纯 VTK 中添加了一个示例,其中旋转了一个立方体,并通过旋转捕获了流畅的视频。之后启动交互器,之后用户就可以和场景进行交互了。
import os
import vtk
import numpy as np
def vtkRotationMovie(renderWindow, filename='c:/test.avi'):
global degrees
degrees = 0
windowToImageFilter = vtk.vtkWindowToImageFilter()
windowToImageFilter.SetInput(renderWindow)
windowToImageFilter.SetInputBufferTypeToRGB()
windowToImageFilter.ReadFrontBufferOff()
windowToImageFilter.Update()
if os.name == 'nt':
writer = vtk.vtkAVIWriter()
else:
writer = vtk.vtkOggTheoraWriter()
writer.SetInputConnection(windowToImageFilter.GetOutputPort())
writer.SetRate(10) # Not needed for Ogg
try:
os.remove(filename)
except OSError:
pass
writer.SetFileName(filename)
writer.Start()
timerId = renderWindow.GetInteractor().CreateRepeatingTimer(50)
def cb(interactor, event):
global degrees
step = 5
if (degrees > 359):
interactor.DestroyTimer(timerId)
writer.End()
return
interactor.GetRenderWindow().Render()
cam = interactor.GetRenderWindow().GetRenderers().GetFirstRenderer().GetActiveCamera()
cam.Azimuth(step)
cam.OrthogonalizeViewUp()
windowToImageFilter.Modified()
writer.Write()
degrees = degrees + step
renderWindow.GetInteractor().AddObserver('TimerEvent', cb)
renderWindow.GetInteractor().Start()
# create a rendering window and renderer
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# create cube
cube = vtk.vtkCubeSource()
# mapper
cubeMapper = vtk.vtkPolyDataMapper()
cubeMapper.SetInputConnection(cube.GetOutputPort())
# actor
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)
# assign actor to the renderer
ren.AddActor(cubeActor)
ren.SetBackground(.3,.2,.1)
# enable user interface interactor
iren.Initialize()
renWin.Render()
vtkRotationMovie(renWin, filename='./test.avi')
iren.Start()
我正在寻找一种在 pyvista
中 交互 期间有效捕获帧缓冲区的方法,以便我可以在模型移动之后制作视频屏幕。
我遇到的问题是,当我单击屏幕与 viewer/plotter 交互时,按下鼠标按钮时没有写入任何帧,模型正在移动到下一个位置。这导致视频中有 'jerky' 个动作。
有没有办法绕过这种行为,即使在被操纵时也能有效地执行绘图仪 window 的屏幕截图之类的操作?也许通过直接访问帧缓冲区或类似的东西?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyvista as pv
import numpy as np
from pyvista import examples
import matplotlib as mpl
import matplotlib.pyplot as plt
px = int(round(1920*0.4))
py = int(round(1000*0.4))
mesh = examples.download_st_helens().warp_by_scalar()
p = pv.Plotter()
p.set_background(color='k')
cmap = mpl.cm.get_cmap('viridis')
p.add_mesh(mesh, lighting=True, texture=False, cmap=cmap, smooth_shading=True)
p.show_grid()
p.show(window_size=[px,py], auto_close=False, interactive_update=True)
p.render()
p.open_movie('anim.mp4',framerate=60)
i=0
while (i<100):
i+=1
p.write_frame()
print(i)
p.close()
我在纯 VTK 中添加了一个示例,其中旋转了一个立方体,并通过旋转捕获了流畅的视频。之后启动交互器,之后用户就可以和场景进行交互了。
import os
import vtk
import numpy as np
def vtkRotationMovie(renderWindow, filename='c:/test.avi'):
global degrees
degrees = 0
windowToImageFilter = vtk.vtkWindowToImageFilter()
windowToImageFilter.SetInput(renderWindow)
windowToImageFilter.SetInputBufferTypeToRGB()
windowToImageFilter.ReadFrontBufferOff()
windowToImageFilter.Update()
if os.name == 'nt':
writer = vtk.vtkAVIWriter()
else:
writer = vtk.vtkOggTheoraWriter()
writer.SetInputConnection(windowToImageFilter.GetOutputPort())
writer.SetRate(10) # Not needed for Ogg
try:
os.remove(filename)
except OSError:
pass
writer.SetFileName(filename)
writer.Start()
timerId = renderWindow.GetInteractor().CreateRepeatingTimer(50)
def cb(interactor, event):
global degrees
step = 5
if (degrees > 359):
interactor.DestroyTimer(timerId)
writer.End()
return
interactor.GetRenderWindow().Render()
cam = interactor.GetRenderWindow().GetRenderers().GetFirstRenderer().GetActiveCamera()
cam.Azimuth(step)
cam.OrthogonalizeViewUp()
windowToImageFilter.Modified()
writer.Write()
degrees = degrees + step
renderWindow.GetInteractor().AddObserver('TimerEvent', cb)
renderWindow.GetInteractor().Start()
# create a rendering window and renderer
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# create cube
cube = vtk.vtkCubeSource()
# mapper
cubeMapper = vtk.vtkPolyDataMapper()
cubeMapper.SetInputConnection(cube.GetOutputPort())
# actor
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)
# assign actor to the renderer
ren.AddActor(cubeActor)
ren.SetBackground(.3,.2,.1)
# enable user interface interactor
iren.Initialize()
renWin.Render()
vtkRotationMovie(renWin, filename='./test.avi')
iren.Start()