Merging r58475 through r58700 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / blenloader / intern / readfile.c
index a425928130d51c098bcf7a9db3e783ed5c848b02..e71b3c644599f66c1f4a7e0f736b7e4f9162c713 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
+#include "BLI_threads.h"
 
 #include "BLF_translation.h"
 
@@ -1315,6 +1316,8 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
                        oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
                if (ima->gputexture)
                        oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
+               if (ima->rr)
+                       oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
                for (a=0; a < IMA_MAX_RENDER_SLOT; a++)
                        if (ima->renders[a])
                                oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
@@ -1356,12 +1359,14 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                                ima->bindcode = 0;
                                ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                                ima->gputexture = NULL;
+                               ima->rr = NULL;
                        }
                }
                for (i = 0; i < IMA_MAX_RENDER_SLOT; i++)
                        ima->renders[i] = newimaadr(fd, ima->renders[i]);
                
                ima->gputexture = newimaadr(fd, ima->gputexture);
+               ima->rr = newimaadr(fd, ima->rr);
        }
        for (; sce; sce = sce->id.next) {
                if (sce->nodetree && sce->nodetree->previews) {
@@ -2361,6 +2366,21 @@ static void lib_link_nodetree(FileData *fd, Main *main)
        }
 }
 
+/* get node tree stored locally in other IDs */
+static bNodeTree *nodetree_from_id(ID *id)
+{
+       if (!id)
+               return NULL;
+       switch (GS(id->name)) {
+               case ID_SCE: return ((Scene *)id)->nodetree;
+               case ID_MA: return ((Material *)id)->nodetree;
+               case ID_WO: return ((World *)id)->nodetree;
+               case ID_LA: return ((Lamp *)id)->nodetree;
+               case ID_TE: return ((Tex *)id)->nodetree;
+       }
+       return NULL;
+}
+
 /* updates group node socket identifier so that
  * external links to/from the group node are preserved.
  */
@@ -2374,7 +2394,7 @@ static void lib_node_do_versions_group_indices(bNode *gnode)
                int old_index = sock->to_index;
                
                for (link = ngroup->links.first; link; link = link->next) {
-                       if (link->tonode->type == NODE_GROUP_OUTPUT && link->fromsock->own_index == old_index) {
+                       if (link->tonode == NULL && link->fromsock->own_index == old_index) {
                                strcpy(sock->identifier, link->fromsock->identifier);
                                /* deprecated */
                                sock->own_index = link->fromsock->own_index;
@@ -2387,7 +2407,7 @@ static void lib_node_do_versions_group_indices(bNode *gnode)
                int old_index = sock->to_index;
                
                for (link = ngroup->links.first; link; link = link->next) {
-                       if (link->fromnode->type == NODE_GROUP_INPUT && link->tosock->own_index == old_index) {
+                       if (link->fromnode == NULL && link->tosock->own_index == old_index) {
                                strcpy(sock->identifier, link->tosock->identifier);
                                /* deprecated */
                                sock->own_index = link->tosock->own_index;
@@ -2506,9 +2526,11 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
                                                        link->fromsock = node_group_input_find_socket(input_node, link->fromsock->identifier);
                                                        ++num_inputs;
                                                        
-                                                       if (input_locx > link->tonode->locx - offsetx)
-                                                               input_locx = link->tonode->locx - offsetx;
-                                                       input_locy += link->tonode->locy;
+                                                       if (link->tonode) {
+                                                               if (input_locx > link->tonode->locx - offsetx)
+                                                                       input_locx = link->tonode->locx - offsetx;
+                                                               input_locy += link->tonode->locy;
+                                                       }
                                                }
                                                else
                                                        free_link = TRUE;
@@ -2520,9 +2542,11 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
                                                        link->tosock = node_group_output_find_socket(output_node, link->tosock->identifier);
                                                        ++num_outputs;
                                                        
-                                                       if (output_locx < link->fromnode->locx + offsetx)
-                                                               output_locx = link->fromnode->locx + offsetx;
-                                                       output_locy += link->fromnode->locy;
+                                                       if (link->fromnode) {
+                                                               if (output_locx < link->fromnode->locx + offsetx)
+                                                                       output_locx = link->fromnode->locx + offsetx;
+                                                               output_locy += link->fromnode->locy;
+                                                       }
                                                }
                                                else
                                                        free_link = TRUE;
@@ -2559,8 +2583,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
        {
                FOREACH_NODETREE(main, ntree, id) {
                        /* make an update call for the tree */
-                       if (ntree->update)
-                               ntreeUpdateTree(ntree);
+                       ntreeUpdateTree(main, ntree);
                } FOREACH_NODETREE_END
        }
 }
@@ -2944,8 +2967,10 @@ static void lib_link_lamp(FileData *fd, Main *main)
                        
                        la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system
                        
-                       if (la->nodetree)
+                       if (la->nodetree) {
                                lib_link_ntree(fd, &la->id, la->nodetree);
+                               la->nodetree->id.lib = la->id.lib;
+                       }
                        
                        la->id.flag -= LIB_NEED_LINK;
                }
@@ -3090,7 +3115,6 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
        
        mb->disp.first = mb->disp.last = NULL;
        mb->editelems = NULL;
-       mb->bb = NULL;
 /*     mb->edit_elems.first= mb->edit_elems.last= NULL;*/
        mb->lastelem = NULL;
 }
@@ -3117,8 +3141,10 @@ static void lib_link_world(FileData *fd, Main *main)
                                }
                        }
                        
