3
$\begingroup$

I have a script that generates random hair I want it to play animation from 1st frame to 250th, and then output a rendered image of 250th frame, or simply give me the 250th frame without playing animation (that would a be better option)

Here's my code to play animation:

# Animation Frame Timer
def stop_playback(scene):
    if scene.frame_current == 250:
        bpy.ops.screen.animation_cancel(restore_frame=False)

bpy.app.handlers.frame_change_pre.append(stop_playback)
bpy.ops.screen.animation_play()

bpy.data.scenes["Scene"].frame_set(250)

I have 2 scripts. One for generating hair, and one for rendering my output image. I use this command in terminal to execute it:

#!/bin/bash
frames_cnt=#needed number of images
output_frame_path='BlenderRepository/RenderedImages/LongHair'

for (( i=1; i<=frames_cnt; i++ )); do
  echo "Rendering frame ${i}/${frames_cnt}..."

  (
    cd /home/ds/Documents/blender2.80/
    ./blender --background una.blend --python BlenderRepository/Scripts/Config/LongHair/LongHair.py --python BlenderRepository/Scripts/Config/LongHair/RenderLongHairImage.py -- "${output_frame_path}/frame_${i}.png"
  )

  echo "Frame ${i}/${frames_cnt} has been rendered"
done

When I executing my script via terminal, I suppose it gives me the 1st frame as output. Well, formally its 250th frame, but it looks like 1st frame, as you can see here: enter image description here

And here's example when I manually execute my scripts via blender one by one: enter image description here

You can see that the animation has been played, and its 250th frame, as hair lay down. I executed my 1st script for generating hair, wait for animation to run from 1 to 250th frame, and then executed the 2nd script.

So my question is how can I make it work automatically? Is it possible to make it work that way in the --background? I mean I want my second script wait for 1st script to end animation run, so I can get the right image of 250th frame.

2 Particle Systems code:

psys = ob.particle_systems[-1]
psys1 = ob.particle_systems[-1]

pc = psys.point_cache
pc1 = psys1.point_cache

print(pc.frame_start, pc.frame_end)

bpy.ops.ptcache.bake({"point_cache": pc}, bake=True)
bpy.ops.ptcache.bake({"point_cache": pc1}, bake=True)
$\endgroup$
  • $\begingroup$ Have you tested to see if blender in background mode bakes the simulation as animation is played. which it appears is what you are relying on here I would recommend looking at the cache panel. Try bake the animation, then render. Notice after a bake the button is toggled to "free bake", see if using the same logic the draw uses works with your script... else maybe bake n save. Then render. $\endgroup$ – batFINGER Jul 30 at 11:38
  • $\begingroup$ @batFINGER I've never used bake animation before, gonna give it a try now $\endgroup$ – cxnt Jul 30 at 11:42
  • $\begingroup$ @batFINGER could you please tell me how do I test to see if blender in background mode bakes the simulation as animation is played? and how do I bake the animation in blender 2.8? $\endgroup$ – cxnt Jul 30 at 11:57
  • $\begingroup$ Added a script to bake point cache as an answer, too long to comment. Use it instead of the play stop script. Match the point cache frame start and end to scene. $\endgroup$ – batFINGER Jul 30 at 12:28
4
$\begingroup$

Bake the Pointcache

Here is a test script that bakes the first particle system on context object to first point cache.

import bpy
context = bpy.context

ob = context.object
# assume we have a particle system
ps = ob.particle_systems[0]
pc = ps.point_cache

# match bake to animation
print(pc.frame_start, pc.frame_end)

bpy.ops.ptcache.bake({"point_cache": pc}, bake=True)

Have a look at the PointCache members in the API, and will see that among others it has

pc.is_baking
pc.is_baked

Now to test this in bg mode.

Confirmation

Can confirm that, with script above named test.py the command blender2.8 is an alias to my blender version 2.8

blender2.8 -b test.blend -P test.py -f 250

when run on blend that is no more than default cube, with default hair particle system, (with dynamics) produces following output

Read blend: /home/batfinger/blender/test/test.blend
1 250
bake: frame 1 :: 250
bake: frame 2 :: 250
bake: frame 3 :: 250
bake: frame 4 :: 250 
...


bake: frame 248 :: 250
bake: frame 249 :: 250
bake: frame 250 :: 250
Fra:250 Mem:182.13M (0.00M, Peak 183.09M) | Time:00:00.33 | Syncing Cube
Fra:250 Mem:182.17M (0.00M, Peak 183.09M) | Time:00:00.38 | Syncing Lamp
Fra:250 Mem:182.17M (0.00M, Peak 183.09M) | Time:00:00.38 | Syncing Camera
Fra:250 Mem:182.18M (0.00M, Peak 183.09M) | Time:00:00.41 | Rendering 1 / 64 samples
Fra:250 Mem:182.17M (0.00M, Peak 183.09M) | Time:00:00.77 | Rendering 26 / 64 samples
Fra:250 Mem:182.17M (0.00M, Peak 183.09M) | Time:00:00.97 | Rendering 51 / 64 samples
Fra:250 Mem:182.17M (0.00M, Peak 183.09M) | Time:00:01.07 | Rendering 64 / 64 samples
Fra:250 Mem:124.26M (0.00M, Peak 183.09M) | Time:00:01.30 | Sce: Scene Ve:0 Fa:0 La:0
Saved: '/tmp/0250.png'
 Time: 00:02.24 (Saving: 00:00.94)

enter image description here /tmp/0250.png

$\endgroup$
  • $\begingroup$ Gonna try it now, thanks @batFINGER $\endgroup$ – cxnt Jul 30 at 12:30
  • $\begingroup$ It works indeed, thanks a lot for help!!! @batFINGER $\endgroup$ – cxnt Jul 30 at 13:02
  • $\begingroup$ Cheers. Please consider editing title of question to something like "CLI How to render last frame of hair dynamics sym" or the like. $\endgroup$ – batFINGER Jul 30 at 13:07
  • $\begingroup$ also is there a way to bake animation for two particle systems? as I use 2. It perfectly works now, but I'm just wondering if there's a way to catalyze this process as it runs 1 to 250 two times. I add my edition of your code to the bottom of my question, so you can look at it @batFINGER $\endgroup$ – cxnt Jul 30 at 13:26
  • $\begingroup$ Have a look at the bake all button. $\endgroup$ – batFINGER Jul 30 at 13:32

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.