[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41476] trunk/blender/source/blender: Depsgraph/Python: callbacks and properties to detect datablock changes

Dalai Felinto dfelinto at gmail.com
Thu Nov 3 01:32:32 CET 2011


Hi Brecht,

First of all, thanks for this fantastic commit :) Seriously this is
highly needed.

I found a possible bug. If I animate an object position, the
is_updated is updated for every frame when I play back.
If I animate a material the materials.is_updated is not set via the playback.

Is this by design/peformance?
Thanks again,

Dalai
--
www.dalaifelinto.com
@dfelinto

Now I miss one extra thing here. If the parameter is animated the data
block is not marked as is_updated when frame changes

2011/11/2 Brecht Van Lommel <brechtvanlommel at pandora.be>:
> 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
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list