-                       if (wrld->nodetree)
+                       if (wrld->nodetree) {
                                lib_link_ntree(fd, &wrld->id, wrld->nodetree);
+                               wrld->nodetree->id.lib = wrld->id.lib;
+                       }
                        
                        wrld->id.flag -= LIB_NEED_LINK;
                }
@@ -3264,10 +3290,10 @@ static void direct_link_image(FileData *fd, Image *ima)
                ima->bindcode = 0;
                ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                ima->gputexture = NULL;
+               ima->rr = NULL;
        }
        
        ima->anim = NULL;
-       ima->rr = NULL;
        ima->repbind = NULL;
        
        /* undo system, try to restore render buffers */
@@ -3364,11 +3390,8 @@ static void direct_link_curve(FileData *fd, Curve *cu)
                if (cu->wordspace == 0.0f) cu->wordspace = 1.0f;
        }
 
-       cu->bev.first = cu->bev.last = NULL;
-       cu->disp.first = cu->disp.last = NULL;
        cu->editnurb = NULL;
        cu->lastsel = NULL;
-       cu->path = NULL;
        cu->editfont = NULL;
        
        for (nu = cu->nurb.first; nu; nu = nu->next) {
@@ -3406,8 +3429,10 @@ static void lib_link_texture(FileData *fd, Main *main)
                        if (tex->ot)
                                tex->ot->object = newlibadr(fd, tex->id.lib, tex->ot->object);
                        
-                       if (tex->nodetree)
+                       if (tex->nodetree) {
                                lib_link_ntree(fd, &tex->id, tex->nodetree);
+                               tex->nodetree->id.lib = tex->id.lib;
+                       }
                        
                        tex->id.flag -= LIB_NEED_LINK;
                }
@@ -3488,8 +3513,10 @@ static void lib_link_material(FileData *fd, Main *main)
                                }
                        }
                        
-                       if (ma->nodetree)
+                       if (ma->nodetree) {
                                lib_link_ntree(fd, &ma->id, ma->nodetree);
+                               ma->nodetree->id.lib = ma->id.lib;
+                       }
                        
                        ma->id.flag -= LIB_NEED_LINK;
                }
@@ -4117,6 +4144,11 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        mesh->bb = NULL;
        mesh->edit_btmesh = NULL;
        
+       /* happens with old files */
+       if (mesh->mselect == NULL) {
+               mesh->totselect = 0;
+       }
+
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
        if (mesh->mr) {
@@ -4577,6 +4609,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                smd->domain->smd = smd;
                                
                                smd->domain->fluid = NULL;
+                               smd->domain->fluid_mutex = BLI_rw_mutex_alloc();
                                smd->domain->wt = NULL;
                                smd->domain->shadow = NULL;
                                smd->domain->tex = NULL;
@@ -4775,13 +4808,14 @@ static void direct_link_object(FileData *fd, Object *ob)
        
        /* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
        ob->flag &= ~OB_FROMGROUP;
-       
+
        /* loading saved files with editmode enabled works, but for undo we like
-        * to stay in object mode during undo presses so keep editmode disabled */
-       if (fd->memfile)
+        * to stay in object mode during undo presses so keep editmode disabled.
+        *
+        * Also when linking in a file don't allow editmode: [#34776] */
+       if (fd->memfile || (ob->id.flag & (LIB_EXTERN | LIB_INDIRECT))) {
                ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
-       
-       ob->disp.first = ob->disp.last = NULL;
+       }
        
        ob->adt = newdataadr(fd, ob->adt);
        direct_link_animdata(fd, ob->adt);
@@ -4977,6 +5011,9 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->gpulamp.first= ob->gpulamp.last = NULL;
        link_list(fd, &ob->pc_ids);
 
+       /* Runtime curve data  */
+       ob->curve_cache = NULL;
+
        /* in case this value changes in future, clamp else we get undefined behavior */
        CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
 
@@ -5023,6 +5060,7 @@ static void lib_link_scene(FileData *fd, Main *main)
        Sequence *seq;
        SceneRenderLayer *srl;
        TimeMarker *marker;
+       FreestyleModuleConfig *fmc;
        FreestyleLineSet *fls;
        
        for (sce = main->scene.first; sce; sce = sce->id.next) {
@@ -5132,12 +5170,16 @@ static void lib_link_scene(FileData *fd, Main *main)
                        
                        if (sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
+                               sce->nodetree->id.lib = sce->id.lib;
                                composite_patch(sce->nodetree, sce);
                        }
                        
                        for (srl = sce->r.layers.first; srl; srl = srl->next) {
                                srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override);
                                srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override);
+                               for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
+                                       fmc->script = newlibadr(fd, sce->id.lib, fmc->script);
+                               }
                                for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
                                        fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle);
                                        fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
