Messing around with pre/post handlers

I came across the following post on Blender Artists and decided to attempt the problem using Python

http://blenderartists.org/forum/showthread.php?268640-Saving-the-render-inside-the-blend-file

It is still WIP and possibly buggy, but the solution follows anyway.

Since I have never used handlers, I started from the Blender Python Console.

>>> bpy.app.handlers

bpy.app.handlers(frame_change_pre=[], frame_change_post=[], render_pre=[], render_post=[], render_stats=[], render_complete=[], render_cancel=[], load_pre=[], load_post=[], save_pre=[], save_post=[], scene_update_pre=[], scene_update_post=[], persistent=<class 'persistent'>)

>>> bpy.app.handlers.
                     count(
                     frame_change_post
                     frame_change_pre
                     index(
                     load_post
                     load_pre
                     n_fields
                     n_sequence_fields
                     n_unnamed_fields
                     persistent(
                     render_cancel
                     render_complete
                     render_post
                     render_pre
                     render_stats
                     save_post
                     save_pre
                     scene_update_post
                     scene_update_pre


Then I searched Google and chanced upon the following link
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.61/Python

The Script

After reading the above document, I wrote the following demo program.

import bpy
from bpy.app.handlers import persistent 
@persistent
def PostLoadSession(self):
    print("post load")
    scene = bpy.context.scene
    srrid = 'srrid'
    if srrid not in scene or not scene[srrid]:
        print("Nothing was rendered previously")
    else:
        print('Last image rendered was {0}.{1}.png'.format('RenderResult' ,scene[srrid])) 
bpy.app.handlers.load_post.append(PostLoadSession)

@persistent
def PreRender(self):
    print("pre render")
    scene = bpy.context.scene
    srrid = 'srrid'
    if srrid not in scene:
        print('This is the first time you are rendering from this file')
        scene[srrid] = 0
        print('Created {0}'.format(srrid)) 
bpy.app.handlers.render_pre.append(PreRender)

@persistent
def PostRender(self):
    print("post render")
    scene = bpy.context.scene
    srrid = 'srrid'
    if srrid not in scene:
        print('PreRender was not called')
    else:
        scene[srrid] += 1
        print('Saved render result as {0}.{1}.png'.format('RenderResult', scene[srrid])) 
bpy.app.handlers.render_complete.append(PostRender)

How to get this script hooked up?

  1. I opened a new session of  Blender
  2. In the Script Editor, Created a new filed and named it saveRenderResult.py
  3. Insert the code listed above into the text editor
  4. Click on the register checkbox
  5. CTRL+U to save default preferences
  6. Close and Open Blender
  7. Create a scene and save the file
  8. Press F12 to Render
  9. Look in the System Console for the message

Output

found bundled python: /home/satishg/bin/blender-2.64-linux-glibc27-x86_64/2.64/python
read blend: /home/satishg/Desktop/blender/2.64/rhWorkflow/Scene.blend
pre render
This is the first time you are rendering from this file
Created srrid
post render
Saved render result as RenderResult.1.png
pre render
post render
Saved render result as RenderResult.2.png
pre render
post render
Saved render result as RenderResult.3.png

Another example

The following is a slightly adapted version from the Blender Wiki..
import bpy 
def scene_update(context):
    objects = bpy.data.objects
    if objects.is_updated:
        print("one or more objects were updated")
        for object in objects:
            if object.is_updated:
                print("=> {0}".format(object.name))
 
bpy.app.handlers.scene_update_post.append(scene_update)

 References





Comments

Popular Posts