Corrections to alpha pipeline do_versions
[blender.git] / source / blender / blenloader / intern / readfile.c
index 6658be9..93bc050 100644 (file)
@@ -81,6 +81,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"
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
 
+#include "BLF_translation.h"
+
 #include "BKE_anim.h"
 #include "BKE_action.h"
 #include "BKE_armature.h"
  * - join all Mains
  * - link all LibBlocks and indirect pointers to libblocks
  * - 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]) */
+ */
 
 /***/
 
@@ -358,36 +347,39 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
 }
 
 /* for libdata, nr has ID code, no increment */
-static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib) 
+static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
 {
-       int i;
-       
-       if (addr == NULL) return NULL;
-       
+       if (addr == NULL) {
+               return NULL;
+       }
+
        /* lasthit works fine for non-libdata, linking there is done in same sequence as writing */
        if (onm->sorted) {
                OldNew entry_s, *entry;
-               
+
                entry_s.old = addr;
-               
+
                entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
                if (entry) {
                        ID *id = entry->newp;
-                       
+
                        if (id && (!lib || id->lib)) {
-                               return entry->newp;
+                               return id;
                        }
                }
        }
-       
-       for (i = 0; i < onm->nentries; i++) {
-               OldNew *entry = &onm->entries[i];
-               
-               if (entry->old == addr) {
-                       ID *id = entry->newp;
-                       
-                       if (id && (!lib || id->lib)) {
-                               return entry->newp;
+       else {
+               /* note, this can be a bottle neck when loading some files */
+               unsigned int nentries = (unsigned int)onm->nentries;
+               unsigned int i;
+               OldNew *entry;
+
+               for (i = 0, entry = onm->entries; i < nentries; i++, entry++) {
+                       if (entry->old == addr) {
+                               ID *id = id = entry->newp;
+                               if (id && (!lib || id->lib)) {
+                                       return id;
+                               }
                        }
                }
        }
@@ -538,7 +530,9 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
        
        BLI_strncpy(name1, filepath, sizeof(name1));
        cleanup_path(relabase, name1);
-//     printf("blo_find_main: original in  %s\n", name);
+       
+//     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) {
@@ -816,7 +810,7 @@ static void decode_blender_header(FileData *fd)
                        /* is the file saved in a different endian
                         * than we need ?
                         */
-                       if (((((char*)&remove_this_endian_test)[0]==1)?L_ENDIAN:B_ENDIAN) != ((header[8]=='v')?L_ENDIAN:B_ENDIAN)) {
+                       if (((((char *)&remove_this_endian_test)[0] == 1) ? L_ENDIAN : B_ENDIAN) != ((header[8] == 'v') ? L_ENDIAN : B_ENDIAN)) {
                                fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
                        }
                        
@@ -938,7 +932,7 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, unsigned int s
                        if (chunkoffset+readsize > chunk->size)
                                readsize= chunk->size-chunkoffset;
                        
-                       memcpy((char*)buffer + totread, chunk->buf + chunkoffset, readsize);
+                       memcpy((char *)buffer + totread, chunk->buf + chunkoffset, readsize);
                        totread += readsize;
                        filedata->seek += readsize;
                        seek += readsize;
@@ -976,13 +970,13 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
        
        if (fd->flags & FD_FLAGS_FILE_OK) {
                if (!read_file_dna(fd)) {
-                       BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", incomplete", fd->relabase);
+                       BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', incomplete", fd->relabase);
                        blo_freefiledata(fd);
                        fd = NULL;
                }
-       } 
+       }
        else {
-               BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", not a blend file", fd->relabase);
+               BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
                blo_freefiledata(fd);
                fd = NULL;
        }
@@ -999,7 +993,8 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports)
        gzfile = BLI_gzopen(filepath, "rb");
        
        if (gzfile == (gzFile)Z_NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file");
+               BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s",
+                           filepath, errno ? strerror(errno) : TIP_("unknown error reading file"));
                return NULL;
        }
        else {
@@ -1014,19 +1009,71 @@ FileData *blo_openblenderfile(const char *filepath, 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(void *mem, int memsize, ReportList *reports)
 {
        if (!mem || memsize<SIZEOFBLENDERHEADER) {
-               BKE_report(reports, RPT_ERROR, (mem)? "Unable to read": "Unable to open");
+               BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read"): TIP_("Unable to open"));
                return NULL;
        }
        else {
                FileData *fd = filedata_new();
+               char *cp = mem;
+               
                fd->buffer = mem;
                fd->buffersize = memsize;
-               fd->read = fd_read_from_memory;
-               fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
                
+               /* 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);
        }
 }
@@ -1034,7 +1081,7 @@ FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
 FileData *blo_openblendermemfile(MemFile *memfile, ReportList *reports)
 {
        if (!memfile) {
-               BKE_report(reports, RPT_ERROR, "Unable to open blend <memory>");
+               BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>");
                return NULL;
        }
        else {
@@ -1060,6 +1107,12 @@ 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);
                        fd->buffer = NULL;
@@ -1083,6 +1136,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)
@@ -1126,7 +1181,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
                /* the last part of the dir is a .blend file, no group follows */
                *fd = '/'; /* put back the removed slash separating the dir and the .blend file name */
        }
-       else {          
+       else {
                char *gp = fd + 1; // in case we have a .blend file, gp points to the group
                
                /* Find the last slash */
@@ -1148,25 +1203,33 @@ static void *newdataadr(FileData *fd, void *adr)                /* only direct databocks */
        return oldnewmap_lookup_and_inc(fd->datamap, adr);
 }
 
-static void *newglobadr(FileData *fd, void *adr)               /* direct datablocks with global linking */
+static void *newglobadr(FileData *fd, void *adr)           /* direct datablocks with global linking */
 {
        return oldnewmap_lookup_and_inc(fd->globmap, adr);
 }
 
-static void *newimaadr(FileData *fd, void *adr)                /* used to restore image data after undo */
+static void *newimaadr(FileData *fd, void *adr)                    /* used to restore image data after undo */
 {
        if (fd->imamap && adr)
                return oldnewmap_lookup_and_inc(fd->imamap, adr);
        return NULL;
 }
 
-static void *newmclipadr(FileData *fd, void *adr)              /* used to restore movie clip data after undo */
+static void *newmclipadr(FileData *fd, void *adr)      /* used to restore movie clip data after undo */
 {
        if (fd->movieclipmap && adr)
                return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
        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 */
 {
@@ -1290,6 +1353,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                        if (NULL == newimaadr(fd, ibuf)) {      /* so was restored */
                                BLI_remlink(&ima->ibufs, ibuf);
                                ima->bindcode = 0;
+                               ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                                ima->gputexture = NULL;
                        }
                }
@@ -1362,6 +1426,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)
@@ -1628,6 +1757,19 @@ static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endi
 {
 }
 
+/* ************ READ ID *************** */
+
+static void direct_link_id(FileData *fd, ID *id)
+{
+       /*link direct data of ID properties*/
+       if (id->properties) {
+               id->properties = newdataadr(fd, id->properties);
+               if (id->properties) { /* this case means the data was written incorrectly, it should not happen */
+                       IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               }
+       }
+}
+
 /* ************ READ CurveMapping *************** */
 
 /* cuma itself has been read! */
@@ -1688,10 +1830,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;
@@ -1709,6 +1851,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;
                }
        }
        
@@ -1719,7 +1862,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
 
 /* Legacy Data Support (for Version Patching) ----------------------------- */
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void lib_link_ipo(FileData *fd, Main *main)
 {
        Ipo *ipo;
@@ -1736,7 +1879,7 @@ static void lib_link_ipo(FileData *fd, Main *main)
        }
 }
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void direct_link_ipo(FileData *fd, Ipo *ipo)
 {
        IpoCurve *icu;
@@ -1750,7 +1893,7 @@ static void direct_link_ipo(FileData *fd, Ipo *ipo)
        }
 }
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
 {
        bActionStrip *strip;
@@ -1765,7 +1908,7 @@ static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
        }
 }
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void direct_link_nlastrips(FileData *fd, ListBase *strips)
 {
        bActionStrip *strip;
@@ -1776,7 +1919,7 @@ static void direct_link_nlastrips(FileData *fd, ListBase *strips)
                link_list(fd, &strip->modifiers);
 }
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
 {
        bConstraintChannel *chan;
@@ -1821,7 +1964,7 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
                        
                        for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
                                DRIVER_TARGETS_LOOPER(dvar)
-                               {       
+                               {
                                        /* only relink if still used */
                                        if (tarIndex < dvar->num_targets)
                                                dtar->id = newlibadr(fd, id->lib, dtar->id); 
@@ -1947,12 +2090,12 @@ static void lib_link_action(FileData *fd, Main *main)
                if (act->id.flag & LIB_NEED_LINK) {
                        act->id.flag -= LIB_NEED_LINK;
                        
-// XXX depreceated - old animation system <<<
+// XXX deprecated - old animation system <<<
                        for (chan=act->chanbase.first; chan; chan=chan->next) {
                                chan->ipo = newlibadr_us(fd, act->id.lib, chan->ipo);
                                lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
                        }
-// >>> XXX depreceated - old animation system
+// >>> XXX deprecated - old animation system
                        
                        lib_link_fcurves(fd, &act->id, &act->curves);
                }
@@ -1961,21 +2104,21 @@ static void lib_link_action(FileData *fd, Main *main)
 
 static void direct_link_action(FileData *fd, bAction *act)
 {
-       bActionChannel *achan; // XXX depreceated - old animation system
+       bActionChannel *achan; // XXX deprecated - old animation system
        bActionGroup *agrp;
 
        link_list(fd, &act->curves);
-       link_list(fd, &act->chanbase); // XXX depreceated - old animation system
+       link_list(fd, &act->chanbase); // XXX deprecated - old animation system
        link_list(fd, &act->groups);
        link_list(fd, &act->markers);
 
-// XXX depreceated - old animation system <<<
+// XXX deprecated - old animation system <<<
        for (achan = act->chanbase.first; achan; achan=achan->next) {
                achan->grp = newdataadr(fd, achan->grp);
                
                link_list(fd, &achan->constraintChannels);
        }
-// >>> XXX depreceated - old animation system
+// >>> XXX deprecated - old animation system
 
        direct_link_fcurves(fd, &act->curves);
        
@@ -2389,6 +2532,8 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        ntree->adt = newdataadr(fd, ntree->adt);
        direct_link_animdata(fd, ntree->adt);
        
+       ntree->id.flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);
+
        link_list(fd, &ntree->nodes);
        for (node = ntree->nodes.first; node; node = node->next) {
                node->typeinfo = NULL;
@@ -2396,6 +2541,14 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                link_list(fd, &node->inputs);
                link_list(fd, &node->outputs);
                
+               link_list(fd, &node->internal_links);
+               for (link = node->internal_links.first; link; link = link->next) {
+                       link->fromnode = newdataadr(fd, link->fromnode);
+                       link->fromsock = newdataadr(fd, link->fromsock);
+                       link->tonode = newdataadr(fd, link->tonode);
+                       link->tosock = newdataadr(fd, link->tosock);
+               }
+               
                if (node->type == CMP_NODE_MOVIEDISTORTION) {
                        node->storage = newmclipadr(fd, node->storage);
                }
@@ -2404,8 +2557,18 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                
                if (node->storage) {
                        /* could be handlerized at some point */
-                       if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
-                               direct_link_curvemapping(fd, node->storage);
+                       if (ntree->type==NTREE_SHADER) {
+                               if (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) {
+                                       direct_link_curvemapping(fd, node->storage);
+                               }
+                               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) {
                                if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
                                        direct_link_curvemapping(fd, node->storage);
@@ -2488,14 +2651,14 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                        con->type = CONSTRAINT_TYPE_NULL;
                }
                /* own ipo, all constraints have it */
-               con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX depreceated - old animation system
+               con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX deprecated - old animation system
        }
        
        /* relink all ID-blocks used by the constraints */
        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)
@@ -2516,27 +2679,33 @@ 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;
+
                                con->lin_error = 0.f;
                                con->rot_error = 0.f;
+
+                               /* 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;
+                       }
                }
        }
 }
@@ -2545,14 +2714,15 @@ static void lib_link_pose(FileData *fd, 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 */
@@ -2647,7 +2817,7 @@ static void lib_link_camera(FileData *fd, Main *main)
                if (ca->id.flag & LIB_NEED_LINK) {
                        if (ca->adt) lib_link_animdata(fd, &ca->id, ca->adt);
                        
-                       ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX depreceated - old animation system
+                       ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX deprecated - old animation system
                        
                        ca->dof_ob = newlibadr_us(fd, ca->id.lib, ca->dof_ob);
                        
@@ -2683,7 +2853,7 @@ static void lib_link_lamp(FileData *fd, Main *main)
                                }
                        }
                        
-                       la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX depreceated - old animation system
+                       la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system
                        
                        if (la->nodetree)
                                lib_link_ntree(fd, &la->id, la->nodetree);
@@ -2709,8 +2879,10 @@ static void direct_link_lamp(FileData *fd, Lamp *la)
                direct_link_curvemapping(fd, la->curfalloff);
 
        la->nodetree= newdataadr(fd, la->nodetree);
-       if (la->nodetree)
+       if (la->nodetree) {
+               direct_link_id(fd, &la->nodetree->id);
                direct_link_nodetree(fd, la->nodetree);
+       }
        
        la->preview = direct_link_preview_image(fd, la->preview);
 }
@@ -2740,7 +2912,7 @@ static void lib_link_key(FileData *fd, Main *main)
                if (key->id.flag & LIB_NEED_LINK) {
                        if (key->adt) lib_link_animdata(fd, &key->id, key->adt);
                        
-                       key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX depreceated - old animation system
+                       key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX deprecated - old animation system
                        key->from = newlibadr(fd, key->id.lib, key->from);
                        
                        key->id.flag -= LIB_NEED_LINK;
@@ -2773,7 +2945,7 @@ static void switch_endian_keyblock(Key *key, KeyBlock *kb)
                        
                        cp += 2;
                }
-               data+= elemsize;
+               data += elemsize;
        }
 }
 
