[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

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Nov 3 11:05:58 CET 2011


Hi,

I didn't have a check for this yet, committed a fix for that now. It's
not possible to ensure this tag happens always currently, since it's
mostly relying on what the depsgraph knows, and that doesn't cover
everything yet. But I'd like to get it working well for at least the
datablock types I've mentioned in the commit log.

Brecht.

On Thu, Nov 3, 2011 at 1:32 AM, Dalai Felinto <dfelinto at gmail.com> wrote:
> 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
>>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>


More information about the Bf-committers mailing list