Skip to main content
added 749 characters in body
Source Link
batFINGER
  • 85.8k
  • 10
  • 118
  • 251

I'd suggest using handlers for this task. Below is a script that adds a full set of render handlers, and prints the current frame (if possible) and name of the handler when that event happenshandler fires.

import bpy   frame_handlers = [name for name in dir(bpy.app.handlers)   if name.startswith("render")]  def handler_function(name): def handler(scene):   print(name) f"{getattr(scene, 'frame_current', 'N/A')} : {name}")  return handler     for name in frame_handlers: handler = getattr(bpy.app.handlers, name, None) if isinstance(handler, islist):  not None: handler.clear() # clear first for testing handler.append(handler_function(name)) 

System console output for a 2 frame animation render, must have started render with current frame set at 0. (v 2.91)

0 : render_init 1 : render_pre 1 : frame_change_pre 1 : frame_change_post Saved: '/tmp/0001.png' Time: 00:00.47N/A : render_stats (Saving: 00:00.03) 1 : render_post 1 : render_write 2 : render_pre 2 : frame_change_pre 2 : frame_change_post Saved: '/tmp/0002.png' Time: 00:00.38N/A : render_stats (Saving: 00:00.02) 2 : render_post 2 : render_write 0 : render_complete 0 : frame_change_pre 0 : frame_change_post 

I'd suggest using handlers for this task. Below is a script that adds a full set of render handlers, and prints the name of the handler when that event happens.

import bpy   frame_handlers = [name for name in dir(bpy.app.handlers)   if name.startswith("render")]  def handler_function(name): def handler(scene): print(name)  return handler   for name in frame_handlers: handler = getattr(bpy.app.handlers, name, None) if handler is not None: handler.append(handler_function(name)) 

I'd suggest using handlers for this task. Below is a script that adds a full set of render handlers, and prints the current frame (if possible) and name of the handler when that handler fires.

import bpy frame_handlers = [name for name in dir(bpy.app.handlers) ] def handler_function(name): def handler(scene):   print(f"{getattr(scene, 'frame_current', 'N/A')} : {name}")  return handler    for name in frame_handlers: handler = getattr(bpy.app.handlers, name, None) if isinstance(handler, list):   handler.clear() # clear first for testing handler.append(handler_function(name)) 

System console output for a 2 frame animation render, must have started render with current frame set at 0. (v 2.91)

0 : render_init 1 : render_pre 1 : frame_change_pre 1 : frame_change_post Saved: '/tmp/0001.png' Time: 00:00.47N/A : render_stats (Saving: 00:00.03) 1 : render_post 1 : render_write 2 : render_pre 2 : frame_change_pre 2 : frame_change_post Saved: '/tmp/0002.png' Time: 00:00.38N/A : render_stats (Saving: 00:00.02) 2 : render_post 2 : render_write 0 : render_complete 0 : frame_change_pre 0 : frame_change_post 
Source Link
batFINGER
  • 85.8k
  • 10
  • 118
  • 251

I'd suggest using handlers for this task. Below is a script that adds a full set of render handlers, and prints the name of the handler when that event happens.

import bpy frame_handlers = [name for name in dir(bpy.app.handlers) if name.startswith("render")] def handler_function(name): def handler(scene): print(name) return handler for name in frame_handlers: handler = getattr(bpy.app.handlers, name, None) if handler is not None: handler.append(handler_function(name)) 

Experiment and see the order the handers are called firing "render_init"... etc until, "render_compete"

Setting it up

In Operator execute, set the scene settings to first batch, call the render op and add the render_complete handler.

# add the handler. bpy.app.handlers.render_complete.append(render_complete) 

The render complete handler

change scene settings to the next batch item and call render op again

You will need to keep tabs on which batch is rendered with an active_index property (or similar), (also handy for displaying the items in a UIList widget) Please note this is just code typed into answer and not tested.

def render_complete(scene): batches = scene.frame_ranges i = batches.active_index if i < len(batches) - 1: batch = batches(i+1) # set up scene bpy.ops.render.render('INVOKE_DEFAUT', animation=True) else: #clear this hander bpy.app.handers.render_complete.remove(render_complete) 

Experiment...