== Constraints System ==
[blender.git] / source / blender / blenloader / intern / readfile.c
index a61e254c5335954a5f72e87b92aad2ab58bc4f68..c140ebb804eed205c68e163e192b1e6e2c50aebf 100644 (file)
 #include "BKE_effect.h" // for give_parteff
 #include "BKE_global.h" // for G
 #include "BKE_group.h"
-#include "BKE_property.h" // for get_property
+#include "BKE_image.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h" // for wich_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_modifier.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
+#include "BKE_property.h" // for get_property
 #include "BKE_sca.h" // for init_actuator
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
@@ -553,8 +554,7 @@ static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
                }
 
                /* this patch is to avoid a long long being read from not-eight aligned positions
-                  is necessary on SGI with -n32 compiling (no, is necessary on
-                  any modern 64bit architecture) */
+                  is necessary on any modern 64bit architecture) */
                memcpy(&old, &bhead8->old, 8);
                bhead4->old = (int) (old >> 3);
 
@@ -793,8 +793,12 @@ static int read_file_dna(FileData *fd)
                        int do_endian_swap= (fd->flags&FD_FLAGS_SWITCH_ENDIAN)?1:0;
 
                        fd->filesdna= dna_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
-                       if (fd->filesdna)
+                       if (fd->filesdna) {
+                               
                                fd->compflags= dna_get_structDNA_compareflags(fd->filesdna, fd->memsdna);
+                               /* used to retrieve ID names from (bhead+1) */
+                               fd->id_name_offs= dna_elem_offset(fd->filesdna, "ID", "char", "name[]");
+                       }
 
                        return 1;
                } else if (bhead->code==ENDB)
