# visual_transform_apply doesn't affect object in Python script

I'm trying to run a rigid body physics simulation and record the results via a script, but I cannot get the post-simulation state of an object, even when I use bpy.ops.object.visual_transform_apply(). The strange part is that if I then use the Python console in the GUI to call bpy.ops.object.visual_transform_apply(), it works (it also works if I use the GUI's button to apply the visual transform: CTRL-A, Visual Transform). I've tried calling scene.update() everywhere, making sure the object is selected, etc., all to no avail.

Here is a minimal case of the problem (tested on Blender 2.71):

import bpy
scene = bpy.context.screen.scene
cube = scene.objects['Cube']
print('pre-simulation: ', cube.location)
bpy.ops.ptcache.bake_all(bake=True)
scene.frame_current = scene.frame_end
bpy.ops.object.visual_transform_apply()
print('post-simulation: ', cube.location)


Save the above code to a .py script and run it with:

blender -nosplash -P <script-name>.py

The script adds the cube as an active rigid body physical object, bakes the physics, applies the visual transform, and then reads the object's location. The output I get is:

pre-simulation:  <Vector (0.0000, 0.0000, 0.0000)>
post-simulation:  <Vector (0.0000, 0.0000, 0.0000)>


But the "Post-simulation:" line should show a large negative Z-coordinate, instead of 0.0000, because the object has fallen under gravity.

Does anyone have any ideas what might be wrong? Is it a bug, or am I missing something? My only guess is that I'm not in the correct context...

Just setting the current frame is not enough:

scene.frame_current = scene.frame_end # does not work as expected


You need to set the frame as follows:

context = bpy.context # or whatever context you have
context.scene.frame_set(scene.frame_end)


As Gaia said, you need to set the frame, but also I think you need to apply the matrix world transformation to your object (or just get its translation if you just want the position) :

So, after setting the current frame :

scene.frame_set(scene.frame_end)


Do :

print('post-simulation: ',cube.matrix_world.translation)


I usually use the matrix world translation to get the world position of an object.

Hope this will help :)