@@ -5474,6 +5516,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        wm->winactive = NULL;
        wm->initialized = 0;
        wm->op_undo_depth = 0;
+       wm->is_interface_locked = 0;
 }
 
 static void lib_link_windowmanager(FileData *fd, Main *main)
@@ -5654,9 +5697,26 @@ static void lib_link_screen(FileData *fd, Main *main)
                                        else if (sl->spacetype == SPACE_NODE) {
                                                SpaceNode *snode = (SpaceNode *)sl;
                                                bNodeTreePath *path, *path_next;
+                                               bNodeTree *ntree;
                                                
-                                               for (path=snode->treepath.first; path; path=path->next) {
-                                                       path->nodetree = newlibadr(fd, sc->id.lib, path->nodetree);
+                                               /* node tree can be stored locally in id too, link this first */
+                                               snode->id = newlibadr(fd, sc->id.lib, snode->id);
+                                               snode->from = newlibadr(fd, sc->id.lib, snode->from);
+                                               
+                                               ntree = nodetree_from_id(snode->id);
+                                               if (ntree)
+                                                       snode->nodetree = ntree;
+                                               else {
+                                                       snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree);
+                                               }
+                                               
+                                               for (path = snode->treepath.first; path; path = path->next) {
+                                                       if (path == snode->treepath.first) {
+                                                               /* first nodetree in path is same as snode->nodetree */
+                                                               path->nodetree = snode->nodetree;
+                                                       }
+                                                       else
+                                                               path->nodetree = newlibadr_us(fd, sc->id.lib, path->nodetree);
                                                        
                                                        if (!path->nodetree)
                                                                break;
@@ -5670,7 +5730,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        MEM_freeN(path);
                                                }
                                                
-                                               snode->nodetree = newlibadr(fd, sc->id.lib, snode->nodetree);
                                                /* edittree is just the last in the path,
                                                 * set this directly since the path may have been shortened above */
                                                if (snode->treepath.last) {
@@ -5679,8 +5738,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                }
                                                else
                                                        snode->edittree = NULL;
-                                               snode->id = newlibadr(fd, sc->id.lib, snode->id);
-                                               snode->from = newlibadr(fd, sc->id.lib, snode->from);
                                        }
                                        else if (sl->spacetype == SPACE_CLIP) {
                                                SpaceClip *sclip = (SpaceClip *)sl;
@@ -5729,52 +5786,38 @@ static bool restore_pointer(ID *id, ID *newid, int user)
 static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
 {
        if (id) {
-               /* node trees can be stored locally in other IDs, needs special handling ... */
-               if (GS(id->name) == ID_NT) {
-                       ID *idn = NULL;
+               ListBase *lb = which_libbase(mainp, GS(id->name));
+               if (lb) {       // there's still risk of checking corrupt mem (freed Ids in oops)
+                       ID *idn = lb->first;
                        
-                       FOREACH_NODETREE(mainp, ntree, owner_id) {
-                               if (restore_pointer(id, &ntree->id, user)) {
-                                       idn = &ntree->id;
+                       for (; idn; idn = idn->next) {
+                               if (restore_pointer(id, idn, user))
                                        break;
-                               }
                        }
-                       FOREACH_NODETREE_END
                        
                        return idn;
                }
-               else {
-                       ListBase *lb = which_libbase(mainp, GS(id->name));
-                       if (lb) {       // there's still risk of checking corrupt mem (freed Ids in oops)
-                               ID *idn = lb->first;
-                               
-                               for (; idn; idn = idn->next) {
-                                       if (restore_pointer(id, idn, user))
-                                               break;
-                               }
-                               
-                               return idn;
-                       }
-               }
        }
        return NULL;
 }
 
+static void lib_link_seq_clipboard_pt_restore(ID *id, Main *newmain)
+{
+       if (id) {
+               /* clipboard must ensure this */
+               BLI_assert(id->newid != NULL);
+               id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, 1);
+       }
+}
 static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
 {
        Main *newmain = (Main *)arg_pt;
-       
-       if (seq->sound) {
-               seq->sound = restore_pointer_by_name(newmain, (ID *)seq->sound, 0);
-               seq->sound->id.us++;
-       }
-       
-       if (seq->scene)
-               seq->scene = restore_pointer_by_name(newmain, (ID *)seq->scene, 1);
-       
-       if (seq->scene_camera)
-               seq->scene_camera = restore_pointer_by_name(newmain, (ID *)seq->scene_camera, 1);
-       
+
+       lib_link_seq_clipboard_pt_restore((ID *)seq->scene, newmain);
+       lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, newmain);
+       lib_link_seq_clipboard_pt_restore((ID *)seq->clip, newmain);
+       lib_link_seq_clipboard_pt_restore((ID *)seq->mask, newmain);
+       lib_link_seq_clipboard_pt_restore((ID *)seq->sound, newmain);
        return 1;
 }
 
@@ -5986,9 +6029,25 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
                                else if (sl->spacetype == SPACE_NODE) {
                                        SpaceNode *snode= (SpaceNode *)sl;
                                        bNodeTreePath *path, *path_next;
+                                       bNodeTree *ntree;
+                                       
+                                       /* node tree can be stored locally in id too, link this first */
+                                       snode->id = restore_pointer_by_name(newmain, snode->id, 1);
+                                       snode->from = restore_pointer_by_name(newmain, snode->from, 0);
+                                       
+                                       ntree = nodetree_from_id(snode->id);
+                                       if (ntree)
+                                               snode->nodetree = ntree;
+                                       else
+                                               snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, 0);
                                        
-                                       for (path=snode->treepath.first; path; path=path->next) {
-                                               path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 0);
+                                       for (path = snode->treepath.first; path; path = path->next) {
+                                               if (path == snode->treepath.first) {
+                                                       /* first nodetree in path is same as snode->nodetree */
+                                                       path->nodetree = snode->nodetree;
+                                               }
+                                               else
+                                                       path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 2);
                                                
                                                if (!path->nodetree)
                                                        break;
@@ -6002,7 +6061,6 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
                                                MEM_freeN(path);
                                        }
                                        
-                                       snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, 0);
                                        /* edittree is just the last in the path,
                                         * set this directly since the path may have been shortened above */
                                        if (snode->treepath.last) {
@@ -6011,8 +6069,6 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
                                        }
                                        else
                                                snode->edittree = NULL;
-                                       snode->id = restore_pointer_by_name(newmain, snode->id, 1);
-                                       snode->from = restore_pointer_by_name(newmain, snode->from, 0);
                                }
                                else if (sl->spacetype == SPACE_CLIP) {
                                        SpaceClip *sclip = (SpaceClip *)sl;
@@ -6111,11 +6167,12 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
                v3d->twtype = V3D_MANIP_TRANSLATE;
 }
 
-static void direct_link_screen(FileData *fd, bScreen *sc)
+static bool direct_link_screen(FileData *fd, bScreen *sc)
 {
        ScrArea *sa;
        ScrVert *sv;
        ScrEdge *se;
+       bool wrong_id = false;
        
        link_list(fd, &(sc->vertbase));
        link_list(fd, &(sc->edgebase));
@@ -6137,8 +6194,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                }
                
                if (se->v1 == NULL) {
-                       printf("error reading screen... file corrupt\n");
-                       se->v1 = se->v2;
+                       printf("Error reading Screen %s... removing it.\n", sc->id.name+2);
+                       BLI_remlink(&sc->edgebase, se);
+                       wrong_id = true;
                }
        }
        
@@ -6203,9 +6261,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                v3d->properties_storage = NULL;
                                v3d->defmaterial = NULL;
                                
-                               /* render can be quite heavy, set to wire on load */
+                               /* render can be quite heavy, set to solid on load */
                                if (v3d->drawtype == OB_RENDER)
-                                       v3d->drawtype = OB_WIRE;
+                                       v3d->drawtype = OB_SOLID;
                                
                                blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
                        }
@@ -6361,7 +6419,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                
                                sclip->scopes.track_search = NULL;
                                sclip->scopes.track_preview = NULL;
-                               sclip->draw_context = NULL;
                                sclip->scopes.ok = 0;
                        }
                }
@@ -6373,6 +6430,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                sa->v3 = newdataadr(fd, sa->v3);
                sa->v4 = newdataadr(fd, sa->v4);
        }
+       
+       return wrong_id;
 }
 
 /* ********** READ LIBRARY *************** */
@@ -6547,7 +6606,7 @@ static void lib_link_group(FileData *fd, Main *main)
                                }
                        }
                        if (add_us) group->id.us++;
-                       rem_from_group(group, NULL, NULL, NULL);        /* removes NULL entries */
+                       BKE_group_object_unlink(group, NULL, NULL, NULL);       /* removes NULL entries */
                }
        }
 }
@@ -6593,15 +6652,12 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
        clip->tracking.stats = NULL;
 
        clip->tracking.stabilization.ok = 0;
