synched with trunk at revision 36569
[blender.git] / source / blender / blenloader / intern / readfile.c
index 3b62b5a..320c169 100644 (file)
  *
  */
 
+/** \file blender/blenloader/intern/readfile.c
+ *  \ingroup blenloader
+ */
+
+
 #include "zlib.h"
 
 #include <limits.h>
@@ -229,7 +234,7 @@ typedef struct OldNewMap {
 
 /* local prototypes */
 static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
-
+static void direct_link_modifiers(FileData *fd, ListBase *lb);
 
 static OldNewMap *oldnewmap_new(void) 
 {
@@ -285,6 +290,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
 {
        int i;
 
+       if(addr==NULL) return NULL;
+
        if (onm->lasthit<onm->nentries-1) {
                OldNew *entry= &onm->entries[++onm->lasthit];
 
@@ -422,7 +429,7 @@ static void split_libdata(ListBase *lb, Main *first)
                                }
                                mainvar= mainvar->next;
                        }
-                       if(mainvar==0) printf("error split_libdata\n");
+                       if(mainvar==NULL) printf("error split_libdata\n");
                }
                id= idnext;
        }
@@ -495,7 +502,7 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, c
        for (m= mainlist->first; m; m= m->next) {
                char *libname= (m->curlib)?m->curlib->filepath:m->name;
                
-               if (BLI_streq(name1, libname)) {
+               if (BLI_path_cmp(name1, libname) == 0) {
                        if(G.f & G_DEBUG) printf("blo_find_main: found library %s\n", libname);
                        return m;
                }
@@ -589,7 +596,7 @@ static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
 
 static BHeadN *get_bhead(FileData *fd)
 {
-       BHeadN *new_bhead = 0;
+       BHeadN *new_bhead = NULL;
        int readsize;
        
        if (fd) {
@@ -654,7 +661,7 @@ static BHeadN *get_bhead(FileData *fd)
                        if ( ! fd->eof) {
                                new_bhead = MEM_mallocN(sizeof(BHeadN) + bhead.len, "new_bhead");
                                if (new_bhead) {
-                                       new_bhead->next = new_bhead->prev = 0;
+                                       new_bhead->next = new_bhead->prev = NULL;
                                        new_bhead->bhead = bhead;
 
                                        readsize = fd->read(fd, new_bhead + 1, bhead.len);
@@ -662,7 +669,7 @@ static BHeadN *get_bhead(FileData *fd)
                                        if (readsize != bhead.len) {
                                                fd->eof = 1;
                                                MEM_freeN(new_bhead);
-                                               new_bhead = 0;
+                                               new_bhead = NULL;
                                        }
                                } else {
                                        fd->eof = 1;
@@ -684,13 +691,13 @@ static BHeadN *get_bhead(FileData *fd)
 BHead *blo_firstbhead(FileData *fd)
 {
        BHeadN *new_bhead;
-       BHead *bhead = 0;
+       BHead *bhead = NULL;
 
        // Rewind the file
        // Read in a new block if necessary
 
        new_bhead = fd->listbase.first;
-       if (new_bhead == 0) {
+       if (new_bhead == NULL) {
                new_bhead = get_bhead(fd);
        }
 
@@ -721,7 +728,7 @@ BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
 
                // get the next BHeadN. If it doesn't exist we read in the next one
                new_bhead = new_bhead->next;
-               if (new_bhead == 0) {
+               if (new_bhead == NULL) {
                        new_bhead = get_bhead(fd);
                }
        }
@@ -944,8 +951,8 @@ FileData *blo_openblenderfile(const char *name, ReportList *reports)
        errno= 0;
        gzfile= gzopen(name, "rb");
 
-       if (gzfile == Z_NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", name, errno ? strerror(errno) : "Unknown erro reading file");
+       if (gzfile == (gzFile)Z_NULL) {
+               BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", name, errno ? strerror(errno) : "Unknown error reading file");
                return NULL;
        } else {
                FileData *fd = filedata_new();
@@ -1007,7 +1014,7 @@ void blo_freefiledata(FileData *fd)
 
                if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
                        MEM_freeN(fd->buffer);
-                       fd->buffer = 0;
+                       fd->buffer = NULL;
                }
 
                // Free all BHeadN data blocks
@@ -1061,7 +1068,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
        /* Find the last slash */
        fd= BLI_last_slash(dir);
 
-       if(fd==0) return 0;
+       if(fd==NULL) return 0;
        *fd= 0;
        if(BLO_has_bfile_extension(fd+1)) {
                /* the last part of the dir is a .blend file, no group follows */
@@ -1195,11 +1202,11 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
        OldNew *entry= fd->imamap->entries;
        Image *ima= oldmain->image.first;
        Scene *sce= oldmain->scene.first;
-       int i, a;
+       int i;
        
        /* used entries were restored, so we put them to zero */
        for (i=0; i<fd->imamap->nentries; i++, entry++) {
-                if (entry->nr>0)
+               if (entry->nr>0)
                        entry->newp= NULL;
        }
        
@@ -1215,10 +1222,10 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                                ima->gputexture= NULL;
                        }
                }
+               for(i=0; i<IMA_MAX_RENDER_SLOT; i++)
+                       ima->renders[i]= newimaadr(fd, ima->renders[i]);
 
                ima->gputexture= newimaadr(fd, ima->gputexture);
-               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
-                       ima->renders[a]= newimaadr(fd, ima->renders[a]);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1310,7 +1317,7 @@ static void link_glob_list(FileData *fd, ListBase *lb)            /* for glob data */
        Link *ln, *prev;
        void *poin;
 
-       if(lb->first==0) return;
+       if(lb->first==NULL) return;
        poin= newdataadr(fd, lb->first);
        if(lb->first) {
                oldnewmap_insert(fd->globmap, lb->first, poin, 0);
@@ -1318,7 +1325,7 @@ static void link_glob_list(FileData *fd, ListBase *lb)            /* for glob data */
        lb->first= poin;
 
        ln= lb->first;
-       prev= 0;
+       prev= NULL;
        while(ln) {
                poin= newdataadr(fd, ln->next);
                if(ln->next) {
@@ -1459,7 +1466,7 @@ static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, FileData *f
        }
 }
 
-void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
+static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
 {
        switch (prop->type) {
                case IDP_GROUP:
@@ -1496,7 +1503,7 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
 }
 
 /*stub function*/
-void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd))
+static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd))
 {
 }
 
@@ -1858,6 +1865,10 @@ static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list)
                
                /* reassign the counted-reference to action */
                strip->act = newlibadr_us(fd, id->lib, strip->act);
+               
+               /* fix action id-root (i.e. if it comes from a pre 2.57 .blend file) */
+               if ((strip->act) && (strip->act->idroot == 0))
+                       strip->act->idroot = GS(id->name);
        }
 }
 
@@ -1889,7 +1900,7 @@ static void direct_link_nladata_strips(FileData *fd, ListBase *list)
                
                /* strip's F-Modifiers */
                link_list(fd, &strip->modifiers);
-               direct_link_fcurves(fd, &strip->modifiers);
+               direct_link_modifiers(fd, &strip->modifiers);
        }
 }
 
@@ -1951,6 +1962,12 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
        adt->action= newlibadr_us(fd, id->lib, adt->action);
        adt->tmpact= newlibadr_us(fd, id->lib, adt->tmpact);
        
+       /* fix action id-roots (i.e. if they come from a pre 2.57 .blend file) */
+       if ((adt->action) && (adt->action->idroot == 0))
+               adt->action->idroot = GS(id->name);
+       if ((adt->tmpact) && (adt->tmpact->idroot == 0))
+               adt->tmpact->idroot = GS(id->name);
+       
        /* link drivers */
        lib_link_fcurves(fd, id, &adt->drivers);
        
@@ -2028,6 +2045,55 @@ static void lib_link_nodetree(FileData *fd, Main *main)
        }
 }
 
