Dev:Source/Render/UpdateAPI

提供: wiki
移動先: 案内検索

Update API

In 2.61, some new features were added to support detecting when certain datablocks are modified. This is useful for render engines that need to do interactive rendering, or scripts that want to automatically synchronize data from Blender to somewhere else.

Additions

Two new python handlers were added: scene_update_pre() and scene_update_post() These run before and after Blender does a scene update on making modifications to the scene.

Datablocks now have an is_updated property. This will be set to true in the above callbacks if the datablock was tagged to be updated. This works for the most common datablocks used for rendering: object, material, world, lamsp, texture, mesh, curve.

Datablock collections also have an is_updated property. If this is set, it means one datablock of this type was added, removed or modified. It's also useful as a quick check to avoid looping over all datablocks.

RenderEngine.view_update() can also check these properties, for interactive viewport rendering.

Implementation

The dependency graph now flushes the LIB_ID_RECALC flag, which means we can use it to detect if a datablock was updated, requiring e.g. a recalculation of constraints, modifiers, etc. Note that both objects that were directly modified by the user, or objects that depend on other modified objects are tagged.

A function DAG_id_type_tag was also added to make it possible to tag datablock collections on e.g. datablock removal.

Note that datablocks being tagged does not mean that they have actually changed, e.g. an f-curve might have the same value when switching to another frame, and the object still is tagged for an update. It's merely an indication that a datablock might have changed.

Example

import bpy

def scene_update(context):
    if bpy.data.objects.is_updated:
        print("One or more objects were updated!")
        for ob in bpy.data.objects:
            if ob.is_updated:
                print("=>", ob.name)

bpy.app.handlers.scene_update_post.append(scene_update)