[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