@@ -2808,9 +2980,9 @@ static void lib_link_mball(FileData *fd, Main *main)
                        if (mb->adt) lib_link_animdata(fd, &mb->id, mb->adt);
                        
                        for (a = 0; a < mb->totcol; a++) 
-                               mb->mat[a]= newlibadr_us(fd, mb->id.lib, mb->mat[a]);
+                               mb->mat[a] = newlibadr_us(fd, mb->id.lib, mb->mat[a]);
                        
-                       mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX depreceated - old animation system
+                       mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX deprecated - old animation system
                        
                        mb->id.flag -= LIB_NEED_LINK;
                }
@@ -2846,7 +3018,7 @@ static void lib_link_world(FileData *fd, Main *main)
                if (wrld->id.flag & LIB_NEED_LINK) {
                        if (wrld->adt) lib_link_animdata(fd, &wrld->id, wrld->adt);
                        
-                       wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX depreceated - old animation system
+                       wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system
                        
                        for (a=0; a < MAX_MTEX; a++) {
                                mtex = wrld->mtex[a];
@@ -2876,8 +3048,10 @@ static void direct_link_world(FileData *fd, World *wrld)
        }
        
        wrld->nodetree = newdataadr(fd, wrld->nodetree);
-       if (wrld->nodetree)
+       if (wrld->nodetree) {
+               direct_link_id(fd, &wrld->nodetree->id);
                direct_link_nodetree(fd, wrld->nodetree);
+       }
        
        wrld->preview = direct_link_preview_image(fd, wrld->preview);
 }
@@ -2932,11 +3106,10 @@ 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);
-       link_list(fd, &text->markers);
        
        text->curl = newdataadr(fd, text->curl);
        text->sell = newdataadr(fd, text->sell);
@@ -2996,10 +3169,11 @@ static void direct_link_image(FileData *fd, Image *ima)
                link_ibuf_list(fd, &ima->ibufs);
        else
                ima->ibufs.first = ima->ibufs.last = NULL;
