0
$\begingroup$

I have a script to run animation which is simulating sewing clothes. Below is a part of my code to add handle and start animation.

def sew(body_name, garment_name, export_body):
    body_obj = bpy.data.objects[body_name]
    garment_obj = bpy.data.objects[garment_name]
    s = bpy.context.scene
    s.frame_start = 1
    s.frame_end = 40
    s.frame_current = 1
    def stop_playback(scene):
        if scene.frame_current == 25:
            bpy.ops.screen.animation_cancel(restore_frame=False)
            after_sew(garment_name, export_body)
    bpy.app.handlers.frame_change_post.append(stop_playback)
    bpy.ops.screen.animation_play()

While intending to run the sewing animation from frame 1 to frame 25, I want to keep the python execution active so it will run after_sew() when the animation is done. When I run the script inside Blender's TextEditor, it does wait until the animation complete, and the after_sew() function does run accordingly. However, when I try to run this in background:

    blender myblend.blend -b --python sewing.py

The script will compile until this sew() function, start the animation, but then exit immediately without waiting for the animation reach frame 25, thus after_sew() will not run.

Is there any way to make python wait until animation done with an UI-less Blender?

I've found other similar thread talking about animation, but they are mostly about rendering with a camera which I don't need. What I only need is to export the sewed cloth at frame 25 using the after_sew() function.

$\endgroup$
6
  • $\begingroup$ Why does the animation need to play. Does script not work if you iteratively set the scene frame? $\endgroup$
    – batFINGER
    Oct 1 at 9:08
  • $\begingroup$ How can I do that? Didn't know there is a way to iteratively set the scene frame. And will that work in a UI-less Blender? $\endgroup$ Oct 1 at 15:20
  • 2
    $\begingroup$ Scene.frame_set(100), yes it will work in headless mode. $\endgroup$
    – brockmann
    Oct 1 at 16:31
  • $\begingroup$ I see. Thank you very much! $\endgroup$ Oct 2 at 0:23
  • 1
    $\begingroup$ No problem @kelvinhong方 Recently updated: What is the Python script to set the current frame Does that answer your question? $\endgroup$
    – brockmann
    Oct 2 at 6:52
0
$\begingroup$

It turns out that I don't need handler. Just iteratively change the frames as suggested by @batFINGER and @brockmann

def sew(body_name, garment_name, export_body):
    body_obj = bpy.data.objects[body_name]
    garment_obj = bpy.data.objects[garment_name]
    s = bpy.context.scene
    s.frame_start = 1
    s.frame_end = 40
    s.frame_current = 1
    for i in range(2, 26):
        bpy.context.scene.frame_set(i)

And this does work with a headless Blender.

$\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.