Revision: 41476
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41476
Author:   blendix
Date:     2011-11-02 20:56:52 +0000 (Wed, 02 Nov 2011)
Log Message:
-----------
Depsgraph/Python: callbacks and properties to detect datablock changes

* Adds two new python handlers: 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.

http://wiki.blender.org/index.php/Dev:2.6/Source/Render/UpdateAPI

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_depsgraph.h
    trunk/blender/source/blender/blenkernel/BKE_scene.h
    trunk/blender/source/blender/blenkernel/intern/depsgraph.c
    trunk/blender/source/blender/blenkernel/intern/scene.c
    trunk/blender/source/blender/blenlib/BLI_callbacks.h
    trunk/blender/source/blender/editors/object/object_add.c
    trunk/blender/source/blender/editors/object/object_edit.c
    trunk/blender/source/blender/makesdna/DNA_ID.h
    trunk/blender/source/blender/makesrna/intern/rna_ID.c
    trunk/blender/source/blender/makesrna/intern/rna_main_api.c
    trunk/blender/source/blender/makesrna/intern/rna_object.c
    trunk/blender/source/blender/makesrna/intern/rna_scene_api.c
    trunk/blender/source/blender/python/intern/bpy_app_handlers.c
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c

Modified: trunk/blender/source/blender/blenkernel/BKE_depsgraph.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_depsgraph.h     2011-11-02 
19:24:30 UTC (rev 41475)
+++ trunk/blender/source/blender/blenkernel/BKE_depsgraph.h     2011-11-02 
20:56:52 UTC (rev 41476)
@@ -120,6 +120,12 @@
 void   DAG_id_tag_update(struct ID *id, short flag);
                /* flush all tagged updates */
 void   DAG_ids_flush_tagged(struct Main *bmain);
+               /* check and clear ID recalc flags */
+void   DAG_ids_check_recalc(struct Main *bmain);
+void   DAG_ids_clear_recalc(struct Main *bmain);
+               /* test if any of this id type is tagged for update */
+void   DAG_id_type_tag(struct Main *bmain, short idtype);
+int            DAG_id_type_tagged(struct Main *bmain, short idtype);
 
                /* (re)-create dependency graph for armature pose */
 void   DAG_pose_sort(struct Object *ob);

Modified: trunk/blender/source/blender/blenkernel/BKE_scene.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_scene.h 2011-11-02 19:24:30 UTC 
(rev 41475)
+++ trunk/blender/source/blender/blenkernel/BKE_scene.h 2011-11-02 20:56:52 UTC 
(rev 41476)
@@ -88,6 +88,8 @@
 float BKE_curframe(struct Scene *scene);
 
 void scene_update_tagged(struct Main *bmain, struct Scene *sce);
+void scene_clear_tagged(struct Main *bmain, struct Scene *sce);
+
 void scene_update_for_newframe(struct Main *bmain, struct Scene *sce, unsigned 
int lay);
 
 void scene_add_render_layer(struct Scene *sce);

Modified: trunk/blender/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/depsgraph.c  2011-11-02 
19:24:30 UTC (rev 41475)
+++ trunk/blender/source/blender/blenkernel/intern/depsgraph.c  2011-11-02 
20:56:52 UTC (rev 41476)
@@ -1761,9 +1761,22 @@
        sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
 }
 
+static void lib_id_recalc_tag(Main *bmain, ID *id)
+{
+       id->flag |= LIB_ID_RECALC;
+       bmain->id_tag_update[id->name[0]] = 1;
+}
+
+static void lib_id_recalc_data_tag(Main *bmain, ID *id)
+{
+       id->flag |= LIB_ID_RECALC_DATA;
+       bmain->id_tag_update[id->name[0]] = 1;
+}
+
 /* node was checked to have lasttime != curtime and is if type ID_OB */
 static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
 {
+       Main *bmain= G.main;
        DagAdjList *itA;
        Object *ob, *obc;
        int oldflag, changed=0;
@@ -1789,20 +1802,24 @@
                                                if(itA->type & DAG_RL_OB_OB) {
                                                        //printf("ob %s changes 
ob %s\n", ob->id.name, obc->id.name);
                                                        obc->recalc |= 
OB_RECALC_OB;
+                                                       
lib_id_recalc_tag(bmain, &obc->id);
                                                }
                                                if(itA->type & DAG_RL_OB_DATA) {
                                                        //printf("ob %s changes 
obdata %s\n", ob->id.name, obc->id.name);
                                                        obc->recalc |= 
OB_RECALC_DATA;
+                                                       
lib_id_recalc_data_tag(bmain, &obc->id);
                                                }
                                        }
                                        if(ob->recalc & OB_RECALC_DATA) {
                                                if(itA->type & DAG_RL_DATA_OB) {
                                                        //printf("obdata %s 
changes ob %s\n", ob->id.name, obc->id.name);
                                                        obc->recalc |= 
OB_RECALC_OB;
+                                                       
lib_id_recalc_tag(bmain, &obc->id);
                                                }
                                                if(itA->type & 
DAG_RL_DATA_DATA) {
                                                        //printf("obdata %s 
changes obdata %s\n", ob->id.name, obc->id.name);
                                                        obc->recalc |= 
OB_RECALC_DATA;
+                                                       
lib_id_recalc_data_tag(bmain, &obc->id);
                                                }
                                        }
                                        if(oldflag!=obc->recalc) changed= 1;