-       
+
        /* if not restored, we keep the binded opengl index */
        if (ima->ibufs.first == NULL) {
                ima->bindcode = 0;
+               ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                ima->gputexture = NULL;
        }
        
@@ -3043,11 +3217,11 @@ static void lib_link_curve(FileData *fd, Main *main)
                        cu->taperobj = newlibadr(fd, cu->id.lib, cu->taperobj);
                        cu->textoncurve = newlibadr(fd, cu->id.lib, cu->textoncurve);
                        cu->vfont = newlibadr_us(fd, cu->id.lib, cu->vfont);
-                       cu->vfontb = newlibadr_us(fd, cu->id.lib, cu->vfontb);                  
+                       cu->vfontb = newlibadr_us(fd, cu->id.lib, cu->vfontb);
                        cu->vfonti = newlibadr_us(fd, cu->id.lib, cu->vfonti);
                        cu->vfontbi = newlibadr_us(fd, cu->id.lib, cu->vfontbi);
                        
-                       cu->ipo = newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX depreceated - old animation system
+                       cu->ipo = newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX deprecated - old animation system
                        cu->key = newlibadr_us(fd, cu->id.lib, cu->key);
                        
                        cu->id.flag -= LIB_NEED_LINK;
@@ -3077,7 +3251,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
        cu->mat = newdataadr(fd, cu->mat);
        test_pointer_array(fd, (void **)&cu->mat);
        cu->str = newdataadr(fd, cu->str);
-       cu->strinfo= newdataadr(fd, cu->strinfo);       
+       cu->strinfo= newdataadr(fd, cu->strinfo);
        cu->tb = newdataadr(fd, cu->tb);
 
        if (cu->vfont == NULL) link_list(fd, &(cu->nurb));
@@ -3088,14 +3262,14 @@ static void direct_link_curve(FileData *fd, Curve *cu)
                if (cu->tb) {
                        memcpy(tb, cu->tb, cu->totbox*sizeof(TextBox));
                        MEM_freeN(cu->tb);
-                       cu->tb = tb;                    
+                       cu->tb = tb;
                }
                else {
                        cu->totbox = 1;
                        cu->actbox = 1;
                        cu->tb = tb;
                        cu->tb[0].w = cu->linewidth;
-               }               
+               }
                if (cu->wordspace == 0.0f) cu->wordspace = 1.0f;
        }
 
@@ -3158,7 +3332,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        tex->env = newdataadr(fd, tex->env);
        if (tex->env) {
                tex->env->ima = NULL;
-               memset(tex->env->cube, 0, 6*sizeof(void *));
+               memset(tex->env->cube, 0, 6 * sizeof(void *));
                tex->env->ok= 0;
        }
        tex->pd = newdataadr(fd, tex->pd);
@@ -3184,8 +3358,10 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        tex->ot = newdataadr(fd, tex->ot);
        
        tex->nodetree = newdataadr(fd, tex->nodetree);
-       if (tex->nodetree)
+       if (tex->nodetree) {
+               direct_link_id(fd, &tex->nodetree->id);
                direct_link_nodetree(fd, tex->nodetree);
+       }
        
        tex->preview = direct_link_preview_image(fd, tex->preview);
        
@@ -3244,8 +3420,10 @@ static void direct_link_material(FileData *fd, Material *ma)
        ma->ramp_spec = newdataadr(fd, ma->ramp_spec);
        
        ma->nodetree = newdataadr(fd, ma->nodetree);
-       if (ma->nodetree)
+       if (ma->nodetree) {
+               direct_link_id(fd, &ma->nodetree->id);
                direct_link_nodetree(fd, ma->nodetree);
+       }
        
        ma->preview = direct_link_preview_image(fd, ma->preview);
        ma->gpumaterial.first = ma->gpumaterial.last = NULL;
@@ -3260,7 +3438,7 @@ static const char *ptcache_data_struct[] = {
        "", // BPHYS_DATA_ROTATION
        "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
        "", // BPHYS_DATA_SIZE:
-       "", // BPHYS_DATA_TIMES:        
+       "", // BPHYS_DATA_TIMES:
        "BoidData" // case BPHYS_DATA_BOIDS:
 };
 static void direct_link_pointcache(FileData *fd, PointCache *cache)
@@ -3335,6 +3513,8 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
 {
        if (pd && pd->tex)
                pd->tex = newlibadr_us(fd, id->lib, pd->tex);
+       if (pd && pd->f_source)
+               pd->f_source = newlibadr_us(fd, id->lib, pd->f_source);
 }
 
 static void lib_link_particlesettings(FileData *fd, Main *main)
