Update scene while script's running

I am not entirely sure how to describe my problem, so I will just give the details of what I’m doing;

I have 2 objects, Object A with a displace modifier, with an animated origin entity for the displace texture, to simulate ocean waves, and another identical object B without any modifiers, and I made a script that takes object A, duplicates it, applies the modifier, joins it as a shape key with Object B and proceeds to the next frame. I am doing all that beacuse the game I want to port this to, has support for shape keys, and I can use them to fake animate ocean displacement like that.

The problem is that while the script works fine if I run it manually for each frame, it doesn’t seem to work when it has to change frames on its own. The the shape keys it creates are all identical.

Here’s my script


import bpy

frames = 1
frames = bpy.context.scene.frame_end
copyFrom = bpy.data.objects["copyFrom"] 
copyTo = bpy.data.objects["copyTo"] 
x = 0

# First deselect everything, and make sure that copyFrom is selected and active
bpy.ops.object.select_all(action='DESELECT')
bpy.context.scene.objects.active = bpy.data.objects["copyFrom"]
copyFrom.select = True

# Duplicate copyFrom
bpy.ops.object.duplicate()
bpy.ops.object.modifier_apply (modifier='Displace')

# The duplication auto selects and activates the new clone
# Select the destination and join as shapes
Temp = bpy.context.object
Temp.name = "Frame_" + str(x)
copyTo.select = True
bpy.context.scene.objects.active = bpy.data.objects["copyTo"]
bpy.ops.object.join_shapes()

bpy.ops.object.select_all(action='DESELECT')
Temp.select = True
bpy.context.scene.objects.active = Temp
bpy.ops.object.delete()
bpy.ops.anim.change_frame(frame = x)


So far, the object with the animated modifier has to be called “copyFrom” and the one I am baking the shake keys is “copyTo”, the variable x is what I eventually plan to use for a for loop.

An easy test I did, was set my cursor at frame 0, and x = 60, when I run the script, the shape key it creates is the one that exists on frame 0, insead of frame 60, and oddly if I run the script again, then the proper shape key gets created.

I hope some one can help me, I’ve been cobbling this script all week x3

I assume you need to set the frame first before applying the modifier. Here’s a modified version of your script (untested):

import bpy

copyFrom = bpy.data.objects["copyFrom"] 
copyTo = bpy.data.objects["copyTo"] 
x = 60

bpy.context.scene.frame_set(x)

# First deselect everything, and make sure that copyFrom is selected and active
bpy.ops.object.select_all(action='DESELECT')
bpy.context.scene.objects.active = bpy.data.objects["copyFrom"]
copyFrom.select = True

# Duplicate copyFrom
bpy.ops.object.duplicate()
bpy.ops.object.modifier_apply (modifier='Displace')

# The duplication auto selects and activates the new clone
# Select the destination and join as shapes
Temp = bpy.context.object
Temp.name = "Frame_" + str(x)
copyTo.select = True
bpy.context.scene.objects.active = bpy.data.objects["copyTo"]
bpy.ops.object.join_shapes()

bpy.ops.object.select_all(action='DESELECT')
Temp.select = True
bpy.context.scene.objects.active = Temp
bpy.ops.object.delete()

Ohhh I see, it’s not that, actually it’s

bpy.ops.anim.change_frame(x)
bpy.context.scene.frame_set(x)

I was using the first one, where as if I use the frame_set one, it works, sigh, why 2 separate commands, I never found the second one anywhere when searching though the docs…

Thank you very much!

well there are actually even more command for it, but scene.frame_set is the one to be used if you need animations etc. be updated. The other commands are there as they are needed for certain editors, and since most of the stuff is exposed to python, you can use a variety of them. But only a few are globally working.