diff options
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2213 |
1 files changed, 1658 insertions, 555 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 203af1d8316..082702f6d9d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -41,6 +41,7 @@ #include <math.h> // for fabs #include <stdarg.h> /* for va_start/end */ +#include "BLI_utildefines.h" #ifndef WIN32 # include <unistd.h> // for read close #else @@ -70,6 +71,7 @@ #include "DNA_key_types.h" #include "DNA_lattice_types.h" #include "DNA_lamp_types.h" +#include "DNA_linestyle_types.h" #include "DNA_meta_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -81,6 +83,7 @@ #include "DNA_packedFile_types.h" #include "DNA_particle_types.h" #include "DNA_property_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_text_types.h" #include "DNA_view3d_types.h" #include "DNA_screen_types.h" @@ -116,6 +119,7 @@ #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_deform.h" +#include "BKE_depsgraph.h" #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_global.h" // for G @@ -124,6 +128,7 @@ #include "BKE_lattice.h" #include "BKE_library.h" // for which_libbase #include "BKE_idcode.h" +#include "BKE_idprop.h" #include "BKE_material.h" #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) @@ -147,7 +152,11 @@ #include "IMB_imbuf.h" // for proxy / timecode versioning stuff +#include "NOD_common.h" #include "NOD_socket.h" +#include "NOD_composite.h" +#include "NOD_shader.h" +#include "NOD_texture.h" #include "BLO_readfile.h" #include "BLO_undofile.h" @@ -210,20 +219,6 @@ * - initialize FileGlobal and copy pointers to Global */ -/* also occurs in library.c */ -/* GS reads the memory pointed at in a specific ordering. There are, - * however two definitions for it. I have jotted them down here, both, - * but I think the first one is actually used. The thing is that - * big-endian systems might read this the wrong way round. OTOH, we - * constructed the IDs that are read out with this macro explicitly as - * well. I expect we'll sort it out soon... */ - -/* from blendef: */ -#define GS(a) (*((short *)(a))) - -/* from misc_util: flip the bytes from x */ -/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */ - /***/ typedef struct OldNew { @@ -389,7 +384,7 @@ static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib) for (i = 0, entry = onm->entries; i < nentries; i++, entry++) { if (entry->old == addr) { - ID *id = id = entry->newp; + ID *id = entry->newp; if (id && (!lib || id->lib)) { return id; } @@ -504,16 +499,6 @@ void blo_split_main(ListBase *mainlist, Main *main) split_libdata(lbarray[i], main->next); } -/* removes things like /blah/blah/../../blah/ etc, then writes in *name the full path */ -static void cleanup_path(const char *relabase, char *name) -{ - char filename[FILE_MAXFILE]; - - BLI_splitdirstring(name, filename); - BLI_cleanup_dir(relabase, name); - strcat(name, filename); -} - static void read_file_version(FileData *fd, Main *main) { BHead *bhead; @@ -542,8 +527,10 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab char name1[FILE_MAX]; BLI_strncpy(name1, filepath, sizeof(name1)); - cleanup_path(relabase, name1); -// printf("blo_find_main: original in %s\n", name); + BLI_cleanup_path(relabase, name1); + +// printf("blo_find_main: relabase %s\n", relabase); +// printf("blo_find_main: original in %s\n", filepath); // printf("blo_find_main: converted to %s\n", name1); for (m = mainlist->first; m; m = m->next) { @@ -839,7 +826,7 @@ static int read_file_dna(FileData *fd) for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) { if (bhead->code == DNA1) { - int do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) ? 1 : 0; + const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap); if (fd->filesdna) { @@ -962,11 +949,11 @@ static FileData *filedata_new(void) fd->filedes = -1; fd->gzfiledes = NULL; - /* XXX, this doesn't need to be done all the time, - * but it keeps us re-entrant, remove once we have - * a lib that provides a nice lock. - zr - */ - fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, 0); + /* XXX, this doesn't need to be done all the time, + * but it keeps us re-entrant, remove once we have + * a lib that provides a nice lock. - zr + */ + fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false); fd->datamap = oldnewmap_new(); fd->globmap = oldnewmap_new(); @@ -1020,7 +1007,47 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) } } -FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports) +static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size) +{ + int err; + + filedata->strm.next_out = (Bytef *) buffer; + filedata->strm.avail_out = size; + + // Inflate another chunk. + err = inflate (&filedata->strm, Z_SYNC_FLUSH); + + if (err == Z_STREAM_END) { + return 0; + } + else if (err != Z_OK) { + printf("fd_read_gzip_from_memory: zlib error\n"); + return 0; + } + + filedata->seek += size; + + return (size); +} + +static int fd_read_gzip_from_memory_init(FileData *fd) +{ + + fd->strm.next_in = (Bytef *) fd->buffer; + fd->strm.avail_in = fd->buffersize; + fd->strm.total_out = 0; + fd->strm.zalloc = Z_NULL; + fd->strm.zfree = Z_NULL; + + if (inflateInit2(&fd->strm, (16+MAX_WBITS)) != Z_OK) + return 0; + + fd->read = fd_read_gzip_from_memory; + + return 1; +} + +FileData *blo_openblendermemory(const void *mem, int memsize, ReportList *reports) { if (!mem || memsize<SIZEOFBLENDERHEADER) { BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read"): TIP_("Unable to open")); @@ -1028,9 +1055,21 @@ FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports) } else { FileData *fd = filedata_new(); + const char *cp = mem; + fd->buffer = mem; fd->buffersize = memsize; + + /* test if gzip */ + if (cp[0] == 0x1f && cp[1] == 0x8b) { + if (0 == fd_read_gzip_from_memory_init(fd)) { + blo_freefiledata(fd); + return NULL; + } + } + else fd->read = fd_read_from_memory; + fd->flags |= FD_FLAGS_NOT_MY_BUFFER; return blo_decode_and_check(fd, reports); @@ -1066,8 +1105,14 @@ void blo_freefiledata(FileData *fd) gzclose(fd->gzfiledes); } + if (fd->strm.next_in) { + if (inflateEnd (&fd->strm) != Z_OK) { + printf("close gzip stream error\n"); + } + } + if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) { - MEM_freeN(fd->buffer); + MEM_freeN((void *)fd->buffer); fd->buffer = NULL; } @@ -1089,6 +1134,8 @@ void blo_freefiledata(FileData *fd) oldnewmap_free(fd->imamap); if (fd->movieclipmap) oldnewmap_free(fd->movieclipmap); + if (fd->packedmap) + oldnewmap_free(fd->packedmap); if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) oldnewmap_free(fd->libmap); if (fd->bheadmap) @@ -1124,7 +1171,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group) dir[len - 1] = '\0'; /* Find the last slash */ - fd = BLI_last_slash(dir); + fd = (char *)BLI_last_slash(dir); if (fd == NULL) return 0; *fd = 0; @@ -1133,10 +1180,10 @@ int BLO_is_a_library(const char *path, char *dir, char *group) *fd = '/'; /* put back the removed slash separating the dir and the .blend file name */ } else { - char *gp = fd + 1; // in case we have a .blend file, gp points to the group + const char * const gp = fd + 1; // in case we have a .blend file, gp points to the group /* Find the last slash */ - fd = BLI_last_slash(dir); + fd = (char *)BLI_last_slash(dir); if (!fd || !BLO_has_bfile_extension(fd+1)) return 0; /* now we know that we are in a blend file and it is safe to @@ -1173,6 +1220,14 @@ static void *newmclipadr(FileData *fd, void *adr) /* used to restor return NULL; } +static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */ +{ + if (fd->packedmap && adr) + return oldnewmap_lookup_and_inc(fd->packedmap, adr); + + return oldnewmap_lookup_and_inc(fd->datamap, adr); +} + static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ { @@ -1264,10 +1319,12 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain) oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0); } for (; sce; sce = sce->id.next) { - if (sce->nodetree) { - bNode *node; - for (node = sce->nodetree->nodes.first; node; node = node->next) - oldnewmap_insert(fd->imamap, node->preview, node->preview, 0); + if (sce->nodetree && sce->nodetree->previews) { + bNodeInstanceHashIterator iter; + NODE_INSTANCE_HASH_ITER(iter, sce->nodetree->previews) { + bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter); + oldnewmap_insert(fd->imamap, preview, preview, 0); + } } } } @@ -1306,10 +1363,23 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) ima->gputexture = newimaadr(fd, ima->gputexture); } for (; sce; sce = sce->id.next) { - if (sce->nodetree) { - bNode *node; - for (node = sce->nodetree->nodes.first; node; node = node->next) - node->preview = newimaadr(fd, node->preview); + if (sce->nodetree && sce->nodetree->previews) { + bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews"); + bNodeInstanceHashIterator iter; + + /* reconstruct the preview hash, only using remaining pointers */ + NODE_INSTANCE_HASH_ITER(iter, sce->nodetree->previews) { + bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter); + if (preview) { + bNodePreview *new_preview = newimaadr(fd, preview); + if (new_preview) { + bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter); + BKE_node_instance_hash_insert(new_previews, key, new_preview); + } + } + } + BKE_node_instance_hash_free(sce->nodetree->previews, NULL); + sce->nodetree->previews = new_previews; } } } @@ -1332,7 +1402,7 @@ void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) for (; sce; sce = sce->id.next) { if (sce->nodetree) { bNode *node; - for (node = sce->nodetree->nodes.first; node; node= node->next) + for (node = sce->nodetree->nodes.first; node; node = node->next) if (node->type == CMP_NODE_MOVIEDISTORTION) oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0); } @@ -1369,6 +1439,71 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) } } +/* XXX disabled this feature - packed files also belong in temp saves and quit.blend, to make restore work */ + +static void insert_packedmap(FileData *fd, PackedFile *pf) +{ + oldnewmap_insert(fd->packedmap, pf, pf, 0); + oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0); +} + +void blo_make_packed_pointer_map(FileData *fd, Main *oldmain) +{ + Image *ima; + VFont *vfont; + bSound *sound; + Library *lib; + + fd->packedmap = oldnewmap_new(); + + for (ima = oldmain->image.first; ima; ima = ima->id.next) + if (ima->packedfile) + insert_packedmap(fd, ima->packedfile); + + for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next) + if (vfont->packedfile) + insert_packedmap(fd, vfont->packedfile); + + for (sound = oldmain->sound.first; sound; sound = sound->id.next) + if (sound->packedfile) + insert_packedmap(fd, sound->packedfile); + + for (lib = oldmain->library.first; lib; lib = lib->id.next) + if (lib->packedfile) + insert_packedmap(fd, lib->packedfile); + +} + +/* set old main packed data to zero if it has been restored */ +/* this works because freeing old main only happens after this call */ +void blo_end_packed_pointer_map(FileData *fd, Main *oldmain) +{ + Image *ima; + VFont *vfont; + bSound *sound; + Library *lib; + OldNew *entry = fd->packedmap->entries; + int i; + + /* used entries were restored, so we put them to zero */ + for (i=0; i < fd->packedmap->nentries; i++, entry++) { + if (entry->nr > 0) + entry->newp = NULL; + } + + for (ima = oldmain->image.first; ima; ima = ima->id.next) + ima->packedfile = newpackedadr(fd, ima->packedfile); + + for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next) + vfont->packedfile = newpackedadr(fd, vfont->packedfile); + + for (sound = oldmain->sound.first; sound; sound = sound->id.next) + sound->packedfile = newpackedadr(fd, sound->packedfile); + + for (lib = oldmain->library.first; lib; lib = lib->id.next) + lib->packedfile = newpackedadr(fd, lib->packedfile); +} + /* undo file support: add all library pointers in lookup */ void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd) @@ -1708,10 +1843,10 @@ static void direct_link_script(FileData *UNUSED(fd), Script *script) static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf) { - PackedFile *pf = newdataadr(fd, oldpf); + PackedFile *pf = newpackedadr(fd, oldpf); if (pf) { - pf->data = newdataadr(fd, pf->data); + pf->data = newpackedadr(fd, pf->data); } return pf; @@ -1729,6 +1864,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p if (prv->rect[i]) { prv->rect[i] = newdataadr(fd, prv->rect[i]); } + prv->gputexture[i] = NULL; } } @@ -2171,17 +2307,42 @@ static void direct_link_motionpath(FileData *fd, bMotionPath *mpath) /* ************ READ NODE TREE *************** */ +static void lib_link_node_socket(FileData *fd, ID *UNUSED(id), bNodeSocket *sock) +{ + /* Link ID Properties -- and copy this comment EXACTLY for easy finding + * of library blocks that implement this.*/ + if (sock->prop) + IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); +} + /* singe node tree (also used for material/scene trees), ntree is not NULL */ static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree) { bNode *node; + bNodeSocket *sock; if (ntree->adt) lib_link_animdata(fd, &ntree->id, ntree->adt); ntree->gpd = newlibadr_us(fd, id->lib, ntree->gpd); - for (node = ntree->nodes.first; node; node = node->next) - node->id = newlibadr_us(fd, id->lib, node->id); + for (node = ntree->nodes.first; node; node = node->next) { + /* Link ID Properties -- and copy this comment EXACTLY for easy finding + * of library blocks that implement this.*/ + if (node->prop) + IDP_LibLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + + node->id= newlibadr_us(fd, id->lib, node->id); + + for (sock = node->inputs.first; sock; sock = sock->next) + lib_link_node_socket(fd, id, sock); + for (sock = node->outputs.first; sock; sock = sock->next) + lib_link_node_socket(fd, id, sock); + } + + for (sock = ntree->inputs.first; sock; sock = sock->next) + lib_link_node_socket(fd, id, sock); + for (sock = ntree->outputs.first; sock; sock = sock->next) + lib_link_node_socket(fd, id, sock); } /* library ntree linking after fileread */ @@ -2198,131 +2359,49 @@ static void lib_link_nodetree(FileData *fd, Main *main) } } -static void do_versions_socket_default_value(bNodeSocket *sock) -{ - bNodeSocketValueFloat *valfloat; - bNodeSocketValueVector *valvector; - bNodeSocketValueRGBA *valrgba; - - if (sock->default_value) - return; - - switch (sock->type) { - case SOCK_FLOAT: - valfloat = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueFloat), "default socket value"); - valfloat->value = sock->ns.vec[0]; - valfloat->min = sock->ns.min; - valfloat->max = sock->ns.max; - valfloat->subtype = PROP_NONE; - break; - case SOCK_VECTOR: - valvector = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueVector), "default socket value"); - copy_v3_v3(valvector->value, sock->ns.vec); - valvector->min = sock->ns.min; - valvector->max = sock->ns.max; - valvector->subtype = PROP_NONE; - break; - case SOCK_RGBA: - valrgba = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueRGBA), "default socket value"); - copy_v4_v4(valrgba->value, sock->ns.vec); - break; - } -} - -void blo_do_versions_nodetree_default_value(bNodeTree *ntree) -{ - bNode *node; - bNodeSocket *sock; - for (node=ntree->nodes.first; node; node=node->next) { - for (sock=node->inputs.first; sock; sock=sock->next) - do_versions_socket_default_value(sock); - for (sock=node->outputs.first; sock; sock=sock->next) - do_versions_socket_default_value(sock); - } - for (sock=ntree->inputs.first; sock; sock=sock->next) - do_versions_socket_default_value(sock); - for (sock=ntree->outputs.first; sock; sock=sock->next) - do_versions_socket_default_value(sock); -} - -static void lib_nodetree_init_types_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - ntreeInitTypes(ntree); - - /* need to do this here instead of in do_versions, otherwise next function can crash */ - blo_do_versions_nodetree_default_value(ntree); - - /* XXX could be replaced by do_versions for new nodes */ - for (node=ntree->nodes.first; node; node=node->next) - node_verify_socket_templates(ntree, node); -} - -/* updates group node socket own_index so that +/* updates group node socket identifier so that * external links to/from the group node are preserved. */ static void lib_node_do_versions_group_indices(bNode *gnode) { bNodeTree *ngroup = (bNodeTree*)gnode->id; - bNode *intnode; - bNodeSocket *sock, *gsock, *intsock; - int found; + bNodeSocket *sock; + bNodeLink *link; - for (sock=gnode->outputs.first; sock; sock=sock->next) { + for (sock=gnode->outputs.first; sock; sock = sock->next) { int old_index = sock->to_index; - for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) { - if (gsock->link && gsock->link->fromsock->own_index == old_index) { - sock->own_index = gsock->own_index; - break; + + for (link = ngroup->links.first; link; link = link->next) { + if (link->tonode->type == NODE_GROUP_OUTPUT && link->fromsock->own_index == old_index) { + strcpy(sock->identifier, link->fromsock->identifier); + /* deprecated */ + sock->own_index = link->fromsock->own_index; + sock->to_index = 0; + sock->groupsock = NULL; } } } - for (sock=gnode->inputs.first; sock; sock=sock->next) { + for (sock=gnode->inputs.first; sock; sock = sock->next) { int old_index = sock->to_index; - /* can't use break in double loop */ - found = 0; - for (intnode=ngroup->nodes.first; intnode && !found; intnode=intnode->next) { - for (intsock=intnode->inputs.first; intsock; intsock=intsock->next) { - if (intsock->own_index == old_index && intsock->link) { - sock->own_index = intsock->link->fromsock->own_index; - found = 1; - break; - } + + for (link = ngroup->links.first; link; link = link->next) { + if (link->fromnode->type == NODE_GROUP_INPUT && link->tosock->own_index == old_index) { + strcpy(sock->identifier, link->tosock->identifier); + /* deprecated */ + sock->own_index = link->tosock->own_index; + sock->to_index = 0; + sock->groupsock = NULL; } } } } -/* updates external links for all group nodes in a tree */ -static void lib_nodetree_do_versions_group_indices_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == NODE_GROUP) { - bNodeTree *ngroup = (bNodeTree*)node->id; - if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE)) - lib_node_do_versions_group_indices(node); - } - } -} - -/* make an update call for the tree */ -static void lib_nodetree_do_versions_update_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - if (ntree->update) - ntreeUpdateTree(ntree); -} - /* verify types for nodes and groups, all data has to be read */ /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic * typedefs */ static void lib_verify_nodetree(Main *main, int UNUSED(open)) { bNodeTree *ntree; - int i; - bNodeTreeType *ntreetype; /* this crashes blender on undo/redo */ #if 0 @@ -2332,41 +2411,143 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open)) #endif /* set node->typeinfo pointers */ - for (i = 0; i < NUM_NTREE_TYPES; ++i) { - ntreetype = ntreeGetType(i); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, lib_nodetree_init_types_cb); - } - for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) - lib_nodetree_init_types_cb(NULL, NULL, ntree); + FOREACH_NODETREE(main, ntree, id) { + ntreeSetTypes(NULL, ntree); + } FOREACH_NODETREE_END + + /* verify static socket templates */ + FOREACH_NODETREE(main, ntree, id) { + bNode *node; + for (node=ntree->nodes.first; node; node=node->next) + node_verify_socket_templates(ntree, node); + } FOREACH_NODETREE_END { int has_old_groups = 0; /* XXX this should actually be part of do_versions, but since we need * finished library linking, it is not possible there. Instead in do_versions - * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the + * we have set the NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2 flag, so at this point we can do the * actual group node updates. */ for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) { - if (ntree->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE) { - /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */ - node_group_expose_all_sockets(ntree); + if (ntree->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2) has_old_groups = 1; - } } if (has_old_groups) { - for (i = 0; i < NUM_NTREE_TYPES; ++i) { - ntreetype = ntreeGetType(i); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_group_indices_cb); - } + FOREACH_NODETREE(main, ntree, id) { + /* updates external links for all group nodes in a tree */ + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == NODE_GROUP) { + bNodeTree *ngroup = (bNodeTree*)node->id; + if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2)) + lib_node_do_versions_group_indices(node); + } + } + } FOREACH_NODETREE_END } for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) - ntree->flag &= ~NTREE_DO_VERSIONS_GROUP_EXPOSE; + ntree->flag &= ~NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2; } + + { + /* Convert the previously used ntree->inputs/ntree->outputs lists to interface nodes. + * Pre 2.56.2 node trees automatically have all unlinked sockets exposed already + * (see NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2). + * + * XXX this should actually be part of do_versions, + * but needs valid typeinfo pointers to create interface nodes. + * + * Note: theoretically only needed in node groups (main->nodetree), + * but due to a temporary bug such links could have been added in all trees, + * so have to clean up all of them ... + */ + FOREACH_NODETREE(main, ntree, id) { + if (ntree->flag & NTREE_DO_VERSIONS_CUSTOMNODES_GROUP) { + bNode *input_node = NULL, *output_node = NULL; + int num_inputs = 0, num_outputs = 0; + bNodeLink *link, *next_link; + /* Only create new interface nodes for actual older files. + * New file versions already have input/output nodes with duplicate links, + * in that case just remove the invalid links. + */ + int create_io_nodes = (ntree->flag & NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE); + + float input_locx = 1000000.0f, input_locy = 0.0f; + float output_locx = -1000000.0f, output_locy = 0.0f; + /* rough guess, not nice but we don't have access to UI constants here ... */ + static const float offsetx = 42 + 3*20 + 20; + /*static const float offsety = 0.0f;*/ + + if (create_io_nodes) { + if (ntree->inputs.first) + input_node = nodeAddStaticNode(NULL, ntree, NODE_GROUP_INPUT); + + if (ntree->outputs.first) + output_node = nodeAddStaticNode(NULL, ntree, NODE_GROUP_OUTPUT); + } + + /* Redirect links from/to the node tree interface to input/output node. + * If the fromnode/tonode pointers are NULL, this means a link from/to + * the ntree interface sockets, which need to be redirected to new interface nodes. + */ + for (link = ntree->links.first; link; link = next_link) { + int free_link = FALSE; + next_link = link->next; + + if (link->fromnode == NULL) { + if (input_node) { + link->fromnode = input_node; + link->fromsock = node_group_input_find_socket(input_node, link->fromsock->identifier); + ++num_inputs; + + if (input_locx > link->tonode->locx - offsetx) + input_locx = link->tonode->locx - offsetx; + input_locy += link->tonode->locy; + } + else + free_link = TRUE; + } + + if (link->tonode == NULL) { + if (output_node) { + link->tonode = output_node; + link->tosock = node_group_output_find_socket(output_node, link->tosock->identifier); + ++num_outputs; + + if (output_locx < link->fromnode->locx + offsetx) + output_locx = link->fromnode->locx + offsetx; + output_locy += link->fromnode->locy; + } + else + free_link = TRUE; + } + + if (free_link) + nodeRemLink(ntree, link); + } + + if (num_inputs > 0) { + input_locy /= num_inputs; + input_node->locx = input_locx; + input_node->locy = input_locy; + } + if (num_outputs > 0) { + output_locy /= num_outputs; + output_node->locx = output_locx; + output_node->locy = output_locy; + } + + /* clear do_versions flags */ + ntree->flag &= ~(NTREE_DO_VERSIONS_CUSTOMNODES_GROUP | NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE); + } + } + FOREACH_NODETREE_END + } + /* verify all group user nodes */ for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) { ntreeVerifyNodes(main, &ntree->id); @@ -2374,21 +2555,22 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open)) /* make update calls where necessary */ { - for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) + FOREACH_NODETREE(main, ntree, id) { + /* make an update call for the tree */ if (ntree->update) ntreeUpdateTree(ntree); - - for (i = 0; i < NUM_NTREE_TYPES; i++) { - ntreetype = ntreeGetType(i); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_update_cb); - } + } FOREACH_NODETREE_END } } static void direct_link_node_socket(FileData *fd, bNodeSocket *sock) { + sock->prop = newdataadr(fd, sock->prop); + if (sock->prop) + IDP_DirectLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + sock->link = newdataadr(fd, sock->link); + sock->typeinfo = NULL; sock->storage = newdataadr(fd, sock->storage); sock->default_value = newdataadr(fd, sock->default_value); sock->cache = NULL; @@ -2403,6 +2585,10 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) bNodeLink *link; ntree->init = 0; /* to set callbacks and force setting types */ + ntree->is_updating = FALSE; + ntree->typeinfo= NULL; + ntree->interface_type = NULL; + ntree->progress = NULL; ntree->execdata = NULL; @@ -2418,6 +2604,10 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &node->inputs); link_list(fd, &node->outputs); + node->prop = newdataadr(fd, node->prop); + if (node->prop) + IDP_DirectLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + link_list(fd, &node->internal_links); for (link = node->internal_links.first; link; link = link->next) { link->fromnode = newdataadr(fd, link->fromnode); @@ -2429,8 +2619,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) if (node->type == CMP_NODE_MOVIEDISTORTION) { node->storage = newmclipadr(fd, node->storage); } - else + else { node->storage = newdataadr(fd, node->storage); + } if (node->storage) { /* could be handlerized at some point */ @@ -2441,9 +2632,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) else if (node->type==SH_NODE_SCRIPT) { NodeShaderScript *nss = (NodeShaderScript *) node->storage; nss->bytecode = newdataadr(fd, nss->bytecode); - nss->prop = newdataadr(fd, nss->prop); - if (nss->prop) - IDP_DirectLinkProperty(nss->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } } else if (ntree->type==NTREE_COMPOSIT) { @@ -2462,14 +2650,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) } link_list(fd, &ntree->links); - /* external sockets */ - link_list(fd, &ntree->inputs); - link_list(fd, &ntree->outputs); - /* and we connect the rest */ for (node = ntree->nodes.first; node; node = node->next) { node->parent = newdataadr(fd, node->parent); - node->preview = newimaadr(fd, node->preview); node->lasty = 0; for (sock = node->inputs.first; sock; sock = sock->next) @@ -2477,6 +2660,10 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) for (sock = node->outputs.first; sock; sock = sock->next) direct_link_node_socket(fd, sock); } + + /* interface socket lists */ + link_list(fd, &ntree->inputs); + link_list(fd, &ntree->outputs); for (sock = ntree->inputs.first; sock; sock = sock->next) direct_link_node_socket(fd, sock); for (sock = ntree->outputs.first; sock; sock = sock->next) @@ -2489,6 +2676,29 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link->tosock = newdataadr(fd, link->tosock); } +#if 0 + if (ntree->previews) { + bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews"); + bNodeInstanceHashIterator iter; + + NODE_INSTANCE_HASH_ITER(iter, ntree->previews) { + bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter); + if (preview) { + bNodePreview *new_preview = newimaadr(fd, preview); + if (new_preview) { + bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter); + BKE_node_instance_hash_insert(new_previews, key, new_preview); + } + } + } + BKE_node_instance_hash_free(ntree->previews, NULL); + ntree->previews = new_previews; + } +#else + /* XXX TODO */ + ntree->previews = NULL; +#endif + /* type verification is in lib-link */ } @@ -2535,7 +2745,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) cld.fd = fd; cld.id = id; - id_loop_constraints(conlist, lib_link_constraint_cb, &cld); + BKE_id_loop_constraints(conlist, lib_link_constraint_cb, &cld); } static void direct_link_constraints(FileData *fd, ListBase *lb) @@ -2556,15 +2766,15 @@ static void direct_link_constraints(FileData *fd, ListBase *lb) data->prop = newdataadr(fd, data->prop); if (data->prop) IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - } break; + } case CONSTRAINT_TYPE_SPLINEIK: { bSplineIKConstraint *data= con->data; - + data->points= newdataadr(fd, data->points); - } break; + } case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; @@ -2574,30 +2784,32 @@ static void direct_link_constraints(FileData *fd, ListBase *lb) /* version patch for runtime flag, was not cleared in some case */ data->flag &= ~CONSTRAINT_IK_AUTO; + break; } case CONSTRAINT_TYPE_CHILDOF: { /* XXX version patch, in older code this flag wasn't always set, and is inherent to type */ if (con->ownspace == CONSTRAINT_SPACE_POSE) con->flag |= CONSTRAINT_SPACEONCE; - } break; + } } } } -static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) +static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) { bPoseChannel *pchan; bArmature *arm = ob->data; - int rebuild; + int rebuild = 0; if (!pose || !arm) return; - - /* always rebuild to match proxy or lib changes */ - rebuild = ob->proxy || (ob->id.lib==NULL && arm->id.lib); + /* always rebuild to match proxy or lib changes, but on Undo */ + if (fd->memfile == NULL) + if (ob->proxy || (ob->id.lib==NULL && arm->id.lib)) + rebuild = 1; if (ob->proxy) { /* sync proxy layer */ @@ -2629,7 +2841,7 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) } if (rebuild) { - ob->recalc = (OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); pose->flag |= POSE_RECALC; } } @@ -2981,7 +3193,7 @@ static void direct_link_text(FileData *fd, Text *text) if (text->flags & TXT_ISEXT) { BKE_text_reload(text); } - else { + /* else { */ #endif link_list(fd, &text->lines); @@ -3129,7 +3341,9 @@ static void direct_link_curve(FileData *fd, Curve *cu) cu->strinfo= newdataadr(fd, cu->strinfo); cu->tb = newdataadr(fd, cu->tb); - if (cu->vfont == NULL) link_list(fd, &(cu->nurb)); + if (cu->vfont == NULL) { + link_list(fd, &(cu->nurb)); + } else { cu->nurb.first=cu->nurb.last= NULL; @@ -3709,8 +3923,10 @@ static void lib_link_mesh(FileData *fd, Main *main) me->mat[i] = newlibadr_us(fd, me->id.lib, me->mat[i]); } } - else me->totcol = 0; - + else { + me->totcol = 0; + } + me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys me->key = newlibadr_us(fd, me->id.lib, me->key); me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh); @@ -4035,15 +4251,13 @@ static void lib_link_object(FileData *fd, Main *main) ob->proxy = NULL; if (ob->id.lib) - printf("Proxy lost from object %s lib %s\n", ob->id.name+2, ob->id.lib->name); + printf("Proxy lost from object %s lib %s\n", ob->id.name + 2, ob->id.lib->name); else - printf("Proxy lost from object %s lib <NONE>\n", ob->id.name+2); + printf("Proxy lost from object %s lib <NONE>\n", ob->id.name + 2); } else { /* this triggers object_update to always use a copy */ ob->proxy->proxy_from = ob; - /* force proxy updates after load/undo, a bit weak */ - ob->recalc = ob->proxy->recalc = (OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } } ob->proxy_group = newlibadr(fd, ob->id.lib, ob->proxy_group); @@ -4053,9 +4267,9 @@ static void lib_link_object(FileData *fd, Main *main) if (ob->data==NULL && poin!=NULL) { if (ob->id.lib) - printf("Can't find obdata of %s lib %s\n", ob->id.name+2, ob->id.lib->name); + printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->name); else - printf("Object %s lost data.\n", ob->id.name+2); + printf("Object %s lost data.\n", ob->id.name + 2); ob->type = OB_EMPTY; warn = 1; @@ -4096,7 +4310,7 @@ static void lib_link_object(FileData *fd, Main *main) /* if id.us==0 a new base will be created later on */ /* WARNING! Also check expand_object(), should reflect the stuff below. */ - lib_link_pose(fd, ob, ob->pose); + lib_link_pose(fd, main, ob, ob->pose); lib_link_constraints(fd, &ob->id, &ob->constraints); // XXX deprecated - old animation system <<< @@ -4241,6 +4455,11 @@ static void lib_link_object(FileData *fd, Main *main) lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem); lib_link_modifiers(fd, ob); + + if (ob->rigidbody_constraint) { + ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1); + ob->rigidbody_constraint->ob2 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob2); + } } } @@ -4664,6 +4883,20 @@ static void direct_link_object(FileData *fd, Object *ob) } ob->bsoft = newdataadr(fd, ob->bsoft); ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */ + + ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object); + if (ob->rigidbody_object) { + RigidBodyOb *rbo = ob->rigidbody_object; + + /* must nullify the references to physics sim objects, since they no-longer exist + * (and will need to be recalculated) + */ + rbo->physics_object = NULL; + rbo->physics_shape = NULL; + } + ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint); + if (ob->rigidbody_constraint) + ob->rigidbody_constraint->physics_constraint = NULL; link_list(fd, &ob->particlesystem); direct_link_particlesystems(fd, &ob->particlesystem); @@ -4757,7 +4990,7 @@ static void composite_patch(bNodeTree *ntree, Scene *scene) { bNode *node; - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (node->id==NULL && ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) node->id = &scene->id; } @@ -4788,6 +5021,7 @@ static void lib_link_scene(FileData *fd, Main *main) Sequence *seq; SceneRenderLayer *srl; TimeMarker *marker; + FreestyleLineSet *fls; for (sce = main->scene.first; sce; sce = sce->id.next) { if (sce->id.flag & LIB_NEED_LINK) { @@ -4882,6 +5116,18 @@ static void lib_link_scene(FileData *fd, Main *main) BKE_sequencer_update_muting(sce->ed); BKE_sequencer_update_sound_bounds_all(sce); + + /* rigidbody world relies on it's linked groups */ + if (sce->rigidbody_world) { + RigidBodyWorld *rbw = sce->rigidbody_world; + if (rbw->group) + rbw->group = newlibadr(fd, sce->id.lib, rbw->group); + if (rbw->constraints) + rbw->constraints = newlibadr(fd, sce->id.lib, rbw->constraints); + if (rbw->effector_weights) + rbw->effector_weights->group = newlibadr(fd, sce->id.lib, rbw->effector_weights->group); + } + if (sce->nodetree) { lib_link_ntree(fd, &sce->id, sce->nodetree); composite_patch(sce->nodetree, sce); @@ -4890,6 +5136,10 @@ static void lib_link_scene(FileData *fd, Main *main) for (srl = sce->r.layers.first; srl; srl = srl->next) { srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override); srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override); + for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { + fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle); + fls->group = newlibadr_us(fd, sce->id.lib, fls->group); + } } /*Game Settings: Dome Warp Text*/ sce->gm.dome.warptext = newlibadr(fd, sce->id.lib, sce->gm.dome.warptext); @@ -4958,9 +5208,10 @@ static void direct_link_scene(FileData *fd, Scene *sce) Editing *ed; Sequence *seq; MetaStack *ms; + RigidBodyWorld *rbw; + SceneRenderLayer *srl; sce->theDag = NULL; - sce->dagisvalid = 0; sce->obedit = NULL; sce->stats = NULL; sce->fps_info = NULL; @@ -4991,6 +5242,16 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->imapaint.paintcursor = NULL; sce->toolsettings->particle.paintcursor = NULL; + + /* in rare cases this is needed, see [#33806] */ + if (sce->toolsettings->vpaint) { + sce->toolsettings->vpaint->vpaint_prev = NULL; + sce->toolsettings->vpaint->tot = 0; + } + if (sce->toolsettings->wpaint) { + sce->toolsettings->wpaint->wpaint_prev = NULL; + sce->toolsettings->wpaint->tot = 0; + } } if (sce->ed) { @@ -5126,6 +5387,13 @@ static void direct_link_scene(FileData *fd, Scene *sce) link_list(fd, &(sce->markers)); link_list(fd, &(sce->transform_spaces)); link_list(fd, &(sce->r.layers)); + + for(srl = sce->r.layers.first; srl; srl = srl->next) { + link_list(fd, &(srl->freestyleConfig.modules)); + } + for(srl = sce->r.layers.first; srl; srl = srl->next) { + link_list(fd, &(srl->freestyleConfig.linesets)); + } sce->nodetree = newdataadr(fd, sce->nodetree); if (sce->nodetree) { @@ -5134,6 +5402,29 @@ static void direct_link_scene(FileData *fd, Scene *sce) } direct_link_view_settings(fd, &sce->view_settings); + + sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world); + rbw = sce->rigidbody_world; + if (rbw) { + /* must nullify the reference to physics sim object, since it no-longer exist + * (and will need to be recalculated) + */ + rbw->physics_world = NULL; + rbw->objects = NULL; + rbw->numbodies = 0; + + /* set effector weights */ + rbw->effector_weights = newdataadr(fd, rbw->effector_weights); + if (!rbw->effector_weights) + rbw->effector_weights = BKE_add_effector_weights(NULL); + + /* link cache */ + direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE); + /* make sure simulation starts from the beginning after loading file */ + if (rbw->pointcache) { + rbw->ltime = (float)rbw->pointcache->startframe; + } + } } /* ************ READ WM ***************** */ @@ -5160,6 +5451,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->drawdata = NULL; win->drawmethod = -1; win->drawfail = 0; + win->active = 0; } wm->timers.first = wm->timers.last = NULL; @@ -5231,27 +5523,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) /* ****************** READ SCREEN ***************** */ -static void butspace_version_132(SpaceButs *buts) -{ - buts->v2d.tot.xmin = 0.0f; - buts->v2d.tot.ymin = 0.0f; - buts->v2d.tot.xmax = 1279.0f; - buts->v2d.tot.ymax = 228.0f; - - buts->v2d.min[0] = 256.0f; - buts->v2d.min[1] = 42.0f; - - buts->v2d.max[0] = 2048.0f; - buts->v2d.max[1] = 450.0f; - - buts->v2d.minzoom = 0.5f; - buts->v2d.maxzoom = 1.21f; - - buts->v2d.scroll = 0; - buts->v2d.keepzoom = 1; - buts->v2d.keeptot = 1; -} - /* note: file read without screens option G_FILE_NO_UI; * check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) @@ -5305,18 +5576,9 @@ static void lib_link_screen(FileData *fd, Main *main) else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid); - sbuts->mainbo = sbuts->mainb; - sbuts->mainbuser = sbuts->mainb; - if (main->versionfile < 132) - butspace_version_132(sbuts); } else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - sfile->files = NULL; - sfile->op = NULL; - sfile->layout = NULL; - sfile->folders_prev = NULL; - sfile->folders_next = NULL; + ; } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; @@ -5348,12 +5610,6 @@ static void lib_link_screen(FileData *fd, Main *main) */ sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); - sseq->scopes.reference_ibuf = NULL; - sseq->scopes.zebra_ibuf = NULL; - sseq->scopes.waveform_ibuf = NULL; - sseq->scopes.sep_waveform_ibuf = NULL; - sseq->scopes.vector_ibuf = NULL; - sseq->scopes.histogram_ibuf = NULL; } else if (sl->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)sl; @@ -5368,7 +5624,6 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceText *st= (SpaceText *)sl; st->text= newlibadr(fd, sc->id.lib, st->text); - st->drawcache= NULL; } else if (sl->spacetype == SPACE_SCRIPT) { SpaceScript *scpt = (SpaceScript *)sl; @@ -5385,7 +5640,6 @@ static void lib_link_screen(FileData *fd, Main *main) TreeStoreElem *tselem; int a; - so->tree.first = so->tree.last= NULL; so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { @@ -5397,42 +5651,40 @@ static void lib_link_screen(FileData *fd, Main *main) } else if (sl->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)sl; + bNodeTreePath *path, *path_next; - snode->id = newlibadr(fd, sc->id.lib, snode->id); - snode->edittree = NULL; - - if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { - /* internal data, a bit patchy */ - snode->nodetree = NULL; - if (snode->id) { - if (GS(snode->id->name)==ID_MA) - snode->nodetree = ((Material *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_WO) - snode->nodetree = ((World *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_LA) - snode->nodetree = ((Lamp *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_SCE) - snode->nodetree = ((Scene *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_TE) - snode->nodetree = ((Tex *)snode->id)->nodetree; - } + for (path=snode->treepath.first; path; path=path->next) { + path->nodetree = newlibadr(fd, sc->id.lib, path->nodetree); + + if (!path->nodetree) + break; } - else { - snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree); + + /* remaining path entries are invalid, remove */ + for (; path; path = path_next) { + path_next = path->next; + + BLI_remlink(&snode->treepath, path); + MEM_freeN(path); } - snode->linkdrag.first = snode->linkdrag.last = NULL; + 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) { + path = snode->treepath.last; + snode->edittree = path->nodetree; + } + 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; sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask); - - sclip->scopes.track_search = NULL; - sclip->scopes.track_preview = NULL; - sclip->draw_context = NULL; - sclip->scopes.ok = 0; } else if (sl->spacetype == SPACE_LOGIC) { SpaceLogic *slogic = (SpaceLogic *)sl; @@ -5446,27 +5698,62 @@ static void lib_link_screen(FileData *fd, Main *main) } } -/* Only for undo files, or to restore a screen after reading without UI... */ +static bool restore_pointer(ID *id, ID *newid, int user) +{ + if (strcmp(newid->name + 2, id->name + 2) == 0) { + if (newid->lib == id->lib) { + if (user == 1) { + if (newid->us == 0) { + newid->us++; + } + } + else if (user == 2) { + id_us_ensure_real(newid); + } + return true; + } + } + return false; +} + +/** + * Only for undo files, or to restore a screen after reading without UI... + * + * user + * - 0: no usercount change + * - 1: ensure a user + * - 2: ensure a real user (even if a fake one is set) + */ static void *restore_pointer_by_name(Main *mainp, ID *id, int user) { if (id) { - 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; - char *name = id->name + 2; + /* node trees can be stored locally in other IDs, needs special handling ... */ + if (GS(id->name) == ID_NT) { + ID *idn = NULL; - for (; idn; idn = idn->next) { - if (idn->name[2] == name[0] && strcmp(idn->name+2, name) == 0) { - if (idn->lib == id->lib) { - if (user && idn->us == 0) idn->us++; - break; - } + FOREACH_NODETREE(mainp, ntree, owner_id) { + if (restore_pointer(id, &ntree->id, user)) { + idn = &ntree->id; + 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; } @@ -5567,7 +5854,9 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc } #endif } - else if (v3d->scenelock) v3d->lay = sc->scene->lay; + else if (v3d->scenelock) { + v3d->lay = sc->scene->lay; + } /* not very nice, but could help */ if ((v3d->layact & v3d->lay) == 0) v3d->layact = v3d->lay; @@ -5625,7 +5914,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; - sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 1); + sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 2); /* this will be freed, not worth attempting to find same scene, * since it gets initialized later */ @@ -5641,7 +5930,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc * so assume that here we're doing for undo only... */ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1); - sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 1); + sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 2); } else if (sl->spacetype == SPACE_SEQ) { SpaceSeq *sseq = (SpaceSeq *)sl; @@ -5694,30 +5983,40 @@ 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; - snode->id = restore_pointer_by_name(newmain, snode->id, 1); - snode->edittree = NULL; + for (path=snode->treepath.first; path; path=path->next) { + path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 0); + + if (!path->nodetree) + break; + } - if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { - snode->nodetree = NULL; - if (snode->id) { - if (GS(snode->id->name)==ID_MA) - snode->nodetree = ((Material *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_SCE) - snode->nodetree = ((Scene *)snode->id)->nodetree; - else if (GS(snode->id->name)==ID_TE) - snode->nodetree = ((Tex *)snode->id)->nodetree; - } + /* remaining path entries are invalid, remove */ + for (; path; path = path_next) { + path_next = path->next; + + BLI_remlink(&snode->treepath, path); + MEM_freeN(path); } - else { - snode->nodetree= restore_pointer_by_name(newmain, &snode->nodetree->id, 1); + + 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) { + path = snode->treepath.last; + snode->edittree = path->nodetree; } + 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; - sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); - sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 1); + sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 2); + sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 2); sclip->scopes.ok = 0; } @@ -5737,6 +6036,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) { Panel *pa; + uiList *ui_list; link_list(fd, &ar->panels); @@ -5747,6 +6047,12 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) pa->type = NULL; } + link_list(fd, &ar->ui_lists); + + for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) { + ui_list->type = NULL; + } + ar->regiondata = newdataadr(fd, ar->regiondata); if (ar->regiondata) { if (spacetype == SPACE_VIEW3D) { @@ -5756,6 +6062,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->clipbb = newdataadr(fd, rv3d->clipbb); rv3d->depths = NULL; + rv3d->gpuoffscreen = NULL; rv3d->ri = NULL; rv3d->render_engine = NULL; rv3d->sms = NULL; @@ -5774,6 +6081,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) ar->type = NULL; ar->swap = 0; ar->do_draw = FALSE; + ar->regiontimer = NULL; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } @@ -5842,6 +6150,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sa->handlers.first = sa->handlers.last = NULL; sa->type = NULL; /* spacetype callbacks */ + sa->region_active_win = -1; for (ar = sa->regionbase.first; ar; ar = ar->next) direct_link_region(fd, ar, sa->spacetype); @@ -5890,6 +6199,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) v3d->afterdraw_xray.first = v3d->afterdraw_xray.last = NULL; v3d->afterdraw_xraytransp.first = v3d->afterdraw_xraytransp.last = NULL; v3d->properties_storage = NULL; + v3d->defmaterial = NULL; /* render can be quite heavy, set to wire on load */ if (v3d->drawtype == OB_RENDER) @@ -5918,6 +6228,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw } + soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; @@ -5950,6 +6261,15 @@ static void direct_link_screen(FileData *fd, bScreen *sc) snode->gpd = newdataadr(fd, snode->gpd); direct_link_gpencil(fd, snode->gpd); } + + link_list(fd, &snode->treepath); + snode->edittree = NULL; + snode->linkdrag.first = snode->linkdrag.last = NULL; + } + else if (sl->spacetype == SPACE_TEXT) { + SpaceText *st= (SpaceText *)sl; + + st->drawcache= NULL; } else if (sl->spacetype == SPACE_TIME) { SpaceTime *stime = (SpaceTime *)sl; @@ -5965,6 +6285,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } } else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + /* grease pencil data is not a direct data and can't be linked from direct_link* * functions, it should be linked from lib_link* functions instead * @@ -5973,17 +6295,26 @@ static void direct_link_screen(FileData *fd, bScreen *sc) * simple return NULL here (sergey) */ #if 0 - SpaceSeq *sseq = (SpaceSeq *)sl; if (sseq->gpd) { sseq->gpd = newdataadr(fd, sseq->gpd); direct_link_gpencil(fd, sseq->gpd); } #endif + sseq->scopes.reference_ibuf = NULL; + sseq->scopes.zebra_ibuf = NULL; + sseq->scopes.waveform_ibuf = NULL; + sseq->scopes.sep_waveform_ibuf = NULL; + sseq->scopes.vector_ibuf = NULL; + sseq->scopes.histogram_ibuf = NULL; + } else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; + sbuts->path= NULL; sbuts->texuser= NULL; + sbuts->mainbo = sbuts->mainb; + sbuts->mainbuser = sbuts->mainb; } else if (sl->spacetype == SPACE_CONSOLE) { SpaceConsole *sconsole = (SpaceConsole *)sl; @@ -6023,6 +6354,14 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sfile->op = NULL; sfile->params = newdataadr(fd, sfile->params); } + else if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + sclip->scopes.track_search = NULL; + sclip->scopes.track_preview = NULL; + sclip->draw_context = NULL; + sclip->scopes.ok = 0; + } } sa->actionzones.first = sa->actionzones.last = NULL; @@ -6041,6 +6380,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) { Main *newmain; + /* check if the library was already read */ for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) { if (newmain->curlib) { if (BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) { @@ -6059,14 +6399,14 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) } } } - /* make sure we have full path in lib->filename */ + /* make sure we have full path in lib->filepath */ BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name)); - cleanup_path(fd->relabase, lib->filepath); + BLI_cleanup_path(fd->relabase, lib->filepath); -#if 0 - printf("direct_link_library: name %s\n", lib->name); - printf("direct_link_library: filename %s\n", lib->filename); -#endif +// printf("direct_link_library: name %s\n", lib->name); +// printf("direct_link_library: filepath %s\n", lib->filepath); + + lib->packedfile = direct_link_packedfile(fd, lib->packedfile); /* new main */ newmain= MEM_callocN(sizeof(Main), "directlink"); @@ -6256,6 +6596,9 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip) clip->tracking.dopesheet.ok = 0; clip->tracking.dopesheet.channels.first = clip->tracking.dopesheet.channels.last = NULL; + clip->tracking.dopesheet.coverage_segments.first = clip->tracking.dopesheet.coverage_segments.last = NULL; + + clip->prefetch_ok = FALSE; link_list(fd, &tracking->objects); @@ -6389,6 +6732,179 @@ static void lib_link_mask(FileData *fd, Main *main) } } +/* ************ READ LINE STYLE ***************** */ + +static void lib_link_linestyle(FileData *fd, Main *main) +{ + FreestyleLineStyle *linestyle; + LineStyleModifier *m; + + linestyle = main->linestyle.first; + while (linestyle) { + if (linestyle->id.flag & LIB_NEED_LINK) { + linestyle->id.flag -= LIB_NEED_LINK; + + if (linestyle->id.properties) + IDP_LibLinkProperty(linestyle->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + if (linestyle->adt) + lib_link_animdata(fd, &linestyle->id, linestyle->adt); + for (m = linestyle->color_modifiers.first; m; m = m->next) { + switch (m->type) { + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleColorModifier_DistanceFromObject *cm = (LineStyleColorModifier_DistanceFromObject *)m; + cm->target = newlibadr(fd, linestyle->id.lib, cm->target); + } + break; + } + } + for (m = linestyle->alpha_modifiers.first; m; m = m->next){ + switch (m->type) { + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleAlphaModifier_DistanceFromObject *am = (LineStyleAlphaModifier_DistanceFromObject *)m; + am->target = newlibadr(fd, linestyle->id.lib, am->target); + } + break; + } + } + for (m = linestyle->thickness_modifiers.first; m; m = m->next){ + switch (m->type) { + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleThicknessModifier_DistanceFromObject *tm = (LineStyleThicknessModifier_DistanceFromObject *)m; + tm->target = newlibadr(fd, linestyle->id.lib, tm->target); + } + break; + } + } + } + linestyle = linestyle->id.next; + } +} + +static void direct_link_linestyle_color_modifier(FileData *fd, LineStyleModifier *modifier) +{ + switch (modifier->type) { + case LS_MODIFIER_ALONG_STROKE: + { + LineStyleColorModifier_AlongStroke *m = (LineStyleColorModifier_AlongStroke *)modifier; + m->color_ramp = newdataadr(fd, m->color_ramp); + } + break; + case LS_MODIFIER_DISTANCE_FROM_CAMERA: + { + LineStyleColorModifier_DistanceFromCamera *m = (LineStyleColorModifier_DistanceFromCamera *)modifier; + m->color_ramp = newdataadr(fd, m->color_ramp); + } + break; + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleColorModifier_DistanceFromObject *m = (LineStyleColorModifier_DistanceFromObject *)modifier; + m->color_ramp = newdataadr(fd, m->color_ramp); + } + break; + case LS_MODIFIER_MATERIAL: + { + LineStyleColorModifier_Material *m = (LineStyleColorModifier_Material *)modifier; + m->color_ramp = newdataadr(fd, m->color_ramp); + } + break; + } +} + +static void direct_link_linestyle_alpha_modifier(FileData *fd, LineStyleModifier *modifier) +{ + switch (modifier->type) { + case LS_MODIFIER_ALONG_STROKE: + { + LineStyleAlphaModifier_AlongStroke *m = (LineStyleAlphaModifier_AlongStroke *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_DISTANCE_FROM_CAMERA: + { + LineStyleAlphaModifier_DistanceFromCamera *m = (LineStyleAlphaModifier_DistanceFromCamera *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleAlphaModifier_DistanceFromObject *m = (LineStyleAlphaModifier_DistanceFromObject *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_MATERIAL: + { + LineStyleAlphaModifier_Material *m = (LineStyleAlphaModifier_Material *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + } +} + +static void direct_link_linestyle_thickness_modifier(FileData *fd, LineStyleModifier *modifier) +{ + switch (modifier->type) { + case LS_MODIFIER_ALONG_STROKE: + { + LineStyleThicknessModifier_AlongStroke *m = (LineStyleThicknessModifier_AlongStroke *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_DISTANCE_FROM_CAMERA: + { + LineStyleThicknessModifier_DistanceFromCamera *m = (LineStyleThicknessModifier_DistanceFromCamera *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_DISTANCE_FROM_OBJECT: + { + LineStyleThicknessModifier_DistanceFromObject *m = (LineStyleThicknessModifier_DistanceFromObject *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + case LS_MODIFIER_MATERIAL: + { + LineStyleThicknessModifier_Material *m = (LineStyleThicknessModifier_Material *)modifier; + m->curve = newdataadr(fd, m->curve); + direct_link_curvemapping(fd, m->curve); + } + break; + } +} + +static void direct_link_linestyle_geometry_modifier(FileData *UNUSED(fd), LineStyleModifier *UNUSED(modifier)) +{ +} + +static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle) +{ + LineStyleModifier *modifier; + + linestyle->adt= newdataadr(fd, linestyle->adt); + direct_link_animdata(fd, linestyle->adt); + link_list(fd, &linestyle->color_modifiers); + for(modifier = linestyle->color_modifiers.first; modifier; modifier = modifier->next) + direct_link_linestyle_color_modifier(fd, modifier); + link_list(fd, &linestyle->alpha_modifiers); + for(modifier = linestyle->alpha_modifiers.first; modifier; modifier = modifier->next) + direct_link_linestyle_alpha_modifier(fd, modifier); + link_list(fd, &linestyle->thickness_modifiers); + for(modifier = linestyle->thickness_modifiers.first; modifier; modifier = modifier->next) + direct_link_linestyle_thickness_modifier(fd, modifier); + link_list(fd, &linestyle->geometry_modifiers); + for(modifier = linestyle->geometry_modifiers.first; modifier; modifier = modifier->next) + direct_link_linestyle_geometry_modifier(fd, modifier); +} + /* ************** GENERAL & MAIN ******************** */ @@ -6423,6 +6939,7 @@ static const char *dataname(short id_code) case ID_PA: return "Data from PA"; case ID_GD: return "Data from GD"; case ID_MC: return "Data from MC"; + case ID_LS: return "Data from LS"; } return "Data from Lib Block"; @@ -6599,6 +7116,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_MSK: direct_link_mask(fd, (Mask *)id); break; + case ID_LS: + direct_link_linestyle(fd, (FreestyleLineStyle *)id); + break; } oldnewmap_free_unused(fd->datamap); @@ -6625,6 +7145,17 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->globalf = fg->globalf; BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename)); + /* error in 2.65 and older: main->name was not set if you save from startup (not after loading file) */ + if (bfd->filename[0] == 0) { + if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1)) + if ((G.fileflags & G_FILE_RECOVER)==0) + BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename)); + + /* early 2.50 version patch - filename not in FileGlobal struct at all */ + if (fd->fileversion <= 250) + BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename)); + } + if (G.fileflags & G_FILE_RECOVER) BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase)); @@ -6650,7 +7181,6 @@ static void link_global(FileData *fd, BlendFileData *bfd) } } -/* deprecated, only keep this for readfile.c */ void convert_tface_mt(FileData *fd, Main *main) { Main *gmain; @@ -6685,22 +7215,6 @@ static void do_versions_nodetree_image_default_alpha_output(bNodeTree *ntree) } } -static void do_version_ntree_tex_mapping_260(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_MAPPING) { - TexMapping *tex_mapping; - - tex_mapping= node->storage; - tex_mapping->projx= PROJ_X; - tex_mapping->projy= PROJ_Y; - tex_mapping->projz= PROJ_Z; - } - } -} - static void do_versions_nodetree_convert_angle(bNodeTree *ntree) { bNode *node; @@ -6922,7 +7436,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo nimf->format = sce->r.im_format; /* transfer render format toggle to node format toggle */ - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { NodeImageMultiFileSocket *simf = sock->storage; simf->use_node_format = simf->use_render_format; } @@ -6976,7 +7490,7 @@ static void do_versions_nodetree_file_output_layers_2_64_5(bNodeTree *ntree) for (node=ntree->nodes.first; node; node=node->next) { if (node->type == CMP_NODE_OUTPUT_FILE) { bNodeSocket *sock; - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { NodeImageMultiFileSocket *input = sock->storage; /* multilayer names are stored as separate strings now, @@ -7035,123 +7549,6 @@ static void do_versions_nodetree_frame_2_64_6(bNodeTree *ntree) } } -static void do_version_ntree_image_user_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) { - NodeTexImage *tex = node->storage; - - tex->iuser.frames= 1; - tex->iuser.sfra= 1; - tex->iuser.fie_ima= 2; - tex->iuser.ok= 1; - } - } -} - -static void do_version_ntree_dilateerode_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_DILATEERODE) { - if (node->storage == NULL) { - NodeDilateErode *data = MEM_callocN(sizeof(NodeDilateErode), __func__); - data->falloff = PROP_SMOOTH; - node->storage = data; - } - } - } -} - -static void do_version_ntree_defocus_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_DEFOCUS) { - NodeDefocus *data = node->storage; - if (data->maxblur == 0.0f) { - data->maxblur = 16.0f; - } - } - } -} - -static void do_version_ntree_mask_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_MASK) { - if (node->storage == NULL) { - NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__); - /* move settings into own struct */ - data->size_x = (int)node->custom3; - data->size_y = (int)node->custom4; - node->custom3 = 0.5f; /* default shutter */ - node->storage = data; - } - } - } -} - -static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_KEYING) { - NodeKeyingData *data = node->storage; - - if (data->despill_balance == 0.0f) { - data->despill_balance = 0.5f; - } - } - } -} - -static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) - if (node->type == SH_NODE_TEX_COORD) - node->flag |= NODE_OPTIONS; -} - -static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - bNodeSocket *sock; - - for (node = ntree->nodes.first; node; node = node->next) { - if (!ELEM(node->type, NODE_GROUP, CMP_NODE_IMAGE)) { - for (sock = node->inputs.first; sock; sock = sock->next) - sock->flag &= ~SOCK_DYNAMIC; - for (sock = node->outputs.first; sock; sock = sock->next) - sock->flag &= ~SOCK_DYNAMIC; - } - } -} - -static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) -{ - bNode *node; - bNodeLink *link, *nextlink; - - for (node = ntree->nodes.first; node; node = node->next) { - for (link = node->internal_links.first; link; link = nextlink) { - nextlink = link->next; - if (!link->fromnode || !link->fromsock || !link->tonode || !link->tosock) { - BLI_remlink(&node->internal_links, link); - } - } - } -} - static void do_version_logic_264(ListBase *regionbase) { ARegion *ar; @@ -7204,6 +7601,171 @@ static void do_versions_affine_tracker_track(MovieTrackingTrack *track) } +static const char *node_get_static_idname(int type, int treetype) +{ + /* use static type info header to map static int type to identifier string */ + #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ + case ID: return #Category #StructName; + + /* XXX hack, group types share a single static integer identifier, but are registered as separate types */ + if (type == NODE_GROUP) { + switch (treetype) { + case NTREE_COMPOSIT: return "CompositorNodeGroup"; + case NTREE_SHADER: return "ShaderNodeGroup"; + case NTREE_TEXTURE: return "TextureNodeGroup"; + } + } + else { + switch (type) { + #include "NOD_static_types.h" + } + } + return ""; +} + +static const char *node_socket_get_static_idname(bNodeSocket *sock) +{ + switch (sock->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *dval = sock->default_value; + return nodeStaticSocketType(SOCK_FLOAT, dval->subtype); + } + case SOCK_INT: { + bNodeSocketValueInt *dval = sock->default_value; + return nodeStaticSocketType(SOCK_INT, dval->subtype); + } + case SOCK_BOOLEAN: { + return nodeStaticSocketType(SOCK_BOOLEAN, PROP_NONE); + } + case SOCK_VECTOR: { + bNodeSocketValueVector *dval = sock->default_value; + return nodeStaticSocketType(SOCK_VECTOR, dval->subtype); + } + case SOCK_RGBA: { + return nodeStaticSocketType(SOCK_RGBA, PROP_NONE); + } + case SOCK_STRING: { + bNodeSocketValueString *dval = sock->default_value; + return nodeStaticSocketType(SOCK_STRING, dval->subtype); + } + case SOCK_SHADER: { + return nodeStaticSocketType(SOCK_SHADER, PROP_NONE); + } + } + return ""; +} + +static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_group)) +{ + /* initialize node tree type idname */ + { + bNode *node; + bNodeSocket *sock; + + ntree->typeinfo = NULL; + + /* tree type idname */ + switch (ntree->type) { + case NTREE_COMPOSIT: + strcpy(ntree->idname, "CompositorNodeTree"); + break; + case NTREE_SHADER: + strcpy(ntree->idname, "ShaderNodeTree"); + break; + case NTREE_TEXTURE: + strcpy(ntree->idname, "TextureNodeTree"); + break; + } + + /* node type idname */ + for (node=ntree->nodes.first; node; node=node->next) { + BLI_strncpy(node->idname, node_get_static_idname(node->type, ntree->type), sizeof(node->idname)); + + /* existing old nodes have been initialized already */ + node->flag |= NODE_INIT; + + /* sockets idname */ + for (sock = node->inputs.first; sock; sock = sock->next) + BLI_strncpy(sock->idname, node_socket_get_static_idname(sock), sizeof(sock->idname)); + for (sock = node->outputs.first; sock; sock = sock->next) + BLI_strncpy(sock->idname, node_socket_get_static_idname(sock), sizeof(sock->idname)); + } + /* tree sockets idname */ + for (sock = ntree->inputs.first; sock; sock = sock->next) + BLI_strncpy(sock->idname, node_socket_get_static_idname(sock), sizeof(sock->idname)); + for (sock = ntree->outputs.first; sock; sock = sock->next) + BLI_strncpy(sock->idname, node_socket_get_static_idname(sock), sizeof(sock->idname)); + } + + /* initialize socket in_out values */ + { + bNode *node; + bNodeSocket *sock; + + for (node=ntree->nodes.first; node; node=node->next) { + for (sock = node->inputs.first; sock; sock = sock->next) + sock->in_out = SOCK_IN; + for (sock = node->outputs.first; sock; sock = sock->next) + sock->in_out = SOCK_OUT; + } + for (sock = ntree->inputs.first; sock; sock = sock->next) + sock->in_out = SOCK_IN; + for (sock = ntree->outputs.first; sock; sock = sock->next) + sock->in_out = SOCK_OUT; + } + + /* initialize socket identifier strings */ + { + bNode *node; + bNodeSocket *sock; + + for (node=ntree->nodes.first; node; node=node->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { + BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier)); + BLI_uniquename(&node->inputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier)); + } + for (sock = node->outputs.first; sock; sock = sock->next) { + BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier)); + BLI_uniquename(&node->outputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier)); + } + } + for (sock = ntree->inputs.first; sock; sock = sock->next) { + BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier)); + BLI_uniquename(&ntree->inputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier)); + } + for (sock = ntree->outputs.first; sock; sock = sock->next) { + BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier)); + BLI_uniquename(&ntree->outputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier)); + } + } +} + +/* initialize userdef with non-UI dependency stuff */ +/* other initializers (such as theme color defaults) go to resources.c */ +static void do_versions_userdef(FileData *fd, BlendFileData *bfd) +{ + Main *bmain = bfd->main; + UserDef *user = bfd->user; + + if (user == NULL) return; + + if (MAIN_VERSION_OLDER(bmain, 266, 4)) { + bTheme *btheme; + + /* themes for Node and Sequence editor were not using grid color, but back. we copy this over then */ + for (btheme = user->themes.first; btheme; btheme = btheme->next) { + copy_v4_v4_char(btheme->tnode.grid, btheme->tnode.back); + copy_v4_v4_char(btheme->tseq.grid, btheme->tseq.back); + } + } + + if (bmain->versionfile < 267) { + + if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit")) + user->image_gpubuffer_limit = 20; + + } +} static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7269,10 +7831,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 2)) { - bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_mapping_260); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_SHADER) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_MAPPING) { + TexMapping *tex_mapping; + + tex_mapping= node->storage; + tex_mapping->projx= PROJ_X; + tex_mapping->projy= PROJ_Y; + tex_mapping->projz= PROJ_Z; + } + } + } + } FOREACH_NODETREE_END } if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 4)) { @@ -7503,7 +8076,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (ob = main->object.first; ob; ob = ob->id.next) { bConstraint *con; for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = constraint_get_typeinfo(con); + bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); if (!cti) continue; @@ -7527,7 +8100,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) prop = BKE_bproperty_object_get(ob, "Text"); if (prop) { BKE_reportf_wrap(fd->reports, RPT_WARNING, - TIP_("Game property name conflict in object '%s':\ntext objects reserve the " + TIP_("Game property name conflict in object '%s': text objects reserve the " "['Text'] game property to change their content through logic bricks"), ob->id.name + 2); } @@ -7884,7 +8457,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (md->type == eModifierType_Smoke) { SmokeModifierData *smd = (SmokeModifierData *)md; if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { - int maxres = MAX3(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]); + int maxres = max_iii(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]); smd->domain->scale = smd->domain->dx * maxres; smd->domain->dx = 1.0f / smd->domain->scale; } @@ -7908,16 +8481,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 9)) { - bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_image_user_264); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_SHADER) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) { + NodeTexImage *tex = node->storage; + + tex->iuser.frames= 1; + tex->iuser.sfra= 1; + tex->iuser.fie_ima= 2; + tex->iuser.ok= 1; + } + } + } + } FOREACH_NODETREE_END } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 10)) { { Scene *scene; - bNodeTreeType *ntreetype; // composite redesign for (scene=main->scene.first; scene; scene=scene->id.next) { if (scene->nodetree) { @@ -7926,11 +8509,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - ntreetype = ntreeGetType(NTREE_COMPOSIT); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_defocus_264); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_DEFOCUS) { + NodeDefocus *data = node->storage; + if (data->maxblur == 0.0f) { + data->maxblur = 16.0f; + } + } + } + } + } FOREACH_NODETREE_END } { @@ -7988,19 +8580,40 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 13)) { - bNodeTreeType *ntreetype = ntreeGetType(NTREE_COMPOSIT); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_dilateerode_264); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_DILATEERODE) { + if (node->storage == NULL) { + NodeDilateErode *data = MEM_callocN(sizeof(NodeDilateErode), __func__); + data->falloff = PROP_SMOOTH; + node->storage = data; + } + } + } + } + } FOREACH_NODETREE_END } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 14)) { ParticleSettings *part; - bNodeTreeType *ntreetype = ntreeGetType(NTREE_COMPOSIT); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_keying_despill_balance); - + + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_KEYING) { + NodeKeyingData *data = node->storage; + + if (data->despill_balance == 0.0f) { + data->despill_balance = 0.5f; + } + } + } + } + } FOREACH_NODETREE_END + /* keep compatibility for dupliobject particle size */ for (part=main->particle.first; part; part=part->id.next) if (ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) @@ -8009,12 +8622,25 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 17)) { - bNodeTreeType *ntreetype = ntreeGetType(NTREE_COMPOSIT); - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_mask_264); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_MASK) { + if (node->storage == NULL) { + NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__); + /* move settings into own struct */ + data->size_x = (int)node->custom3; + data->size_y = (int)node->custom4; + node->custom3 = 0.5f; /* default shutter */ + node->storage = data; + } + } + } + } + } FOREACH_NODETREE_END } - + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 18)) { Scene *scene; @@ -8139,15 +8765,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 1)) { - bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); - bNodeTree *ntree; - - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_coord_from_dupli_264); - - for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) - if (ntree->type==NTREE_SHADER) - do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_SHADER) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) + if (node->type == SH_NODE_TEX_COORD) + node->flag |= NODE_OPTIONS; + } + } FOREACH_NODETREE_END } if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) { @@ -8233,28 +8858,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 4)) { - /* Fix for old node flags: Apparently the SOCK_DYNAMIC flag has been in use for other - * purposes before and then removed and later reused for SOCK_DYNAMIC. This socket should - * only be used by certain node types which don't use template lists, cleaning this up here. - */ - bNodeTreeType *ntreetype; - bNodeTree *ntree; - - ntreetype = ntreeGetType(NTREE_COMPOSIT); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); - ntreetype = ntreeGetType(NTREE_SHADER); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); - ntreetype = ntreeGetType(NTREE_TEXTURE); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); - - for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) - do_version_node_cleanup_dynamic_sockets_264(NULL, NULL, ntree); - } - if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 5)) { /* set a unwrapping margin and ABF by default */ Scene *scene; @@ -8271,22 +8874,19 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* Fix for bug #32982, internal_links list could get corrupted from r51630 onward. * Simply remove bad internal_links lists to avoid NULL pointers. */ - bNodeTreeType *ntreetype; - bNodeTree *ntree; - - ntreetype = ntreeGetType(NTREE_COMPOSIT); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); - ntreetype = ntreeGetType(NTREE_SHADER); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); - ntreetype = ntreeGetType(NTREE_TEXTURE); - if (ntreetype && ntreetype->foreach_nodetree) - ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); - - for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) - do_version_node_fix_internal_links_264(NULL, NULL, ntree); - + FOREACH_NODETREE(main, ntree, id) + bNode *node; + bNodeLink *link, *nextlink; + + for (node = ntree->nodes.first; node; node = node->next) { + for (link = node->internal_links.first; link; link = nextlink) { + nextlink = link->next; + if (!link->fromnode || !link->fromsock || !link->tonode || !link->tosock) { + BLI_remlink(&node->internal_links, link); + } + } + } + FOREACH_NODETREE_END } if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) { @@ -8382,8 +8982,390 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) { + bScreen *sc; + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + switch (sl->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d = (View3D *)sl; + v3d->flag2 |= V3D_SHOW_GPENCIL; + break; + } + case SPACE_SEQ: + { + SpaceSeq *sseq = (SpaceSeq *)sl; + sseq->flag |= SEQ_SHOW_GPENCIL; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = (SpaceImage *)sl; + sima->flag |= SI_SHOW_GPENCIL; + break; + } + case SPACE_NODE: + { + SpaceNode *snode = (SpaceNode *)sl; + snode->flag |= SNODE_SHOW_GPENCIL; + break; + } + case SPACE_CLIP: + { + SpaceClip *sclip = (SpaceClip *)sl; + sclip->flag |= SC_SHOW_GPENCIL; + break; + } + } + } + } + } + } + + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) { + Scene *scene; + Image *image; + Tex *tex; + + for (scene = main->scene.first; scene; scene = scene->id.next) { + Sequence *seq; + bool set_premul = false; + + SEQ_BEGIN (scene->ed, seq) + { + if (seq->flag & SEQ_MAKE_PREMUL) { + seq->alpha_mode = SEQ_ALPHA_STRAIGHT; + } + else { + BKE_sequence_alpha_mode_from_extension(seq); + } + } + SEQ_END + + if (scene->r.bake_samples == 0) + scene->r.bake_samples = 256; + + if (scene->world) { + World *world = blo_do_versions_newlibadr(fd, scene->id.lib, scene->world); + + if (world && is_zero_v3(&world->horr)) { + if ((world->skytype & WO_SKYBLEND) == 0 || is_zero_v3(&world->zenr)) { + set_premul = true; + } + } + } + else + set_premul = true; + + if (set_premul) { + printf("2.66 versioning fix: replacing black sky with premultiplied alpha for scene %s\n", scene->id.name + 2); + scene->r.alphamode = R_ALPHAPREMUL; + } + } + + for (image = main->image.first; image; image = image->id.next) { + if (image->flag & IMA_DO_PREMUL) { + image->alpha_mode = IMA_ALPHA_STRAIGHT; + } + else { + BKE_image_alpha_mode_from_extension(image); + } + } + + for (tex = main->tex.first; tex; tex = tex->id.next) { + if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) { + image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima); + + if (image && (image->flag & IMA_DO_PREMUL) == 0) + image->flag |= IMA_IGNORE_ALPHA; + } + } + + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_IMAGE) { + Image *image = blo_do_versions_newlibadr(fd, ntree->id.lib, node->id); + + if (image) { + if ((image->flag & IMA_DO_PREMUL) == 0 && image->alpha_mode == IMA_ALPHA_STRAIGHT) + node->custom1 |= CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT; + } + } + } + } + } FOREACH_NODETREE_END + } + else if (main->versionfile < 266 || (main->versionfile == 266 && main->subversionfile < 1)) { + /* texture use alpha was removed for 2.66 but added back again for 2.66a, + * for compatibility all textures assumed it to be enabled */ + Tex *tex; + + for (tex = main->tex.first; tex; tex = tex->id.next) + if (tex->type == TEX_IMAGE) + tex->imaflag |= TEX_USEALPHA; + } + + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { + Curve *cu; + + for (cu = main->curve.first; cu; cu = cu->id.next) { + if (cu->flag & (CU_FRONT | CU_BACK)) { + if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) { + Nurb *nu; + + for (nu = cu->nurb.first; nu; nu = nu->next) { + int a; + + if (nu->bezt) { + BezTriple *bezt = nu->bezt; + a = nu->pntsu; + + while (a--) { + bezt->radius = 1.0f; + bezt++; + } + } + else if (nu->bp) { + BPoint *bp = nu->bp; + a = nu->pntsu * nu->pntsv; + + while (a--) { + bp->radius = 1.0f; + bp++; + } + } + } + } + } + } + } + + if (MAIN_VERSION_OLDER(main, 265, 9)) { + Mesh *me; + for (me = main->mesh.first; me; me = me->id.next) { + BKE_mesh_do_versions_cd_flag_init(me); + } + } + + if (MAIN_VERSION_OLDER(main, 265, 10)) { + Brush *br; + for (br = main->brush.first; br; br = br->id.next) { + if (br->ob_mode & OB_MODE_TEXTURE_PAINT) { + br->mtex.brush_map_mode = MTEX_MAP_MODE_TILED; + } + } + } + + // add storage for compositor translate nodes when not existing + if (MAIN_VERSION_OLDER(main, 265, 11)) { + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_TRANSLATE && node->storage == NULL) { + node->storage = MEM_callocN(sizeof(NodeTranslateData), "node translate data"); + } + } + } + } FOREACH_NODETREE_END + } + + if (MAIN_VERSION_OLDER(main, 266, 2)) { + FOREACH_NODETREE(main, ntree, id) { + do_versions_nodetree_customnodes(ntree, ((ID *)ntree == id)); + } FOREACH_NODETREE_END + } + + if (MAIN_VERSION_OLDER(main, 266, 2)) { + bScreen *sc; + for (sc= main->screen.first; sc; sc= sc->id.next) { + ScrArea *sa; + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + for (sl= sa->spacedata.first; sl; sl= sl->next) { + if (sl->spacetype==SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + + /* reset pointers to force tree path update from context */ + snode->nodetree = NULL; + snode->edittree = NULL; + snode->id = NULL; + snode->from = NULL; + + /* convert deprecated treetype setting to tree_idname */ + switch (snode->treetype) { + case NTREE_COMPOSIT: + strcpy(snode->tree_idname, "CompositorNodeTree"); + break; + case NTREE_SHADER: + strcpy(snode->tree_idname, "ShaderNodeTree"); + break; + case NTREE_TEXTURE: + strcpy(snode->tree_idname, "TextureNodeTree"); + break; + } + } + } + } + } + } + + /* Set flag for delayed do_versions in lib_verify_nodetree. It needs valid typeinfo pointers ... */ + { + FOREACH_NODETREE(main, ntree, id) { + /* XXX This should be kept without version check for now! + * As long as USE_NODE_COMPAT_CUSTOMNODES is active, files will write links + * to tree interface sockets for forward compatibility. These links need to be removed again + * on file load in new versions. + * Once forward compatibility is not required any longer, make a subversion bump + * and only execute this for older versions. + */ + ntree->flag |= NTREE_DO_VERSIONS_CUSTOMNODES_GROUP; + + /* Only add interface nodes once. + * In old Blender versions they will be removed automatically due to undefined type */ + if (MAIN_VERSION_OLDER(main, 266, 2)) + ntree->flag |= NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE; + } + FOREACH_NODETREE_END + } + + if (MAIN_VERSION_OLDER(main, 266, 3)) { + { + /* Fix for a very old issue: + * Node names were nominally made unique in r24478 (2.50.8), but the do_versions check + * to update existing node names only applied to main->nodetree (i.e. group nodes). + * Uniqueness is now required for proper preview mapping, + * so do this now to ensure old files don't break. + */ + bNode *node; + FOREACH_NODETREE(main, ntree, id) { + if (id == &ntree->id) + continue; /* already fixed for node groups */ + + for (node = ntree->nodes.first; node; node = node->next) + nodeUniqueName(ntree, node); + } + FOREACH_NODETREE_END + } + } + + if (main->versionfile < 267) { + + /* TIP: to initialize new variables added, use the new function + DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname") + example: + if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit")) + user->image_gpubuffer_limit = 10; + */ + + } + + /* default values in Freestyle settings */ + { + Scene *sce; + SceneRenderLayer *srl; + FreestyleLineStyle *linestyle; + + for(sce = main->scene.first; sce; sce = sce->id.next) { + if (sce->r.line_thickness_mode == 0) { + sce->r.line_thickness_mode = R_LINE_THICKNESS_ABSOLUTE; + sce->r.unit_line_thickness = 1.0f; + } + for(srl = sce->r.layers.first; srl; srl = srl->next) { + if (srl->freestyleConfig.mode == 0) + srl->freestyleConfig.mode = FREESTYLE_CONTROL_EDITOR_MODE; + if (srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE || + srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL) { + srl->freestyleConfig.raycasting_algorithm = 0; /* deprecated */ + srl->freestyleConfig.flags |= FREESTYLE_CULLING; + } + } + } + for(linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) { +#if 1 + /* disable the Misc panel for now */ + if (linestyle->panel == LS_PANEL_MISC) { + linestyle->panel = LS_PANEL_STROKES; + } +#endif + if (linestyle->thickness_position == 0) { + linestyle->thickness_position = LS_THICKNESS_CENTER; + linestyle->thickness_ratio = 0.5f; + } + if (linestyle->chaining == 0) + linestyle->chaining = LS_CHAINING_PLAIN; + if (linestyle->rounds == 0) + linestyle->rounds = 3; + } + } + /* The code segment below will be removed when the trunk merger is done. + For now it is kept for backward compatibility, giving branch users time + to migrate to the new CustomData-based edge/face marks. */ + { + Mesh *me; + MEdge *medge; + MPoly *mpoly; + int i, found; + + for (me = main->mesh.first; me; me = me->id.next) { + /* Freestyle edge marks */ + found = 0; + medge = me->medge; + for (i = 0; i < me->totedge; i++) { + if (medge->flag & ME_FREESTYLE_EDGE) { + found = 1; + break; + } + medge++; + } + if (found) { + FreestyleEdge *fed = CustomData_add_layer(&me->edata, CD_FREESTYLE_EDGE, CD_CALLOC, NULL, me->totedge); + medge = me->medge; + for (i = 0; i < me->totedge; i++) { + if (medge->flag & ME_FREESTYLE_EDGE) { + medge->flag &= ~ME_FREESTYLE_EDGE; + fed->flag |= FREESTYLE_EDGE_MARK; + } + medge++; + fed++; + } + printf("Migrated to CustomData-based Freestyle edge marks\n"); + } + /* Freestyle face marks */ + found = 0; + mpoly = me->mpoly; + for (i = 0; i < me->totpoly; i++) { + if (mpoly->flag & ME_FREESTYLE_FACE) { + found = 1; + break; + } + mpoly++; + } + if (found) { + FreestyleFace *ffa = CustomData_add_layer(&me->pdata, CD_FREESTYLE_FACE, CD_CALLOC, NULL, me->totpoly); + mpoly = me->mpoly; + for (i = 0; i < me->totpoly; i++) { + if (mpoly->flag & ME_FREESTYLE_FACE) { + mpoly->flag &= ~ME_FREESTYLE_FACE; + ffa->flag |= FREESTYLE_FACE_MARK; + } + mpoly++; + ffa++; + } + printf("Migrated to CustomData-based Freestyle face marks\n"); + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ - /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ + /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ /* don't forget to set version number in blender.c! */ } @@ -8401,8 +9383,11 @@ static void lib_link_all(FileData *fd, Main *main) { oldnewmap_sort(fd); + /* No load UI for undo memfiles */ + if (fd->memfile == NULL) { lib_link_windowmanager(fd, main); lib_link_screen(fd, main); + } lib_link_scene(fd, main); lib_link_object(fd, main); lib_link_curve(fd, main); @@ -8428,6 +9413,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_particlesettings(fd, main); lib_link_movieclip(fd, main); lib_link_mask(fd, main); + lib_link_linestyle(fd, main); lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ @@ -8449,9 +9435,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) wmKeyMap *keymap; wmKeyMapItem *kmi; wmKeyMapDiffItem *kmdi; + bAddon *addon; bfd->user = user= read_struct(fd, bhead, "user def"); + /* User struct has separate do-version handling */ + user->versionfile = bfd->main->versionfile; + user->subversionfile = bfd->main->subversionfile; + /* read all data into fd->datamap */ bhead = read_data_into_oldnewmap(fd, bhead, "user def"); @@ -8487,6 +9478,13 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) direct_link_keymapitem(fd, kmi); } + for (addon = user->addons.first; addon; addon = addon->next) { + addon->prop = newdataadr(fd, addon->prop); + if (addon->prop) { + IDP_DirectLinkProperty(addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } + } + // XXX user->uifonts.first = user->uifonts.last= NULL; @@ -8565,9 +9563,11 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) } /* do before read_libraries, but skip undo case */ -// if (fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton) + if (fd->memfile==NULL) do_versions(fd, NULL, bfd->main); + do_versions_userdef(fd, bfd); + read_libraries(fd, &mainlist); blo_join_main(&mainlist); @@ -8610,7 +9610,7 @@ static void sort_bhead_old_map(FileData *fd) fd->tot_bheadmap = tot; if (tot == 0) return; - bhs = fd->bheadmap = MEM_mallocN(tot*sizeof(struct BHeadSort), STRINGIFY(BHeadSort)); + bhs = fd->bheadmap = MEM_mallocN(tot * sizeof(struct BHeadSort), "BHeadSort"); for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead), bhs++) { bhs->bhead = bhead; @@ -8675,9 +9675,10 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead) return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name)); } -static void expand_doit(FileData *fd, Main *mainvar, void *old) +static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) { BHead *bhead; + FileData *fd = fdhandle; ID *id; bhead = find_bhead(fd, old); @@ -8690,6 +9691,14 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) Library *lib = read_struct(fd, bheadlib, "Library"); Main *ptr = blo_find_main(fd, lib->name, fd->relabase); + if (ptr->curlib == NULL) { + const char *idname= bhead_id_name(fd, bhead); + + BKE_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB ERROR: Data refers to main .blend file: '%s' from %s"), + idname, mainvar->curlib->filepath); + return; + } + else id = is_yet_read(fd, ptr, bhead); if (id == NULL) { @@ -8744,7 +9753,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) } } - +static void (*expand_doit)(void *, Main *, void *); // XXX deprecated - old animation system static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo) @@ -9129,7 +10138,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) ced.fd = fd; ced.mainvar = mainvar; - id_loop_constraints(lb, expand_constraint_cb, &ced); + BKE_id_loop_constraints(lb, expand_constraint_cb, &ced); /* deprecated manual expansion stuff */ for (curcon = lb->first; curcon; curcon = curcon->next) { @@ -9335,13 +10344,19 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) if (ob->pd && ob->pd->tex) expand_doit(fd, mainvar, ob->pd->tex); - + + if (ob->rigidbody_constraint) { + expand_doit(fd, mainvar, ob->rigidbody_constraint->ob1); + expand_doit(fd, mainvar, ob->rigidbody_constraint->ob2); + } + } static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) { Base *base; SceneRenderLayer *srl; + FreestyleLineSet *lineset; for (base = sce->base.first; base; base = base->next) { expand_doit(fd, mainvar, base->object); @@ -9362,6 +10377,11 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) for (srl = sce->r.layers.first; srl; srl = srl->next) { expand_doit(fd, mainvar, srl->mat_override); expand_doit(fd, mainvar, srl->light_override); + for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { + if (lineset->group) + expand_doit(fd, mainvar, lineset->group); + expand_doit(fd, mainvar, lineset->linestyle); + } } if (sce->r.dometext) @@ -9381,6 +10401,11 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) } SEQ_END } + + if (sce->rigidbody_world) { + expand_doit(fd, mainvar, sce->rigidbody_world->group); + expand_doit(fd, mainvar, sce->rigidbody_world->constraints); + } #ifdef DURIAN_CAMERA_SWITCH { @@ -9455,20 +10480,44 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask) } } -static void expand_main(FileData *fd, Main *mainvar) +static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *linestyle) +{ + LineStyleModifier *m; + + if (linestyle->adt) + expand_animdata(fd, mainvar, linestyle->adt); + for (m = linestyle->color_modifiers.first; m; m = m->next) { + if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) + expand_doit(fd, mainvar, ((LineStyleColorModifier_DistanceFromObject *)m)->target); + } + for (m = linestyle->alpha_modifiers.first; m; m = m->next){ + if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) + expand_doit(fd, mainvar, ((LineStyleAlphaModifier_DistanceFromObject *)m)->target); + } + for (m = linestyle->thickness_modifiers.first; m; m = m->next){ + if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) + expand_doit(fd, mainvar, ((LineStyleThicknessModifier_DistanceFromObject *)m)->target); + } +} + +void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *)) +{ + expand_doit = expand_doit_func; +} + +void BLO_expand_main(void *fdhandle, Main *mainvar) { ListBase *lbarray[MAX_LIBARRAY]; + FileData *fd = fdhandle; ID *id; int a, do_it = TRUE; - if (fd == NULL) return; - while (do_it) { do_it = FALSE; a = set_listbasepointers(mainvar, lbarray); while (a--) { - id= lbarray[a]->first; + id = lbarray[a]->first; while (id) { if (id->flag & LIB_NEED_EXPAND) { switch (GS(id->name)) { @@ -9541,6 +10590,9 @@ static void expand_main(FileData *fd, Main *mainvar) case ID_MSK: expand_mask(fd, mainvar, (Mask *)id); break; + case ID_LS: + expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id); + break; } do_it = TRUE; @@ -9553,6 +10605,9 @@ static void expand_main(FileData *fd, Main *mainvar) } } + +/* ***************************** */ + static int object_in_any_scene(Main *mainvar, Object *ob) { Scene *sce; @@ -9565,7 +10620,7 @@ static int object_in_any_scene(Main *mainvar, Object *ob) return 0; } -static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const short is_link) +static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const short is_link, const short active_lay) { Object *ob; Base *base; @@ -9608,7 +10663,10 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const if (do_it) { base = MEM_callocN(sizeof(Base), "add_ext_base"); - BLI_addtail(&(sce->base), base); + BLI_addtail(&sce->base, base); + + if (active_lay) ob->lay = sce->lay; + base->lay = ob->lay; base->object = ob; base->flag = ob->flag; @@ -9632,7 +10690,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene) Base *base; /* BKE_object_add(...) messes with the selection */ - Object *ob = BKE_object_add_only_object(OB_EMPTY, group->id.name+2); + Object *ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2); ob->type = OB_EMPTY; ob->lay = scene->lay; @@ -9640,13 +10698,13 @@ static void give_base_to_groups(Main *mainvar, Scene *scene) base = BKE_scene_base_add(scene, ob); base->flag |= SELECT; base->object->flag= base->flag; - ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; + DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); scene->basact = base; /* assign the group */ ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; - rename_id(&ob->id, group->id.name+2); + rename_id(&ob->id, group->id.name + 2); copy_v3_v3(ob->loc, scene->cursor); } } @@ -9679,7 +10737,8 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons } else { /* already linked */ - printf("append: already linked\n"); + if (G.debug) + printf("append: already linked\n"); oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); if (id->flag & LIB_INDIRECT) { id->flag -= LIB_INDIRECT; @@ -9701,6 +10760,28 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons return (found) ? id : NULL; } +/* simple reader for copy/paste buffers */ +void BLO_library_append_all(Main *mainl, BlendHandle *bh) +{ + FileData *fd = (FileData *)(bh); + BHead *bhead; + ID *id = NULL; + + for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) { + if (bhead->code == ENDB) + break; + if (bhead->code == ID_OB) + read_libblock(fd, mainl, bhead, LIB_TESTIND, &id); + + if (id) { + /* sort by name in list */ + ListBase *lb = which_libbase(mainl, GS(id->name)); + id_sort_by_name(lb, id); + } + } +} + + static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag) { ID *id= append_named_part(mainl, fd, idname, idcode); @@ -9805,8 +10886,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in Main *mainvar; Library *curlib; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + /* make main consistent */ - expand_main(*fd, mainl); + BLO_expand_main(*fd, mainl); /* do this when expand found other libs */ read_libraries(*fd, (*fd)->mainlist); @@ -9841,7 +10925,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in /* don't instance anything when linking in scenes, assume the scene its self instances the data */ } else { - give_base_to_objects(mainvar, scene, curlib, idcode, is_link); + give_base_to_objects(mainvar, scene, curlib, idcode, is_link, flag & FILE_ACTIVELAY); if (flag & FILE_GROUP_INSTANCE) { give_base_to_groups(mainvar, scene); @@ -9901,6 +10985,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ListBase *lbarray[MAX_LIBARRAY]; int a, do_it = TRUE; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + while (do_it) { do_it = FALSE; @@ -9914,12 +11001,26 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) FileData *fd = mainptr->curlib->filedata; if (fd == NULL) { + /* printf and reports for now... its important users know this */ - BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"), - mainptr->curlib->filepath, mainptr->curlib->name); - fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); - + /* if packed file... */ + if (mainptr->curlib->packedfile) { + PackedFile *pf = mainptr->curlib->packedfile; + + BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"), + mainptr->curlib->name); + fd = blo_openblendermemory(pf->data, pf->size, basefd->reports); + + + /* needed for library_append and read_libraries */ + BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase)); + } + else { + BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"), + mainptr->curlib->filepath, mainptr->curlib->name); + fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); + } /* allow typing in a new lib path */ if (G.debug_value == -666) { while (fd == NULL) { @@ -9933,7 +11034,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (scanf("%s", newlib_path) > 0) { BLI_strncpy(mainptr->curlib->name, newlib_path, sizeof(mainptr->curlib->name)); BLI_strncpy(mainptr->curlib->filepath, newlib_path, sizeof(mainptr->curlib->filepath)); - cleanup_path(G.main->name, mainptr->curlib->filepath); + BLI_cleanup_path(G.main->name, mainptr->curlib->filepath); fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -9965,7 +11066,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* subversion */ read_file_version(fd, mainptr); } - else mainptr->curlib->filedata = NULL; + else { + mainptr->curlib->filedata = NULL; + } if (fd == NULL) { BKE_reportf_wrap(basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"), @@ -9989,7 +11092,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) BKE_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB ERROR: %s: '%s' missing from '%s'"), BKE_idcode_to_name(GS(id->name)), - id->name+2, mainptr->curlib->filepath); + id->name + 2, mainptr->curlib->filepath); } change_idid_adr(mainlist, basefd, id, realid); @@ -10000,7 +11103,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } } - expand_main(fd, mainptr); + BLO_expand_main(fd, mainptr); } } |