@@ -3347,7 +3527,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
        for (part = main->particle.first; part; part = part->id.next) {
                if (part->id.flag & LIB_NEED_LINK) {
                        if (part->adt) lib_link_animdata(fd, &part->id, part->adt);
-                       part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system
+                       part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX deprecated - old animation system
                        
                        part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
                        part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
@@ -3363,32 +3543,31 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
                        if (part->dupliweights.first && part->dup_group) {
                                int index_ok = 0;
                                /* check for old files without indices (all indexes 0) */
-                               dw = part->dupliweights.first;
                                if (part->dupliweights.first == part->dupliweights.last) {
                                        /* special case for only one object in the group */
                                        index_ok = 1;
                                }
-                               else { 
-                                       for (; dw; dw=dw->next) {
+                               else {
+                                       for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                                if (dw->index > 0) {
                                                        index_ok = 1;
                                                        break;
                                                }
                                        }
                                }
-                               
+
                                if (index_ok) {
                                        /* if we have indexes, let's use them */
-                                       dw = part->dupliweights.first;
-                                       for (; dw; dw=dw->next) {
+                                       for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                                GroupObject *go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index);
-                                               dw->ob = go ? go->ob : NULL;
+                                               dw->ob = go ? newlibadr(fd, part->id.lib, dw->ob) : NULL;
                                        }
                                }
                                else {
                                        /* otherwise try to get objects from own library (won't work on library linked groups) */
-                                       for (; dw; dw=dw->next)
+                                       for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                                dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+                                       }
                                }
                        }
                        else {
@@ -3567,10 +3746,10 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                        psys->clmd->clothObject = NULL;
                        
                        psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
-                       psys->clmd->sim_parms->effector_weights = NULL;
                        psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
                        
                        if (psys->clmd->sim_parms) {
+                               psys->clmd->sim_parms->effector_weights = NULL;
                                if (psys->clmd->sim_parms->presets > 10)
                                        psys->clmd->sim_parms->presets = 0;
                        }
@@ -3605,7 +3784,7 @@ static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
 
 static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
 {
-       int i;  
+       int i;
        for (i = 0; i < fdata->totlayer; i++) {
                CustomDataLayer *layer = &fdata->layers[i];
                
@@ -3624,12 +3803,13 @@ static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata
                
                if (layer->type == CD_MTEXPOLY) {
                        MTexPoly *tf= layer->data;
-                       int i;
+                       int j;
                        
-                       for (i = 0; i < totface; i++, tf++) {
+                       for (j = 0; j < totface; j++, tf++) {
                                tf->tpage = newlibadr(fd, me->id.lib, tf->tpage);
-                               if (tf->tpage && tf->tpage->id.us==0)
+                               if (tf->tpage && tf->tpage->id.us == 0) {
                                        tf->tpage->id.us = 1;
+                               }
                        }
                }
        }
@@ -3665,7 +3845,14 @@ static void lib_link_mesh(FileData *fd, Main *main)
                        if (me->mr && me->mr->levels.first)
                                lib_link_customdata_mtface(fd, me, &me->mr->fdata,
                                                           ((MultiresLevel*)me->mr->levels.first)->totface);
-                       
+               }
+       }
+
+       /* convert texface options to material */
+       convert_tface_mt(fd, main);
+
+       for (me = main->mesh.first; me; me = me->id.next) {
+               if (me->id.flag & LIB_NEED_LINK) {
                        /*check if we need to convert mfaces to mpolys*/
                        if (me->totface && !me->totpoly) {
                                /* temporarily switch main so that reading from
@@ -3677,18 +3864,11 @@ static void lib_link_mesh(FileData *fd, Main *main)
                                
                                G.main = gmain;
                        }
-               }
-       }
-
-       /* convert texface options to material */
-       convert_tface_mt(fd, main);
 
-       for (me = main->mesh.first; me; me = me->id.next) {
-               if (me->id.flag & LIB_NEED_LINK) {
                        /*
                         * Re-tessellate, even if the polys were just created from tessfaces, this
                         * is important because it:
-                        *  - fill the CD_POLYINDEX layer
+                        *  - fill the CD_ORIGINDEX layer
                         *  - gives consistency of tessface between loading from a file and
                         *    converting an edited BMesh back into a mesh (i.e. it replaces
                         *    quad tessfaces in a loaded mesh immediately, instead of lazily
@@ -3783,7 +3963,7 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
        /* annoying workaround for bug [#31079] loading legacy files with
         * no polygons _but_ have stale customdata */
        if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
-               memset(data, 0, sizeof(*data));
+               CustomData_reset(data);
                return;
        }
        
@@ -3841,35 +4021,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
        direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
        
-       
-#ifdef USE_BMESH_FORWARD_COMPAT
-       /* NEVER ENABLE THIS CODE INTO BMESH!
-        * THIS IS FOR LOADING BMESH INTO OLDER FILES ONLY */
-       mesh->mpoly = newdataadr(fd, mesh->mpoly);
-       mesh->mloop = newdataadr(fd, mesh->mloop);
-
-       direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
-       direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
-
-       if (mesh->mpoly) {
-               /* be clever and load polygons as mfaces */
-               mesh->totface= BKE_mesh_mpoly_to_mface(&mesh->fdata, &mesh->ldata, &mesh->pdata,
-                                                  mesh->totface, mesh->totloop, mesh->totpoly);
-               
-               CustomData_free(&mesh->pdata, mesh->totpoly);
-               memset(&mesh->pdata, 0, sizeof(CustomData));
-               mesh->totpoly = 0;
-               
-               CustomData_free(&mesh->ldata, mesh->totloop);
-               memset(&mesh->ldata, 0, sizeof(CustomData));
-               mesh->totloop = 0;
-               
-               mesh_update_customdata_pointers(mesh);
-       }
-
-#endif
-       
-       
        mesh->bb = NULL;
        mesh->edit_btmesh = NULL;
        
@@ -3937,7 +4088,7 @@ static void lib_link_latt(FileData *fd, Main *main)
                if (lt->id.flag & LIB_NEED_LINK) {
                        if (lt->adt) lib_link_animdata(fd, &lt->id, lt->adt);
                        
-                       lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX depreceated - old animation system
+                       lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX deprecated - old animation system
                        lt->key = newlibadr_us(fd, lt->id.lib, lt->key);
                        
                        lt->id.flag -= LIB_NEED_LINK;
@@ -3991,10 +4142,10 @@ static void lib_link_object(FileData *fd, Main *main)
                        if (ob->id.properties) IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
                        if (ob->adt) lib_link_animdata(fd, &ob->id, ob->adt);
                        
-// XXX depreceated - old animation system <<<                  
+// XXX deprecated - old animation system <<<
                        ob->ipo = newlibadr_us(fd, ob->id.lib, ob->ipo);
                        ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
-// >>> XXX depreceated - old animation system
+// >>> XXX deprecated - old animation system
 
                        ob->parent = newlibadr(fd, ob->id.lib, ob->parent);
                        ob->track = newlibadr(fd, ob->id.lib, ob->track);
@@ -4016,8 +4167,6 @@ static void lib_link_object(FileData *fd, Main *main)
                                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);
@@ -4073,16 +4222,16 @@ static void lib_link_object(FileData *fd, Main *main)
                        lib_link_pose(fd, ob, ob->pose);
                        lib_link_constraints(fd, &ob->id, &ob->constraints);
                        
-// XXX depreceated - old animation system <<<  
+// XXX deprecated - old animation system <<<
                        lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels);
                        lib_link_nlastrips(fd, &ob->id, &ob->nlastrips);
-// >>> XXX depreceated - old animation system
+// >>> XXX deprecated - old animation system
                        
                        for (paf = ob->effect.first; paf; paf = paf->next) {
                                if (paf->type == EFF_PARTICLE) {
                                        paf->group = newlibadr_us(fd, ob->id.lib, paf->group);
                                }
-                       }                               
+                       }
                        
                        for (sens = ob->sensors.first; sens; sens = sens->next) {
                                for (a = 0; a < sens->totlinks; a++)
@@ -4215,6 +4364,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);
+                       }
                }
        }
        
@@ -4346,10 +4500,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) {
                                        if (smd->domain->point_cache[1]) {
                                                PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]);
-                                               if (cache->flag & PTCACHE_FAKE_SMOKE)
-                                                       ; /* Smoke was already saved in "new format" and this cache is a fake one. */
-                                               else
+                                               if (cache->flag & PTCACHE_FAKE_SMOKE) {
+                                                       /* Smoke was already saved in "new format" and this cache is a fake one. */
+                                               }
+                                               else {
                                                        printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n");
+                                               }
                                                BKE_ptcache_free(cache);
                                        }
                                        smd->domain->ptcaches[1].first = NULL;
@@ -4362,19 +4518,27 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                smd->coll = NULL;
                                smd->flow = newdataadr(fd, smd->flow);
                                smd->flow->smd = smd;
+                               smd->flow->dm = NULL;
+                               smd->flow->verts_old = NULL;
+                               smd->flow->numverts = 0;
                                smd->flow->psys = newdataadr(fd, smd->flow->psys);
                        }
                        else if (smd->type == MOD_SMOKE_TYPE_COLL) {
                                smd->flow = NULL;
                                smd->domain = NULL;
                                smd->coll = newdataadr(fd, smd->coll);
-                               smd->coll->smd = smd;
                                if (smd->coll) {
-                                       smd->coll->points = NULL;
-                                       smd->coll->numpoints = 0;
+                                       smd->coll->smd = smd;
+                                       smd->coll->verts_old = NULL;
+                                       smd->coll->numverts = 0;
+                                       smd->coll->dm = NULL;
                                }
-                               else
+                               else {
                                        smd->type = 0;
+                                       smd->flow = NULL;
+                                       smd->domain = NULL;
+                                       smd->coll = NULL;
+                               }
                        }
                }
                else if (md->type == eModifierType_DynamicPaint) {
@@ -4537,10 +4701,10 @@ static void direct_link_object(FileData *fd, Object *ob)
                direct_link_motionpath(fd, ob->mpath);
        
        link_list(fd, &ob->defbase);
-// XXX depreceated - old animation system <<<
+// XXX deprecated - old animation system <<<
        direct_link_nlastrips(fd, &ob->nlastrips);
        link_list(fd, &ob->constraintChannels);
-// >>> XXX depreceated - old animation system 
+// >>> XXX deprecated - old animation system
        
        ob->mat= newdataadr(fd, ob->mat);
        test_pointer_array(fd, (void **)&ob->mat);
@@ -4604,7 +4768,7 @@ static void direct_link_object(FileData *fd, Object *ob)
        direct_link_partdeflect(ob->pd);
        ob->soft= newdataadr(fd, ob->soft);
        if (ob->soft) {
-               SoftBody *sb = ob->soft;                
+               SoftBody *sb = ob->soft;
                
                sb->bpoint = NULL;      // init pointers so it gets rebuilt nicely
                sb->bspring = NULL;
@@ -4628,6 +4792,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);
@@ -4781,8 +4959,7 @@ static void lib_link_scene(FileData *fd, Main *main)
                                base->object = newlibadr_us(fd, sce->id.lib, base->object);
                                
                                if (base->object == NULL) {
-                                       BKE_reportf_wrap(fd->reports, RPT_ERROR,
-                                                        "LIB ERROR: Object lost from scene:'%s\'",
+                                       BKE_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB ERROR: object lost from scene: '%s'"),
                                                         sce->id.name + 2);
                                        BLI_remlink(&sce->base, base);
                                        if (base == sce->basact) sce->basact = NULL;
@@ -4847,6 +5024,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);
@@ -4923,6 +5112,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
+       RigidBodyWorld *rbw;
        
        sce->theDag = NULL;
        sce->dagisvalid = 0;
@@ -4956,6 +5146,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) {
@@ -5048,7 +5248,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                                        ed->seqbasep = (ListBase *)(poin+offset);
                                else
                                        ed->seqbasep = &ed->seqbase;
-                       }                       
+                       }
                        /* stack */
                        link_list(fd, &(ed->metastack));
                        