@@ -1833,6 +1850,7 @@
                                        if(itA->type & 
(DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) {
                                                // printf("parent %s changes ob 
%s\n", ob->id.name, obc->id.name);
                                                obc->recalc |= OB_RECALC_DATA;
+                                               lib_id_recalc_data_tag(bmain, 
&obc->id);
                                        }
                                }
                        }
@@ -1872,6 +1890,7 @@
 /* node was checked to have lasttime != curtime , and is of type ID_OB */
 static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, 
int reset)
 {
+       Main *bmain= G.main;
        DagAdjList *itA;
        Object *ob;
        
@@ -1883,8 +1902,10 @@
                                ob= (Object*)(itA->node->ob);
 
                                if(reset || (ob->recalc & OB_RECALC_ALL)) {
-                                       if(BKE_ptcache_object_reset(scene, ob, 
PTCACHE_RESET_DEPSGRAPH))
+                                       if(BKE_ptcache_object_reset(scene, ob, 
PTCACHE_RESET_DEPSGRAPH)) {
                                                ob->recalc |= OB_RECALC_DATA;
+                                               lib_id_recalc_data_tag(bmain, 
&ob->id);
+                                       }
 
                                        flush_pointcache_reset(scene, 
itA->node, curtime, 1);
                                }
@@ -2001,8 +2022,10 @@
                                ob= (Object*)(itA->node->ob);
 
                                if(ob->recalc & OB_RECALC_ALL) {
-                                       if(BKE_ptcache_object_reset(sce, ob, 
PTCACHE_RESET_DEPSGRAPH))
+                                       if(BKE_ptcache_object_reset(sce, ob, 
PTCACHE_RESET_DEPSGRAPH)) {
                                                ob->recalc |= OB_RECALC_DATA;
+                                               lib_id_recalc_data_tag(bmain, 
&ob->id);
+                                       }
 
                                        flush_pointcache_reset(sce, itA->node, 
lasttime, 1);
                                }
@@ -2204,6 +2227,12 @@
                        }
                }
        }               
+
+       if(ob->recalc & OB_RECALC_OB)
+               lib_id_recalc_tag(G.main, &ob->id);
+       if(ob->recalc & OB_RECALC_DATA)
+               lib_id_recalc_data_tag(G.main, &ob->id);
+
 }
 /* flag all objects that need recalc, for changes in time for example */
 /* do_time: make this optional because undo resets objects to their animated 
locations without this */
@@ -2362,6 +2391,9 @@
                DAG_scene_update_flags(bmain, scene, lay, do_time);
                scene->lay_updated |= lay;
        }
+
+       /* hack to get objects updating on layer changes */
+       DAG_id_type_tag(bmain, ID_OB);
 }
 
 static void dag_id_flush_update__isDependentTexture(void *userData, Object 
*UNUSED(ob), ID **idpoin)
@@ -2408,6 +2440,7 @@
                        for(obt=bmain->object.first; obt; obt= obt->id.next) {
                                if(!(ob && obt == ob) && obt->data == id) {
                                        obt->recalc |= OB_RECALC_DATA;
+                                       lib_id_recalc_data_tag(bmain, &obt->id);
                                        BKE_ptcache_object_reset(sce, obt, 
PTCACHE_RESET_DEPSGRAPH);
                                }
                        }