@@ -1108,8 +1112,9 @@ void blo_make_image_pointer_map(FileData *fd)
        fd->imamap= oldnewmap_new();
        
        for(;ima; ima= ima->id.next) {
-               if(ima->ibuf)
-                       oldnewmap_insert(fd->imamap, ima->ibuf, ima->ibuf, 0);
+               Link *ibuf= ima->ibufs.first;
+               for(; ibuf; ibuf= ibuf->next) 
+                       oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1136,11 +1141,15 @@ void blo_end_image_pointer_map(FileData *fd)
        }
        
        for(;ima; ima= ima->id.next) {
-               if(ima->ibuf) {
-                       ima->ibuf= newimaadr(fd, ima->ibuf);
-                       /* this mirrors direct_link_image */
-                       if(ima->ibuf==NULL)
+               Link *ibuf, *next;
+               
+               /* this mirrors direct_link_image */
+               for(ibuf= ima->ibufs.first; ibuf; ibuf= next) {
+                       next= ibuf->next;
+                       if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
+                               BLI_remlink(&ima->ibufs, ibuf);
                                ima->bindcode= 0;
+                       }
                }
        }
        for(; sce; sce= sce->id.next) {
@@ -1155,11 +1164,11 @@ void blo_end_image_pointer_map(FileData *fd)
 /* undo file support: add all library pointers in lookup */
 void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
 {
-       Main *main= mainlist->first;
+       Main *ptr= mainlist->first;
        ListBase *lbarray[MAX_LIBARRAY];
        
-       for(main= main->next; main; main= main->next) {
-               int i= set_listbasepointers(main, lbarray);
+       for(ptr= ptr->next; ptr; ptr= ptr->next) {
+               int i= set_listbasepointers(ptr, lbarray);
                while(i--) {
                        ID *id;
                        for(id= lbarray[i]->first; id; id= id->next)
@@ -1177,7 +1186,7 @@ static void switch_endian_structs(struct SDNA *filesdna, BHead *bhead)
        int blocksize, nblocks;
        char *data;
 
-       data= (char *)(bhead+1); /*  BHEAD+DATA dependancy */
+       data= (char *)(bhead+1);
        blocksize= filesdna->typelens[ filesdna->structs[bhead->SDNAnr][0] ];
 
        nblocks= bhead->nr;
@@ -1193,6 +1202,7 @@ static void *read_struct(FileData *fd, BHead *bh, char *blockname)
        void *temp= NULL;
 
        if (bh->len) {
+               /* switch is based on file dna */
                if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN))
                        switch_endian_structs(fd->filesdna, bh);
 
@@ -1201,7 +1211,7 @@ static void *read_struct(FileData *fd, BHead *bh, char *blockname)
                                temp= dna_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
                        } else {
                                temp= MEM_mallocN(bh->len, blockname);
-                               memcpy(temp, (bh+1), bh->len); /*  BHEAD+DATA dependancy */
+                               memcpy(temp, (bh+1), bh->len);
                        }
                }
        }
@@ -1213,11 +1223,11 @@ static void link_list(FileData *fd, ListBase *lb)               /* only direct data */
 {
        Link *ln, *prev;
 
-       if(lb->first==0) return;
+       if(lb->first==NULL) return;
 
        lb->first= newdataadr(fd, lb->first);
        ln= lb->first;
-       prev= 0;
+       prev= NULL;
        while(ln) {
                ln->next= newdataadr(fd, ln->next);
                ln->prev= prev;
@@ -1480,9 +1490,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                        /* could be handlerized at some point */
                        if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
                                direct_link_curvemapping(fd, node->storage);
-                       else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
-                               direct_link_curvemapping(fd, node->storage);
-                       
+                       else if(ntree->type==NTREE_COMPOSIT) {
+                               if( ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB))
+                                       direct_link_curvemapping(fd, node->storage);
+                               else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+                                       ((ImageUser *)node->storage)->ok= 1;
+                       }
                }
                link_list(fd, &node->inputs);
                link_list(fd, &node->outputs);
@@ -1598,6 +1611,15 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                }
 
                switch (con->type) {
+               case CONSTRAINT_TYPE_PYTHON:
+                       {
+                               bPythonConstraint *data;
+                               data= (bPythonConstraint*)con->data;
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                               data->text = newlibadr(fd, id->lib, data->text);
+                               //IDP_LibLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                       }
+                       break;
                case CONSTRAINT_TYPE_ACTION:
                        {
                                bActionConstraint *data;
@@ -1611,21 +1633,21 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                bLocateLikeConstraint *data;
                                data= ((bLocateLikeConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
                case CONSTRAINT_TYPE_ROTLIKE:
                        {
                                bRotateLikeConstraint *data;
                                data= ((bRotateLikeConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
                case CONSTRAINT_TYPE_SIZELIKE:
                        {
                                bSizeLikeConstraint *data;
                                data= ((bSizeLikeConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
                case CONSTRAINT_TYPE_KINEMATIC:
                        {
@@ -1653,55 +1675,43 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                bLockTrackConstraint *data;
                                data= ((bLockTrackConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
                case CONSTRAINT_TYPE_FOLLOWPATH:
                        {
                                bFollowPathConstraint *data;
                                data= ((bFollowPathConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
-                       break;
-               case CONSTRAINT_TYPE_DISTANCELIMIT:
-                       {
-                               bDistanceLimitConstraint *data;
-                               data= ((bDistanceLimitConstraint*)con->data);
-                               data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
                case CONSTRAINT_TYPE_STRETCHTO:
                        {
                                bStretchToConstraint *data;
                                data= ((bStretchToConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
-                       break;
-               case CONSTRAINT_TYPE_LOCLIMIT:
-                       {
-                               bLocLimitConstraint *data;
-                               data= ((bLocLimitConstraint*)con->data);
-                       };
+                       }
                        break;
-               case CONSTRAINT_TYPE_ROTLIMIT:
+               case CONSTRAINT_TYPE_RIGIDBODYJOINT:
                        {
-                               bRotLimitConstraint *data;
-                               data= ((bRotLimitConstraint*)con->data);
-                       };
+                               bRigidBodyJointConstraint *data;
+                               data= ((bRigidBodyJointConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
                        break;
-               case CONSTRAINT_TYPE_SIZELIMIT:
+               case CONSTRAINT_TYPE_CLAMPTO:
                        {
-                               bSizeLimitConstraint *data;
-                               data= ((bSizeLimitConstraint*)con->data);
-                       };
+                               bClampToConstraint *data;
+                               data= ((bClampToConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
                        break;
-               case CONSTRAINT_TYPE_RIGIDBODYJOINT:
+               case CONSTRAINT_TYPE_CHILDOF:
                        {
-                               bRigidBodyJointConstraint *data;
-                               data= ((bRigidBodyJointConstraint*)con->data);
+                               bChildOfConstraint *data;
+                               data= ((bChildOfConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
-                       };
+                       }
                        break;
-
                case CONSTRAINT_TYPE_NULL:
                        break;
                }
@@ -1715,6 +1725,11 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
        link_list(fd, lb);
        for (cons=lb->first; cons; cons=cons->next) {
                cons->data = newdataadr(fd, cons->data);
+               if (cons->type == CONSTRAINT_TYPE_PYTHON) {
+                       bPythonConstraint *data= cons->data;
+                       data->prop = newdataadr(fd, data->prop);
+                       IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               }
        }
 }
 
@@ -2167,16 +2182,38 @@ static void lib_link_image(FileData *fd, Main *main)
        }
 }
 
+static void link_ibuf_list(FileData *fd, ListBase *lb)
+{
+       Link *ln, *prev;
+       
+       if(lb->first==NULL) return;
+       
+       lb->first= newimaadr(fd, lb->first);
+       ln= lb->first;
+       prev= NULL;
+       while(ln) {
+               ln->next= newimaadr(fd, ln->next);
+               ln->prev= prev;
+               prev= ln;
+               ln= ln->next;
+       }
+       lb->last= prev;
+}
+
 static void direct_link_image(FileData *fd, Image *ima)
 {
        /* for undo system, pointers could be restored */
-       ima->ibuf= newimaadr(fd, ima->ibuf);
-       /* if restored, we keep the binded opengl index */
-       if(ima->ibuf==NULL)
+       if(fd->imamap)
+               link_ibuf_list(fd, &ima->ibufs);
+       else
+               ima->ibufs.first= ima->ibufs.last= NULL;
+       
+       /* if not restored, we keep the binded opengl index */
+       if(ima->ibufs.first==NULL)
                ima->bindcode= 0;
        
-       memset(ima->mipmap, 0, sizeof(ima->mipmap));
        ima->anim= NULL;
+       ima->rr= NULL;
        ima->repbind= NULL;
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
@@ -2319,10 +2356,11 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        tex->coba= newdataadr(fd, tex->coba);
        tex->env= newdataadr(fd, tex->env);
        if(tex->env) {
-               tex->env->ima= 0;
+               tex->env->ima= NULL;
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
+       tex->iuser.ok= 1;
 }
 
 
@@ -2395,6 +2433,18 @@ static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
        }
 }
 
+static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
+{
+       int i;  
+       for(i=0; i<fdata->totlayer; i++) {
+               CustomDataLayer *layer = &fdata->layers[i];
+               
+               if(layer->type == CD_MTFACE)
+                       lib_link_mtface(fd, me, layer->data, totface);
+       }
+
+}
+
 static void lib_link_mesh(FileData *fd, Main *main)
 {
        Mesh *me;
@@ -2420,12 +2470,11 @@ static void lib_link_mesh(FileData *fd, Main *main)
                        me->key= newlibadr_us(fd, me->id.lib, me->key);
                        me->texcomesh= newlibadr_us(fd, me->id.lib, me->texcomesh);
 
-                       for(i=0; i<me->fdata.totlayer; i++) {
-                               CustomDataLayer *layer = &me->fdata.layers[i];
+                       lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
+                       if(me->mr && me->mr->levels.first)
+                               lib_link_customdata_mtface(fd, me, &me->mr->fdata,
+                                                          ((MultiresLevel*)me->mr->levels.first)->totface);
 
-                               if(layer->type == CD_MTFACE)
-                                       lib_link_mtface(fd, me, layer->data, me->totface);
-                       }
                        me->id.flag -= LIB_NEEDLINK;
                }
                me= me->id.next;
@@ -2455,15 +2504,10 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
        while (i < data->totlayer) {
                CustomDataLayer *layer = &data->layers[i];
 
-               if (layer->type < CD_NUMTYPES) {
+               if (CustomData_verify_versions(data, i)) {
                        layer->data = newdataadr(fd, layer->data);
                        i++;
                }
-               else {
-                       /* delete layer with unknown type */
-                       layer->data = NULL;
-                       CustomData_free_layer(data, layer->type, 0);
-               }
        }
 }
 
@@ -2480,14 +2524,23 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        mesh->mcol= newdataadr(fd, mesh->mcol);
        mesh->msticky= newdataadr(fd, mesh->msticky);
        mesh->dvert= newdataadr(fd, mesh->dvert);
+       
+       /* Partial-mesh visibility (do this before using totvert, totface, or totedge!) */
+       mesh->pv= newdataadr(fd, mesh->pv);
+       if(mesh->pv) {
+               mesh->pv->vert_map= newdataadr(fd, mesh->pv->vert_map);
+               mesh->pv->edge_map= newdataadr(fd, mesh->pv->edge_map);
+               mesh->pv->old_faces= newdataadr(fd, mesh->pv->old_faces);
+               mesh->pv->old_edges= newdataadr(fd, mesh->pv->old_edges);
+       }
 
        /* normally direct_link_dverts should be called in direct_link_customdata,
           but for backwards compat in do_versions to work we do it here */
-       direct_link_dverts(fd, mesh->totvert, mesh->dvert);
+       direct_link_dverts(fd, mesh->pv ? mesh->pv->totvert : mesh->totvert, mesh->dvert);
 
-       direct_link_customdata(fd, &mesh->vdata, mesh->totvert);
-       direct_link_customdata(fd, &mesh->edata, mesh->totedge);
-       direct_link_customdata(fd, &mesh->fdata, mesh->totface);
+       direct_link_customdata(fd, &mesh->vdata, mesh->pv ? mesh->pv->totvert : mesh->totvert);
+       direct_link_customdata(fd, &mesh->edata, mesh->pv ? mesh->pv->totedge : mesh->totedge);
+       direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
 
        mesh->bb= NULL;
        mesh->oc= 0;
@@ -2497,34 +2550,42 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        mesh->mr= newdataadr(fd, mesh->mr);
        if(mesh->mr) {
                MultiresLevel *lvl;
+               
                link_list(fd, &mesh->mr->levels);
                lvl= mesh->mr->levels.first;
+               
                direct_link_customdata(fd, &mesh->mr->vdata, lvl->totvert);
+               direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
+               direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
+               
+               if(mesh->mr->edge_flags)
+                       mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
+               if(mesh->mr->edge_creases)
+                       mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
+               
+               if(!mesh->mr->edge_flags)
+                       mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
+               if(!mesh->mr->edge_creases)
+                       mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
+
+               mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
+                       
                for(; lvl; lvl= lvl->next) {
                        lvl->verts= newdataadr(fd, lvl->verts);
                        lvl->faces= newdataadr(fd, lvl->faces);
                        lvl->edges= newdataadr(fd, lvl->edges);
-                       lvl->texcolfaces= newdataadr(fd, lvl->texcolfaces);
-
-                       /* Recalculating the maps is faster than reading them from the file */
-                       multires_calc_level_maps(lvl);
+                       lvl->colfaces= newdataadr(fd, lvl->colfaces);
+                       lvl->edge_boundary_states= NULL;
+                       lvl->vert_face_map = lvl->vert_edge_map = NULL;
+                       lvl->map_mem= NULL;
                }
        }
-
-       /* PMV */
-       mesh->pv= newdataadr(fd, mesh->pv);
-       if(mesh->pv) {
-               mesh->pv->vert_map= newdataadr(fd, mesh->pv->vert_map);
-               mesh->pv->edge_map= newdataadr(fd, mesh->pv->edge_map);
-               mesh->pv->old_faces= newdataadr(fd, mesh->pv->old_faces);
-               mesh->pv->old_edges= newdataadr(fd, mesh->pv->old_edges);
-       }
        
        if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) {
                TFace *tf= mesh->tface;
                int i;
 
-               for (i=0; i<mesh->totface; i++, tf++) {
+               for (i=0; i< (mesh->pv ? mesh->pv->totface : mesh->totface); i++, tf++) {
                        SWITCH_INT(tf->col[0]);
                        SWITCH_INT(tf->col[1]);
                        SWITCH_INT(tf->col[2]);
@@ -2569,6 +2630,9 @@ static void lib_link_modifiers__linkModifiers(void *userData, Object *ob,
        FileData *fd = userData;
 
        *idpoin = newlibadr(fd, ob->id.lib, *idpoin);
+       /* hardcoded bad exception; non-object modifier data gets user count (texture, displace) */
+       if(*idpoin && GS((*idpoin)->name)!=ID_OB)
+               (*idpoin)->us++;
 }
 static void lib_link_modifiers(FileData *fd, Object *ob)
 {
@@ -2619,7 +2683,7 @@ static void lib_link_object(FileData *fd, Main *main)
                                ob->type= OB_EMPTY;
                                warn= 1;
                                if(ob->id.lib) printf("Can't find obdata of %s lib %s\n", ob->id.name+2, ob->id.lib->name);
-                               else printf("Object %s lost data. Lib:%x\n", ob->id.name+2, (unsigned int) ob->id.lib);
+                               else printf("Object %s lost data.", ob->id.name+2);
                                
                                if(ob->pose) {
                                        free_pose_channels(ob->pose);
@@ -2993,6 +3057,7 @@ static void lib_link_scene(FileData *fd, Main *main)
        Base *base, *next;
        Editing *ed;
        Sequence *seq;
+       SceneRenderLayer *srl;
        int a;
        
        sce= main->scene.first;
@@ -3016,8 +3081,7 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        mtex->tex= newlibadr_us(fd, sce->id.lib, mtex->tex);
                        }
 
-                       base= sce->base.first;
-                       while(base) {
+                       for(base= sce->base.first; base; base= next) {
                                next= base->next;
 
                                /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */
@@ -3032,7 +3096,6 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        if(base==sce->basact) sce->basact= 0;
                                        MEM_freeN(base);
                                }
-                               base= next;
                        }
 
                        ed= sce->ed;
@@ -3057,7 +3120,12 @@ static void lib_link_scene(FileData *fd, Main *main)
                        
                        if(sce->nodetree)
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
-
+                       
+                       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);
+                       }
+                       
                        sce->id.flag -= LIB_NEEDLINK;
                }
 
@@ -3098,12 +3166,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        
        sce->toolsettings= newdataadr(fd, sce->toolsettings);
 
-       /* SculptData */
-       sce->sculptdata.active_ob= NULL;
-       sce->sculptdata.vertex_users= NULL;
-       sce->sculptdata.texrndr= NULL;
-       sce->sculptdata.propset= 0;
-       sce->sculptdata.undo= NULL;
+       sce->sculptdata.session= NULL;
        /* SculptData textures */
        for(a=0; a<MAX_MTEX; ++a)
                sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
@@ -3299,10 +3362,8 @@ static void lib_link_screen_sequence_ipos(Main *main)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= main->screen.first;
-       while(sc) {
-               sa= sc->areabase.first;
-               while(sa) {
+       for(sc= main->screen.first; sc; sc= sc->id.next) {
+               for(sa= sc->areabase.first; sa; sa= sa->next) {
                        SpaceLink *sl;
                        for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                if(sl->spacetype == SPACE_IPO) {
@@ -3312,9 +3373,7 @@ static void lib_link_screen_sequence_ipos(Main *main)
                                        }
                                }
                        }
-                       sa= sa->next;
                }
-               sc= sc->id.next;
        }
 }
 
@@ -3327,8 +3386,7 @@ static void lib_link_screen(FileData *fd, Main *main)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= main->screen.first;
-       while(sc) {
+       for(sc= main->screen.first; sc; sc= sc->id.next) {
                if(sc->id.flag & LIB_NEEDLINK) {
                        sc->id.us= 1;
                        sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
@@ -3351,8 +3409,6 @@ static void lib_link_screen(FileData *fd, Main *main)
 
                                                if(v3d->bgpic) {
                                                        v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
-                                                       v3d->bgpic->tex= newlibadr_us(fd, sc->id.lib, v3d->bgpic->tex);
-                                                       v3d->bgpic->rect= NULL;
                                                }
                                                if(v3d->localvd) {
                                                        v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
@@ -3379,9 +3435,11 @@ static void lib_link_screen(FileData *fd, Main *main)
                                        else if(sl->spacetype==SPACE_FILE) {
                                                SpaceFile *sfile= (SpaceFile *)sl;
 
-                                               sfile->filelist= 0;
-                                               sfile->libfiledata= 0;
-                                               sfile->returnfunc= 0;
+                                               sfile->filelist= NULL;
+                                               sfile->libfiledata= NULL;
+                                               sfile->returnfunc= NULL;
+                                               sfile->menup= NULL;
+                                               sfile->pupmenu= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
                                                check_imasel_copy((SpaceImaSel *)sl);
@@ -3441,7 +3499,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                        }
                        sc->id.flag -= LIB_NEEDLINK;
                }
-               sc= sc->id.next;
        }
 }
 
@@ -3479,8 +3536,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= newmain->screen.first;
-       while(sc) {
+       for(sc= newmain->screen.first; sc; sc= sc->id.next) {
                
                sc->scene= curscene;
 
@@ -3509,9 +3565,6 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        
                                        if(v3d->bgpic) {
                                                v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
-                                               v3d->bgpic->tex= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->tex, 1);
-                                               if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect);
-                                               v3d->bgpic->rect= NULL;
                                        }
                                        if(v3d->localvd) {
                                                Base *base;
@@ -3619,10 +3672,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                        }
                        sa= sa->next;
                }
-
-               sc= sc->id.next;
        }
-
 }
 
 static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -3674,16 +3724,22 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                link_list(fd, &(sa->spacedata));
                link_list(fd, &(sa->panels));
 
+               /* accident can happen when read/save new file with older version */
+               if(sa->spacedata.first==NULL && sa->spacetype>SPACE_NLA)
+                       sa->spacetype= SPACE_EMPTY;
+               
                for(pa= sa->panels.first; pa; pa=pa->next) {
                        pa->paneltab= newdataadr(fd, pa->paneltab);
                        pa->active= 0;
                        pa->sortcounter= 0;
                }
-
+               
                for (sl= sa->spacedata.first; sl; sl= sl->next) {
                        if (sl->spacetype==SPACE_VIEW3D) {
                                View3D *v3d= (View3D*) sl;
                                v3d->bgpic= newdataadr(fd, v3d->bgpic);
+                               if(v3d->bgpic)
+                                       v3d->bgpic->iuser.ok= 1;
                                v3d->localvd= newdataadr(fd, v3d->localvd);
                                v3d->afterdraw.first= v3d->afterdraw.last= NULL;
                                v3d->clipbb= newdataadr(fd, v3d->clipbb);
@@ -3714,7 +3770,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                sima->cumap= newdataadr(fd, sima->cumap);
                                if(sima->cumap)
                                        direct_link_curvemapping(fd, sima->cumap);
-                               sima->info_str= NULL;
+                               sima->info_str= sima->info_spare= NULL;
+                               sima->spare= NULL;
+                               sima->iuser.ok= 1;
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
@@ -3897,15 +3955,6 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        ListBase *lb;
        char *allocname;
        
-       if(bhead->code==ID_ID) {
-               ID *linkedid= (ID *)(bhead + 1); /*  BHEAD+DATA dependancy */
-
-               lb= wich_libbase(main, GS(linkedid->name));
-       }
-       else {
-               lb= wich_libbase(main, bhead->code);
-       }
-
        /* read libblock */
        id = read_struct(fd, bhead, "lib block");
        if (id_r)
@@ -3914,6 +3963,15 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                return blo_nextbhead(fd, bhead);
        
        oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);      /* for ID_ID check */
+       
+       /* do after read_struct, for dna reconstruct */
+       if(bhead->code==ID_ID) {
+               lb= wich_libbase(main, GS(id->name));
+       }
+       else {
+               lb= wich_libbase(main, bhead->code);
+       }
+       
        BLI_addtail(lb, id);
 
        /* clear first 8 bits */
@@ -4040,10 +4098,6 @@ static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg)
        bfd->displaymode= fg->displaymode;
        bfd->globalf= fg->globalf;
        
-       bfd->main->subversionfile= fg->subversion;
-       bfd->main->minversionfile= fg->minversion;
-       bfd->main->minsubversionfile= fg->minsubversion;
-       
        bfd->curscreen= newlibadr(fd, 0, fg->curscreen);
        bfd->curscene= newlibadr(fd, 0, fg->curscene);
        // this happens in files older than 2.35
@@ -4149,6 +4203,29 @@ static void ntree_version_241(bNodeTree *ntree)
        }
 }
 
+static void ntree_version_242(bNodeTree *ntree)
+{
+       bNode *node;
+       
+       if(ntree->type==NTREE_COMPOSIT) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(node->type==CMP_NODE_HUE_SAT) {
+                               if(node->storage) {
+                                       NodeHueSat *nhs= node->storage;
+                                       if(nhs->val==0.0f) nhs->val= 1.0f;
+                               }
+                       }
+               }
+       }
+       else if(ntree->type==NTREE_SHADER) {
+               for(node= ntree->nodes.first; node; node= node->next)
+                       if(node->type == SH_NODE_GEOMETRY && node->storage == NULL)
+                               node->storage= MEM_callocN(sizeof(NodeGeometry), "NodeGeometry");
+       }
+       
+}
+
+
 /* somehow, probably importing via python, keyblock adrcodes are not in order */
 static void sort_shape_fix(Main *main)
 {
@@ -4175,31 +4252,33 @@ static void sort_shape_fix(Main *main)
 
 static void customdata_version_242(Mesh *me)
 {
+       CustomDataLayer *layer;
        MTFace *mtf;
        MCol *mcol;
        TFace *tf;
-       int a;
+       int a, mtfacen, mcoln;
 
        if (!me->vdata.totlayer) {
-               CustomData_add_layer(&me->vdata, CD_MVERT, 0, me->mvert, me->totvert);
+               CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, me->mvert, me->totvert);
 
                if (me->msticky)
-                       CustomData_add_layer(&me->vdata, CD_MSTICKY, 0, me->msticky, me->totvert);
+                       CustomData_add_layer(&me->vdata, CD_MSTICKY, CD_ASSIGN, me->msticky, me->totvert);
                if (me->dvert)
-                       CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, 0, me->dvert, me->totvert);
+                       CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_ASSIGN, me->dvert, me->totvert);
        }
 
        if (!me->edata.totlayer)
-               CustomData_add_layer(&me->edata, CD_MEDGE, 0, me->medge, me->totedge);
+               CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->medge, me->totedge);
        
        if (!me->fdata.totlayer) {
-               CustomData_add_layer(&me->fdata, CD_MFACE, 0, me->mface, me->totface);
-
-               if (me->mcol || me->tface)
-                       me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, 0, me->mcol, me->totface);
+               CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->mface, me->totface);
 
                if (me->tface) {
-                       me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, 0, NULL, me->totface);
+                       if (me->mcol)
+                               MEM_freeN(me->mcol);
+
+                       me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
+                       me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface);
 
                        mtf= me->mtface;
                        mcol= me->mcol;
@@ -4220,6 +4299,9 @@ static void customdata_version_242(Mesh *me)
                        MEM_freeN(me->tface);
                        me->tface= NULL;
                }
+               else if (me->mcol) {
+                       me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, me->mcol, me->totface);
+               }
        }
 
        if (me->tface) {
@@ -4227,13 +4309,81 @@ static void customdata_version_242(Mesh *me)
                me->tface= NULL;
        }
 
+       for (a=0, mtfacen=0, mcoln=0; a < me->fdata.totlayer; a++) {
+               layer= &me->fdata.layers[a];
+
+               if (layer->type == CD_MTFACE) {
+                       if (layer->name[0] == 0) {
+                               if (mtfacen == 0) strcpy(layer->name, "UVTex");
+                               else sprintf(layer->name, "UVTex.%.3d", mtfacen);
+                       }
+                       mtfacen++;
+               }
+               else if (layer->type == CD_MCOL) {
+                       if (layer->name[0] == 0) {
+                               if (mcoln == 0) strcpy(layer->name, "Col");
+                               else sprintf(layer->name, "Col.%.3d", mcoln);
+                       }
+                       mcoln++;
+               }
+       }
+
        mesh_update_customdata_pointers(me);
 }
 
+/*only copy render texface layer from active*/
+static void customdata_version_243(Mesh *me)
+{
+       CustomDataLayer *layer;
+       int a;
+
+       for (a=0; a < me->fdata.totlayer; a++) {
+               layer= &me->fdata.layers[a];
+               layer->active_rnd = layer->active;
+       }
+}
+
+/* struct NodeImageAnim moved to ImageUser, and we make it default available */
+static void do_version_ntree_242_2(bNodeTree *ntree)
+{
+       bNode *node;
+       
+       if(ntree->type==NTREE_COMPOSIT) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+                               /* only image had storage */
+                               if(node->storage) {
+                                       NodeImageAnim *nia= node->storage;
+                                       ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "ima user node");
+
+                                       iuser->frames= nia->frames;
+                                       iuser->sfra= nia->sfra;
+                                       iuser->offset= nia->nr-1;
+                                       iuser->cycl= nia->cyclic;
+                                       iuser->fie_ima= 2;
+                                       iuser->ok= 1;
+                                       
+                                       node->storage= iuser;
+                                       MEM_freeN(nia);
+                               }
+                               else {
+                                       ImageUser *iuser= node->storage= MEM_callocN(sizeof(ImageUser), "node image user");
+                                       iuser->sfra= 1;
+                                       iuser->fie_ima= 2;
+                                       iuser->ok= 1;
+                               }
+                       }
+               }
+       }
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
 
+       if(G.f & G_DEBUG)
+               printf("read file %s\n  Version %d sub %d\n", fd->filename, main->versionfile, main->subversionfile);
+       
        if(main->versionfile == 100) {
                /* tex->extend and tex->imageflag have changed: */
                Tex *tex = main->tex.first;
@@ -4248,10 +4398,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        }
                                }
 
-                               if(tex->imaflag & TEX_ANIM5) {
-                                       tex->imaflag |= TEX_MORKPATCH;
-                                       tex->imaflag |= TEX_ANTIALI;
-                               }
                        }
                        tex= tex->id.next;
                }