+/* updates group node socket own_index so that
+ * external links to/from the group node are preserved.
+ */
+static void lib_node_do_versions_group(bNode *gnode)
+{
+       bNodeTree *ngroup= (bNodeTree*)gnode->id;
+       bNode *intnode;
+       bNodeSocket *sock, *gsock, *intsock;
+       int found;
+       
+       for (sock=gnode->outputs.first; sock; sock=sock->next) {
+               int old_index = sock->to_index;
+               for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) {
+                       if (gsock->link && gsock->link->fromsock->own_index == old_index) {
+                               sock->own_index = gsock->own_index;
+                               break;
+                       }
+               }
+       }
+       for (sock=gnode->inputs.first; sock; sock=sock->next) {
+               int old_index = sock->to_index;
+               /* can't use break in double loop */
+               found = 0;
+               for (intnode=ngroup->nodes.first; intnode && !found; intnode=intnode->next) {
+                       for (intsock=intnode->inputs.first; intsock; intsock=intsock->next) {
+                               if (intsock->own_index == old_index && intsock->link) {
+                                       sock->own_index = intsock->link->fromsock->own_index;
+                                       found = 1;
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+/* updates external links for all group nodes in a tree */
+static void lib_nodetree_do_versions_group(bNodeTree *ntree)
+{
+       bNode *node;
+       
+       for (node=ntree->nodes.first; node; node=node->next) {
+               if (node->type==NODE_GROUP) {
+                       bNodeTree *ngroup= (bNodeTree*)node->id;
+                       if (ngroup->flag & NTREE_DO_VERSIONS)
+                               lib_node_do_versions_group(node);
+               }
+       }
+}
+
 /* verify types for nodes and groups, all data has to be read */
 /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
 * typedefs*/
@@ -2046,10 +2112,43 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
        /* now create the own typeinfo structs an verify nodes */
        /* here we still assume no groups in groups */
        for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
-               ntreeVerifyTypes(ntree);        /* internal nodes, no groups! */
-               ntreeMakeOwnType(ntree);        /* for group usage */
+               ntreeVerifyTypes(ntree);                /* internal nodes, no groups! */
        }
        
+       {
+               int has_old_groups=0;
+               /* XXX this should actually be part of do_versions, but since we need
+                * finished library linking, it is not possible there. Instead in do_versions
+                * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the
+                * actual group node updates.
+                */
+               for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
+                       if (ntree->flag & NTREE_DO_VERSIONS) {
+                               /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
+                               nodeGroupExposeAllSockets(ntree);
+                               has_old_groups = 1;
+                       }
+               }
+               /* now verify all types in material trees, groups are set OK now */
+               for(ma= main->mat.first; ma; ma= ma->id.next) {
+                       if(ma->nodetree)
+                               lib_nodetree_do_versions_group(ma->nodetree);
+               }
+               /* and scene trees */
+               for(sce= main->scene.first; sce; sce= sce->id.next) {
+                       if(sce->nodetree)
+                               lib_nodetree_do_versions_group(sce->nodetree);
+               }
+               /* and texture trees */
+               for(tx= main->tex.first; tx; tx= tx->id.next) {
+                       if(tx->nodetree)
+                               lib_nodetree_do_versions_group(tx->nodetree);
+               }
+               
+               for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+                       ntree->flag &= ~NTREE_DO_VERSIONS;
+       }
+
        /* now verify all types in material trees, groups are set OK now */
        for(ma= main->mat.first; ma; ma= ma->id.next) {
                if(ma->nodetree)
@@ -2078,7 +2177,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        bNodeLink *link;
        
        ntree->init= 0;         /* to set callbacks and force setting types */
-       ntree->owntype= NULL;
        ntree->progress= NULL;
        
        ntree->adt= newdataadr(fd, ntree->adt);
@@ -2116,6 +2214,10 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        }
        link_list(fd, &ntree->links);
        
+       /* external sockets */
+       link_list(fd, &ntree->inputs);
+       link_list(fd, &ntree->outputs);
+       
        /* and we connect the rest */
        for(node= ntree->nodes.first; node; node= node->next) {
                node->preview= newimaadr(fd, node->preview);
@@ -2125,13 +2227,16 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                for(sock= node->outputs.first; sock; sock= sock->next)
                        sock->ns.data= NULL;
        }
+       for(sock= ntree->outputs.first; sock; sock= sock->next)
+               sock->link= newdataadr(fd, sock->link);
+       
        for(link= ntree->links.first; link; link= link->next) {
                link->fromnode= newdataadr(fd, link->fromnode);
                link->tonode= newdataadr(fd, link->tonode);
                link->fromsock= newdataadr(fd, link->fromsock);
                link->tosock= newdataadr(fd, link->tosock);
        }
-               
+       
        /* type verification is in lib-link */
 }
 
@@ -2680,8 +2785,18 @@ static void direct_link_image(FileData *fd, Image *ima)
        ima->anim= NULL;
        ima->rr= NULL;
        ima->repbind= NULL;
-       memset(ima->renders, 0, sizeof(ima->renders));
-       ima->last_render_slot= ima->render_slot;
+       
+       /* undo system, try to restore render buffers */
+       if(fd->imamap) {
+               int a;
+               
+               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+                       ima->renders[a]= newimaadr(fd, ima->renders[a]);
+       }
+       else {
+               memset(ima->renders, 0, sizeof(ima->renders));
+               ima->last_render_slot= ima->render_slot;
+       }
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
        ima->preview = direct_link_preview_image(fd, ima->preview);
@@ -2755,7 +2870,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
 
        if(cu->vfont == NULL) link_list(fd, &(cu->nurb));
        else {
-               cu->nurb.first=cu->nurb.last= 0;
+               cu->nurb.first=cu->nurb.last= NULL;
 
                tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "TextBoxread");
                if (cu->tb) {
@@ -2768,7 +2883,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
                        cu->tb = tb;
                        cu->tb[0].w = cu->linewidth;
                }               
-               if (cu->wordspace == 0.0) cu->wordspace = 1.0;
+               if (cu->wordspace == 0.0f) cu->wordspace = 1.0f;
        }
 
        cu->bev.first=cu->bev.last= NULL;
