1
$\begingroup$

I am working with a rigid body sequence consisting of a number of objects (leaves) that fall on to a plane. I want to loop through a number of different starting locations and rotations of the leaf set (among other changes), so the result (final frame) should be rendered to file before starting again with new leaf parameters.

My code uses bpy.ops.screen.animation.play to create an animation sequence, then I have tried to render the result (last frame) to a file using bpy.ops.render.render(write_still=True).

I can play and stop the animation, but when I then call bpy.ops.render.render(write_still=True) it renders the output of Frame 1, and doesn't show the animation playing in real time in the viewport or the timeline.

I can, after running the script to play and stop the animation, call bpy.ops.render.render(write_still=True) in the Python console and it succeeds in rendering/saving the final frame. However this makes the looped multiple sequences harder to manage if I need to use the Python console after each (~3minute) render sequence.

Basic code for running animation and attempting to render/save final frame to file below, thanks for any help! I feel that a handler is useful, perhaps?

import bpy
import os

filepath = bpy.data.filepath
directory = os.path.dirname(filepath)
print(directory)

for scene in bpy.data.scenes:
    scene = bpy.context.scene

def stop_playback(scene):
    if bpy.data.scenes['Scene'].frame_current == bpy.data.scenes['Scene'].frame_end:
        bpy.ops.screen.animation_cancel(restore_frame=False)

def start_anim():
    bpy.ops.screen.frame_jump(end=False)
    bpy.app.handlers.frame_change_post.append(stop_playback)
    bpy.ops.screen.animation_play()

def write_image():        
    filePath = bpy.data.scenes['Scene'].render.filepath       
    bpy.data.scenes['Scene'].render.filepath = os.path.join(filePath, 'BOB' + "_")
    bpy.data.scenes['Scene'].frame_set(bpy.data.scenes['Scene'].frame_end-1)

    bpy.ops.render.render(animation=False, write_still=True, use_viewport=True, layer="", scene="Scene")
    bpy.data.scenes['Scene'].render.filepath = filePath

if __name__ == "__main__":
    start_anim()
    bpy.data.scenes['Scene'].update()
    write_image()}
$\endgroup$
0
$\begingroup$

I assume you are using Blender 2.79, it may not work. But in Blender 2.80, this is how I would do:

if __name__ == "__main__":
    bpy.ops.screen.animation_play()
    write_image()

Does the issue persist with Blender 2.80?

$\endgroup$

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

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.