from Jesse Kaukonen (gekko)
--- text from the patch.
Recently Campbell Barton added callback functionality for Python's usage, but this only includes pre- and post-render callbacks. There are no callbacks for the duration of the render. This patch adds the few lines required for executing a callback while Blender Render is working. The callback resides in the rendering pipeline stats function, so whenever statistics are printed, the callback is executed. This functionality is required if one wants to:
1) Observe what is happening while Blender is rendering via the command line
2) Add custom statistics that Blender prints while the renderer works
3) The user wants to continue executing his Python script without the code halting at bpy.ops.render.render()
Personally I'm currently using this for printing out more detailed progress reports at Renderfarm.fi (such as CPU time, time spent rendering, total progress in regards to the entire rendering process). Tested on Windows, Linux and OS X.
Example on how to use the callback:
def statscall(context): print("Thanks for calling!")
bpy.app.handlers.render_stats.append(statscall)
bpy.ops.render.render(animation=False, write_still=True)
* replace by BLI_snprintf in various places, note _snprintf on windows
does not properly null terminate the string.
* fix overflow in sequencer proxy code due to buffer being smaller than
specified size.
* fix some usage of snprintf as strcpy, this is will go wrong if the
string contains % characters.
* remove BLI_dynstr_printf function in gpu module, use BLI_dynstr_appendf
- dont use hash lookups in this case because converting the string to unicode and doing a hash lookup is slower then looping over the keys and comparing (which avoids creating and throwning away a unicode string).
existing check for driver to use GIL was not thread safe and could cause, details in the report.
This bug was caused by a check to avoid hanging, a fix for [#27683] that worked in 2.4x because the UI didn't use python to draw while rendering.
Apply a different fix for [#27683], when calling an operator, call PyEval_SaveThread(), then PyEval_RestoreThread() so the GIL can be aquired by threads started by the operator - in this case bake starting a thread that evaluates drivers.
Python:
* adds bpy.app.handlers which contains lists, each for an event type:
render_pre, render_post, load_pre, load_post, save_pre, save_post
* each list item needs to be a callable object which takes 1 argument (the ID).
* callbacks are cleared on file load.
Example:
def MyFunc(scene): print("Callback:", data)
bpy.app.handlers.render_post.append(MyFunc)
C:
* This patch adds a generic C callback api which is currently only used by python.
* Unlike python callbacks these are not cleared on file load.
- add support for IDProp array slicing, but not resizing.
- rename array attribute type to typecode and use chars 'f', 'd', 'i' which match pythons array module. (was using int's which only have a meaning internally).
- rename function 'convert_to_pyobject' to 'to_dict' and 'to_list' for IDProp group and array types respectively.
- remove 'len' array attribute, calling len(array) is fine.
This means script authors can perform actions using these callbacks rather then on drawing which puts blender in a readonly state.
Simple example:
import bpy
def up_func(self, context):
print("test")
bpy.types.Scene.testprop = bpy.props.FloatProperty(update=up_func)
bpy.context.scene.testprop = 11
# prints -> test