[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
Wed Nov 2 21:56:54 CET 2011


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. @@



More information about the Bf-blender-cvs mailing list