@@ -2829,7 +2944,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        
        tex->plugin= newdataadr(fd, tex->plugin);
        if(tex->plugin) {
-               tex->plugin->handle= 0;
+               tex->plugin->handle= NULL;
                open_plugin_tex(tex->plugin);
                /* initialize data for this instance, if an initialization
                 * function exists.
@@ -2848,6 +2963,10 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        if(tex->pd) {
                tex->pd->point_tree = NULL;
                tex->pd->coba= newdataadr(fd, tex->pd->coba);
+               tex->pd->falloff_curve= newdataadr(fd, tex->pd->falloff_curve);
+               if(tex->pd->falloff_curve) {
+                       direct_link_curvemapping(fd, tex->pd->falloff_curve);
+               }
        }
        
        tex->vd= newdataadr(fd, tex->vd);
@@ -3007,7 +3126,7 @@ static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointC
        }
 }
 
-void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
+static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
 {
        if(pd && pd->tex)
                pd->tex=newlibadr_us(fd, id->lib, pd->tex);
@@ -3017,6 +3136,8 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 {
        ParticleSettings *part;
        ParticleDupliWeight *dw;
+       MTex *mtex;
+       int a;
 
        part= main->particle.first;
        while(part) {
@@ -3062,6 +3183,15 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
                                        }
                                }
                        }
+                       
+                       for(a=0; a<MAX_MTEX; a++) {
+                               mtex= part->mtex[a];
+                               if(mtex) {
+                                       mtex->tex = newlibadr_us(fd, part->id.lib, mtex->tex);
+                                       mtex->object = newlibadr(fd, part->id.lib, mtex->object);
+                               }
+                       }
+
                        part->id.flag -= LIB_NEEDLINK;
                }
                part= part->id.next;
@@ -3075,6 +3205,7 @@ static void direct_link_partdeflect(PartDeflect *pd)
 
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
+       int a;
        part->adt= newdataadr(fd, part->adt);
        part->pd= newdataadr(fd, part->pd);
        part->pd2= newdataadr(fd, part->pd2);
@@ -3102,6 +3233,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
                        link_list(fd, &state->actions);
                }
        }
+       for(a=0; a<MAX_MTEX; a++) {
+               part->mtex[a]= newdataadr(fd, part->mtex[a]);
+       }
 }
 
 static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
@@ -3212,6 +3346,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                }
 
                psys->tree = NULL;
+               psys->bvhtree = NULL;
        }
        return;
 }
@@ -3281,15 +3416,19 @@ static void lib_link_mesh(FileData *fd, Main *main)
 
 static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
 {
-       int     i;
+       int i;
 
-       if (!mdverts)
+       if (mdverts == NULL) {
                return;
+       }
 
-       for (i=0; i<count; i++) {
-               mdverts[i].dw=newdataadr(fd, mdverts[i].dw);
-               if (!mdverts[i].dw)
-                       mdverts[i].totweight=0;
+       for (i= count; i > 0; i--, mdverts++) {
+               if(mdverts->dw) {
+                       mdverts->dw= newdataadr(fd, mdverts->dw);
+               }
+               if (mdverts->dw == NULL) {
+                       mdverts->totweight= 0;
+               }
        }
 }
 
@@ -3559,7 +3698,7 @@ static void lib_link_object(FileData *fd, Main *main)
 
                        ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd);
                        ob->duplilist= NULL;
-            
+
                        ob->id.flag -= LIB_NEEDLINK;
                        /* if id.us==0 a new base will be created later on */
                        
@@ -3630,7 +3769,12 @@ static void lib_link_object(FileData *fd, Main *main)
                                }
                                else if(act->type==ACT_OBJECT) {
                                        bObjectActuator *oa= act->data;
-                                       oa->reference= newlibadr(fd, ob->id.lib, oa->reference);
+                                       if(oa==NULL) {
+                                               init_actuator(act);
+                                       }
+                                       else {
+                                               oa->reference= newlibadr(fd, ob->id.lib, oa->reference);
+                                       }
                                }
                                else if(act->type==ACT_EDIT_OBJECT) {
                                        bEditObjectActuator *eoa= act->data;
@@ -3642,15 +3786,6 @@ static void lib_link_object(FileData *fd, Main *main)
                                                eoa->me= newlibadr(fd, ob->id.lib, eoa->me);
                                        }
                                }
-                               else if(act->type==ACT_OBJECT) {
-                                       bObjectActuator *oa= act->data;
-                                       if(oa==NULL) {
-                                               init_actuator(act);
-                                       }
-                                       else {
-                                               oa->reference= newlibadr(fd, ob->id.lib, oa->reference);
-                                       }
-                               }
                                else if(act->type==ACT_SCENE) {
                                        bSceneActuator *sa= act->data;
                                        sa->camera= newlibadr(fd, ob->id.lib, sa->camera);
@@ -3803,7 +3938,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                if (md->type==eModifierType_Subsurf) {
                        SubsurfModifierData *smd = (SubsurfModifierData*) md;
 
-                       smd->emCache = smd->mCache = 0;
+                       smd->emCache = smd->mCache = NULL;
                }
                else if (md->type==eModifierType_Armature) {
                        ArmatureModifierData *amd = (ArmatureModifierData*) md;
@@ -3838,7 +3973,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        
                        fluidmd->fss= newdataadr(fd, fluidmd->fss);
                        fluidmd->fss->fmd= fluidmd;
-                       fluidmd->fss->meshSurfNormals = 0;
+                       fluidmd->fss->meshSurfNormals = NULL;
                }
                else if (md->type==eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData*) md;
@@ -3865,7 +4000,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 
                                /* Smoke uses only one cache from now on, so store pointer convert */
                                if(smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) {
-                                       printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n");
+                                       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
+                                                       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;
                                        smd->domain->ptcaches[1].last = NULL;
                                        smd->domain->point_cache[1] = NULL;
@@ -3914,7 +4056,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        collmd->current_x = NULL;
                        collmd->current_xnew = NULL;
                        collmd->current_v = NULL;
-                       collmd->time = -1000;
+                       collmd->time_x = collmd->time_xnew = -1000;
                        collmd->numverts = 0;
                        collmd->bvhtree = NULL;
                        collmd->mfaces = NULL;
@@ -3949,7 +4091,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                } else if (md->type==eModifierType_Explode) {
                        ExplodeModifierData *psmd = (ExplodeModifierData*) md;
 
-                       psmd->facepa=0;
+                       psmd->facepa=NULL;
                }
                else if (md->type==eModifierType_MeshDeform) {
                        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
@@ -3985,6 +4127,13 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                                SWITCH_INT(mmd->bindcos[a])
                        }
                }
+               else if (md->type==eModifierType_Warp) {
+                       WarpModifierData *tmd = (WarpModifierData *) md;
+
+                       tmd->curfalloff= newdataadr(fd, tmd->curfalloff);
+                       if(tmd->curfalloff)
+                               direct_link_curvemapping(fd, tmd->curfalloff);
+               }
        }
 }
 
@@ -4116,7 +4265,7 @@ static void direct_link_object(FileData *fd, Object *ob)
        prop= ob->prop.first;
        while(prop) {
                prop->poin= newdataadr(fd, prop->poin);
-               if(prop->poin==0) prop->poin= &prop->data;
+               if(prop->poin==NULL) prop->poin= &prop->data;
                prop= prop->next;
        }
 
@@ -4199,7 +4348,6 @@ static void direct_link_object(FileData *fd, Object *ob)
 
        if(ob->sculpt) {
                ob->sculpt= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
-               ob->sculpt->ob= ob;
        }
 }
 
@@ -4263,13 +4411,14 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: Object lost from scene:'%s\'\n", sce->id.name+2);
                                        if(G.background==0) printf("LIB ERROR: base removed from scene:'%s\'\n", sce->id.name+2);
                                        BLI_remlink(&sce->base, base);
