在 pyvista 中保存屏幕截图,包括交互/旋转

问题描述

我正在寻找一种方法来在 pyvista交互期间有效地捕获帧缓冲区,以便之后我可以制作模型在屏幕上移动的视频。 >

我遇到的问题是,当我单击屏幕与查看器/绘图仪进行交互时,在按下鼠标按钮并且模型移动到下一个位置时没有写入任何帧。这会导致视频中出现“生涩”的动作。

有没有办法绕过这种行为来有效地执行诸如绘图仪窗口的屏幕截图之类的操作,即使在被操纵时也是如此?也许通过直接访问帧缓冲区或类似的东西?

#!/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()

enter image description here

解决方法

我在纯 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()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...