# CLI How to render last frame of hair dynamics sym?

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:

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

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)

• 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. – batFINGER Jul 30 at 11:38
• @batFINGER I've never used bake animation before, gonna give it a try now – cxnt Jul 30 at 11:42
• @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? – cxnt Jul 30 at 11:57
• 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. – batFINGER Jul 30 at 12:28

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)


/tmp/0250.png

• Gonna try it now, thanks @batFINGER – cxnt Jul 30 at 12:30
• It works indeed, thanks a lot for help!!! @batFINGER – cxnt Jul 30 at 13:02
• Cheers. Please consider editing title of question to something like "CLI How to render last frame of hair dynamics sym" or the like. – batFINGER Jul 30 at 13:07
• 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 – cxnt Jul 30 at 13:26
• Have a look at the bake all button. – batFINGER Jul 30 at 13:32