Depsgraph hack feature - experimental
authorTon Roosendaal <ton@blender.org>
Thu, 10 Jan 2013 18:20:29 +0000 (18:20 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 10 Jan 2013 18:20:29 +0000 (18:20 +0000)
Many depsgraph failures are because some data in the graph is being
recalculated too early (or not at all).

Since we better support animators with working renders, here's a hack to
allow manual additional updates on frame changes.

In Property Editor, Object, Panel "Relations Extra" you now have two
buttons:
- Extra Object Update
- Extra Data Update

This will do an extra update of object and/or its data ONLY on frame changes.
Update happens as last.

Tested on files collected in Wiki todo, several cases now work OK, especially
the lags on updates.

release/scripts/startup/bl_ui/properties_object.py
source/blender/blenkernel/intern/scene.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_object.c

index 8a668b5..9518074 100644 (file)
@@ -289,6 +289,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
         row.active = ((ob.parent is not None) and (ob.use_slow_parent))
         row.prop(ob, "slow_parent_offset", text="Offset")
 
+        layout.prop(ob, "extra_recalc_object")
+        layout.prop(ob, "extra_recalc_data")
+
 
 from bl_ui.properties_animviz import (MotionPathButtonsPanel,
                                       OnionSkinButtonsPanel)
index bccbdc4..9cf0724 100644 (file)
@@ -1031,6 +1031,47 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
        }
 }
 
+/* deps hack - do extra recalcs at end */
+static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
+{
+       Base *base;
+               
+       scene->customdata_mask = scene_parent->customdata_mask;
+       
+       /* sets first, we allow per definition current scene to have
+        * dependencies on sets, but not the other way around. */
+       if (scene->set)
+               scene_depsgraph_hack(scene->set, scene_parent);
+       
+       for (base = scene->base.first; base; base = base->next) {
+               Object *ob = base->object;
+               
+               if (ob->depsflag) {
+                       int recalc = 0;
+                       // printf("depshack %s\n", ob->id.name+2);
+                       
+                       if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
+                               recalc |= OB_RECALC_OB;
+                       if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
+                               recalc |= OB_RECALC_DATA;
+                       
+                       ob->recalc |= recalc;
+                       BKE_object_handle_update(scene_parent, ob);
+                       
+                       if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
+                               GroupObject *go;
+                               
+                               for (go = ob->dup_group->gobject.first; go; go = go->next) {
+                                       if (go->ob)
+                                               go->ob->recalc |= recalc;
+                               }
+                               group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+                       }
+               }
+       }
+
+}
+
 static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
 {
        Base *base;
@@ -1066,6 +1107,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
 
        /* update masking curves */
        BKE_mask_update_scene(bmain, scene, FALSE);
+       
 }
 
 /* this is called in main loop, doing tagged updates before redraw */
@@ -1158,6 +1200,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        /* BKE_object_handle_update() on all objects, groups and sets */
        scene_update_tagged_recursive(bmain, sce, sce);
 
+       scene_depsgraph_hack(sce, sce);
+
        /* notify editors and python about recalc */
        BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
        BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
index 89328c3..559ba44 100644 (file)
@@ -178,7 +178,7 @@ typedef struct Object {
        short ipoflag;                          // xxx deprecated... old animation system
        short scaflag;                          /* ui state for game logic */
        char scavisflag;                        /* more display settings for game logic */
-       char pad5;
+       char depsflag;
 
        int dupon, dupoff, dupsta, dupend;
 
@@ -530,6 +530,10 @@ typedef struct DupliObject {
 #define OB_BODY_TYPE_NAVMESH           7
 #define OB_BODY_TYPE_CHARACTER                 8
 
+/* ob->depsflag */
+#define OB_DEPS_EXTRA_OB_RECALC                1
+#define OB_DEPS_EXTRA_DATA_RECALC      2
+
 /* ob->scavisflag */
 #define OB_VIS_SENS            1
 #define OB_VIS_CONT            2
index 80d74c3..a617c78 100644 (file)
@@ -2469,6 +2469,15 @@ static void rna_def_object(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship");
        RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
        
+       /* depsgraph hack */
+       prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC);
+       RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack");
+       
+       prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC);
+       RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack");
+       
        /* duplicates */
        prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag");