The app handler "render_pre" behaving strangely.

The point of this script is to auto increment the render slot before rendering. This code will only increment the slot if first an image has been rendered and then once it reaches the 8th slot it will just start rendering over the slots in sequence again.

For some reason whether using “render_pre” or “render_init” app handlers my function isn’t run until after the image has been rendered which is the opposite of what it’s supposed to do. You can see the first line of the function prints the render result image name (which shouldn’t exist at the time the function is being processed). I’ve thrown a try/except statement around this example incase when you run the script it actually works like it is supposed to and the first render result image does not exist.

Anyone know why this is happening or if something’s just wrong with my computer or version of Blender? Anyone mind running this code? Thanks.



import bpy


#Auto increment render slots
def autoRenderSlots(scene):

    try:
        print(bpy.data.images['Render Result'].name)
    except:
        pass

    r = bpy.data.images['Render Result']    
    rSlot = r.render_slots.active_index
    
    if rSlot < 7:
        rSlot += 1
    else:
        rSlot = 0 
    r.render_slots.active_index = rSlot
    
    return


#Register apphandler
bpy.app.handlers.render_pre.append(autoRenderSlots)



When I run the script with a notably longer render (I just set sampled motion blur very high) then I see that the script is run before rendering. But I guess that the slot which the renderer renders to is determined before this handler. That may or may not be intentional on the part of the API.

Thankyou Bayesian. Good to know this issue isn’t local to my machine. If the function is able to print the render result image name as the first step of the function (before it should have ever been rendered), it sort of looks a lot like the render process was entirely completed before render_pre was ever called. I tried printing a render result image name in a fresh Blend file that had no image data blocks or renders, and it won’t print the name, so it’s not default behavior.

Made a simple operator just to make sure there wasn’t something wacky with the code. It works fine when called as an operator (with a render.render operator as the last step). Guess my custom operator will have to do for now… actually this is probably a cleaner way to handle this.

As I said, I think that the render slot is determined as part of the render operator. If you invoke your code as an operator and modify the slot before you call the render operator, then the render slot is already changed when the render operator is invoked. The render_pre handler is obviously called within the render operator, not before it…