-                                       if(base==sce->basact) sce->basact= 0;
+                                       if(base==sce->basact) sce->basact= NULL;
                                        MEM_freeN(base);
                                }
                        }
 
                        SEQ_BEGIN(sce->ed, seq) {
                                if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
+                               seq->scene_sound = NULL;
                                if(seq->scene) {
                                        seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
                                        seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
@@ -4286,7 +4435,7 @@ static void lib_link_scene(FileData *fd, Main *main)
                                                seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
                                        }
                                }
-                               seq->anim= 0;
+                               seq->anim= NULL;
                        }
                        SEQ_END
 
@@ -4346,8 +4495,10 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        sce->theDag = NULL;
        sce->dagisvalid = 0;
        sce->obedit= NULL;
-       sce->stats= 0;
+       sce->stats= NULL;
        sce->fps_info= NULL;
+       sce->customdata_mask_modal= 0;
+       sce->lay_updated = 0;
 
        sound_create_scene(sce);
 
@@ -4389,7 +4540,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        seq->seq2= newdataadr(fd, seq->seq2);
                        seq->seq3= newdataadr(fd, seq->seq3);
                        /* a patch: after introduction of effects with 3 input strips */
-                       if(seq->seq3==0) seq->seq3= seq->seq2;
+                       if(seq->seq3==NULL) seq->seq3= seq->seq2;
 
                        seq->plugin= newdataadr(fd, seq->plugin);
                        seq->effectdata= newdataadr(fd, seq->effectdata);
@@ -4413,32 +4564,32 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                                        seq->strip->stripdata = newdataadr(
                                                fd, seq->strip->stripdata);
                                } else {
-                                       seq->strip->stripdata = 0;
+                                       seq->strip->stripdata = NULL;
                                }
                                if (seq->flag & SEQ_USE_CROP) {
                                        seq->strip->crop = newdataadr(
                                                fd, seq->strip->crop);
                                } else {
-                                       seq->strip->crop = 0;
+                                       seq->strip->crop = NULL;
                                }
                                if (seq->flag & SEQ_USE_TRANSFORM) {
                                        seq->strip->transform = newdataadr(
                                                fd, seq->strip->transform);
                                } else {
-                                       seq->strip->transform = 0;
+                                       seq->strip->transform = NULL;
                                }
                                if (seq->flag & SEQ_USE_PROXY) {
                                        seq->strip->proxy = newdataadr(
                                                fd, seq->strip->proxy);
-                                       seq->strip->proxy->anim = 0;
+                                       seq->strip->proxy->anim = NULL;
                                } else {
-                                       seq->strip->proxy = 0;
+                                       seq->strip->proxy = NULL;
                                }
                                if (seq->flag & SEQ_USE_COLOR_BALANCE) {
                                        seq->strip->color_balance = newdataadr(
                                                fd, seq->strip->color_balance);
                                } else {
-                                       seq->strip->color_balance = 0;
+                                       seq->strip->color_balance = NULL;
                                }
                                if (seq->strip->color_balance) {
                                        // seq->strip->color_balance->gui = 0; // XXX - peter, is this relevant in 2.5?
@@ -4790,6 +4941,8 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        else if(GS(snode->id->name)==ID_TE)
                                                                snode->nodetree= ((Tex *)snode->id)->nodetree;
                                                }
+                                               
+                                               snode->linkdrag.first = snode->linkdrag.last = NULL;
                                        }
                                }
                                sa= sa->next;
@@ -5045,7 +5198,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                        rv3d->clipbb= newdataadr(fd, rv3d->clipbb);
                        
                        rv3d->depths= NULL;
-                       rv3d->retopo_view_data= NULL;
                        rv3d->ri= NULL;
                        rv3d->sms= NULL;
                        rv3d->smooth_timer= NULL;
@@ -5230,10 +5382,12 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                
                                /* WARNING: gpencil data is no longer stored directly in sima after 2.5 
                                 * so sacrifice a few old files for now to avoid crashes with new files!
-                                */
-                               //sima->gpd= newdataadr(fd, sima->gpd);
-                               //if (sima->gpd)
-                               //      direct_link_gpencil(fd, sima->gpd);
+                                * committed: r28002 */
+#if 0
+                               sima->gpd= newdataadr(fd, sima->gpd);
+                               if (sima->gpd)
+                                       direct_link_gpencil(fd, sima->gpd);
+#endif
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
@@ -5325,7 +5479,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
        
        for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) {
                if(newmain->curlib) {
-                       if(strcmp(newmain->curlib->filepath, lib->filepath)==0) {
+                       if(BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) {
                                printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath);
                                BKE_reportf(fd->reports, RPT_WARNING, "Library '%s', '%s' had multiple instances, save and reload!", lib->name, lib->filepath);
 
@@ -5700,8 +5854,8 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
 static void link_global(FileData *fd, BlendFileData *bfd)
 {
        
-       bfd->curscreen= newlibadr(fd, 0, bfd->curscreen);
-       bfd->curscene= newlibadr(fd, 0, bfd->curscene);
+       bfd->curscreen= newlibadr(fd, NULL, bfd->curscreen);
+       bfd->curscene= newlibadr(fd, NULL, bfd->curscene);
        // this happens in files older than 2.35
        if(bfd->curscene==NULL) {
                if(bfd->curscreen) bfd->curscene= bfd->curscreen->scene;
@@ -5714,7 +5868,7 @@ static void vcol_to_fcol(Mesh *me)
        unsigned int *mcol, *mcoln, *mcolmain;
        int a;
 
-       if(me->totface==0 || me->mcol==0) return;
+       if(me->totface==0 || me->mcol==NULL) return;
 
        mcoln= mcolmain= MEM_mallocN(4*sizeof(int)*me->totface, "mcoln");
        mcol = (unsigned int *)me->mcol;
@@ -6374,7 +6528,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                
                                ar->v2d.max[0]= MAXFRAMEF;
                                ar->v2d.max[1]= FLT_MAX;
-                               
+
                                ar->v2d.minzoom= 0.01f;
                                ar->v2d.maxzoom= 50;
                                ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
@@ -6525,10 +6679,14 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen)
                        }
                        else if (sl->spacetype==SPACE_IMAGE) {
                                SpaceImage *sima= (SpaceImage *)sl;
+#if 0                  /* see comment on r28002 */
                                if(sima->gpd) {
                                        versions_gpencil_add_main(&main->gpencil, (ID *)sima->gpd, "GPencil Image");
                                        sima->gpd= NULL;
                                }
+#else
+                               sima->gpd= NULL;
+#endif
                        }
                }
        }               
@@ -6581,7 +6739,6 @@ static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype)
                        mtex->lifefac= (neg & MAP_PA_LIFE)? -varfac: varfac;
                        mtex->sizefac= (neg & MAP_PA_SIZE)? -varfac: varfac;
                        mtex->ivelfac= (neg & MAP_PA_IVEL)? -varfac: varfac;
-                       mtex->pvelfac= (neg & MAP_PA_PVEL)? -varfac: varfac;
 
                        mtex->shadowfac= (neg & LAMAP_SHAD)? -colfac: colfac;
 
@@ -6692,7 +6849,7 @@ static void do_version_bone_roll_256(Bone *bone)
        float submat[3][3];
        
        copy_m3_m4(submat, bone->arm_mat);
