Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-11-03 00:56:52 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-11-03 00:56:52 +0400
commit723e129252f82cc81faa8834a68c79e4439ee8fa (patch)
tree9c1c1e2aa9265e33702007da68b28b3159766aac /source/blender/blenkernel
parentac52c79cb19ac85e06651a7b9af2e54efcd45a97 (diff)
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
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h6
-rw-r--r--source/blender/blenkernel/BKE_scene.h2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c125
-rw-r--r--source/blender/blenkernel/intern/scene.c14
4 files changed, 132 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 59b7712a5a4..0b0637fb42a 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -120,6 +120,12 @@ void DAG_ids_flush_update(struct Main *bmain, int time);
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);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 45ee6fd4ebd..4806a288cee 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -88,6 +88,8 @@ int scene_check_setscene(struct Main *bmain, struct Scene *sce);
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);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index c9df8a135fe..9d51571346f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1761,9 +1761,22 @@ void DAG_scene_sort(Main *bmain, Scene *sce)
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 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
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 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
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 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
/* 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 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int
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 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
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 @@ static void dag_object_time_update_flags(Object *ob)
}
}
}
+
+ 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 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
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 @@ static void dag_id_flush_update(Scene *sce, ID *id)
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 @@ static void dag_id_flush_update(Scene *sce, ID *id)
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 @@ static void dag_id_flush_update(Scene *sce, ID *id)
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 @@ static void dag_id_flush_update(Scene *sce, ID *id)
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 @@ void DAG_ids_flush_tagged(Main *bmain)
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 @@ void DAG_ids_flush_tagged(Main *bmain)
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;
}
}
+ }
+ }
+
+ /* 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;
- have_tag = 1;
+ /* 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 @@ void DAG_id_tag_update(ID *id, short flag)
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_tag_update(ID *id, short flag)
}
}
+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 */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index c902bee80a8..b25120c0fff 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -992,6 +992,8 @@ void scene_update_tagged(Main *bmain, Scene *scene)
{
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 @@ void scene_update_tagged(Main *bmain, Scene *scene)
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);
+}
+
/* applies changes right away, does all sets too */
void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
{
@@ -1039,6 +1050,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
* so dont call within 'scene_update_tagged_recursive' */
DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still
+ BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_PRE);
+
/* All 'standard' (i.e. without any dependencies) animation is handled here,
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
@@ -1052,6 +1065,7 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
scene_update_tagged_recursive(bmain, sce, sce);
/* keep this last */
+ BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_POST);
}