diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-08-22 20:43:19 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-08-28 21:52:54 +0300 |
commit | 34ed58dcaffd957f50380f4115d2cb9c46de31ee (patch) | |
tree | c287b36c4862433f6b55e1fc8cb2d7c2dffbd589 /source/blender/blenkernel/intern/node.c | |
parent | 69a966aca0c147ef21eeee986cc73554bfe5e948 (diff) |
Fix T68971: Copy As New Driver from Material node creates a bad reference.
NodeTree structures of materials and some other data blocks are
effectively node group datablock objects that are contained inside
the parent block. Thus, direct references to them are only valid
while blender is running, and are lost on save.
Fix Copy As New Driver to create a reference that goes through
the owner datablock, by adding a new ID flag to mark private
pseudo-datablocks.
Also fix functions that return full paths to structures and
properties, e.g. used in python tooltips. Functions for paths
from ID to struct or property can't be changed because of
Animation Data related code.
Reviewers: mont29
Differential Revision: https://developer.blender.org/D5559
Diffstat (limited to 'source/blender/blenkernel/intern/node.c')
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 206c59c110a..2eba71fa6bd 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1406,6 +1406,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) } else { ntree = MEM_callocN(sizeof(bNodeTree), "new node tree"); + ntree->id.flag |= LIB_PRIVATE_DATA; *((short *)ntree->id.name) = ID_NT; BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name)); } @@ -2172,6 +2173,7 @@ void ntreeSetOutput(bNodeTree *ntree) * might be different for editor or for "real" use... */ } +/* Returns the private NodeTree object of the datablock, if it has one. */ bNodeTree *ntreeFromID(const ID *id) { switch (GS(id->name)) { @@ -2192,6 +2194,28 @@ bNodeTree *ntreeFromID(const ID *id) } } +/* Finds and returns the datablock that privately owns the given tree, or NULL. */ +ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree) +{ + ListBase *lists[] = {&bmain->materials, + &bmain->lights, + &bmain->worlds, + &bmain->textures, + &bmain->scenes, + &bmain->linestyles, + NULL}; + + for (int i = 0; lists[i] != NULL; i++) { + LISTBASE_FOREACH (ID *, id, lists[i]) { + if (ntreeFromID(id) == ntree) { + return id; + } + } + } + + return NULL; +} + void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist, const bool lib_local) { BKE_id_make_local_generic(bmain, &ntree->id, id_in_mainlist, lib_local); |