@@ -5082,7 +5282,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        }
        if (sce->r.ffcodecdata.properties) {
                sce->r.ffcodecdata.properties = newdataadr(fd, sce->r.ffcodecdata.properties);
-               if (sce->r.ffcodecdata.properties) { 
+               if (sce->r.ffcodecdata.properties) {
                        IDP_DirectLinkProperty(sce->r.ffcodecdata.properties, 
                                (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
                }
@@ -5093,10 +5293,34 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        link_list(fd, &(sce->r.layers));
        
        sce->nodetree = newdataadr(fd, sce->nodetree);
-       if (sce->nodetree)
+       if (sce->nodetree) {
+               direct_link_id(fd, &sce->nodetree->id);
                direct_link_nodetree(fd, sce->nodetree);
+       }
 
        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 = rbw->pointcache->startframe;
+       }
 }
 
 /* ************ READ WM ***************** */
@@ -5123,6 +5347,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;
@@ -5194,27 +5419,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)
@@ -5268,18 +5472,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;
@@ -5311,12 +5506,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;
@@ -5331,7 +5520,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;
@@ -5348,7 +5536,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) {
@@ -5362,7 +5549,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                SpaceNode *snode = (SpaceNode *)sl;
                                                
                                                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 */
@@ -5383,19 +5569,12 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                else {
                                                        snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree);
                                                }
-                                               
-                                               snode->linkdrag.first = snode->linkdrag.last = NULL;
                                        }
                                        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;
@@ -5409,7 +5588,14 @@ static void lib_link_screen(FileData *fd, Main *main)
        }
 }
 
-/* Only for undo files, or to restore a screen after reading without UI... */
+/**
+ * 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) {
@@ -5422,7 +5608,14 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
                        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++;
+                                               if (user == 1) {
+                                                       if (idn->us == 0) {
+                                                               idn->us++;
+                                                       }
+                                               }
+                                               else if (user == 2) {
+                                                       id_us_ensure_real(idn);
+                                               }
                                                break;
                                        }
                                }
@@ -5588,7 +5781,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 */
@@ -5604,7 +5797,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;
@@ -5679,8 +5872,8 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
                                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;
                                }
@@ -5700,6 +5893,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);
 
@@ -5709,7 +5903,13 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                pa->activedata = NULL;
                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) {
@@ -5737,6 +5937,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));
 }
 
@@ -5805,6 +6006,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);
@@ -5853,6 +6055,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)
@@ -5881,6 +6084,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;
@@ -5913,6 +6117,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        snode->gpd = newdataadr(fd, snode->gpd);
                                        direct_link_gpencil(fd, snode->gpd);
                                }
+                               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;
@@ -5928,6 +6139,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
                                 *
@@ -5936,17 +6149,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;
@@ -5986,6 +6208,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;
@@ -6004,15 +6234,16 @@ 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) {
                                BKE_reportf_wrap(fd->reports, RPT_WARNING,
-                                                "Library '%s', '%s' had multiple instances, save and reload!",
+                                                TIP_("Library '%s', '%s' had multiple instances, save and reload!"),
                                                 lib->name, lib->filepath);
                                
                                change_idid_adr(fd->mainlist, fd, lib, newmain->curlib);
-//                             change_idid_adr_fd(fd, lib, newmain->curlib);
+/*                             change_idid_adr_fd(fd, lib, newmain->curlib); */
                                
                                BLI_remlink(&main->library, lib);
                                MEM_freeN(lib);
@@ -6022,12 +6253,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);
        
 //     printf("direct_link_library: name %s\n", lib->name);
-//     printf("direct_link_library: filename %s\n", lib->filename);
+//     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");
@@ -6130,7 +6363,7 @@ static void lib_link_sound(FileData *fd, Main *main)
        for (sound = main->sound.first; sound; sound = sound->id.next) {
                if (sound->id.flag & LIB_NEED_LINK) {
                        sound->id.flag -= LIB_NEED_LINK;
-                       sound->ipo = newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
+                       sound->ipo = newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system
                        
                        sound_load(main, sound);
                }
@@ -6464,6 +6697,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        bhead = read_data_into_oldnewmap(fd, bhead, allocname);
        
        /* init pointers direct data */
+       direct_link_id(fd, id);
+       
        switch (GS(id->name)) {
                case ID_WM:
                        direct_link_windowmanager(fd, (wmWindowManager *)id);
@@ -6560,14 +6795,6 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                        break;
        }
        
-       /*link direct data of ID properties*/
-       if (id->properties) {
-               id->properties = newdataadr(fd, id->properties);
-               if (id->properties) { /* this case means the data was written incorrectly, it should not happen */
-                       IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-               }
-       }
-       
        oldnewmap_free_unused(fd->datamap);
        oldnewmap_clear(fd->datamap);
        
@@ -6592,6 +6819,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));
        
@@ -6630,7 +6868,7 @@ void convert_tface_mt(FileData *fd, Main *main)
                G.main = main;
                
                if (!(do_version_tface(main, 1))) {
-                       BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem. Error in console");
+                       BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)");
                }
                
                //XXX hack, material.c uses G.main allover the place, instead of main
@@ -6687,7 +6925,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
                        /* Convert degrees to radians. */
                        NodeDefocus *nqd = node->storage;
                        /* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
-                       nqd->rotation = DEG2RADF(nqd->rotation*255.0f);
+                       nqd->rotation = DEG2RADF(nqd->rotation * 255.0f);
                }
                else if (node->type == CMP_NODE_CHROMA_MATTE) {
                        /* Convert degrees to radians. */
@@ -6699,7 +6937,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
                        /* Convert degrees to radians. */
                        NodeGlare *ndg = node->storage;
                        /* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
-                       ndg->angle_ofs = DEG2RADF(ndg->angle_ofs*255.0f);
+                       ndg->angle_ofs = DEG2RADF(ndg->angle_ofs * 255.0f);
                }
                /* XXX TexMapping struct is used by other nodes too (at least node_composite_mapValue),
                 *     but not the rot part...
@@ -6803,7 +7041,6 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree)
 static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNodeTree *ntree)
 {
        bNode *node;
-       bNodeSocket *sock;
        
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->type == CMP_NODE_OUTPUT_FILE) {
@@ -6880,6 +7117,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
                }
                else if (node->type==CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED) {
                        NodeImageMultiFile *nimf = node->storage;
+                       bNodeSocket *sock;
                        
                        /* CMP_NODE_OUTPUT_MULTI_FILE has been redeclared as CMP_NODE_OUTPUT_FILE */
                        node->type = CMP_NODE_OUTPUT_FILE;
@@ -7033,15 +7271,29 @@ static void do_version_ntree_dilateerode_264(void *UNUSED(data), ID *UNUSED(id),
        }
 }
 
-static void do_version_ntree_mask_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+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_MASK) {
-                       if (node->storage == NULL) {
-                               NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__);
-                               /* move settings into own struct */
+               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 */
@@ -7066,6 +7318,108 @@ static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUS
        }
 }
 
