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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r--source/blender/blenloader/intern/readfile.c2213
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);
}
}