-       clip->tracking.stabilization.scaleibuf = NULL;
        clip->tracking.stabilization.rot_track = newdataadr(fd, clip->tracking.stabilization.rot_track);
 
        clip->tracking.dopesheet.ok = 0;
        clip->tracking.dopesheet.channels.first = clip->tracking.dopesheet.channels.last = NULL;
        clip->tracking.dopesheet.coverage_segments.first = clip->tracking.dopesheet.coverage_segments.last = NULL;
 
-       clip->prefetch_ok = FALSE;
-
        link_list(fd, &tracking->objects);
        
        for (object = tracking->objects.first; object; object = object->next) {
@@ -6760,7 +6816,7 @@ static void lib_link_linestyle(FileData *fd, Main *main)
                                        break;
                                }
                        }
-                       for (m = linestyle->alpha_modifiers.first; m; m = m->next){
+                       for (m = linestyle->alpha_modifiers.first; m; m = m->next) {
                                switch (m->type) {
                                case LS_MODIFIER_DISTANCE_FROM_OBJECT:
                                        {
@@ -6770,7 +6826,7 @@ static void lib_link_linestyle(FileData *fd, Main *main)
                                        break;
                                }
                        }
-                       for (m = linestyle->thickness_modifiers.first; m; m = m->next){
+                       for (m = linestyle->thickness_modifiers.first; m; m = m->next) {
                                switch (m->type) {
                                case LS_MODIFIER_DISTANCE_FROM_OBJECT:
                                        {
@@ -6982,6 +7038,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        ID *id;
        ListBase *lb;
        const char *allocname;
+       bool wrong_id = false;
        
        /* read libblock */
        id = read_struct(fd, bhead, "lib block");
@@ -7029,7 +7086,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                        direct_link_windowmanager(fd, (wmWindowManager *)id);
                        break;
                case ID_SCR:
-                       direct_link_screen(fd, (bScreen *)id);
+                       wrong_id = direct_link_screen(fd, (bScreen *)id);
                        break;
                case ID_SCE:
                        direct_link_scene(fd, (Scene *)id);
@@ -7126,6 +7183,10 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        oldnewmap_free_unused(fd->datamap);
        oldnewmap_clear(fd->datamap);
        
+       if (wrong_id) {
+               BKE_libblock_free(lb, id);
+       }
+       
        return (bhead);
 }
 
@@ -7361,7 +7422,6 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
                        bNodeSocket *old_image = BLI_findlink(&node->inputs, 0);
                        bNodeSocket *old_z = BLI_findlink(&node->inputs, 1);
                        bNodeSocket *sock;
-                       char basepath[FILE_MAXDIR];
                        char filename[FILE_MAXFILE];
                        
                        /* ugly, need to remove the old inputs list to avoid bad pointer checks when adding new sockets.
@@ -7373,6 +7433,8 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
                        
                        /* looks like storage data can be messed up somehow, stupid check here */
                        if (old_data) {
+                               char basepath[FILE_MAXDIR];
+
                                /* split off filename from the old path, to be used as socket sub-path */
                                BLI_split_dirfile(old_data->name, basepath, filename, sizeof(basepath), sizeof(filename));
                                
@@ -7380,7 +7442,6 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
                                nimf->format = old_data->im_format;
                        }
                        else {
-                               basepath[0] = '\0';
                                BLI_strncpy(filename, old_image->name, sizeof(filename));
                        }
                        
@@ -7628,31 +7689,38 @@ static const char *node_get_static_idname(int type, int treetype)
 static const char *node_socket_get_static_idname(bNodeSocket *sock)
 {
        switch (sock->type) {
-       case SOCK_FLOAT: {
-               bNodeSocketValueFloat *dval = sock->default_value;
-               return nodeStaticSocketType(SOCK_FLOAT, dval->subtype);
-       }
-       case SOCK_INT: {
-               bNodeSocketValueInt *dval = sock->default_value;
-               return nodeStaticSocketType(SOCK_INT, dval->subtype);
-       }
-       case SOCK_BOOLEAN: {
-               return nodeStaticSocketType(SOCK_BOOLEAN, PROP_NONE);
-       }
-       case SOCK_VECTOR: {
-               bNodeSocketValueVector *dval = sock->default_value;
-               return nodeStaticSocketType(SOCK_VECTOR, dval->subtype);
-       }
-       case SOCK_RGBA: {
-               return nodeStaticSocketType(SOCK_RGBA, PROP_NONE);
-       }
-       case SOCK_STRING: {
-               bNodeSocketValueString *dval = sock->default_value;
-               return nodeStaticSocketType(SOCK_STRING, dval->subtype);
-       }
-       case SOCK_SHADER: {
-               return nodeStaticSocketType(SOCK_SHADER, PROP_NONE);
-       }
+               case SOCK_FLOAT:
+               {
+                       bNodeSocketValueFloat *dval = sock->default_value;
+                       return nodeStaticSocketType(SOCK_FLOAT, dval->subtype);
+               }
+               case SOCK_INT:
+               {
+                       bNodeSocketValueInt *dval = sock->default_value;
+                       return nodeStaticSocketType(SOCK_INT, dval->subtype);
+               }
+               case SOCK_BOOLEAN:
+               {
+                       return nodeStaticSocketType(SOCK_BOOLEAN, PROP_NONE);
+               }
+               case SOCK_VECTOR:
+               {
+                       bNodeSocketValueVector *dval = sock->default_value;
+                       return nodeStaticSocketType(SOCK_VECTOR, dval->subtype);
+               }
+               case SOCK_RGBA:
+               {
+                       return nodeStaticSocketType(SOCK_RGBA, PROP_NONE);
+               }
+               case SOCK_STRING:
+               {
+                       bNodeSocketValueString *dval = sock->default_value;
+                       return nodeStaticSocketType(SOCK_STRING, dval->subtype);
+               }
+               case SOCK_SHADER:
+               {
+                       return nodeStaticSocketType(SOCK_SHADER, PROP_NONE);
+               }
        }
        return "";
 }
@@ -7724,27 +7792,27 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro
                for (node=ntree->nodes.first; node; node=node->next) {
                        for (sock = node->inputs.first; sock; sock = sock->next) {
                                BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier));
-                               BLI_uniquename(&node->inputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
+                               BLI_uniquename(&node->inputs, sock, "socket", '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
                        }
                        for (sock = node->outputs.first; sock; sock = sock->next) {
                                BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier));
-                               BLI_uniquename(&node->outputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
+                               BLI_uniquename(&node->outputs, sock, "socket", '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
                        }
                }
                for (sock = ntree->inputs.first; sock; sock = sock->next) {
                        BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier));
-                       BLI_uniquename(&ntree->inputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
+                       BLI_uniquename(&ntree->inputs, sock, "socket", '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
                }
                for (sock = ntree->outputs.first; sock; sock = sock->next) {
                        BLI_strncpy(sock->identifier, sock->name, sizeof(sock->identifier));
-                       BLI_uniquename(&ntree->outputs, sock, sock->identifier, '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
+                       BLI_uniquename(&ntree->outputs, sock, "socket", '.', offsetof(bNodeSocket, identifier), sizeof(sock->identifier));
                }
        }
 }
 
 /* initialize userdef with non-UI dependency stuff */
 /* other initializers (such as theme color defaults) go to resources.c */
-static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
+static void do_versions_userdef(FileData *UNUSED(fd), BlendFileData *bfd)
 {
        Main *bmain = bfd->main;
        UserDef *user = bfd->user;
@@ -7760,14 +7828,8 @@ static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
                        copy_v4_v4_char(btheme->tseq.grid, btheme->tseq.back);
                }
        }
-       
-       if (bmain->versionfile < 267) {
-       
-               if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
-                       user->image_gpubuffer_limit = 20;
-               
-       }
 }
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -8124,7 +8186,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                if (ba->axis==(float) 'x') ba->axis=OB_POSX;
                                                else if (ba->axis==(float)'y') ba->axis=OB_POSY;
                                                /* don't do an if/else to avoid imediate subversion bump*/
-//                                     ba->axis=((ba->axis == (float) 'x')?OB_POSX_X:OB_POSY);
+//                                             ba->axis=((ba->axis == (float)'x') ? OB_POSX_X : OB_POSY);
                                        }
                                }
                        }
