1

我正在寻找一种在交互过程中有效捕获帧缓冲区的方法,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()

在此处输入图像描述

4

1 回答 1

2

我在纯 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()
于 2021-04-15T21:36:21.087 回答