From 81a762e79f8391942026f8c8614fe5c364b85168 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 3 Dec 2012 16:21:43 +0000 Subject: [PATCH] Fix cycles viewport render getting stuck with driven/animated nodes, the updated flag would not get cleared due to the nodetree not being a real datablock. --- source/blender/blenkernel/BKE_node.h | 2 ++ source/blender/blenkernel/intern/depsgraph.c | 25 ++++++++++++++++---- source/blender/blenkernel/intern/node.c | 16 +++++++++++++ source/blender/blenloader/intern/readfile.c | 2 ++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 515bb37b249..b8f168cbdea 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -314,6 +314,8 @@ void ntreeUserIncrefID(struct bNodeTree *ntree); void ntreeUserDecrefID(struct bNodeTree *ntree); +struct bNodeTree *ntreeFromID(struct ID *id); + void ntreeMakeLocal(struct bNodeTree *ntree); int ntreeHasType(struct bNodeTree *ntree, int type); void ntreeUpdateTree(struct bNodeTree *ntree); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d23a608d31f..3ed759392b6 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1940,13 +1940,13 @@ void DAG_scene_sort(Main *bmain, Scene *sce) static void lib_id_recalc_tag(Main *bmain, ID *id) { id->flag |= LIB_ID_RECALC; - bmain->id_tag_update[id->name[0]] = 1; + DAG_id_type_tag(bmain, GS(id->name)); } 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; + DAG_id_type_tag(bmain, GS(id->name)); } /* node was checked to have lasttime != curtime and is if type ID_OB */ @@ -2818,6 +2818,7 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) void DAG_ids_clear_recalc(Main *bmain) { ListBase *lbarray[MAX_LIBARRAY]; + bNodeTree *ntree; int a; /* loop over all ID types */ @@ -2830,9 +2831,15 @@ void DAG_ids_clear_recalc(Main *bmain) /* 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) + for (; id; id = id->next) { if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + + /* some ID's contain semi-datablock nodetree */ + ntree = ntreeFromID(id); + if (ntree && (ntree->id.flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))) + ntree->id.flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + } } } @@ -2899,8 +2906,18 @@ void DAG_id_tag_update(ID *id, short flag) } } -void DAG_id_type_tag(struct Main *bmain, short idtype) +void DAG_id_type_tag(Main *bmain, short idtype) { + if (idtype == ID_NT) { + /* stupid workaround so parent datablocks of nested nodetree get looped + * over when we loop over tagged datablock types */ + DAG_id_type_tag(bmain, ID_MA); + DAG_id_type_tag(bmain, ID_TE); + DAG_id_type_tag(bmain, ID_LA); + DAG_id_type_tag(bmain, ID_WO); + DAG_id_type_tag(bmain, ID_SCE); + } + bmain->id_tag_update[((char *)&idtype)[0]] = 1; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 70867a45fd7..17dcf34b71f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -38,9 +38,13 @@ #include "DNA_action_types.h" #include "DNA_anim_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_world_types.h" #include "BLI_string.h" #include "BLI_math.h" @@ -1154,6 +1158,18 @@ void ntreeSetOutput(bNodeTree *ntree) * might be different for editor or for "real" use... */ } +bNodeTree *ntreeFromID(ID *id) +{ + switch (GS(id->name)) { + case ID_MA: return ((Material*)id)->nodetree; + case ID_LA: return ((Lamp*)id)->nodetree; + case ID_WO: return ((World*)id)->nodetree; + case ID_TE: return ((Tex*)id)->nodetree; + case ID_SCE: return ((Scene*)id)->nodetree; + default: return NULL; + } +} + typedef struct MakeLocalCallData { ID *group_id; ID *new_id; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 375b1cf47a2..2c3d3f631bd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2409,6 +2409,8 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) ntree->adt = newdataadr(fd, ntree->adt); direct_link_animdata(fd, ntree->adt); + ntree->id.flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); + link_list(fd, &ntree->nodes); for (node = ntree->nodes.first; node; node = node->next) { node->typeinfo = NULL;