Notifiers and Updates
After manipulating data, the rest of Blender needs to be notified and updated to account for these changes, so the proper redraws, modifiers, statistics updates, will be executed. Typically a dependency graph update, redraw call, and/or redraw tag need to be done.
Looking at similar code to see what kind of updates they do is often the quickest way to find out what to. But keep the following guidelines in mind:
- Notifier: A notifier needs to be sent when manipulating data that is used by multiple places in Blender. In many cases notifiers and redraw tags are mutually exclusive, while dependency graph updates will always have an accompanying notifier.
- Dependency Graph: These need to be done when changing an Object or something that can be an object's data (e.g. a Mesh or Armature), and only if the part being changed affects the object's transformation, derived mesh or armature pose. This excludes selection.
- Redraw Tag: Screens, areas and regions need to be directly tagged for redraws only when changing the screen, area or region itself, e.g. zooming in or out, splitting windows, etc.
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *data);
The type parameter is constructed by combining a number flags defined in WM_types.h, to indicate the type of notifier. The data parameter indicates which data was changed. It is not required, but if it is specified it can be used by listeners to do more selective updates. If it is NULL it is assumed all data of this type has changed.
More info about how to use notifiers.
There are two common calls to the dependency graph.
void DAG_id_tag_update(ID *id, short flag);
Here id is the datablock within which data was changed. At the moment of writing, the only datablocks supported are Object and datablocks which can be used by Object.data, e.g. Mesh, Curve, Armature, .. . For Objects, flag is either OB_RECALC_OB if the change affects the object transformation, or OB_RECALC_DATA if the change affects the object data, or a combination of both.
This call will tag all necessary objects for recalculation later on, based on the dependency graph.
void DAG_scene_sort(Scene *sce);
This needs to be called when the dependency graph structure changes and needs to be rebuilt. This typically happens when changing pointers, e.g. setting the target object in a constraint.
void ED_region_tag_redraw(ARegion *ar); void ED_area_tag_redraw(ScrArea *sa); void ED_area_tag_refresh(ScrArea *sa);
These are some common calls to do local refreshes. They will typically be called when changing the view in some way, or by the listeners for notifiers.