+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_translate_wrapping(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       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");
+               }
+       }
+}
+
+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;
+       
+       /* view settings for logic changed */
+       for (ar = regionbase->first; ar; ar = ar->next) {
+               if (ar->regiontype == RGN_TYPE_WINDOW) {
+                       if (ar->v2d.keeptot == 0) {
+                               ar->v2d.maxzoom = 1.5f;
+                               
+                               ar->v2d.keepzoom = V2D_KEEPZOOM | V2D_LIMITZOOM | V2D_KEEPASPECT;
+                               ar->v2d.keeptot = V2D_KEEPTOT_BOUNDS;
+                               ar->v2d.align = V2D_ALIGN_NO_POS_Y | V2D_ALIGN_NO_NEG_X;
+                               ar->v2d.keepofs = V2D_KEEPOFS_Y;
+                       }
+               }
+       }
+       
+
+}
+
+static void do_versions_affine_tracker_track(MovieTrackingTrack *track)
+{
+       int i;
+
+       for (i = 0; i < track->markersnr; i++) {
+               MovieTrackingMarker *marker = &track->markers[i];
+
+               if (is_zero_v2(marker->pattern_corners[0]) && is_zero_v2(marker->pattern_corners[1]) &&
+                   is_zero_v2(marker->pattern_corners[2]) && is_zero_v2(marker->pattern_corners[3]))
+                       {
+                               marker->pattern_corners[0][0] = track->pat_min[0];
+                               marker->pattern_corners[0][1] = track->pat_min[1];
+
+                               marker->pattern_corners[1][0] = track->pat_max[0];
+                               marker->pattern_corners[1][1] = track->pat_min[1];
+
+                               marker->pattern_corners[2][0] = track->pat_max[0];
+                               marker->pattern_corners[2][1] = track->pat_max[1];
+
+                               marker->pattern_corners[3][0] = track->pat_min[0];
+                               marker->pattern_corners[3][1] = track->pat_max[1];
+                       }
+
+               if (is_zero_v2(marker->search_min) && is_zero_v2(marker->search_max)) {
+                       copy_v2_v2(marker->search_min, track->search_min);
+                       copy_v2_v2(marker->search_max, track->search_max);
+               }
+       }
+}
+
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7179,9 +7533,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                v3d->bundle_drawtype = OB_PLAINAXES;
                                                }
                                                else if (sl->spacetype == SPACE_CLIP) {
-                                                       SpaceClip *sc = (SpaceClip *)sl;
-                                                       if (sc->scopes.track_preview_height == 0)
-                                                               sc->scopes.track_preview_height = 120;
+                                                       SpaceClip *sclip = (SpaceClip *)sl;
+                                                       if (sclip->scopes.track_preview_height == 0)
+                                                               sclip->scopes.track_preview_height = 120;
                                                }
                                        }
                                }
@@ -7261,10 +7615,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        if ( (ob->dsize[i] == 0.0f) || /* simple case, user never touched dsize */
                                             (ob->size[i]  == 0.0f))   /* cant scale the dsize to give a non zero result, so fallback to 1.0f */
                                        {
-                                               ob->dscale[i]= 1.0f;
+                                               ob->dscale[i] = 1.0f;
                                        }
                                        else {
-                                               ob->dscale[i]= (ob->size[i] + ob->dsize[i]) / ob->size[i];
+                                               ob->dscale[i] = (ob->size[i] + ob->dsize[i]) / ob->size[i];
                                        }
                                }
                        }
@@ -7365,7 +7719,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;
@@ -7389,8 +7743,8 @@ 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,
-                                                                "Game property name conflict in object: \"%s\".\nText objects reserve the "
-                                                                "[\"Text\"] game property to change their content through Logic Bricks.",
+                                                                TIP_("Game property name conflict in object '%s':\ntext objects reserve the "
+                                                                     "['Text'] game property to change their content through logic bricks"),
                                                                 ob->id.name + 2);
                                        }
                                }
@@ -7583,13 +7937,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if (main->versionfile < 263) {
                /* Default for old files is to save particle rotations to pointcache */
                ParticleSettings *part;
-               for (part = main->particle.first; part; part = part->id.next)
+               for (part = main->particle.first; part; part = part->id.next) {
                        part->flag |= PART_ROTATIONS;
-               {
-                       /* Default for old files is to save particle rotations to pointcache */
-                       ParticleSettings *part;
-                       for (part = main->particle.first; part; part = part->id.next)
-                               part->flag |= PART_ROTATIONS;
                }
        }
 
@@ -7751,7 +8100,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;
                                        }
@@ -7784,6 +8133,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        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) {
@@ -7792,6 +8142,11 @@ 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);
+                       
                }
 
                {
@@ -7833,32 +8188,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                        track = clip->tracking.tracks.first;
                        while (track) {
-                               int i;
-
-                               for (i = 0; i < track->markersnr; i++) {
-                                       MovieTrackingMarker *marker = &track->markers[i];
-
-                                       if (is_zero_v2(marker->pattern_corners[0]) && is_zero_v2(marker->pattern_corners[1]) &&
-                                           is_zero_v2(marker->pattern_corners[2]) && is_zero_v2(marker->pattern_corners[3]))
-                                       {
-                                               marker->pattern_corners[0][0] = track->pat_min[0];
-                                               marker->pattern_corners[0][1] = track->pat_min[1];
-
-                                               marker->pattern_corners[1][0] = track->pat_max[0];
-                                               marker->pattern_corners[1][1] = track->pat_min[1];
-
-                                               marker->pattern_corners[2][0] = track->pat_max[0];
-                                               marker->pattern_corners[2][1] = track->pat_max[1];
-
-                                               marker->pattern_corners[3][0] = track->pat_min[0];
-                                               marker->pattern_corners[3][1] = track->pat_max[1];
-                                       }
-
-                                       if (is_zero_v2(marker->search_min) && is_zero_v2(marker->search_max)) {
-                                               copy_v2_v2(marker->search_min, track->search_min);
-                                               copy_v2_v2(marker->search_max, track->search_max);
-                                       }
-                               }
+                               do_versions_affine_tracker_track(track);
 
                                track = track->next;
                        }
@@ -7998,8 +8328,483 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                }
                        }
                }