@@ -8876,7 +8938,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* Fix for bug #32982, internal_links list could get corrupted from r51630 onward.
                 * Simply remove bad internal_links lists to avoid NULL pointers.
                 */
-               FOREACH_NODETREE(main, ntree, id)
+               FOREACH_NODETREE(main, ntree, id) {
                        bNode *node;
                        bNodeLink *link, *nextlink;
                        
@@ -8888,7 +8950,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        }
                                }
                        }
-               FOREACH_NODETREE_END
+               FOREACH_NODETREE_END
        }
        
        if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) {
@@ -9262,22 +9324,55 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Brush *brush;
                for (brush = main->brush.first; brush; brush = brush->id.next) {
                        default_mtex(&brush->mask_mtex);
+
+                       if (brush->ob_mode & OB_MODE_TEXTURE_PAINT) {
+                               brush->spacing /= 2;
+                       }
+               }
+       }
+
+       if (!MAIN_VERSION_ATLEAST(main, 266, 6)) {
+               Brush *brush;
+               #define BRUSH_TEXTURE_OVERLAY (1 << 21)
+
+               for (brush = main->brush.first; brush; brush = brush->id.next) {
+                       brush->overlay_flags = 0;
+                       if (brush->flag & BRUSH_TEXTURE_OVERLAY)
+                               brush->overlay_flags |= (BRUSH_OVERLAY_PRIMARY | BRUSH_OVERLAY_CURSOR);
                }
+               #undef BRUSH_TEXTURE_OVERLAY
        }
 
        if (main->versionfile < 267) {
-               
+               //if (!DNA_struct_elem_find(fd->filesdna, "Brush", "int", "stencil_pos")) {
+               Brush *brush;
+
+               for (brush = main->brush.first; brush; brush = brush->id.next) {
+                       if (brush->stencil_dimension[0] == 0) {
+                               brush->stencil_dimension[0] = 256;
+                               brush->stencil_dimension[1] = 256;
+                               brush->stencil_pos[0] = 256;
+                               brush->stencil_pos[1] = 256;
+                       }
+                       if (brush->mask_stencil_dimension[0] == 0) {
+                               brush->mask_stencil_dimension[0] = 256;
+                               brush->mask_stencil_dimension[1] = 256;
+                               brush->mask_stencil_pos[0] = 256;
+                               brush->mask_stencil_pos[1] = 256;
+                       }
+               }
+
                /* TIP: to initialize new variables added, use the new function
-                  DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname")
-                  example: 
-                               if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
-                                       user->image_gpubuffer_limit = 10;
+                * DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname")
+                * example:
+                * if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
+                *     user->image_gpubuffer_limit = 10;
                 */
                
        }
        
        /* default values in Freestyle settings */