@@ -4768,16 +4914,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* have to check the exact multiplier */
        }
 
-       if(main->versionfile <= 210) {
-               Scene *sce= main->scene.first;
-
-               while(sce) {
-                       if(sce->r.postmul== 0.0) sce->r.postmul= 1.0;
-                       if(sce->r.postgamma== 0.0) sce->r.postgamma= 1.0;
-                       sce= sce->id.next;
-               }
-       }
-
        if(main->versionfile <= 211) {
                /* Render setting: per scene, the applicable gamma value
                 * can be set. Default is 1.0, which means no
@@ -4785,11 +4921,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                bActuator *act;
                bObjectActuator *oa;
                Object *ob;
-               Scene *sce= main->scene.first;
-               while(sce) {
-                       sce->r.gamma = 2.0;
-                       sce= sce->id.next;
-               }
 
                /* added alpha in obcolor */
                ob= main->object.first;
@@ -5325,21 +5456,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Lamp *la;
                World *wrld;
 
+               /* 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->ang==0.0) {
-                               ma->ang= 1.0;
-                               ma->ray_depth= 2;
-                               ma->ray_depth_tra= 2;
-                               ma->fresnel_tra= 0.0;
-                               ma->fresnel_mir= 0.0;
-                       }
-                       else if(ma->ang<1.0) {          // temporal, because of IOR & fresnel change
-                               ma->ang= 1.0f/ma->ang;
-                               ma->fresnel_tra= ma->ang;
-                               ma->fresnel_mir= ma->ang;
-                       }
+
+                       ma->ang= 1.0;
+                       ma->ray_depth= 2;
+                       ma->ray_depth_tra= 2;
+                       ma->fresnel_tra= 0.0;
+                       ma->fresnel_mir= 0.0;
+
                        ma= ma->id.next;
                }
                sce= main->scene.first;
@@ -5533,7 +5660,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        tex= tex->id.next;
                }
                while(sce) {
-                       sce->r.postsat= 1.0;
                        ed= sce->ed;
                        if(ed) {
                                WHILE_SEQ(&ed->seqbase) {
@@ -5553,16 +5679,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                bScreen *sc;
 
                while(sce) {
-                       
-                       if(sce->r.postsat==0.0) sce->r.postsat= 1.0f;
-                       
-                       if(sce->r.zgamma==0.0) {
-                               sce->r.focus= 0.9f;
-                               sce->r.zgamma= 1.0f;
-                               sce->r.zsigma= 4.0f;
-                               sce->r.zblur= 10.0f;
-                               sce->r.zmin= 0.8f;
-                       }
                        if(sce->editbutsize==0.0) sce->editbutsize= 0.1f;
                        
                        sce= sce->id.next;
@@ -6038,8 +6154,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Nurb *nu;
                BezTriple *bezt;
                BPoint *bp;
+               bNodeTree *ntree;
                int a;
-
+               
                for(sc= main->screen.first; sc; sc= sc->id.next) {
                        ScrArea *sa;
                        sa= sc->areabase.first;
@@ -6060,14 +6177,22 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                for(sce= main->scene.first; sce; sce= sce->id.next) {
                        if (sce->toolsettings->select_thresh == 0.0f)
                                sce->toolsettings->select_thresh= 0.01f;
+                       if (sce->toolsettings->clean_thresh == 0.0f) 
+                               sce->toolsettings->clean_thresh = 0.1f;
+                               
                        if (sce->r.threads==0) {
                                if (sce->r.mode & R_THREADS)
                                        sce->r.threads= 2;
                                else
                                        sce->r.threads= 1;
                        }
+                       if(sce->nodetree)
+                               ntree_version_242(sce->nodetree);
                }
                
+               for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+                       ntree_version_242(ntree);
+               
                /* add default radius values to old curve points */
                for(cu= main->curve.first; cu; cu= cu->id.next) {
                        for(nu= cu->nurb.first; nu; nu= nu->next) {
@@ -6097,13 +6222,25 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        if (list){
                                bConstraint *curcon;
                                for (curcon = list->first; curcon; curcon=curcon->next){
-                                       if (curcon->type == CONSTRAINT_TYPE_MINMAX){
-                                               bMinMaxConstraint *data = curcon->data;
-                                               if (data->sticky==1) {
-                                                       data->flag|=MINMAX_STICKY;
-                                               } else {
-                                                       data->flag&=~MINMAX_STICKY;
+                                       switch (curcon->type) {
+                                               case CONSTRAINT_TYPE_MINMAX:
+                                               {
+                                                       bMinMaxConstraint *data = curcon->data;
+                                                       if (data->sticky==1) 
+                                                               data->flag |= MINMAX_STICKY;
+                                                       else 
+                                                               data->flag &= ~MINMAX_STICKY;
                                                }
+                                                       break;
+                                               case CONSTRAINT_TYPE_ROTLIKE:
+                                               {
+                                                       bRotateLikeConstraint *data = curcon->data;
+                                                       
+                                                       /* version patch from buttons_object.c */
+                                                       if(data->flag==0) 
+                                                               data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
+                                               }
+                                                       break;
                                        }
                                }
                        }
@@ -6112,24 +6249,36 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                if (ob->pose){
                                        bConstraint *curcon;
                                        bPoseChannel *pchan;
-                                       for (pchan = ob->pose->chanbase.first;
-                                                pchan; pchan=pchan->next){
-                                               for (curcon = pchan->constraints.first;
-                                                        curcon; curcon=curcon->next){
-                                                       if (curcon->type == CONSTRAINT_TYPE_MINMAX){
-                                                               bMinMaxConstraint *data = curcon->data;
-                                                               if (data->sticky==1) {
-                                                                       data->flag|=MINMAX_STICKY;
-                                                               } else {
-                                                                       data->flag&=~MINMAX_STICKY;
+                                       for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
+                                               for (curcon = pchan->constraints.first; curcon; curcon=curcon->next){
+                                                       switch (curcon->type) {
+                                                               case CONSTRAINT_TYPE_MINMAX:
+                                                               {
+                                                                       bMinMaxConstraint *data = curcon->data;
+                                                                       if (data->sticky==1) 
+                                                                               data->flag |= MINMAX_STICKY;
+                                                                       else 
+                                                                               data->flag &= ~MINMAX_STICKY;
                                                                }
-                                                       }
-                                                       else if (curcon->type == CONSTRAINT_TYPE_KINEMATIC){
-                                                               bKinematicConstraint *data = curcon->data;
-                                                               if (!(data->flag & CONSTRAINT_IK_POS)) {
-                                                                       data->flag |= CONSTRAINT_IK_POS;
-                                                                       data->flag |= CONSTRAINT_IK_STRETCH;
+                                                                       break;
+                                                               case CONSTRAINT_TYPE_KINEMATIC:
+                                                               {
+                                                                       bKinematicConstraint *data = curcon->data;
+                                                                       if (!(data->flag & CONSTRAINT_IK_POS)) {
+                                                                               data->flag |= CONSTRAINT_IK_POS;
+                                                                               data->flag |= CONSTRAINT_IK_STRETCH;
+                                                                       }
                                                                }
+                                                                       break;
+                                                               case CONSTRAINT_TYPE_ROTLIKE:
+                                                               {
+                                                                       bRotateLikeConstraint *data = curcon->data;
+                                                                       
+                                                                       /* version patch from buttons_object.c */
+                                                                       if(data->flag==0) 
+                                                                               data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
+                                                               }
+                                                                       break;
                                                        }
                                                }
                                        }
@@ -6150,6 +6299,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                for(ma = main->mat.first; ma; ma= ma->id.next) {
                        if(ma->shad_alpha==0.0f)
                                ma->shad_alpha= 1.0f;
+                       if(ma->nodetree)
+                               ntree_version_242(ma->nodetree);
                }
 
                for(me=main->mesh.first; me; me=me->id.next)
@@ -6161,10 +6312,306 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                
                /* History fix (python?), shape key adrcode numbers have to be sorted */
                sort_shape_fix(main);
-               
+                               
                /* now, subversion control! */
-               if(main->subversionfile < 1) {
+               if(main->subversionfile < 3) {
+                       bScreen *sc;
+                       Image *ima;
+                       Tex *tex;
+                       
+                       /* Image refactor initialize */
+                       for(ima= main->image.first; ima; ima= ima->id.next) {
+                               ima->source= IMA_SRC_FILE;
+                               ima->type= IMA_TYPE_IMAGE;
+                               
+                               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))) {
+                                       ima->source= IMA_SRC_VIEWER;
+                                       ima->type= IMA_TYPE_COMPOSITE;
+                               }
+                               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;
+                               }
+                               
+                       }
+                       for(tex= main->tex.first; tex; tex= tex->id.next) {
+                               if(tex->type==TEX_IMAGE && tex->ima) {
+                                       ima= newlibadr(fd, lib, tex->ima);
+                                       if(tex->imaflag & TEX_ANIM5_)
+                                               ima->source= IMA_SRC_MOVIE;
+                                       if(tex->imaflag & TEX_FIELDS_)
+                                               ima->flag |= IMA_FIELDS;
+                                       if(tex->imaflag & TEX_STD_FIELD_)
+                                               ima->flag |= IMA_STD_FIELD;
+                                       if(tex->imaflag & TEX_ANTIALI_)
+                                               ima->flag |= IMA_ANTIALI;
+                               }
+                               tex->iuser.frames= tex->frames;
+                               tex->iuser.fie_ima= tex->fie_ima;
+                               tex->iuser.offset= tex->offset;
+                               tex->iuser.sfra= tex->sfra;
+                               tex->iuser.cycl= (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
+                       }
+                       for(sce= main->scene.first; sce; sce= sce->id.next) {
+                               if(sce->nodetree)
+                                       do_version_ntree_242_2(sce->nodetree);
+                       }
+                       for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+                               do_version_ntree_242_2(ntree);
+                       for(ma = main->mat.first; ma; ma= ma->id.next)
+                               if(ma->nodetree)
+                                       do_version_ntree_242_2(ma->nodetree);
                        
+                       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_IMAGE)
+                                                       ((SpaceImage *)sl)->iuser.fie_ima= 2;
+                                               else if(sl->spacetype==SPACE_VIEW3D) {
+                                                       View3D *v3d= (View3D *)sl;
+                                                       if(v3d->bgpic)
+                                                               v3d->bgpic->iuser.fie_ima= 2;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               if(main->subversionfile < 4) {
+                       for(sce= main->scene.first; sce; sce= sce->id.next) {
+                               sce->r.bake_mode= 1;    /* prevent to include render stuff here */
+                               sce->r.bake_filter= 2;
+                               sce->r.bake_osa= 5;
+                               sce->r.bake_flag= R_BAKE_CLEAR;
+                       }
+               }
+
+               if(main->subversionfile < 5) {
+                       for(sce= main->scene.first; sce; sce= sce->id.next) {
+                               /* improved triangle to quad conversion settings */
+                               if(sce->toolsettings->jointrilimit==0.0f)
+                                       sce->toolsettings->jointrilimit= 0.8f;
+                       }
+               }
+       }
+       if(main->versionfile <= 243) {
+               Object *ob= main->object.first;
+               Camera *cam = main->camera.first;
+               Material *ma;
+               
+               for(; cam; cam= cam->id.next) {
+                       cam->angle= 360.0f * atan(16.0f/cam->lens) / M_PI;
+               }
+
+               for(ma=main->mat.first; ma; ma= ma->id.next) {
+                       if(ma->sss_scale==0.0f) {
+                               ma->sss_radius[0]= 1.0f;
+                               ma->sss_radius[1]= 1.0f;
+                               ma->sss_radius[2]= 1.0f;
+                               ma->sss_col[0]= 0.8f;
+                               ma->sss_col[1]= 0.8f;
+                               ma->sss_col[2]= 0.8f;
+                               ma->sss_error= 0.05f;
+                               ma->sss_scale= 0.1f;
+                               ma->sss_ior= 1.3f;
+                               ma->sss_colfac= 1.0f;
+                               ma->sss_texfac= 0.0f;
+                       }
+                       if(ma->sss_front==0 && ma->sss_back==0) {
+                               ma->sss_front= 1.0f;
+                               ma->sss_back= 1.0f;
+                       }
+                       if(ma->sss_col[0]==0 && ma->sss_col[1]==0 && ma->sss_col[2]==0) {
+                               ma->sss_col[0]= ma->r;
+                               ma->sss_col[1]= ma->g;
+                               ma->sss_col[2]= ma->b;
+                       }
+               }
+               
+               for(; ob; ob= ob->id.next) {
+                       bDeformGroup *curdef;
+                       
+                       for(curdef= ob->defbase.first; curdef; curdef=curdef->next) {
+                               /* replace an empty-string name with unique name */
+                               if (curdef->name[0] == '\0') {
+                                       unique_vertexgroup_name(curdef, ob);
+                               }
+                       }
+
+                       if(main->versionfile < 243 || main->subversionfile < 1) {
+                               ModifierData *md;
+
+                               /* translate old mirror modifier axis values to new flags */
+                               for (md=ob->modifiers.first; md; md=md->next) {
+                                       if (md->type==eModifierType_Mirror) {
+                                               MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+                                               switch(mmd->axis)
+                                               {
+                                               case 0:
+                                                       mmd->flag |= MOD_MIR_AXIS_X;
+                                                       break;
+                                               case 1:
+                                                       mmd->flag |= MOD_MIR_AXIS_Y;
+                                                       break;
+                                               case 2:
+                                                       mmd->flag |= MOD_MIR_AXIS_Z;
+                                                       break;
+                                               }
+
+                                               mmd->axis = 0;
+                                       }
+                               }
+                       }
+               }
+               
+               /* render layer added, this is not the active layer */
+               if(main->versionfile <= 243 || main->subversionfile < 2) {
+                       Mesh *me;
+                       for(me=main->mesh.first; me; me=me->id.next)
+                               customdata_version_243(me);
+               }
+       }
+       if(main->versionfile <= 244) {
+               Scene *sce;
+               bScreen *sc;
+               Object *ob;
+
+               if(main->versionfile != 244 || main->subversionfile < 2) {
+                       Mesh *me;
+                       
+                       for(sce= main->scene.first; sce; sce= sce->id.next)
+                               sce->r.mode |= R_SSS;
+
+                       /* Copy over old per-level multires vertex data
+                          into a single vertex array in struct Multires */
+                       
+                       for(me = main->mesh.first; me; me=me->id.next) {
+                               if(me->mr) {
+                                       MultiresLevel *lvl = me->mr->levels.last;
+                                       if(lvl) {
+                                               me->mr->verts = lvl->verts;
+                                               lvl->verts = NULL;
+                                               /* Don't need the other vert arrays */
+                                               for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
+                                                       MEM_freeN(lvl->verts);
+                                                       lvl->verts = NULL;
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       /* correct older action editors - incorrect scrolling */
+                       for(sc= main->screen.first; sc; sc= sc->id.next) {
+                               ScrArea *sa;
+                               sa= sc->areabase.first;
+                               while(sa) {
+                                       SpaceLink *sl;
+
+                                       for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                               if(sl->spacetype==SPACE_ACTION) {
+                                                       SpaceAction *saction= (SpaceAction*) sl;
+                                                       
+                                                       saction->v2d.tot.ymin= -1000.0;
+                                                       saction->v2d.tot.ymax= 0.0;
+                                                       
+                                                       saction->v2d.cur.ymin= -75.0;
+                                                       saction->v2d.cur.ymax= 5.0;
+                                               }
+                                       }
+                                       sa = sa->next;
+                               }
+                       }
+               }
+               if (main->subversionfile < 3) {
+                       for(ob = main->object.first; ob; ob= ob->id.next) {
+                               ListBase *list;
+                               list = &ob->constraints;
+                               float temp_size[3];
+
+                               /* fix up constraints due to constraint recode changes */
+                               if (list) {
+                                       bConstraint *curcon;
+                                       for (curcon = list->first; curcon; curcon=curcon->next) {
+                                               /* old CONSTRAINT_LOCAL check -> convert to CONSTRAINT_SPACE_LOCAL */
+                                               if (curcon->flag & 0x20) {
+                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                       curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+                                               }
+                                               
+                                               switch (curcon->type) {
+                                                       case CONSTRAINT_TYPE_ACTION:
+                                                       {
+                                                               bActionConstraint *data= (bActionConstraint *)curcon->data;
+                                                               
+                                                               if (data->local)
+                                                                       curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+                                                       }                                                       
+                                                               break;
+                                                       case CONSTRAINT_TYPE_LOCLIMIT:
+                                                       {
+                                                               bLocLimitConstraint *data= (bLocLimitConstraint *)curcon->data;
+                                                               
+                                                               if (data->flag2) {
+                                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                               }
+                                                       }
+                                                               break;
+                                               }       
+                                       }
+                               }
+                               
+                               /* correctly initialise constinv matrix */
+                               Mat4One(ob->constinv);
+
+                               if (ob->type == OB_ARMATURE) {
+                                       if (ob->pose) {
+                                               bConstraint *curcon;
+                                               bPoseChannel *pchan;
+                                               
+                                               for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+                                                       /* make sure constraints are all up to date */
+                                                       for (curcon = pchan->constraints.first; curcon; curcon=curcon->next) {
+                                                               /* old CONSTRAINT_LOCAL check -> convert to CONSTRAINT_SPACE_LOCAL */
+                                                               if (curcon->flag & 0x20) {
+                                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                                       curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+                                                               }
+                                                               
+                                                               switch (curcon->type) {
+                                                                       case CONSTRAINT_TYPE_ACTION:
+                                                                       {
+                                                                               bActionConstraint *data= (bActionConstraint *)curcon->data;
+                                                                               
+                                                                               if (data->local)
+                                                                                       curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+                                                                       }                                                       
+                                                                               break;
+                                                                       case CONSTRAINT_TYPE_LOCLIMIT:
+                                                                       {
+                                                                               bLocLimitConstraint *data= (bLocLimitConstraint *)curcon->data;
+                                                                               
+                                                                               if (data->flag2) {
+                                                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                                                       curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+                                                                               }
+                                                                       }
+                                                                               break;
+                                                               }
+                                                       }
+                                                       
+                                                       /* correctly initialise constinv matrix */
+                                                       Mat4One(pchan->constinv);
+                                               }
+                                       }
+                               }
+                       }
                }
        }
 
@@ -6247,6 +6694,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
                case REND:
                        if (bhead->code==GLOB) {
                                fg= read_struct(fd, bhead, "Global");
+                               /* set right away */
+                               bfd->main->subversionfile= fg->subversion;
+                               bfd->main->minversionfile= fg->minversion;
+                               bfd->main->minsubversionfile= fg->minsubversion;
                        }
                        bhead = blo_nextbhead(fd, bhead);
                        break;
@@ -6318,22 +6769,27 @@ static BHead *find_bhead(FileData *fd, void *old)
        return NULL;
 }
 
-static ID *is_yet_read(Main *mainvar, BHead *bhead)
+char *bhead_id_name(FileData *fd, BHead *bhead)
+{
+       return ((char *)(bhead+1)) + fd->id_name_offs;
+}
+
+static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
 {
        ListBase *lb;
-       ID *idtest, *id;
+       char *idname= bhead_id_name(fd, bhead);
 
-       // BHEAD+DATA dependancy
-       idtest= (ID *)(bhead +1);
-       lb= wich_libbase(mainvar, GS(idtest->name));
+       lb= wich_libbase(mainvar, GS(idname));
+       
        if(lb) {
-               id= lb->first;
+               ID *id= lb->first;
                while(id) {
-                       if( strcmp(id->name, idtest->name)==0 ) return id;
+                       if( strcmp(id->name, idname)==0 ) 
+                               return id;
                        id= id->next;
                }
        }
-       return 0;
+       return NULL;
 }
 
 static void expand_doit(FileData *fd, Main *mainvar, void *old)
@@ -6348,21 +6804,17 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
                        BHead *bheadlib= find_previous_lib(fd, bhead);
 
                        if(bheadlib) {
-                               // BHEAD+DATA dependancy
-                               Library *lib= (Library *)(bheadlib+1);
-                               /* ***************************** */
-                               /* we read the lib->name directly from the bhead, no DNA, potential danger (64 bits?) */
-                               /* ***************************** */
-                               Main *main= blo_find_main(&fd->mainlist, lib->name, fd->filename);
+                               Library *lib= read_struct(fd, bheadlib, "Library");
+                               Main *ptr= blo_find_main(&fd->mainlist, lib->name, fd->filename);
 
-                               id= is_yet_read(main, bhead);
+                               id= is_yet_read(fd, ptr, bhead);
 
-                               if(id==0) {
-                                       read_libblock(fd, main, bhead, LIB_READ+LIB_INDIRECT, NULL);
+                               if(id==NULL) {
+                                       read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
                                        if(G.f & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name);
                                        
                                        /* for outliner dependency only */
-                                       main->curlib->parent= mainvar->curlib;
+                                       ptr->curlib->parent= mainvar->curlib;
                                }
                                else {
                                        //oldnewmap_insert(fd->libmap, bhead->old, id, 1);
@@ -6370,20 +6822,20 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
                                        change_idid_adr_fd(fd, bhead->old, id);
                                        if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
                                }
+                               
+                               MEM_freeN(lib);
                        }
                }
                else {
-                       id= is_yet_read(mainvar, bhead);
+                       id= is_yet_read(fd, mainvar, bhead);
                        if(id==NULL) {
-                               // BHEAD+DATA dependancy
-                               id= (ID *)(bhead+1);
                                read_libblock(fd, mainvar, bhead, LIB_TESTIND, NULL);
                        }
                        else {
                                /* this is actually only needed on UI call? when ID was already read before, and another append
                                   happens which invokes same ID... in that case the lookup table needs this entry */
                                oldnewmap_insert(fd->libmap, bhead->old, id, 1);
-                               // printf("expand: already read %s\n", id->name);
+                               if(G.f & G_DEBUG) printf("expand: already read %s\n", id->name);
                        }
                }
        }
@@ -6556,6 +7008,15 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
 
        for (curcon=lb->first; curcon; curcon=curcon->next) {
                switch (curcon->type) {
+               case CONSTRAINT_TYPE_NULL:
+                       break;
+               case CONSTRAINT_TYPE_PYTHON:
+                       {
+                               bPythonConstraint *data = (bPythonConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                               expand_doit(fd, mainvar, data->text);
+                       }
+                       break;
                case CONSTRAINT_TYPE_ACTION:
                        {
                                bActionConstraint *data = (bActionConstraint*)curcon->data;
@@ -6567,69 +7028,73 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                        {
                                bLocateLikeConstraint *data = (bLocateLikeConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_ROTLIKE:
                        {
                                bRotateLikeConstraint *data = (bRotateLikeConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_SIZELIKE:
                        {
                                bSizeLikeConstraint *data = (bSizeLikeConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_KINEMATIC:
                        {
                                bKinematicConstraint *data = (bKinematicConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_TRACKTO:
                        {
                                bTrackToConstraint *data = (bTrackToConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_MINMAX:
                        {
                                bMinMaxConstraint *data = (bMinMaxConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_LOCKTRACK:
                        {
                                bLockTrackConstraint *data = (bLockTrackConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_FOLLOWPATH:
                        {
                                bFollowPathConstraint *data = (bFollowPathConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
-                       }
-               case CONSTRAINT_TYPE_DISTANCELIMIT:
-                       {
-                               bDistanceLimitConstraint *data = (bDistanceLimitConstraint*)curcon->data;
-                               expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_STRETCHTO:
                        {
                                bStretchToConstraint *data = (bStretchToConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
+                       break;
                case CONSTRAINT_TYPE_RIGIDBODYJOINT:
                        {
                                bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
-                               break;
                        }
-               case CONSTRAINT_TYPE_NULL:
+                       break;
+               case CONSTRAINT_TYPE_CLAMPTO:
+                       {
+                               bClampToConstraint *data = (bClampToConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
+                       break;
+               case CONSTRAINT_TYPE_CHILDOF:
+                       {
+                               bChildOfConstraint *data = (bChildOfConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
                        break;
                default:
                        break;
@@ -6831,17 +7296,22 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
 {
        Base *base;
+       SceneRenderLayer *srl;
 
-       base= sce->base.first;
-       while(base) {
+       for(base= sce->base.first; base; base= base->next) {
                expand_doit(fd, mainvar, base->object);
-               base= base->next;
        }
        expand_doit(fd, mainvar, sce->camera);
        expand_doit(fd, mainvar, sce->world);
        
        if(sce->nodetree)
                expand_nodetree(fd, mainvar, sce->nodetree);
+       
+       for(srl= sce->r.layers.first; srl; srl= srl->next) {
+               expand_doit(fd, mainvar, srl->mat_override);
+               expand_doit(fd, mainvar, srl->light_override);
+       }
+                               
 }
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -6995,19 +7465,19 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
        Base *base;
        BHead *bhead;
        ID *id;
-       int afbreek=0;
+       int endloop=0;
 
        bhead = blo_firstbhead(fd);
-       while(bhead && afbreek==0) {
+       while(bhead && endloop==0) {
 
-               if(bhead->code==ENDB) afbreek= 1;
+               if(bhead->code==ENDB) endloop= 1;
                else if(bhead->code==idcode) {
-                       // BHEAD+DATA dependancy
-                       id= (ID *)(bhead+1);
-                       if(strcmp(id->name+2, name)==0) {
+                       char *idname= bhead_id_name(fd, bhead);
+                               
+                       if(strcmp(idname+2, name)==0) {
 
-                               id= is_yet_read(mainvar, bhead);
-                               if(id==0) {
+                               id= is_yet_read(fd, mainvar, bhead);
+                               if(id==NULL) {
                                        read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
                                }
                                else {
@@ -7023,7 +7493,7 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        base= MEM_callocN( sizeof(Base), "app_nam_part");
                                        BLI_addtail(&scene->base, base);
 
-                                       if(id==0) ob= mainvar->object.last;
+                                       if(id==NULL) ob= mainvar->object.last;
                                        else ob= (Object *)id;
                                        
                                        /* this is bad code... G.vd nor G.scene should be used on this level... */
@@ -7041,7 +7511,7 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                                /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
                                        }
                                }
-                               afbreek= 1;
+                               endloop= 1;
                        }
                }
 
@@ -7055,9 +7525,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
        for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
                if (bhead->code == GS(id->name)) {
-                       ID *idread= (ID *)(bhead+1); /*  BHEAD+DATA dependancy */
-
-                       if (BLI_streq(id->name, idread->name)) {
+                       
+                       if (BLI_streq(id->name, bhead_id_name(fd, bhead))) {
                                id->flag &= ~LIB_READ;
                                id->flag |= LIB_TEST;
 //                             printf("read lib block %s\n", id->name);
@@ -7070,36 +7539,96 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
        }
 }
 
-/* this is a version of BLO_library_append needed by the BPython API, so
- * scripts can load data from .blend files -- see Blender.Library module.*/
+/* common routine to append/link something from a library */
 
-/* append to G.scene */
-void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag)
+static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int idcode,
+               int totsel, FileData *fd)
 {
-       ListBase mainlist;
        Main *mainl;
-       FileData *fd = (FileData *)bh;
+       Library *curlib;
 
        /* make mains */
-       blo_split_main(&mainlist, G.main);
+       blo_split_main(&fd->mainlist, G.main);
 
        /* which one do we need? */
-       mainl = blo_find_main(&mainlist, dir, G.sce);
-
-       append_named_part(fd, mainl, G.scene, name, idcode, flag);
+       mainl = blo_find_main(&fd->mainlist, dir, G.sce);
+       
+       mainl->versionfile= fd->fileversion;    /* needed for do_version */
+       
+       curlib= mainl->curlib;
+       
+       if(totsel==0) {
+               append_named_part(fd, mainl, scene, sfile->file, idcode, sfile->flag);
+       }
+       else {
+               int a;
+               for(a=0; a<sfile->totfile; a++) {
+                       if(sfile->filelist[a].flags & ACTIVE) {
+                               append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag);
+                       }
+               }
+       }
 
        /* make main consistant */
        expand_main(fd, mainl);
 
        /* do this when expand found other libs */
-       read_libraries(fd, &mainlist);
+       read_libraries(fd, &fd->mainlist);
 
-       blo_join_main(&mainlist);
-       G.main= mainlist.first;
+       if(sfile->flag & FILE_STRINGCODE) {
+
+               /* use the full path, this could have been read by other library even */
+               BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name));
+               
+               /* uses current .blend file as reference */
+               BLI_makestringcode(G.sce, mainl->curlib->name);
+       }
+
+       blo_join_main(&fd->mainlist);
+       G.main= fd->mainlist.first;
 
        lib_link_all(fd, G.main);
        lib_verify_nodetree(G.main);
 
+       /* give a base to loose objects. If group append, do it for objects too */
+       if(idcode==ID_GR)
+               give_base_to_objects(scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
+       else
+               give_base_to_objects(scene, &(G.main->object), NULL);
+       
+       /* has been removed... erm, why? s..ton) */
+       /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
+       /* 20041208: put back. It only linked direct, not indirect objects (ton) */
+       
+       /* patch to prevent switch_endian happens twice */
+       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+               blo_freefiledata( fd );
+               sfile->libfiledata= 0;
+       }
+
+       return curlib;
+}
+
+/* this is a version of BLO_library_append needed by the BPython API, so
+ * scripts can load data from .blend files -- see Blender.Library module.*/
+/* append to G.scene */
+/* this should probably be moved into the Python code anyway */
+
+void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, 
+               int idcode, short flag, Scene *scene )
+{
+       SpaceFile sfile;
+
+       /* build a minimal "fake" SpaceFile object */
+       sfile.flag = flag;
+       sfile.totfile = 0;
+       strcpy(sfile.file, name);
+
+       /* try to append the requested object */
+
+       library_append( scene, &sfile, dir, idcode, 0, (FileData *)bh );
+
+       /* do we need to do this? */
        DAG_scene_sort(G.scene);
 }
 
@@ -7108,7 +7637,6 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcod
 void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
 {
        FileData *fd= (FileData*) sfile->libfiledata;
-       Main *mainl;
        Library *curlib;
        Base *centerbase;
        Object *ob;
@@ -7141,64 +7669,8 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
        
        if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
 
-       /* make mains */
-       blo_split_main(&fd->mainlist, G.main);
-
-       /* which one do we need? */
-       mainl = blo_find_main(&fd->mainlist, dir, G.sce);
-       
-       mainl->versionfile= fd->fileversion;    // needed for do_version
-       
-       curlib= mainl->curlib;
-       
-       if(totsel==0) {
-               append_named_part(fd, mainl, G.scene, sfile->file, idcode, sfile->flag);
-       }
-       else {
-               for(a=0; a<sfile->totfile; a++) {
-                       if(sfile->filelist[a].flags & ACTIVE) {
-                               append_named_part(fd, mainl, G.scene, sfile->filelist[a].relname, idcode, sfile->flag);
-                       }
-               }
-       }
-
-       /* make main consistant */
-       expand_main(fd, mainl);
-
-       /* do this when expand found other libs */
-       read_libraries(fd, &fd->mainlist);
+       curlib = library_append( G.scene, sfile, dir, idcode, totsel, fd );
 
-       if(sfile->flag & FILE_STRINGCODE) {
-
-               /* use the full path, this could have been read by other library even */
-               BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name));
-               
-               /* uses current .blend file as reference */
-               BLI_makestringcode(G.sce, mainl->curlib->name);
-       }
-
-       blo_join_main(&fd->mainlist);
-       G.main= fd->mainlist.first;
-
-       lib_link_all(fd, G.main);
-       lib_verify_nodetree(G.main);
-
-       /* give a base to loose objects. If group append, do it for objects too */
-       if(idcode==ID_GR)
-               give_base_to_objects(G.scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
-       else
-               give_base_to_objects(G.scene, &(G.main->object), NULL);
-       
-       /* has been removed... erm, why? (ton) */
-       /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
-       /* 20041208: put back. It only linked direct, not indirect objects (ton) */
-       
-       /* patch to prevent switch_endian happens twice */
-       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
-               blo_freefiledata((FileData*) sfile->libfiledata);
-               sfile->libfiledata= 0;
-       }       
-       
        /* when not linking (appending)... */
        if((sfile->flag & FILE_LINK)==0) {
                if(sfile->flag & FILE_ATCURSOR) {
@@ -7236,7 +7708,6 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
                        }
                }
        }
-       DAG_scene_sort(G.scene);
 }
 
 /* ************* READ LIBRARY ************** */
@@ -7272,7 +7743,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                while(mainptr) {
                        int tot= mainvar_count_libread_blocks(mainptr);
                        
-                       //printf("found LIB_READ %s\n", mainptr->curlib->name);
+                       // printf("found LIB_READ %s\n", mainptr->curlib->name);
                        if(tot) {
                                FileData *fd= mainptr->curlib->filedata;