+
+               {
+                       Mesh *me;
+                       for (me = main->mesh.first; me; me = me->id.next) {
+                               CustomData_update_typemap(&me->vdata);
+                               CustomData_free_layers(&me->vdata, CD_MSTICKY, me->totvert);
+                       }
+               }
+       }
+
+       /* correction for files saved in blender version when BKE_pose_copy_data
+        * didn't copy animation visualization, which lead to deadlocks on motion
+        * path calculation for proxied armatures, see [#32742]
+        */
+       if (main->versionfile < 264) {
+               Object *ob;
+
+               for (ob = main->object.first; ob; ob = ob->id.next) {
+                       if (ob->pose) {
+                               if (ob->pose->avs.path_step == 0) {
+                                       animviz_settings_init(&ob->pose->avs);
+                               }
+                       }
+               }
+       }
+
+       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);
+       }
+
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) {
+               MovieClip *clip;
+
+               for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+                       MovieTracking *tracking = &clip->tracking;
+                       MovieTrackingObject *tracking_object;
+
+                       for (tracking_object = tracking->objects.first;
+                            tracking_object;
+                            tracking_object = tracking_object->next)
+                       {
+                               if (tracking_object->keyframe1 == 0 && tracking_object->keyframe2 == 0) {
+                                       tracking_object->keyframe1 = tracking->settings.keyframe1;
+                                       tracking_object->keyframe2 = tracking->settings.keyframe2;
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) {
+               /* smoke branch */
+               {
+                       Object *ob;
+
+                       for (ob = main->object.first; ob; ob = ob->id.next) {
+                               ModifierData *md;
+                               for (md = ob->modifiers.first; md; md = md->next) {
+                                       if (md->type == eModifierType_Smoke) {
+                                               SmokeModifierData *smd = (SmokeModifierData *)md;
+                                               if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
+                                                       /* keep branch saves if possible */
+                                                       if (!smd->domain->flame_max_temp) {
+                                                               smd->domain->burning_rate = 0.75f;
+                                                               smd->domain->flame_smoke = 1.0f;
+                                                               smd->domain->flame_vorticity = 0.5f;
+                                                               smd->domain->flame_ignition = 1.25f;
+                                                               smd->domain->flame_max_temp = 1.75f;
+                                                               smd->domain->adapt_threshold = 0.02f;
+                                                               smd->domain->adapt_margin = 4;
+                                                               smd->domain->flame_smoke_color[0] = 0.7f;
+                                                               smd->domain->flame_smoke_color[1] = 0.7f;
+                                                               smd->domain->flame_smoke_color[2] = 0.7f;
+                                                       }
+                                               }
+                                               else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) {
+                                                       if (!smd->flow->texture_size) {
+                                                               smd->flow->fuel_amount = 1.0;
+                                                               smd->flow->surface_distance = 1.5;
+                                                               smd->flow->color[0] = 0.7f;
+                                                               smd->flow->color[1] = 0.7f;
+                                                               smd->flow->color[2] = 0.7f;
+                                                               smd->flow->texture_size = 1.0f;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               /* render border for viewport */
+               {
+                       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_VIEW3D) {
+                                                       View3D *v3d = (View3D *)sl;
+                                                       if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f &&
+                                                           v3d->render_border.xmax == 0.0f && v3d->render_border.ymax == 0.0f)
+                                                       {
+                                                               v3d->render_border.xmax = 1.0f;
+                                                               v3d->render_border.ymax = 1.0f;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       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;
+
+               for (scene=main->scene.first; scene; scene=scene->id.next) {
+                       if (scene->toolsettings->uvcalc_margin == 0.0f) {
+                               scene->toolsettings->uvcalc_margin = 0.001f;
+                               scene->toolsettings->unwrapper = 0;
+                       }
+               }
+       }
+
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) {
+               /* 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);
+               
+       }
+       
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) {
+               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;
+                               if ( sa->spacetype == SPACE_LOGIC)
+                                       do_version_logic_264(&sa->regionbase);
+                               
+                               for (sl = sa->spacedata.first; sl; sl = sl->next) {
+                                       if (sl->spacetype == SPACE_LOGIC)
+                                               do_version_logic_264(&sl->regionbase);
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 7)) {
+               /* convert tiles size from resolution and number of tiles */
+               {
+                       Scene *scene;
+
+                       for (scene = main->scene.first; scene; scene = scene->id.next) {
+                               if (scene->r.tilex == 0 || scene->r.tiley == 1) {
+                                       if (scene->r.xparts && scene->r.yparts) {
+                                               /* scene could be set for panoramic rendering, so clamp with the
+                                                * lowest possible tile size value
+                                                */
+                                               scene->r.tilex = max_ii(scene->r.xsch * scene->r.size / scene->r.xparts / 100, 8);
+                                               scene->r.tiley = max_ii(scene->r.ysch * scene->r.size / scene->r.yparts / 100, 8);
+                                       }
+                                       else {
+                                               /* happens when mixing using current trunk and previous release */
+                                               scene->r.tilex = scene->r.tiley = 64;
+                                       }
+                               }
+                       }
+               }
+
+               /* collision masks */
+               {
+                       Object *ob;
+                       for (ob = main->object.first; ob; ob = ob->id.next) {
+                               if (ob->col_group == 0) {
+                                       ob->col_group = 0x01;
+                                       ob->col_mask = 0xff;
+                               }
+                       }
+               }
+
+               /* fallbck resection method settings */
+               {
+                       MovieClip *clip;
+
+                       for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+                               if (clip->tracking.settings.reconstruction_success_threshold == 0.0f) {
+                                       clip->tracking.settings.reconstruction_success_threshold = 1e-3f;
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 7)) {
+               MovieClip *clip;
+
+               for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+                       MovieTrackingTrack *track;
+                       MovieTrackingObject *object;
+
+                       for (track = clip->tracking.tracks.first; track; track = track->next) {
+                               do_versions_affine_tracker_track(track);
+                       }
+
+                       for (object = clip->tracking.objects.first; object; object = object->next) {
+                               for (track = object->tracks.first; track; track = track->next) {
+                                       do_versions_affine_tracker_track(track);
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 265) {
+               Object *ob;
+               for (ob = main->object.first; ob; ob = ob->id.next) {
+                       if (ob->step_height == 0.0f) {
+                               ob->step_height = 0.15f;
+                               ob->jump_speed = 10.0f;
+                               ob->fall_speed = 55.0f;
+                       }
+               }
+       }
+
+       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, *nimage;
+               Tex *tex, *otex;
+
+               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;
+                       }
+                       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 (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;
+
+                       image->flag &= ~IMA_DONE_TAG;
+               }
+
+               /* use alpha flag moved from texture to image datablock */
+               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);
+
+                               /* skip if no image or already tested */
+                               if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
+                                       continue;
+
+                               image->flag |= IMA_DONE_TAG;
+
+                               /* we might have some textures using alpha and others not, so we check if
+                                * they exist and duplicate the image datablock if necessary */
+                               for (otex = main->tex.first; otex; otex = otex->id.next)
+                                       if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
+                                               if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
+                                                       break;
+
+                               if (otex) {
+                                       /* copy image datablock */
+                                       nimage = BKE_image_copy(main, image);
+                                       nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
+                                       nimage->id.us--;
+
+                                       /* we need to do some trickery to make file loading think
+                                        * this new datablock is part of file we're loading */
+                                       blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
+                                       nimage->id.lib = image->id.lib;
+                                       nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
+
+                                       /* assign new image, and update the users counts accordingly */
+                                       for (otex = main->tex.first; otex; otex = otex->id.next) {
+                                               if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
+                                                       if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
+                                                               if (!(otex->id.flag & LIB_NEED_LINK)) {
+                                                                       image->id.us--;
+                                                                       nimage->id.us++;
+                                                               }
+                                                               otex->ima = nimage;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               else {
+                                       /* no other textures using alpha, just set the flag */
+                                       image->flag |= IMA_IGNORE_ALPHA;
+                               }
+                       }
+               }
+
+               for (image = main->image.first; image; image = image->id.next)
+                       image->flag &= ~IMA_DONE_TAG;
+       }
+
+       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_ATLEAST(main, 265, 8)) {
+               Mesh *me;
+               for (me = main->mesh.first; me; me = me->id.next) {
+                       BKE_mesh_do_versions_cd_flag_init(me);
+               }
+       }
+
+       if (!MAIN_VERSION_ATLEAST(main, 265, 9)) {
+               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_ATLEAST(main, 265, 10)) {
+               bNodeTreeType *ntreetype;
+
+               ntreetype = ntreeGetType(NTREE_COMPOSIT);
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_translate_wrapping);
        }
 
+
+
+       // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+
        /* 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! */
 
@@ -8019,8 +8824,11 @@ static void lib_link_all(FileData *fd, Main *main)
 {
        oldnewmap_sort(fd);
        
-       lib_link_windowmanager(fd, main);
-       lib_link_screen(fd, main);
+       /* 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);
@@ -8028,7 +8836,7 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_material(fd, main);
        lib_link_texture(fd, main);
        lib_link_image(fd, main);
-       lib_link_ipo(fd, main);         // XXX depreceated... still needs to be maintained for version patches still
+       lib_link_ipo(fd, main);         // XXX deprecated... still needs to be maintained for version patches still
        lib_link_key(fd, main);
        lib_link_world(fd, main);
        lib_link_lamp(fd, main);
@@ -8067,6 +8875,7 @@ 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");
        
@@ -8104,7 +8913,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
                for (kmi=keymap->items.first; kmi; kmi=kmi->next)
                        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;
        
@@ -8228,7 +9044,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;
@@ -8293,9 +9109,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);
@@ -8308,7 +9125,15 @@ 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);
                                
-                               id = is_yet_read(fd, ptr, bhead);
+                               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) {
                                        read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
@@ -8362,9 +9187,9 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
        }
 }
 
+static void (*expand_doit)(void *, Main *, void *);
 
-
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
 {
        IpoCurve *icu;
@@ -8374,7 +9199,7 @@ static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
        }
 }
 
-// XXX depreceated - old animation system
+// XXX deprecated - old animation system
 static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *chanbase)
 {
        bConstraintChannel *chan;
@@ -8430,7 +9255,7 @@ static void expand_action(FileData *fd, Main *mainvar, bAction *act)
 {
        bActionChannel *chan;
        
-       // XXX depreceated - old animation system --------------
+       // XXX deprecated - old animation system --------------
        for (chan=act->chanbase.first; chan; chan=chan->next) {
                expand_doit(fd, mainvar, chan->ipo);
                expand_constraint_channels(fd, mainvar, &chan->constraintChannels);
@@ -8520,7 +9345,7 @@ static void expand_group(FileData *fd, Main *mainvar, Group *group)
 
 static void expand_key(FileData *fd, Main *mainvar, Key *key)
 {
-       expand_doit(fd, mainvar, key->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, key->ipo); // XXX deprecated - old animation system
        
        if (key->adt)
                expand_animdata(fd, mainvar, key->adt);
@@ -8546,7 +9371,7 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
 static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
 {
        expand_doit(fd, mainvar, tex->ima);
-       expand_doit(fd, mainvar, tex->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, tex->ipo); // XXX deprecated - old animation system
        
        if (tex->adt)
                expand_animdata(fd, mainvar, tex->adt);
@@ -8572,7 +9397,7 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
                }
        }
        
-       expand_doit(fd, mainvar, ma->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, ma->ipo); // XXX deprecated - old animation system
        
        if (ma->adt)
                expand_animdata(fd, mainvar, ma->adt);
@@ -8595,7 +9420,7 @@ static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
                }
        }
        
-       expand_doit(fd, mainvar, la->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, la->ipo); // XXX deprecated - old animation system
        
        if (la->adt)
                expand_animdata(fd, mainvar, la->adt);
@@ -8606,7 +9431,7 @@ static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
 
 static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
 {
-       expand_doit(fd, mainvar, lt->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, lt->ipo); // XXX deprecated - old animation system
        expand_doit(fd, mainvar, lt->key);
        
        if (lt->adt)
@@ -8625,7 +9450,7 @@ static void expand_world(FileData *fd, Main *mainvar, World *wrld)
                }
        }
        
-       expand_doit(fd, mainvar, wrld->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, wrld->ipo); // XXX deprecated - old animation system
        
        if (wrld->adt)
                expand_animdata(fd, mainvar, wrld->adt);
@@ -8656,11 +9481,11 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
        }
        
        expand_doit(fd, mainvar, cu->vfont);
-       expand_doit(fd, mainvar, cu->vfontb);   
+       expand_doit(fd, mainvar, cu->vfontb);
        expand_doit(fd, mainvar, cu->vfonti);
        expand_doit(fd, mainvar, cu->vfontbi);
        expand_doit(fd, mainvar, cu->key);
-       expand_doit(fd, mainvar, cu->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, cu->ipo); // XXX deprecated - old animation system
        expand_doit(fd, mainvar, cu->bevobj);
        expand_doit(fd, mainvar, cu->taperobj);
        expand_doit(fd, mainvar, cu->textoncurve);
@@ -8747,12 +9572,12 @@ 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);
        
-       /* depreceated manual expansion stuff */
+       /* deprecated manual expansion stuff */
        for (curcon = lb->first; curcon; curcon = curcon->next) {
                if (curcon->ipo)
-                       expand_doit(fd, mainvar, curcon->ipo); // XXX depreceated - old animation system
+                       expand_doit(fd, mainvar, curcon->ipo); // XXX deprecated - old animation system
        }
 }
 
@@ -8834,7 +9659,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
        
        expand_doit(fd, mainvar, ob->gpd);
        
-// XXX depreceated - old animation system (for version patching only) 
+// XXX deprecated - old animation system (for version patching only)
        expand_doit(fd, mainvar, ob->ipo);
        expand_doit(fd, mainvar, ob->action);
        
@@ -8845,7 +9670,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                expand_doit(fd, mainvar, strip->act);
                expand_doit(fd, mainvar, strip->ipo);
        }
-// XXX depreceated - old animation system (for version patching only)
+// XXX deprecated - old animation system (for version patching only)
        
        if (ob->adt)
                expand_animdata(fd, mainvar, ob->adt);
@@ -8953,7 +9778,12 @@ 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)
@@ -8999,6 +9829,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
        {
@@ -9017,7 +9852,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
 {
-       expand_doit(fd, mainvar, ca->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, ca->ipo); // XXX deprecated - old animation system
        
        if (ca->adt)
                expand_animdata(fd, mainvar, ca->adt);
@@ -9033,7 +9868,7 @@ static void expand_speaker(FileData *fd, Main *mainvar, Speaker *spk)
 
 static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
 {
-       expand_doit(fd, mainvar, snd->ipo); // XXX depreceated - old animation system
+       expand_doit(fd, mainvar, snd->ipo); // XXX deprecated - old animation system
 }
 
 static void expand_movieclip(FileData *fd, Main *mainvar, MovieClip *clip)
@@ -9073,20 +9908,24 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
        }
 }
 
-static void expand_main(FileData *fd, Main *mainvar)
+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)) {
@@ -9136,7 +9975,7 @@ static void expand_main(FileData *fd, Main *mainvar)
                                                expand_armature(fd, mainvar, (bArmature *)id);
                                                break;
                                        case ID_AC:
-                                               expand_action(fd, mainvar, (bAction *)id); // XXX depreceated - old animation system
+                                               expand_action(fd, mainvar, (bAction *)id); // XXX deprecated - old animation system
                                                break;
                                        case ID_GR:
                                                expand_group(fd, mainvar, (Group *)id);
@@ -9148,7 +9987,7 @@ static void expand_main(FileData *fd, Main *mainvar)
                                                expand_brush(fd, mainvar, (Brush *)id);
                                                break;
                                        case ID_IP:
-                                               expand_ipo(fd, mainvar, (Ipo *)id); // XXX depreceated - old animation system
+                                               expand_ipo(fd, mainvar, (Ipo *)id); // XXX deprecated - old animation system
                                                break;
                                        case ID_PA:
                                                expand_particlesettings(fd, mainvar, (ParticleSettings *)id);
@@ -9171,6 +10010,9 @@ static void expand_main(FileData *fd, Main *mainvar)
        }
 }
 