-       {
+       if (main->versionfile < 267) {
                Scene *sce;
                SceneRenderLayer *srl;
                FreestyleLineStyle *linestyle;
@@ -9296,6 +9391,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        srl->freestyleConfig.flags |= FREESTYLE_CULLING;
                                }
                        }
+
+                       /* not freestyle */
+                       {
+                               MeshStatVis *statvis = &sce->toolsettings->statvis;
+                               if (statvis->thickness_samples == 0) {
+                                       statvis->overhang_axis = OB_NEGZ;
+                                       statvis->overhang_min = 0;
+                                       statvis->overhang_max = DEG2RADF(45.0f);
+
+                                       statvis->thickness_max = 0.1f;
+                                       statvis->thickness_samples = 1;
+
+                                       statvis->distort_min = DEG2RADF(5.0f);
+                                       statvis->distort_max = DEG2RADF(45.0f);
+
+                                       statvis->sharp_min = DEG2RADF(90.0f);
+                                       statvis->sharp_max = DEG2RADF(180.0f);
+                               }
+                       }
+
                }
                for(linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
 #if 1
@@ -9314,63 +9429,106 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                linestyle->rounds = 3;
                }
        }
-       /* The code segment below will be removed when the trunk merger is done.
-          For now it is kept for backward compatibility, giving branch users time
-          to migrate to the new CustomData-based edge/face marks. */
-       {
-               Mesh *me;
-               MEdge *medge;
-               MPoly *mpoly;
-               int i, found;
 
-               for (me = main->mesh.first; me; me = me->id.next) {
-                       /* Freestyle edge marks */
-                       found = 0;
-                       medge = me->medge;
-                       for (i = 0; i < me->totedge; i++) {
-                               if (medge->flag & ME_FREESTYLE_EDGE) {
-                                       found = 1;
+       if (main->versionfile < 267) {
+               /* Initialize the active_viewer_key for compositing */
+               bScreen *screen;
+               Scene *scene;
+               bNodeInstanceKey active_viewer_key = {0};
+               /* simply pick the first node space and use that for the active viewer key */
+               for (screen = main->screen.first; screen; screen = screen->id.next) {
+                       ScrArea *sa;
+                       for (sa = screen->areabase.first; sa; sa = sa->next) {
+                               SpaceLink *sl;
+                               for (sl = sa->spacedata.first; sl; sl= sl->next) {
+                                       if (sl->spacetype == SPACE_NODE) {
+                                               SpaceNode *snode = (SpaceNode *)sl;
+                                               bNodeTreePath *path = snode->treepath.last;
+                                               if (!path)
+                                                       continue;
+                                               
+                                               active_viewer_key = path->parent_key;
+                                               break;
+                                       }
+                               }
+                               if (active_viewer_key.value != 0)
                                        break;
+                       }
+                       if (active_viewer_key.value != 0)
+                               break;
+               }
+               
+               for (scene = main->scene.first; scene; scene = scene->id.next) {
+                       /* NB: scene->nodetree is a local ID block, has been direct_link'ed */
+                       if (scene->nodetree)
+                               scene->nodetree->active_viewer_key = active_viewer_key;
+               }
+       }
+
+       if (MAIN_VERSION_OLDER(main, 267, 1))
+       {
+               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) {
+                                               if (smd->domain->flags & MOD_SMOKE_HIGH_SMOOTH) {
+                                                       smd->domain->highres_sampling = SM_HRES_LINEAR;
+                                               }
+                                               else {
+                                                       smd->domain->highres_sampling = SM_HRES_NEAREST;
+                                               }
+                                       }
                                }
-                               medge++;
                        }
-                       if (found) {
-                               FreestyleEdge *fed = CustomData_add_layer(&me->edata, CD_FREESTYLE_EDGE, CD_CALLOC, NULL, me->totedge);
-                               medge = me->medge;
-                               for (i = 0; i < me->totedge; i++) {
-                                       if (medge->flag & ME_FREESTYLE_EDGE) {
-                                               medge->flag &= ~ME_FREESTYLE_EDGE;
-                                               fed->flag |= FREESTYLE_EDGE_MARK;
+               }
+       }
+
+       if (!MAIN_VERSION_ATLEAST(main, 268, 1)) {
+               Brush *brush;
+               for (brush = main->brush.first; brush; brush = brush->id.next) {
+                       brush->spacing = MAX2(1, brush->spacing);
+               }
+       }
+       
+       {
+               bScreen *sc;
+               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_FLOW) && smd->flow) {
+                                               if (!smd->flow->particle_size) {
+                                                       smd->flow->particle_size = 1.0f;
+                                               }
                                        }
-                                       medge++;
-                                       fed++;
-                               }
-                               me->cd_flag |= ME_CDFLAG_FREESTYLE_EDGE;
-                               printf("Migrated to CustomData-based Freestyle edge marks\n");
-                       }
-                       /* Freestyle face marks */
-                       found = 0;
-                       mpoly = me->mpoly;
-                       for (i = 0; i < me->totpoly; i++) {
-                               if (mpoly->flag & ME_FREESTYLE_FACE) {
-                                       found = 1;
-                                       break;
                                }
-                               mpoly++;
                        }
