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:
authorLukas Toenne <lukas.toenne@googlemail.com>2013-04-17 19:55:10 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2013-04-17 19:55:10 +0400
commit3d7803225122476e5ea3db8da2585fcaff7c7f59 (patch)
tree0a95c03964eb6562f39c44242c35c1f72226f2b5 /source/blender/blenloader
parent45552a45950459e4bb83bc44d41eeaa5457bfdae (diff)
Fix for node editor lib_link and memfile restore (undo): The snode->nodetree/first tree path pointer was not properly mapped on file load due to the fact that it's stored locally in other ID data blocks. Undo was restoring the pointer correctly, but used an ugly hack. Now the SpaceNode->id pointer is linked first, then the datablock is checked for an internal node tree, which is then used instead of trying to lib-link the node tree pointer.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c87
1 files changed, 56 insertions, 31 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 48d412f8a26..c5b319706e4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2361,6 +2361,21 @@ static void lib_link_nodetree(FileData *fd, Main *main)
}
}
+/* get node tree stored locally in other IDs */
+static bNodeTree *nodetree_from_id(ID *id)
+{
+ if (!id)
+ return NULL;
+ switch (GS(id->name)) {
+ case ID_SCE: return ((Scene *)id)->nodetree;
+ case ID_MA: return ((Material *)id)->nodetree;
+ case ID_WO: return ((World *)id)->nodetree;
+ case ID_LA: return ((Lamp *)id)->nodetree;
+ case ID_TE: return ((Tex *)id)->nodetree;
+ }
+ return NULL;
+}
+
/* updates group node socket identifier so that
* external links to/from the group node are preserved.
*/
@@ -5660,9 +5675,25 @@ static void lib_link_screen(FileData *fd, Main *main)
else if (sl->spacetype == SPACE_NODE) {
SpaceNode *snode = (SpaceNode *)sl;
bNodeTreePath *path, *path_next;
+ bNodeTree *ntree;
- for (path=snode->treepath.first; path; path=path->next) {
- path->nodetree = newlibadr(fd, sc->id.lib, path->nodetree);
+ /* node tree can be stored locally in id too, link this first */
+ snode->id = newlibadr(fd, sc->id.lib, snode->id);
+ snode->from = newlibadr(fd, sc->id.lib, snode->from);
+
+ ntree = nodetree_from_id(snode->id);
+ if (ntree)
+ snode->nodetree = ntree;
+ else
+ snode->nodetree = newlibadr(fd, sc->id.lib, snode->nodetree);
+
+ for (path = snode->treepath.first; path; path = path->next) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ path->nodetree = snode->nodetree;
+ }
+ else
+ path->nodetree = newlibadr(fd, sc->id.lib, path->nodetree);
if (!path->nodetree)
break;
@@ -5676,7 +5707,6 @@ static void lib_link_screen(FileData *fd, Main *main)
MEM_freeN(path);
}
- snode->nodetree = newlibadr(fd, sc->id.lib, snode->nodetree);
/* edittree is just the last in the path,
* set this directly since the path may have been shortened above */
if (snode->treepath.last) {
@@ -5685,8 +5715,6 @@ static void lib_link_screen(FileData *fd, Main *main)
}
else
snode->edittree = NULL;
- snode->id = newlibadr(fd, sc->id.lib, snode->id);
- snode->from = newlibadr(fd, sc->id.lib, snode->from);
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
@@ -5735,33 +5763,17 @@ static bool restore_pointer(ID *id, ID *newid, int user)
static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
{
if (id) {
- /* node trees can be stored locally in other IDs, needs special handling ... */
- if (GS(id->name) == ID_NT) {
- ID *idn = NULL;
+ ListBase *lb = which_libbase(mainp, GS(id->name));
+ if (lb) { // there's still risk of checking corrupt mem (freed Ids in oops)
+ ID *idn = lb->first;
- FOREACH_NODETREE(mainp, ntree, owner_id) {
- if (restore_pointer(id, &ntree->id, user)) {
- idn = &ntree->id;
+ for (; idn; idn = idn->next) {
+ if (restore_pointer(id, idn, user))
break;
- }
}
- FOREACH_NODETREE_END
return idn;
}
- else {
- ListBase *lb = which_libbase(mainp, GS(id->name));
- if (lb) { // there's still risk of checking corrupt mem (freed Ids in oops)
- ID *idn = lb->first;
-
- for (; idn; idn = idn->next) {
- if (restore_pointer(id, idn, user))
- break;
- }
-
- return idn;
- }
- }
}
return NULL;
}
@@ -5992,9 +6004,25 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl;
bNodeTreePath *path, *path_next;
+ bNodeTree *ntree;
- for (path=snode->treepath.first; path; path=path->next) {
- path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 0);
+ /* node tree can be stored locally in id too, link this first */
+ snode->id = restore_pointer_by_name(newmain, snode->id, 1);
+ snode->from = restore_pointer_by_name(newmain, snode->from, 0);
+
+ ntree = nodetree_from_id(snode->id);
+ if (ntree)
+ snode->nodetree = ntree;
+ else
+ snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, 0);
+
+ for (path = snode->treepath.first; path; path = path->next) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ path->nodetree = snode->nodetree;
+ }
+ else
+ path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 0);
if (!path->nodetree)
break;
@@ -6008,7 +6036,6 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
MEM_freeN(path);
}
- snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, 0);
/* edittree is just the last in the path,
* set this directly since the path may have been shortened above */
if (snode->treepath.last) {
@@ -6017,8 +6044,6 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
}
else
snode->edittree = NULL;
- snode->id = restore_pointer_by_name(newmain, snode->id, 1);
- snode->from = restore_pointer_by_name(newmain, snode->from, 0);
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;