+
+/* ***************************** */
+       
 static int object_in_any_scene(Main *mainvar, Object *ob)
 {
        Scene *sce;
@@ -9226,7 +10068,7 @@ 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);
                                        base->lay = ob->lay;
                                        base->object = ob;
                                        base->flag = ob->flag;
@@ -9250,7 +10092,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;
                        
@@ -9319,6 +10161,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);
@@ -9423,8 +10287,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);
@@ -9478,7 +10345,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
        if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
                blo_freefiledata(*fd);
                *fd = NULL;
-       }       
+       }
 }
 
 void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
@@ -9519,6 +10386,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;
                
@@ -9532,13 +10402,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,
-                                                        "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) {
@@ -9587,8 +10470,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                        else mainptr->curlib->filedata = NULL;
                                        
                                        if (fd == NULL) {
-                                               BKE_reportf_wrap(basefd->reports, RPT_ERROR,
-                                                                "Can't find lib '%s'",
+                                               BKE_reportf_wrap(basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"),
                                                                 mainptr->curlib->filepath);
                                        }
                                }
@@ -9606,8 +10488,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                                                
                                                                append_id_part(fd, mainptr, id, &realid);
                                                                if (!realid) {
-                                                                       BKE_reportf_wrap(fd->reports, RPT_ERROR,
-                                                                                        "LIB ERROR: %s:'%s' missing from '%s'",
+                                                                       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);
                                                                }
@@ -9620,7 +10502,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                                }
                                        }
                                        
-                                       expand_main(fd, mainptr);
+                                       BLO_expand_main(fd, mainptr);
                                }
                        }
                        
@@ -9638,8 +10520,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                idn = id->next;
                                if (id->flag & LIB_READ) {
                                        BLI_remlink(lbarray[a], id);
-                                       BKE_reportf_wrap(basefd->reports, RPT_ERROR,
-                                                        "LIB ERROR: %s:'%s' unread libblock missing from '%s'",
+                                       BKE_reportf_wrap(basefd->reports, RPT_WARNING,
+                                                        TIP_("LIB ERROR: %s: '%s' unread lib block missing from '%s'"),
                                                         BKE_idcode_to_name(GS(id->name)), id->name + 2, mainptr->curlib->filepath);
                                        change_idid_adr(mainlist, basefd, id, NULL);