-       mat3_to_vec_roll(submat, 0, &bone->arm_roll);
+       mat3_to_vec_roll(submat, NULL, &bone->arm_roll);
        
        for(child = bone->childbase.first; child; child = child->next)
                do_version_bone_roll_256(child);
@@ -6818,19 +6975,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sc= sc->id.next;
                }
        }
-       if(main->versionfile <= 112) {
-               Mesh *me = main->mesh.first;
-               while(me) {
-                       me->cubemapsize= 1.0;
-                       me= me->id.next;
-               }
-       }
        if(main->versionfile <= 113) {
                Material *ma = main->mat.first;
                while(ma) {
-                       if(ma->flaresize==0.0) ma->flaresize= 1.0;
-                       ma->subsize= 1.0;
-                       ma->flareboost= 1.0;
+                       if(ma->flaresize==0.0f) ma->flaresize= 1.0f;
+                       ma->subsize= 1.0f;
+                       ma->flareboost= 1.0f;
                        ma= ma->id.next;
                }
        }
@@ -6838,13 +6988,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if(main->versionfile <= 134) {
                Tex *tex = main->tex.first;
                while (tex) {
-                       if ((tex->rfac == 0.0) &&
-                               (tex->gfac == 0.0) &&
-                               (tex->bfac == 0.0)) {
-                               tex->rfac = 1.0;
-                               tex->gfac = 1.0;
-                               tex->bfac = 1.0;
-                               tex->filtersize = 1.0;
+                       if ((tex->rfac == 0.0f) &&
+                               (tex->gfac == 0.0f) &&
+                               (tex->bfac == 0.0f)) {
+                               tex->rfac = 1.0f;
+                               tex->gfac = 1.0f;
+                               tex->bfac = 1.0f;
+                               tex->filtersize = 1.0f;
                        }
                        tex = tex->id.next;
                }
@@ -6853,13 +7003,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* r-g-b-fac in texture */
                Tex *tex = main->tex.first;
                while (tex) {
-                       if ((tex->rfac == 0.0) &&
-                               (tex->gfac == 0.0) &&
-                               (tex->bfac == 0.0)) {
-                               tex->rfac = 1.0;
-                               tex->gfac = 1.0;
-                               tex->bfac = 1.0;
-                               tex->filtersize = 1.0;
+                       if ((tex->rfac == 0.0f) &&
+                               (tex->gfac == 0.0f) &&
+                               (tex->bfac == 0.0f)) {
+                               tex->rfac = 1.0f;
+                               tex->gfac = 1.0f;
+                               tex->bfac = 1.0f;
+                               tex->filtersize = 1.0f;
                        }
                        tex = tex->id.next;
                }
@@ -6867,7 +7017,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if(main->versionfile <= 153) {
                Scene *sce = main->scene.first;
                while(sce) {
-                       if(sce->r.blurfac==0.0) sce->r.blurfac= 1.0;
+                       if(sce->r.blurfac==0.0f) sce->r.blurfac= 1.0f;
                        sce= sce->id.next;
                }
        }
@@ -6988,8 +7138,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                TFace *tface= me->tface;
                                for(a=0; a<me->totface; a++, tface++) {
                                        for(b=0; b<4; b++) {
-                                               tface->uv[b][0]/= 32767.0;
-                                               tface->uv[b][1]/= 32767.0;
+                                               tface->uv[b][0]/= 32767.0f;
+                                               tface->uv[b][1]/= 32767.0f;
                                        }
                                }
                        }
@@ -7126,13 +7276,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                if(act->type==ACT_OBJECT) {
                                        oa= act->data;
 
-                                       oa->forceloc[0]*= 25.0;
-                                       oa->forceloc[1]*= 25.0;
-                                       oa->forceloc[2]*= 25.0;
+                                       oa->forceloc[0]*= 25.0f;
+                                       oa->forceloc[1]*= 25.0f;
+                                       oa->forceloc[2]*= 25.0f;
 
-                                       oa->forcerot[0]*= 10.0;
-                                       oa->forcerot[1]*= 10.0;
-                                       oa->forcerot[2]*= 10.0;
+                                       oa->forcerot[0]*= 10.0f;
+                                       oa->forcerot[1]*= 10.0f;
+                                       oa->forcerot[2]*= 10.0f;
                                }
                                act= act->next;
                        }
@@ -7141,8 +7291,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                sound = main->sound.first;
                while (sound) {
-                       if (sound->volume < 0.01) {
-                               sound->volume = 1.0;
+                       if (sound->volume < 0.01f) {
+                               sound->volume = 1.0f;
                        }
                        sound = sound->id.next;
                }
@@ -7238,18 +7388,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                if (act->type==ACT_OBJECT) {
                                        /* multiply velocity with 50 in old files */
                                        oa= act->data;
-                                       if (fabs(oa->linearvelocity[0]) >= 0.01f)
-                                               oa->linearvelocity[0] *= 50.0;
-                                       if (fabs(oa->linearvelocity[1]) >= 0.01f)
-                                               oa->linearvelocity[1] *= 50.0;
-                                       if (fabs(oa->linearvelocity[2]) >= 0.01f)
-                                               oa->linearvelocity[2] *= 50.0;
-                                       if (fabs(oa->angularvelocity[0])>=0.01f)
-                                               oa->angularvelocity[0] *= 50.0;
-                                       if (fabs(oa->angularvelocity[1])>=0.01f)
-                                               oa->angularvelocity[1] *= 50.0;
-                                       if (fabs(oa->angularvelocity[2])>=0.01f)
-                                               oa->angularvelocity[2] *= 50.0;
+                                       if (fabsf(oa->linearvelocity[0]) >= 0.01f)
+                                               oa->linearvelocity[0] *= 50.0f;
+                                       if (fabsf(oa->linearvelocity[1]) >= 0.01f)
+                                               oa->linearvelocity[1] *= 50.0f;
+                                       if (fabsf(oa->linearvelocity[2]) >= 0.01f)
+                                               oa->linearvelocity[2] *= 50.0f;
+                                       if (fabsf(oa->angularvelocity[0])>=0.01f)
+                                               oa->angularvelocity[0] *= 50.0f;
+                                       if (fabsf(oa->angularvelocity[1])>=0.01f)
+                                               oa->angularvelocity[1] *= 50.0f;
+                                       if (fabsf(oa->angularvelocity[2])>=0.01f)
+                                               oa->angularvelocity[2] *= 50.0f;
                                }
                                act= act->next;
                        }
@@ -7271,7 +7421,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sound->min_gain = 0.0;
                        sound->distance = 1.0;
 
-                       if (sound->attenuation > 0.0)
+                       if (sound->attenuation > 0.0f)
                                sound->flags |= SOUND_FLAGS_3D;
                        else
                                sound->flags &= ~SOUND_FLAGS_3D;
@@ -7329,7 +7479,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        ob->formfactor = 0.4f;
                        /* patch form factor , note that inertia equiv radius
                         * of a rotation symmetrical obj */
-                       if (ob->inertia != 1.0) {
+                       if (ob->inertia != 1.0f) {
                                ob->formfactor /= ob->inertia * ob->inertia;
                        }
                        ob = ob->id.next;
@@ -7691,7 +7841,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                SpaceLink *sl;
 
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
-                                       if(sl->blockscale==0.0) sl->blockscale= 0.7f;
+                                       if(sl->blockscale==0.0f) sl->blockscale= 0.7f;
                                        /* added: 5x better zoom in for action */
                                        if(sl->spacetype==SPACE_ACTION) {
                                                SpaceAction *sac= (SpaceAction *)sl;
@@ -7735,8 +7885,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                /* introduction of raytrace */
                while(ma) {
-                       if(ma->fresnel_tra_i==0.0) ma->fresnel_tra_i= 1.25;
-                       if(ma->fresnel_mir_i==0.0) ma->fresnel_mir_i= 1.25;
+                       if(ma->fresnel_tra_i==0.0f) ma->fresnel_tra_i= 1.25f;
+                       if(ma->fresnel_mir_i==0.0f) ma->fresnel_mir_i= 1.25f;
 
                        ma->ang= 1.0;
                        ma->ray_depth= 2;
@@ -7748,23 +7898,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
                sce= main->scene.first;
                while(sce) {
-                       if(sce->r.gauss==0.0) sce->r.gauss= 1.0;
+                       if(sce->r.gauss==0.0f) sce->r.gauss= 1.0f;
                        sce= sce->id.next;
                }
                la= main->lamp.first;
                while(la) {
-                       if(la->k==0.0) la->k= 1.0;
+                       if(la->k==0.0f) la->k= 1.0;
                        if(la->ray_samp==0) la->ray_samp= 1;
                        if(la->ray_sampy==0) la->ray_sampy= 1;
                        if(la->ray_sampz==0) la->ray_sampz= 1;
-                       if(la->area_size==0.0) la->area_size= 1.0;
-                       if(la->area_sizey==0.0) la->area_sizey= 1.0;
-                       if(la->area_sizez==0.0) la->area_sizez= 1.0;
+                       if(la->area_size==0.0f) la->area_size= 1.0f;
+                       if(la->area_sizey==0.0f) la->area_sizey= 1.0f;
+                       if(la->area_sizez==0.0f) la->area_sizez= 1.0f;
                        la= la->id.next;
                }
                wrld= main->world.first;
                while(wrld) {
-                       if(wrld->range==0.0) {
+                       if(wrld->range==0.0f) {
                                wrld->range= 1.0f/wrld->exposure;
                        }
                        wrld= wrld->id.next;
@@ -7805,7 +7955,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                tex->flag |= TEX_CHECKER_ODD;
                        }
                        /* copied from kernel texture.c */
-                       if(tex->ns_outscale==0.0) {
+                       if(tex->ns_outscale==0.0f) {
                                /* musgrave */
                                tex->mg_H = 1.0f;
                                tex->mg_lacunarity = 2.0f;
@@ -7823,12 +7973,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
 
                while(wrld) {
-                       if(wrld->aodist==0.0) {
+                       if(wrld->aodist==0.0f) {
                                wrld->aodist= 10.0f;
                                wrld->aobias= 0.05f;
                        }
-                       if(wrld->aosamp==0.0) wrld->aosamp= 5;
-                       if(wrld->aoenergy==0.0) wrld->aoenergy= 1.0;
+                       if(wrld->aosamp==0) wrld->aosamp= 5;
+                       if(wrld->aoenergy==0.0f) wrld->aoenergy= 1.0f;
                        wrld= wrld->id.next;
                }
 
@@ -7840,7 +7990,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        for (sa= sc->areabase.first; sa; sa= sa->next) {
                                SpaceLink *sl;
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
-                                       if(sl->blockscale==0.0) sl->blockscale= 0.7f;
+                                       if(sl->blockscale==0.0f) sl->blockscale= 0.7f;
 
                                        /* added: 5x better zoom in for nla */
                                        if(sl->spacetype==SPACE_NLA) {
@@ -7863,8 +8013,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Object *ob= main->object.first;
                
                while(ma) {
-                       if(ma->rampfac_col==0.0) ma->rampfac_col= 1.0;
-                       if(ma->rampfac_spec==0.0) ma->rampfac_spec= 1.0;
+                       if(ma->rampfac_col==0.0f) ma->rampfac_col= 1.0;
+                       if(ma->rampfac_spec==0.0f) ma->rampfac_spec= 1.0;
                        if(ma->pr_lamp==0) ma->pr_lamp= 3;
                        ma= ma->id.next;
                }
@@ -7925,7 +8075,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Editing *ed;
                
                while(tex) {
-                       if(tex->nabla==0.0) tex->nabla= 0.025f;
+                       if(tex->nabla==0.0f) tex->nabla= 0.025f;
                        tex= tex->id.next;
                }
                while(sce) {
@@ -7948,7 +8098,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                bScreen *sc;
 
                while(cam) {
-                       if(cam->ortho_scale==0.0) {
+                       if(cam->ortho_scale==0.0f) {
                                cam->ortho_scale= 256.0f/cam->lens;
                                if(cam->type==CAM_ORTHO) printf("NOTE: ortho render has changed, tweak new Camera 'scale' value.\n");
                        }
@@ -7976,7 +8126,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
                // init new shader vars
                for (ma= main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->darkness==0.0) {
+                       if(ma->darkness==0.0f) {
                                ma->rms=0.1f;
                                ma->darkness=1.0f;
                        }
@@ -7985,8 +8135,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* softbody init new vars */
                for(ob= main->object.first; ob; ob= ob->id.next) {
                        if(ob->soft) {
-                               if(ob->soft->defgoal==0.0) ob->soft->defgoal= 0.7f;
-                               if(ob->soft->physics_speed==0.0) ob->soft->physics_speed= 1.0f;
+                               if(ob->soft->defgoal==0.0f) ob->soft->defgoal= 0.7f;
+                               if(ob->soft->physics_speed==0.0f) ob->soft->physics_speed= 1.0f;
                                
                                if(ob->soft->interval==0) {
                                        ob->soft->interval= 2;
@@ -8098,7 +8248,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
 
                for (lt=main->latt.first; lt; lt=lt->id.next) {
-                       if (lt->fu==0.0 && lt->fv==0.0 && lt->fw==0.0) {
+                       if (lt->fu==0.0f && lt->fv==0.0f && lt->fw==0.0f) {
                                calc_lat_fudu(lt->flag, lt->pntsu, &lt->fu, &lt->du);
                                calc_lat_fudu(lt->flag, lt->pntsv, &lt->fv, &lt->dv);
                                calc_lat_fudu(lt->flag, lt->pntsw, &lt->fw, &lt->dw);
@@ -8320,7 +8470,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                ntree_version_241(sce->nodetree);
 
                        /* uv calculation options moved to toolsettings */
-                       if (sce->toolsettings->uvcalc_radius == 0.0) {
+                       if (sce->toolsettings->uvcalc_radius == 0.0f) {
                                sce->toolsettings->uvcalc_radius = 1.0f;
                                sce->toolsettings->uvcalc_cubesize = 1.0f;
                                sce->toolsettings->uvcalc_mapdir = 1;
@@ -8376,7 +8526,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                }
                        }
                        /* transmissivity defaults */
-                       if(ma->tx_falloff==0.0) ma->tx_falloff= 1.0;
+                       if(ma->tx_falloff==0.0f) ma->tx_falloff= 1.0f;
                }
                
                /* during 2.41 images with this name were used for viewer node output, lets fix that */
@@ -8574,11 +8724,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                ima->gen_x= 256; ima->gen_y= 256;
                                ima->gen_type= 1;
                                
-                               if(0==strncmp(ima->id.name+2, "Viewer Node", sizeof(ima->id.name+2))) {
+                               if(0==strncmp(ima->id.name+2, "Viewer Node", sizeof(ima->id.name)-2)) {
                                        ima->source= IMA_SRC_VIEWER;
                                        ima->type= IMA_TYPE_COMPOSITE;
                                }
-                               if(0==strncmp(ima->id.name+2, "Render Result", sizeof(ima->id.name+2))) {
+                               if(0==strncmp(ima->id.name+2, "Render Result", sizeof(ima->id.name)-2)) {
                                        ima->source= IMA_SRC_VIEWER;
                                        ima->type= IMA_TYPE_R_RESULT;
                                }
@@ -8595,7 +8745,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                ima->flag |= IMA_STD_FIELD;
                                }
                                tex->iuser.frames= tex->frames;
-                               tex->iuser.fie_ima= tex->fie_ima;
+                               tex->iuser.fie_ima= (char)tex->fie_ima;
                                tex->iuser.offset= tex->offset;
                                tex->iuser.sfra= tex->sfra;
                                tex->iuser.cycl= (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
@@ -8903,7 +9053,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        strcpy (simasel->dir,  U.textudir);     /* TON */
                                                        strcpy (simasel->file, "");
                                                        
-                                                       simasel->returnfunc     =  0;   
+                                                       simasel->returnfunc     =  NULL;
                                                        simasel->title[0]       =  0;
                                                }
                                        }
@@ -9193,7 +9343,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
                Scene *sce;
                Object *ob;
-               PartEff *paf=0;
+               PartEff *paf=NULL;
 
                for(ob = main->object.first; ob; ob= ob->id.next) {
                        if(ob->soft && ob->soft->keys) {
@@ -9479,7 +9629,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                
                                fluidmd->fss->lastgoodframe = INT_MAX;
                                fluidmd->fss->flag = 0;
-                               fluidmd->fss->meshSurfNormals = 0;
+                               fluidmd->fss->meshSurfNormals = NULL;
                        }
                }
        }
@@ -9597,7 +9747,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Lamp *la;
 
                for(la=main->lamp.first; la; la= la->id.next) {
-                       if(la->atm_turbidity == 0.0) {
+                       if(la->atm_turbidity == 0.0f) {
                                la->sun_effect_type = 0;
                                la->horizon_brightness = 1.0f;
                                la->spread = 1.0f;
@@ -9851,8 +10001,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        if(seq->type == SEQ_HD_SOUND)
                                        {
                                                char str[FILE_MAX];
-                                               BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
-                                               BLI_path_abs(str, G.main->name);
+                                               BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
+                                               BLI_path_abs(str, main->name);
                                                seq->sound = sound_new_file(main, str);
                                        }
                                        /* don't know, if anybody used that
@@ -10069,7 +10219,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                for(sce = main->scene.first; sce; sce = sce->id.next) {
                        ts= sce->toolsettings;
-                       if(ts->normalsize == 0.0 || !ts->uv_selectmode || ts->vgroup_weight == 0.0) {
+                       if(ts->normalsize == 0.0f || !ts->uv_selectmode || ts->vgroup_weight == 0.0f) {
                                ts->normalsize= 0.1f;
                                ts->selectmode= SCE_SELECT_VERTEX;
                                
@@ -11296,7 +11446,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
-
+       
        // init facing axis property of steering actuators
        {                                       
                Object *ob;
@@ -11343,7 +11493,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        KeyBlock *kb;
                        
                        for (kb = key->block.first; kb; kb = kb->next) {
-                               if (IS_EQ(kb->slidermin, kb->slidermax) && IS_EQ(kb->slidermax, 0))
+                               if (IS_EQF(kb->slidermin, kb->slidermax) && IS_EQ(kb->slidermax, 0))
                                        kb->slidermax = kb->slidermin + 1.0f;
                        }
                }
@@ -11371,11 +11521,46 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
-       /* put compatibility code here until next subversion bump */
-       
-       {
+       if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)) {
+               bNodeTree *ntree;
+               
+               /* node sockets are not exposed automatically any more,
+                * this mimics the old behaviour by adding all unlinked sockets to groups.
+                */
+               for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
+                       /* XXX Only setting a flag here. Actual adding of group sockets
+                        * is done in lib_verify_nodetree, because at this point the internal
+                        * nodes may not be up-to-date! (missing lib-link)
+                        */
+                       ntree->flag |= NTREE_DO_VERSIONS;
+               }
+       }
+
+       if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile <3)){
                bScreen *sc;
+               Brush *brush;
+               Object *ob;
+               ParticleSettings *part;
+               Material *mat;
+               int tex_nr, transp_tex;
                
+               for(mat = main->mat.first; mat; mat = mat->id.next){
+                       if(!(mat->mode & MA_TRANSP) && !(mat->material_type & MA_TYPE_VOLUME)){
+                               
+                               transp_tex= 0;
+                               
+                               for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++){
+                                       if(!mat->mtex[tex_nr]) continue;
+                                       if(mat->mtex[tex_nr]->mapto & MAP_ALPHA) transp_tex= 1;
+                               }
+                               
+                               if(mat->alpha < 1.0f || mat->fresnel_tra > 0.0f || transp_tex){
+                                       mat->mode |= MA_TRANSP;
+                                       mat->mode &= ~(MA_ZTRANSP|MA_RAYTRANSP);
+                               }
+                       }
+               }
+
                /* redraws flag in SpaceTime has been moved to Screen level */
                for (sc = main->screen.first; sc; sc= sc->id.next) {
                        if (sc->redraws_flag == 0) {
@@ -11384,8 +11569,110 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                sc->redraws_flag = TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
                        }
                }
+
+               for (brush= main->brush.first; brush; brush= brush->id.next) {
+                       if(brush->height == 0)
+                               brush->height= 0.4f;
+               }
+
+               /* replace 'rim material' option for in offset*/
+               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_Solidify) {
+                                       SolidifyModifierData *smd = (SolidifyModifierData *)md;
+                                       if(smd->flag & MOD_SOLIDIFY_RIM_MATERIAL) {
+                                               smd->mat_ofs_rim= 1;
+                                               smd->flag &= ~MOD_SOLIDIFY_RIM_MATERIAL;
+                                       }
+                               }
+                       }
+               }
+
+               /* particle draw color from material */
+               for(part = main->particle.first; part; part = part->id.next) {
+                       if(part->draw & PART_DRAW_MAT_COL)
+                               part->draw_col = PART_DRAW_COL_MAT;
+               }
+       }
+
+       if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 6)){
+               Mesh *me;
+
+               for(me= main->mesh.first; me; me= me->id.next)
+                       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
        }
 
+       if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)){
+               /* update blur area sizes from 0..1 range to 0..100 percentage */
+               Scene *scene;
+               bNode *node;
+               for (scene=main->scene.first; scene; scene=scene->id.next)
+                       if (scene->nodetree)
+                               for (node=scene->nodetree->nodes.first; node; node=node->next)
+                                       if (node->type==CMP_NODE_BLUR) {
+                                               NodeBlurData *nbd= node->storage;
+                                               nbd->percentx *= 100.0f;
+                                               nbd->percenty *= 100.0f;
+                                       }
+       }
+
+       /* put compatibility code here until next subversion bump */
+
+       {
+               /* screen view2d settings were not properly initialized [#27164]
+                * v2d->scroll caused the bug but best reset other values too which are in old blend files only.
+                * need to make less ugly - possibly an iterator? */
+               bScreen *screen;
+               for(screen= main->screen.first; screen; screen= screen->id.next) {
+                       ScrArea *sa;
+                       /* add regions */
+                       for(sa= screen->areabase.first; sa; sa= sa->next) {
+                               SpaceLink *sl= sa->spacedata.first;
+                               if(sl->spacetype==SPACE_IMAGE) {
+                                       ARegion *ar;
+                                       for (ar=sa->regionbase.first; ar; ar= ar->next) {
+                                               if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                                       View2D *v2d= &ar->v2d;
+                                                       v2d->minzoom= v2d->maxzoom= v2d->scroll= v2d->keeptot= v2d->keepzoom= v2d->keepofs= v2d->align= 0;
+                                               }
+                                       }
+                               }
+                               for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                       if(sl->spacetype==SPACE_IMAGE) {
+                                               ARegion *ar;
+                                               for (ar=sl->regionbase.first; ar; ar= ar->next) {
+                                                       if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                                               View2D *v2d= &ar->v2d;
+                                                               v2d->minzoom= v2d->maxzoom= v2d->scroll= v2d->keeptot= v2d->keepzoom= v2d->keepofs= v2d->align= 0;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               {
+                       /* Initialize texture point density curve falloff */
+                       Tex *tex;
+                       for(tex= main->tex.first; tex; tex= tex->id.next) {
+                               if(tex->pd) {
+                                       if (tex->pd->falloff_speed_scale == 0.0)
+                                               tex->pd->falloff_speed_scale = 100.0;
+
+                                       if (!tex->pd->falloff_curve) {
+                                               tex->pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1);
+
+                                               tex->pd->falloff_curve->preset = CURVE_PRESET_LINE;
+                                               tex->pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+                                               curvemap_reset(tex->pd->falloff_curve->cm, &tex->pd->falloff_curve->clipr, tex->pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
+                                               curvemapping_changed(tex->pd->falloff_curve, 0);
+                                       }
+                               }
+                       }
+               }
+       }
+       
        //set defaults for obstacle avoidance, recast data
        {
                Scene *sce;
@@ -11422,7 +11709,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                sce->gm.recastData.detailsamplemaxerror = 1.0f;
                }                       
        }
-
+       
        /* 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! */
 
@@ -11876,6 +12163,8 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
 
 static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
 {
+       int a;
+
        expand_doit(fd, mainvar, part->dup_ob);
        expand_doit(fd, mainvar, part->dup_group);
        expand_doit(fd, mainvar, part->eff_group);
@@ -11883,6 +12172,13 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
        
        if(part->adt)
                expand_animdata(fd, mainvar, part->adt);
+
+       for(a=0; a<MAX_MTEX; a++) {
+               if(part->mtex[a]) {
+                       expand_doit(fd, mainvar, part->mtex[a]->tex);
+                       expand_doit(fd, mainvar, part->mtex[a]->object);
+               }
+       }
 }
 
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
@@ -12136,50 +12432,19 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
        }
 }
 
-static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
+static void expand_object_expandModifiers(void *userData, Object *UNUSED(ob),
+                                                                                         ID **idpoin)
 {
-       if (md->type==eModifierType_Lattice) {
-               LatticeModifierData *lmd = (LatticeModifierData*) md;
-                       
-               expand_doit(fd, mainvar, lmd->object);
-       } 
-       else if (md->type==eModifierType_Curve) {
-               CurveModifierData *cmd = (CurveModifierData*) md;
-                       
-               expand_doit(fd, mainvar, cmd->object);
-       }
-       else if (md->type==eModifierType_Array) {
-               ArrayModifierData *amd = (ArrayModifierData*) md;
-                       
-               expand_doit(fd, mainvar, amd->curve_ob);
-               expand_doit(fd, mainvar, amd->offset_ob);
-       }
-       else if (md->type==eModifierType_Mirror) {
-               MirrorModifierData *mmd = (MirrorModifierData*) md;
-                       
-               expand_doit(fd, mainvar, mmd->mirror_ob);
-       }
-       else if (md->type==eModifierType_Displace) {
-               DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-               
-               expand_doit(fd, mainvar, dmd->map_object);
-               expand_doit(fd, mainvar, dmd->texture);
-       }
-       else if (md->type==eModifierType_Smoke) {
-               SmokeModifierData *smd = (SmokeModifierData*) md;
-                       
-               if(smd->type==MOD_SMOKE_TYPE_DOMAIN && smd->domain)
-               {       
-                       expand_doit(fd, mainvar, smd->domain->coll_group);
-                       expand_doit(fd, mainvar, smd->domain->fluid_group);
-                       expand_doit(fd, mainvar, smd->domain->eff_group);
-               }
-       }
+       struct { FileData *fd; Main *mainvar; } *data= userData;
+
+       FileData *fd= data->fd;
+       Main *mainvar= data->mainvar;
+
+       expand_doit(fd, mainvar, *idpoin);
 }
 
 static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 {
-       ModifierData *md;
        ParticleSystem *psys;
        bSensor *sens;
        bController *cont;
@@ -12189,9 +12454,14 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
        int a;
 
        expand_doit(fd, mainvar, ob->data);
-       
-       for (md=ob->modifiers.first; md; md=md->next) {
-               expand_modifier(fd, mainvar, md);
+
+       /* expand_object_expandModifier() */
+       if(ob->modifiers.first) {
+               struct { FileData *fd; Main *mainvar; } data;
+               data.fd= fd;
+               data.mainvar= mainvar;
+
+               modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data);
        }
 
        expand_pose(fd, mainvar, ob->pose);
@@ -12404,7 +12674,7 @@ static void expand_main(FileData *fd, Main *mainvar)
        ID *id;
        int a, doit= 1;
 
-       if(fd==0) return;
+       if(fd==NULL) return;
 
        while(doit) {
                doit= 0;
@@ -12572,7 +12842,9 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
        }
 }
 
-static void append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
+/* returns true if the item was found
+ * but it may already have already been appended/linked */
+static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
 {
        Scene *scene= CTX_data_scene(C);
        Object *ob;
@@ -12580,6 +12852,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
        BHead *bhead;
        ID *id;
        int endloop=0;
+       int found=0;
 
        bhead = blo_firstbhead(fd);
        while(bhead && endloop==0) {
@@ -12589,7 +12862,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
                        char *idname= bhead_id_name(fd, bhead);
                                
                        if(strcmp(idname+2, name)==0) {
-
+                               found= 1;
                                id= is_yet_read(fd, mainl, bhead);
                                if(id==NULL) {
                                        read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
@@ -12636,12 +12909,14 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
 
                bhead = blo_nextbhead(fd, bhead);
        }
+
+       return found;
 }
 
-void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
+int BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
 {
        FileData *fd= (FileData*)(*bh);
-       append_named_part(C, mainl, fd, name, idcode, flag);
+       return append_named_part(C, mainl, fd, name, idcode, flag);
 }
 
 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)