3
$\begingroup$

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']
bpy.ops.rigidbody.objects_add(type='ACTIVE')
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...

$\endgroup$
3
$\begingroup$

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)
$\endgroup$
1
$\begingroup$

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 :)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.