I’ve converted the C++ animation example from the User guide to Python but I can’t quite get it to run correctly. When the code hits scene.Play(), the render window displays the test model (I can’t interact with it), the CPU pegs to 100% on one core, and the TickInternal method on the AnimationCue never gets called.
Can anyone advise what’s going on here? (Python 3.10.4, VTK 9.2)
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkRenderingCore import vtkRenderer, vtkRenderWindow
from vtkmodules.vtkCommonDataModel import vtkAnimationScene
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkRenderingCore import vtkPolyDataMapper, vtkActor, vtkRenderWindowInteractor
from vtkmodules.vtkCommonCore import vtkAnimationCue
find_module=False
if find_module is True:
from vtkmodules.all import *
for c in [vtkRenderer,vtkRenderWindow, vtkSphereSource, vtkPolyDataMapper,vtkAnimationCue]:
print(f"from {c.__module__} import {c.__name__}")
exit()
class vtkCustomAnimationCue(vtkAnimationCue):
def __init__(self, renwin, sphere):
super().__init__()
self.renwin = renwin
self.sphere = sphere
def TickInternal(self, currenttime, deltatime, clocktime):
print('TickInternal')
new_st = currenttime * 180
self.sphere.SetStartTheta(new_st)
self.renwin.Render()
ren1=vtkRenderer()
renWin=vtkRenderWindow()
renWin.SetMultiSamples(0)
renWin.AddRenderer(ren1)
#iren = vtkRenderWindowInteractor()
#iren.SetRenderWindow(renWin)
sphere = vtkSphereSource()
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(sphere.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
ren1.AddActor(actor)
ren1.ResetCamera()
renWin.Render()
scene = vtkAnimationScene()
scene.SetModeToSequence()
scene.SetFrameRate(1)
scene.SetStartTime(0)
scene.SetEndTime(5)
scene.SetLoop(1)
cue1 = vtkCustomAnimationCue(renWin, sphere)
cue1.SetTimeModeToNormalized()
cue1.SetStartTime(0)
cue1.SetEndTime(1.0)
scene.AddCue(cue1)
scene.Play()
scene.Stop()
#iren.Start()
OK - I figured this out. The answer was in the Python wrapper docs"
“It is possible to subclass a VTK class from within Python, but this is of limited use because the C++ virtual methods are not hooked to the Python methods”
And sure enough, when I look at the code for vtkAnimationCue I find that TickInternal is a virtual method…
So the approach I’m using above is just never going to work. So instead of having my animator in a custom vtkAnimationCue class I need to put it into a class/method that I can then use as an Observer on vtkAnimationCue to trigger the update… Which is a little more indirect, but not really a problem.