@@ -2421,8 +2454,10 @@
                                data.is_dependent= 0;
 
                                modifiers_foreachIDLink(obt, 
dag_id_flush_update__isDependentTexture, &data);
-                               if (data.is_dependent)
+                               if (data.is_dependent) {
                                        obt->recalc |= OB_RECALC_DATA;
+                                       lib_id_recalc_data_tag(bmain, &obt->id);
+                               }
 
                                /* particle settings can use the texture as 
well */
                                if(obt->particlesystem.first) {
@@ -2435,7 +2470,8 @@
                                                        mtex = *mtexp;
                                                        if(mtex && mtex->tex == 
(Tex*)id) {
                                                                obt->recalc |= 
OB_RECALC_DATA;
-                                                               
+                                                               
lib_id_recalc_data_tag(bmain, &obt->id);
+
                                                                if(mtex->mapto 
& PAMAP_INIT)
                                                                        
psys->recalc |= PSYS_RECALC_RESET;
                                                                if(mtex->mapto 
& PAMAP_CHILD)
@@ -2455,6 +2491,8 @@
                                Key *key= ob_get_key(obt);
                                if(!(ob && obt == ob) && ((ID *)key == id)) {
                                        obt->flag |= 
(OB_RECALC_OB|OB_RECALC_DATA);
+                                       lib_id_recalc_tag(bmain, &obt->id);
+                                       lib_id_recalc_data_tag(bmain, &obt->id);
                                        BKE_ptcache_object_reset(sce, obt, 
PTCACHE_RESET_DEPSGRAPH);
                                }
                        }
@@ -2479,7 +2517,7 @@
        ListBase *lbarray[MAX_LIBARRAY];
        Scene *sce;
        unsigned int lay;
-       int a, have_tag = 0;
+       int a, do_flush = 0;
 
        dag_current_scene_layers(bmain, &sce, &lay);
 
@@ -2497,23 +2535,64 @@
                   looping over all ID's in case there are no tags */
                if(id && bmain->id_tag_update[id->name[0]]) {
                        for(; id; id=id->next) {
-                               if(id->flag & LIB_ID_RECALC) {
+                               if(id->flag & 
(LIB_ID_RECALC|LIB_ID_RECALC_DATA)) {
                                        dag_id_flush_update(sce, id);
-                                       id->flag &= ~LIB_ID_RECALC;
+                                       do_flush = 1;
                                }
                        }
+               }
+       }
 
-                       have_tag = 1;
+       /* flush changes to other objects */
+       if(do_flush)
+               DAG_scene_flush_update(bmain, sce, lay, 0);
+}
+
+void DAG_ids_check_recalc(Main *bmain)
+{
+       ListBase *lbarray[MAX_LIBARRAY];
+       int a;
+
+       /* loop over all ID types */
+       a  = set_listbasepointers(bmain, lbarray);
+
+       while(a--) {
+               ListBase *lb = lbarray[a];
+               ID *id = lb->first;
+
+               /* we tag based on first ID type character to avoid 
+                  looping over all ID's in case there are no tags */
+               if(id && bmain->id_tag_update[id->name[0]]) {
+                       /* do editors update */
+                       dag_editors_update(bmain, NULL);
+                       return;
                }
        }
+}
 
-       if(have_tag) {
-               /* clear tags */
-               memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
 
-               /* flush changes to other objects */
-               DAG_scene_flush_update(bmain, sce, lay, 0);
+void DAG_ids_clear_recalc(Main *bmain)
+{
+       ListBase *lbarray[MAX_LIBARRAY];
+       int a;
+
+       /* loop over all ID types */
+       a  = set_listbasepointers(bmain, lbarray);
+
+       while(a--) {
+               ListBase *lb = lbarray[a];
+               ID *id = lb->first;
+
+               /* we tag based on first ID type character to avoid 
+                  looping over all ID's in case there are no tags */
+               if(id && bmain->id_tag_update[id->name[0]]) {
+                       for(; id; id=id->next)
+                               if(id->flag & 
(LIB_ID_RECALC|LIB_ID_RECALC_DATA))
+                                       id->flag &= 
~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);
+               }
        }
+
+       memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
 }
 
 void DAG_id_tag_update(ID *id, short flag)
@@ -2523,8 +2602,14 @@
        if(id==NULL) return;
        
        /* tag ID for update */
-       id->flag |= LIB_ID_RECALC;
-       bmain->id_tag_update[id->name[0]] = 1;
+       if(flag) {
+               if(flag & OB_RECALC_OB)
+                       lib_id_recalc_tag(bmain, id);
+               if(flag & (OB_RECALC_DATA|PSYS_RECALC))
+                       lib_id_recalc_data_tag(bmain, id);
+       }
+       else
+               lib_id_recalc_tag(bmain, id);
 
        /* flag is for objects and particle systems */
        if(flag) {
@@ -2556,6 +2641,16 @@
        }
 }
 
+void DAG_id_type_tag(struct Main *bmain, short idtype)
+{
+       bmain->id_tag_update[((char*)&idtype)[0]] = 1;
+}
+
+int DAG_id_type_tagged(Main *bmain, short idtype)
+{
+       return bmain->id_tag_update[((char*)&idtype)[0]];
+}
+
 #if 0 // UNUSED
 /* recursively descends tree, each node only checked once */
 /* node is checked to be of type object */

Modified: trunk/blender/source/blender/blenkernel/intern/scene.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/scene.c      2011-11-02 
19:24:30 UTC (rev 41475)
+++ trunk/blender/source/blender/blenkernel/intern/scene.c      2011-11-02 
20:56:52 UTC (rev 41476)
@@ -992,6 +992,8 @@
 {
        DAG_ids_flush_tagged(bmain);
 
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+
        scene->physics_settings.quick_cache_step= 0;
 
        /* update all objects: drivers, matrices, displists, etc. flags set
@@ -1011,10 +1013,19 @@
        if (scene->physics_settings.quick_cache_step)
                BKE_ptcache_quick_cache_all(bmain, scene);
 
+       DAG_ids_check_recalc(bmain);
+
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
+
        /* in the future this should handle updates for all datablocks, not
           only objects and scenes. - brecht */
 }
 
+void scene_clear_tagged(Main *bmain, Scene *UNUSED(scene))
+{
+       DAG_ids_clear_recalc(bmain);
+}
+

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to