-                       if (found) {
-                               FreestyleFace *ffa = CustomData_add_layer(&me->pdata, CD_FREESTYLE_FACE, CD_CALLOC, NULL, me->totpoly);
-                               mpoly = me->mpoly;
-                               for (i = 0; i < me->totpoly; i++) {
-                                       if (mpoly->flag & ME_FREESTYLE_FACE) {
-                                               mpoly->flag &= ~ME_FREESTYLE_FACE;
-                                               ffa->flag |= FREESTYLE_FACE_MARK;
+               }
+
+               /*
+                * FIX some files have a zoom level of 0, and was checked during the drawing of the node space
+                *
+                * We moved this check to the do versions to be sure the value makes any sense.
+                */
+               for (sc = main->screen.first; sc; sc = sc->id.next) {
+                       ScrArea *sa;
+                       for (sa = sc->areabase.first; sa; sa = sa->next) {
+                               SpaceLink *sl;
+                               for (sl = sa->spacedata.first; sl; sl = sl->next) {
+                                       if (sl->spacetype == SPACE_NODE) {
+                                               SpaceNode *snode = (SpaceNode *)sl;
+                                               if (snode->zoom < 0.02f) {
+                                                       snode->zoom = 1.0;
+                                               }
                                        }
-                                       mpoly++;
-                                       ffa++;
                                }
-                               me->cd_flag |= ME_CDFLAG_FREESTYLE_FACE;
-                               printf("Migrated to CustomData-based Freestyle face marks\n");
                        }
                }
        }
@@ -9466,6 +9624,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
        link_list(fd, &user->themes);
        link_list(fd, &user->user_keymaps);
        link_list(fd, &user->addons);
+       link_list(fd, &user->autoexec_paths);
        
        for (keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
                keymap->modal_items= NULL;
@@ -10367,6 +10526,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
 {
        Base *base;
        SceneRenderLayer *srl;
+       FreestyleModuleConfig *module;
        FreestyleLineSet *lineset;
        
        for (base = sce->base.first; base; base = base->next) {
@@ -10388,6 +10548,10 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
        for (srl = sce->r.layers.first; srl; srl = srl->next) {
                expand_doit(fd, mainvar, srl->mat_override);
                expand_doit(fd, mainvar, srl->light_override);
+               for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
+                       if (module->script)
+                               expand_doit(fd, mainvar, module->script);
+               }
                for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
                        if (lineset->group)
                                expand_doit(fd, mainvar, lineset->group);
@@ -10501,11 +10665,11 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li
                if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
                        expand_doit(fd, mainvar, ((LineStyleColorModifier_DistanceFromObject *)m)->target);
        }
-       for (m = linestyle->alpha_modifiers.first; m; m = m->next){
+       for (m = linestyle->alpha_modifiers.first; m; m = m->next) {
                if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
                        expand_doit(fd, mainvar, ((LineStyleAlphaModifier_DistanceFromObject *)m)->target);
        }
-       for (m = linestyle->thickness_modifiers.first; m; m = m->next){
+       for (m = linestyle->thickness_modifiers.first; m; m = m->next) {
                if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
                        expand_doit(fd, mainvar, ((LineStyleThicknessModifier_DistanceFromObject *)m)->target);
        }