new operator - OBJECT_OT_make_single_user
[blender.git] / source / blender / blenloader / intern / readfile.c
index 5cc3ff7695a28d93dfadf53d821009fc59f1efc8..448eb834818a5c01591e4ecaca8f2899b32dcbbc 100644 (file)
 
 #include "zlib.h"
 
-#ifdef WIN32
-#include "winsock2.h"
-#include "BLI_winstuff.h"
-#endif
-
 #include <limits.h>
 #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
 #include <stdlib.h> // for getenv atoi
@@ -46,6 +41,8 @@
     #include <sys/param.h> // for MAXPATHLEN
 #else
     #include <io.h> // for open close read
+#include "winsock2.h"
+#include "BLI_winstuff.h"
 #endif
 
 #include "DNA_anim_types.h"
 #include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_deform.h"
 #include "BKE_group.h"
 #include "BKE_image.h"
 #include "BKE_ipo.h" 
-#include "BKE_key.h" //void set_four_ipo
 #include "BKE_lattice.h"
 #include "BKE_library.h" // for wich_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_multires.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
+#include "BKE_paint.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_property.h" // for get_ob_property
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
 #include "BKE_bullet.h"                // bsbNew()
-#include "BKE_sculpt.h"
 #include "BKE_sequence.h"
 #include "BKE_texture.h" // for open_plugin_tex
 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
@@ -1069,6 +1066,46 @@ int BLO_has_bfile_extension(char *str)
        return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz"));
 }
 
+int BLO_is_a_library(char *path, char *dir, char *group)
+{
+       /* return ok when a blenderfile, in dir is the filename,
+        * in group the type of libdata
+        */
+       int len;
+       char *fd;
+       
+       strcpy(dir, path);
+       len= strlen(dir);
+       if(len<7) return 0;
+       if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
+       
+       group[0]= 0;
+       dir[len-1]= 0;
+
+       /* Find the last slash */
+       fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+
+       if(fd==0) return 0;
+       *fd= 0;
+       if(BLO_has_bfile_extension(fd+1)) {
+               /* the last part of the dir is a .blend file, no group follows */
+               *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */
+       }
+       else {          
+               char *gp = fd+1; // in case we have a .blend file, gp points to the group
+
+               /* Find the last slash */
+               fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+               if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
+
+               /* now we know that we are in a blend file and it is safe to 
+                  assume that gp actually points to a group */
+               if (BLI_streq("Screen", gp)==0)
+                       BLI_strncpy(group, gp, GROUP_MAX);
+       }
+       return 1;
+}
+
 /* ************** OLD POINTERS ******************* */
 
 static void *newdataadr(FileData *fd, void *adr)               /* only direct databocks */
@@ -1373,12 +1410,10 @@ static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData
        prop->totallen = prop->len;
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
-       if (switch_endian) {
-               array= (IDProperty*) prop->data.pointer;
+       array= (IDProperty*) prop->data.pointer;
 
-               for(i=0; i<prop->len; i++)
-                       IDP_DirectLinkProperty(&array[i], switch_endian, fd);
-       }
+       for(i=0; i<prop->len; i++)
+               IDP_DirectLinkProperty(&array[i], switch_endian, fd);
 }
 
 static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd)
@@ -1390,19 +1425,22 @@ static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *f
        prop->totallen = prop->len;
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
-       if (switch_endian) {
-               if(prop->subtype == IDP_GROUP) {
-                       test_pointer_array(fd, prop->data.pointer);
-                       array= prop->data.pointer;
+       if(prop->subtype == IDP_GROUP) {
+               test_pointer_array(fd, prop->data.pointer);
+               array= prop->data.pointer;
 
-                       for(i=0; i<prop->len; i++)
-                               IDP_DirectLinkProperty(array[i], switch_endian, fd);
-               }
-               else if(prop->subtype == IDP_DOUBLE) {
+               for(i=0; i<prop->len; i++)
+                       IDP_DirectLinkProperty(array[i], switch_endian, fd);
+       }
+       else if(prop->subtype == IDP_DOUBLE) {
+               if (switch_endian) {
                        for (i=0; i<prop->len; i++) {
                                SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
                        }
-               } else {
+               }
+       }
+       else {
+               if (switch_endian) {
                        for (i=0; i<prop->len; i++) {
                                SWITCH_INT(((int*)prop->data.pointer)[i]);
                        }
@@ -2146,6 +2184,8 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data = ((bKinematicConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
                                data->poletar = newlibadr(fd, id->lib, data->poletar);
+                               con->lin_error = 0.f;
+                               con->rot_error = 0.f;
                        }
                        break;
                case CONSTRAINT_TYPE_TRACKTO:
@@ -2293,6 +2333,7 @@ static void lib_link_armature(FileData *fd, Main *main)
 
        while(arm) {
                if(arm->id.flag & LIB_NEEDLINK) {
+                       if (arm->adt) lib_link_animdata(fd, &arm->id, arm->adt);
                        arm->id.flag -= LIB_NEEDLINK;
                }
                arm= arm->id.next;
@@ -2319,6 +2360,7 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
        link_list(fd, &arm->bonebase);
        arm->edbo= NULL;
        arm->sketch = NULL;
+       arm->adt= newdataadr(fd, arm->adt);
        
        bone=arm->bonebase.first;
        while (bone) {
@@ -2962,8 +3004,10 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache)
        else
                cache->mem_cache.first = cache->mem_cache.last = NULL;
 
-       cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
+       cache->flag &= ~PTCACHE_SIMULATION_VALID;
        cache->simframe= 0;
+       cache->edit= NULL;
+       cache->free_edit= NULL;
 }
 
 static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache)
@@ -2989,6 +3033,7 @@ static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointC
 static void lib_link_particlesettings(FileData *fd, Main *main)
 {
        ParticleSettings *part;
+       ParticleDupliWeight *dw;
 
        part= main->particle.first;
        while(part) {
@@ -3000,6 +3045,14 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
                        part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
                        part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
                        part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob);
+
+                       if(part->effector_weights)
+                               part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
+
+                       dw = part->dupliweights.first;
+                       for(; dw; dw=dw->next)
+                               dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+
                        if(part->boids) {
                                BoidState *state = part->boids->states.first;
                                BoidRule *rule;
@@ -3035,6 +3088,13 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
        part->pd= newdataadr(fd, part->pd);
        part->pd2= newdataadr(fd, part->pd2);
 
+       if(part->effector_weights)
+               part->effector_weights = newdataadr(fd, part->effector_weights);
+       else
+               part->effector_weights = BKE_add_effector_weights(part->eff_group);
+
+       link_list(fd, &part->dupliweights);
+
        part->boids= newdataadr(fd, part->boids);
 
        if(part->boids) {
@@ -3052,11 +3112,8 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
 {
        ParticleSystem *psys, *psysnext;
-       int a;
 
        for(psys=particles->first; psys; psys=psysnext){
-               ParticleData *pa;
-               
                psysnext= psys->next;
                
                psys->part = newlibadr_us(fd, id->lib, psys->part);
@@ -3067,12 +3124,6 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase
                                pt->ob=newlibadr(fd, id->lib, pt->ob);
 
                        psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
-
-                       for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){
-                               pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
-                       }
-
-
                }
                else {
                        /* particle modifier must be removed before particle system */
@@ -3120,32 +3171,39 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                }
 
 
-               psys->child=newdataadr(fd,psys->child);
-               psys->effectors.first=psys->effectors.last=0;
-
-               psys->soft= newdataadr(fd, psys->soft);
-               if(psys->soft) {
-                       SoftBody *sb = psys->soft;
-                       sb->particles = psys;
-                       sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
-                       sb->bspring= NULL;
-                       sb->scratch= NULL;
-
-                       direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache);
-               }
+               psys->child = newdataadr(fd,psys->child);
+               psys->effectors = NULL;
 
                link_list(fd, &psys->targets);
 
-               psys->edit = 0;
+               psys->edit = NULL;
                psys->free_edit = NULL;
-               psys->pathcache = 0;
-               psys->childcache = 0;
-               psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
-               psys->childcachebufs.first = psys->childcachebufs.last = 0;
-               psys->reactevents.first = psys->reactevents.last = 0;
+               psys->pathcache = NULL;
+               psys->childcache = NULL;
+               psys->pathcachebufs.first = psys->pathcachebufs.last = NULL;
+               psys->childcachebufs.first = psys->childcachebufs.last = NULL;
+               psys->frand = NULL;
+               psys->pdd = NULL;
 
                direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache);
 
+               if(psys->clmd) {
+                       psys->clmd = newdataadr(fd, psys->clmd);
+                       psys->clmd->clothObject = NULL;
+                       
+                       psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
+                       psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
+                       
+                       if(psys->clmd->sim_parms) {
+                               if(psys->clmd->sim_parms->presets > 10)
+                                       psys->clmd->sim_parms->presets = 0;
+                       }
+
+                       psys->hair_in_dm = psys->hair_out_dm = NULL;
+
+                       psys->clmd->point_cache = psys->pointcache;
+               }
+
                psys->tree = NULL;
        }
        return;
@@ -3449,6 +3507,8 @@ static void lib_link_object(FileData *fd, Main *main)
                        }
                        for(a=0; a<ob->totcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]);
                        
+                       ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd);
+                       
                        ob->id.flag -= LIB_NEEDLINK;
                        /* if id.us==0 a new base will be created later on */
                        
@@ -3572,6 +3632,11 @@ static void lib_link_object(FileData *fd, Main *main)
                                else if(act->type==ACT_STATE) {
                                        /* bStateActuator *statea = act->data; */
                                }
+                               else if(act->type==ACT_ARMATURE) {
+                                       bArmatureActuator *arma= act->data;
+                                       arma->target= newlibadr(fd, ob->id.lib, arma->target);
+                                       arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget);
+                               }
                                act= act->next;
                        }
                        
@@ -3590,6 +3655,17 @@ static void lib_link_object(FileData *fd, Main *main)
                                        smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
                                        smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
                                        smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
+
+                                       smd->domain->effector_weights->group = newlibadr(fd, ob->id.lib, smd->domain->effector_weights->group);
+                               }
+                       }
+
+                       {
+                               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+                               
+                               if(clmd) 
+                               {
+                                       clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
                                }
                        }
                        
@@ -3598,6 +3674,9 @@ static void lib_link_object(FileData *fd, Main *main)
                                if(ob->pd->tex)
                                        ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex);
 
+                       if(ob->soft)
+                               ob->soft->effector_weights->group = newlibadr(fd, ob->id.lib, ob->soft->effector_weights->group);
+
                        lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
                        lib_link_modifiers(fd, ob);
                }
@@ -3633,6 +3712,10 @@ static void direct_link_pose(FileData *fd, bPose *pose)
                pchan->iktree.first= pchan->iktree.last= NULL;
                pchan->path= NULL;
        }
+       pose->ikdata = NULL;
+       if (pose->ikparam != NULL) {
+               pose->ikparam= newdataadr(fd, pose->ikparam);
+       }
 }
 
 static void direct_link_modifiers(FileData *fd, ListBase *lb)
@@ -3673,6 +3756,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                if(clmd->sim_parms->presets > 10)
                                        clmd->sim_parms->presets = 0;
                        }
+
+                       if(clmd->sim_parms->effector_weights)
+                               clmd->sim_parms->effector_weights = newdataadr(fd, clmd->sim_parms->effector_weights);
+                       else
+                               clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
                        
                }
                else if (md->type==eModifierType_Fluidsim) {
@@ -3692,10 +3780,19 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                smd->domain->smd = smd;
 
                                smd->domain->fluid = NULL;
-                               smd->domain->view3d = NULL;
+                               smd->domain->wt = NULL;
+                               smd->domain->shadow = NULL;
                                smd->domain->tex = NULL;
+                               smd->domain->tex_shadow = NULL;
+                               smd->domain->tex_wt = NULL;
+
+                               if(smd->domain->effector_weights)
+                                       smd->domain->effector_weights = newdataadr(fd, smd->domain->effector_weights);
+                               else
+                                       smd->domain->effector_weights = BKE_add_effector_weights(NULL);
 
-                               direct_link_pointcache_list(fd, &smd->domain->ptcaches, &smd->domain->point_cache);
+                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]));
+                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1]));
                        }
                        else if(smd->type==MOD_SMOKE_TYPE_FLOW)
                        {
@@ -3709,12 +3806,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        {
                                smd->flow = NULL;
                                smd->domain = NULL;
-                               smd->coll = NULL;
-                               /*
                                smd->coll = newdataadr(fd, smd->coll);
-                               smd->coll->points = NULL;
-                               smd->coll->numpoints = 0;
-                               */
+                               if(smd->coll)
+                               {
+                                       smd->coll->points = NULL;
+                                       smd->coll->numpoints = 0;
+                               }
+                               else
+                                       smd->type = 0;
+
                        }
                }
                else if (md->type==eModifierType_Collision) {
@@ -3816,7 +3916,10 @@ static void direct_link_object(FileData *fd, Object *ob)
        
        /* weak weak... this was only meant as draw flag, now is used in give_base too */
        ob->flag &= ~OB_FROMGROUP;
-
+       
+       /* editmode doesn't get saved in files, so should get cleared when reloading... */
+       ob->mode &= ~(OB_MODE_EDIT|OB_MODE_PARTICLE_EDIT);
+       
        ob->disp.first=ob->disp.last= NULL;
        
        ob->adt= newdataadr(fd, ob->adt);
@@ -3890,6 +3993,8 @@ static void direct_link_object(FileData *fd, Object *ob)
        }
 
        ob->pd= newdataadr(fd, ob->pd);
+       if(ob->pd)
+               ob->pd->rng=NULL;
        ob->soft= newdataadr(fd, ob->soft);
        if(ob->soft) {
                SoftBody *sb= ob->soft;         
@@ -3907,6 +4012,11 @@ static void direct_link_object(FileData *fd, Object *ob)
                        }
                }
 
+               if(sb->effector_weights)
+                       sb->effector_weights = newdataadr(fd, sb->effector_weights);
+               else
+                       sb->effector_weights = BKE_add_effector_weights(NULL);
+
                direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache);
        }
        ob->bsoft= newdataadr(fd, ob->bsoft);
@@ -3985,6 +4095,8 @@ static void direct_link_object(FileData *fd, Object *ob)
 
                BLI_addhead(&ob->modifiers, hmd);
                BLI_remlink(&ob->hooks, hook);
+               
+               modifier_unique_name(&ob->modifiers, (ModifierData*)hmd);
 
                MEM_freeN(hook);
        }
@@ -3993,6 +4105,7 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->derivedDeform= NULL;
        ob->derivedFinal= NULL;
        ob->gpulamp.first= ob->gpulamp.last= NULL;
+       link_list(fd, &ob->pc_ids);
 
        if(ob->sculpt)
                ob->sculpt= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
@@ -4040,6 +4153,7 @@ static void lib_link_scene(FileData *fd, Main *main)
                        sce->world= newlibadr_us(fd, sce->id.lib, sce->world);
                        sce->set= newlibadr(fd, sce->id.lib, sce->set);
                        sce->ima= newlibadr_us(fd, sce->id.lib, sce->ima);
+                       sce->gpd= newlibadr_us(fd, sce->id.lib, sce->gpd);
                        
                        link_paint(fd, sce, &sce->toolsettings->sculpt->paint);
                        link_paint(fd, sce, &sce->toolsettings->vpaint->paint);
@@ -4054,9 +4168,6 @@ static void lib_link_scene(FileData *fd, Main *main)
                                /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */
                                base->object= newlibadr_us(fd, sce->id.lib, base->object);
                                
-                               /* when save during radiotool, needs cleared */
-                               base->flag &= ~OB_RADIO;
-                               
                                if(base->object==NULL) {
                                        printf("LIB ERROR: base removed\n");
                                        BLI_remlink(&sce->base, base);
@@ -4324,6 +4435,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
                win->timers.first= win->timers.last= NULL;
                win->queue.first= win->queue.last= NULL;
                win->handlers.first= win->handlers.last= NULL;
+               win->modalhandlers.first= win->modalhandlers.last= NULL;
                win->subwindows.first= win->subwindows.last= NULL;
                win->gesture.first= win->gesture.last= NULL;
 
@@ -4333,11 +4445,13 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        }
        
        wm->operators.first= wm->operators.last= NULL;
-       wm->keymaps.first= wm->keymaps.last= NULL;
        wm->paintcursors.first= wm->paintcursors.last= NULL;
        wm->queue.first= wm->queue.last= NULL;
        BKE_reports_init(&wm->reports, RPT_STORE);
 
+       wm->keyconfigs.first= wm->keyconfigs.last= NULL;
+       wm->defaultconf= NULL;
+
        wm->jobs.first= wm->jobs.last= NULL;
        
        wm->windrawable= NULL;
@@ -4347,11 +4461,14 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 static void lib_link_windowmanager(FileData *fd, Main *main)
 {
        wmWindowManager *wm;
+       wmWindow *win;
        
        for(wm= main->wm.first; wm; wm= wm->id.next) {
-               wmWindow *win;
-               for(win= wm->windows.first; win; win= win->next) {
-                       win->screen= newlibadr(fd, NULL, win->screen);
+               if(wm->id.flag & LIB_NEEDLINK) {
+                       for(win= wm->windows.first; win; win= win->next)
+                               win->screen= newlibadr(fd, NULL, win->screen);
+
+                       wm->id.flag -= LIB_NEEDLINK;
                }
        }
 }
@@ -4635,7 +4752,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                                        v3d->layact= v3d->localvd->layact;
                                                        MEM_freeN(v3d->localvd); 
                                                        v3d->localvd= NULL;
-                                                       v3d->localview= 0;
                                                }
                                                */
                                        }
@@ -4778,7 +4894,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                        rv3d->ri= NULL;
                        rv3d->sms= NULL;
                        rv3d->smooth_timer= NULL;
-                       rv3d->lastmode= 0;
                }
        }
        
@@ -4813,6 +4928,10 @@ static void view3d_split_250(View3D *v3d, ListBase *regions)
                        QUATCOPY(rv3d->viewquat, v3d->viewquat);
                }
        }
+
+       /* this was not initialized correct always */
+       if(v3d->twtype == 0)
+               v3d->twtype= V3D_MANIP_TRANSLATE;
 }
 
 static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -5058,7 +5177,7 @@ static void fix_relpaths_library(const char *basepath, Main *main)
 
 static void direct_link_sound(FileData *fd, bSound *sound)
 {
-       sound->snd_sound = NULL;
+       sound->handle = NULL;
 
        sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
        sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
@@ -5073,9 +5192,11 @@ static void lib_link_sound(FileData *fd, Main *main)
                if(sound->id.flag & LIB_NEEDLINK) {
                        sound->id.flag -= LIB_NEEDLINK;
                        sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
-                       sound->stream = 0;
+                       
+                       sound_load(main, sound);
 
-                       sound_load(sound);
+                       if(sound->cache)
+                               sound_cache(sound, 1);
                }
                sound= sound->id.next;
        }
@@ -5156,6 +5277,33 @@ static char *dataname(short id_code)
        
 }
 
+static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, char *allocname)
+{
+       bhead = blo_nextbhead(fd, bhead);
+
+       while(bhead && bhead->code==DATA) {
+               void *data;
+#if 0          
+               /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */         
+               short *sp= fd->filesdna->structs[bhead->SDNAnr];
+               char *allocname = fd->filesdna->types[ sp[0] ];
+               char *tmp= malloc(100);
+               
+               strcpy(tmp, allocname);
+               data= read_struct(fd, bhead, tmp);
+#endif
+               data= read_struct(fd, bhead, allocname);
+               
+               if (data) {
+                       oldnewmap_insert(fd->datamap, bhead->old, data, 0);
+               }
+
+               bhead = blo_nextbhead(fd, bhead);
+       }
+
+       return bhead;
+}
+
 static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **id_r)
 {
        /* this routine reads a libblock and its direct data. Use link functions
@@ -5197,32 +5345,11 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                return blo_nextbhead(fd, bhead);
        }
 
-       bhead = blo_nextbhead(fd, bhead);
-
        /* need a name for the mallocN, just for debugging and sane prints on leaks */
        allocname= dataname(GS(id->name));
        
-               /* read all data */
-       
-       while(bhead && bhead->code==DATA) {
-               void *data;
-#if 0          
-               /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */         
-               short *sp= fd->filesdna->structs[bhead->SDNAnr];
-               char *allocname = fd->filesdna->types[ sp[0] ];
-               char *tmp= malloc(100);
-               
-               strcpy(tmp, allocname);
-               data= read_struct(fd, bhead, tmp);
-#endif
-               data= read_struct(fd, bhead, allocname);
-               
-               if (data) {
-                       oldnewmap_insert(fd->datamap, bhead->old, data, 0);
-               }
-
-               bhead = blo_nextbhead(fd, bhead);
-       }
+       /* read all data into fd->datamap */
+       bhead= read_data_into_oldnewmap(fd, bhead, allocname);
 
        /* init pointers direct data */
        switch( GS(id->name) ) {
@@ -6086,7 +6213,70 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen)
        }               
 }
 
+static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype)
+{
+       MTex *mtex;
+       float varfac, colfac;
+       int a, neg;
 
+       if(!mtex_array)
+               return;
+
+       for(a=0; a<MAX_MTEX; a++) {
+               if(mtex_array[a]) {
+                       mtex= mtex_array[a];
+
+                       neg= mtex->maptoneg;
+                       varfac= mtex->varfac;
+                       colfac= mtex->colfac;
+
+                       if(neg & MAP_DISP) mtex->dispfac= -mtex->dispfac;
+                       if(neg & MAP_NORM) mtex->norfac= -mtex->norfac;
+                       if(neg & MAP_WARP) mtex->warpfac= -mtex->warpfac;
+
+                       mtex->colspecfac= (neg & MAP_COLSPEC)? -colfac: colfac;
+                       mtex->mirrfac= (neg & MAP_COLMIR)? -colfac: colfac;
+                       mtex->alphafac= (neg & MAP_ALPHA)? -varfac: varfac;
+                       mtex->difffac= (neg & MAP_REF)? -varfac: varfac;
+                       mtex->specfac= (neg & MAP_SPEC)? -varfac: varfac;
+                       mtex->emitfac= (neg & MAP_EMIT)? -varfac: varfac;
+                       mtex->hardfac= (neg & MAP_HAR)? -varfac: varfac;
+                       mtex->raymirrfac= (neg & MAP_RAYMIRR)? -varfac: varfac;
+                       mtex->translfac= (neg & MAP_TRANSLU)? -varfac: varfac;
+                       mtex->ambfac= (neg & MAP_AMB)? -varfac: varfac;
+                       mtex->colemitfac= (neg & MAP_EMISSION_COL)? -colfac: colfac;
+                       mtex->colreflfac= (neg & MAP_REFLECTION_COL)? -colfac: colfac;
+                       mtex->coltransfac= (neg & MAP_TRANSMISSION_COL)? -colfac: colfac;
+                       mtex->densfac= (neg & MAP_DENSITY)? -varfac: varfac;
+                       mtex->scatterfac= (neg & MAP_SCATTERING)? -varfac: varfac;
+                       mtex->reflfac= (neg & MAP_REFLECTION)? -varfac: varfac;
+
+                       mtex->timefac= (neg & MAP_PA_TIME)? -varfac: varfac;
+                       mtex->lengthfac= (neg & MAP_PA_LENGTH)? -varfac: varfac;
+                       mtex->clumpfac= (neg & MAP_PA_CLUMP)? -varfac: varfac;
+                       mtex->kinkfac= (neg & MAP_PA_KINK)? -varfac: varfac;
+                       mtex->roughfac= (neg & MAP_PA_ROUGH)? -varfac: varfac;
+                       mtex->padensfac= (neg & MAP_PA_DENS)? -varfac: varfac;
+                       mtex->lifefac= (neg & MAP_PA_LIFE)? -varfac: varfac;
+                       mtex->sizefac= (neg & MAP_PA_SIZE)? -varfac: varfac;
+                       mtex->ivelfac= (neg & MAP_PA_IVEL)? -varfac: varfac;
+                       mtex->pvelfac= (neg & MAP_PA_PVEL)? -varfac: varfac;
+
+                       mtex->shadowfac= (neg & LAMAP_SHAD)? -colfac: colfac;
+
+                       mtex->zenupfac= (neg & WOMAP_ZENUP)? -colfac: colfac;
+                       mtex->zendownfac= (neg & WOMAP_ZENDOWN)? -colfac: colfac;
+                       mtex->blendfac= (neg & WOMAP_BLEND)? -varfac: varfac;
+
+                       if(idtype == ID_MA)
+                               mtex->colfac= (neg & MAP_COL)? -colfac: colfac;
+                       else if(idtype == ID_LA)
+                               mtex->colfac= (neg & LAMAP_COL)? -colfac: colfac;
+                       else if(idtype == ID_WO)
+                               mtex->colfac= (neg & WOMAP_HORIZ)? -colfac: colfac;
+               }
+       }
+}
 
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
@@ -6240,7 +6430,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
        if(main->versionfile <= 140) {
-               /* r-g-b-fac in texure */
+               /* r-g-b-fac in texture */
                Tex *tex = main->tex.first;
                while (tex) {
                        if ((tex->rfac == 0.0) &&
@@ -7468,6 +7658,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                smd->flags |= eSubsurfModifierFlag_ControlEdges;
                                        
                                        BLI_addtail(&ob->modifiers, smd);
+                                       
+                                       modifier_unique_name(&ob->modifiers, (ModifierData*)smd);
                                }
                        }
                        
@@ -8338,8 +8530,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                ob->soft->pointcache= BKE_ptcache_add(&ob->soft->ptcaches);
 
                        for(psys=ob->particlesystem.first; psys; psys=psys->next) {
-                               if(psys->soft && !psys->soft->pointcache)
-                                       psys->soft->pointcache= BKE_ptcache_add(&psys->soft->ptcaches);
+                               //if(psys->soft && !psys->soft->pointcache)
+                               //      psys->soft->pointcache= BKE_ptcache_add(&psys->soft->ptcaches);
                                if(!psys->pointcache)
                                        psys->pointcache= BKE_ptcache_add(&psys->ptcaches);
                        }
@@ -9218,6 +9410,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Material *ma;
                Camera *cam;
                Mesh *me;
+               Curve *cu;
                Scene *sce;
                Tex *tx;
                ParticleSettings *part;
@@ -9295,10 +9488,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                 */
                //do_versions_ipos_to_animato(main);
                
-               /* toolsettings */
-               for(scene= main->scene.first; scene; scene= scene->id.next)
-                       scene->r.audio = scene->audio;
-               
                /* shader, composit and texture node trees have id.name empty, put something in
                 * to have them show in RNA viewer and accessible otherwise.
                 */
@@ -9312,7 +9501,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                strcpy(sce->nodetree->id.name, "NTComposit Nodetree");
 
                        /* move to cameras */
-                       if(sce->r.scemode & R_PANORAMA) {
+                       if(sce->r.mode & R_PANORAMA) {
                                for(base=sce->base.first; base; base=base->next) {
                                        ob= newlibadr(fd, lib, base->object);
 
@@ -9322,7 +9511,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        }
                                }
 
-                               sce->r.scemode &= ~R_PANORAMA;
+                               sce->r.mode &= ~R_PANORAMA;
                        }
                }
                /* and texture trees */
@@ -9364,6 +9553,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                        //BLI_freelistN(&pidlist);
                }
+
+               /* type was a mixed flag & enum. move the 2d flag elsewhere */
+               for(cu = main->curve.first; cu; cu= cu->id.next) {
+                       Nurb *nu;
+
+                       for(nu= cu->nurb.first; nu; nu= nu->next) {
+                               nu->flag |= (nu->type & CU_2D);
+                               nu->type &= CU_TYPE;
+                       }
+               }
        }
 
        if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) {
@@ -9498,16 +9697,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        if (ma->vol.stepsize < 0.0001f) {
                                ma->vol.density = 1.0f;
                                ma->vol.emission = 0.0f;
-                               ma->vol.absorption = 1.0f;
                                ma->vol.scattering = 1.0f;
                                ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
-                               ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
                                ma->vol.density_scale = 1.0f;
                                ma->vol.depth_cutoff = 0.01f;
                                ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
                                ma->vol.stepsize = 0.2f;
-                               ma->vol.shade_stepsize = 0.2f;
-                               ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
+                               ma->vol.shade_type = MA_VOL_SHADE_SHADED;
                                ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
                                ma->vol.precache_resolution = 50;
                        }
@@ -9584,6 +9780,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) {
                Scene *sce;
+               Object *ob;
 
                for(sce = main->scene.first; sce; sce = sce->id.next) {
                        if(fd->fileflags & G_FILE_ENABLE_ALL_FRAMES)
@@ -9616,10 +9813,136 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                        sce->gm.flag |= GAME_DISPLAY_LISTS;
                }
+               
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       if(ob->flag & 8192) // OB_POSEMODE = 8192
+                               ob->mode |= OB_MODE_POSE;
+               }
+       }
+
+       if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) {
+               Scene *sce;
+               Object *ob;
+               Material *ma;
+               Lamp *la;
+               World *wo;
+               Tex *tex;
+               ParticleSettings *part;
+               int do_gravity = 0;
+
+               for(sce = main->scene.first; sce; sce = sce->id.next)
+                       if(sce->unit.scale_length == 0.0f)
+                               sce->unit.scale_length= 1.0f;
+               
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       /* fluid-sim stuff */
+                       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+                       if (fluidmd) fluidmd->fss->fmd = fluidmd;
+                       
+                       /* rotation modes were added, but old objects would now default to being 'quaternion based' */
+                       ob->rotmode= ROT_MODE_EUL;
+               }
+               
+               for(ma = main->mat.first; ma; ma=ma->id.next) {
+                       if(ma->vol.reflection == 0.f) {
+                               ma->vol.reflection = 1.f;
+                               ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
+                               ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
+                       }
+
+                       do_version_mtex_factor_2_50(ma->mtex, ID_MA);
+               }
+
+               for(la = main->lamp.first; la; la=la->id.next)
+                       do_version_mtex_factor_2_50(la->mtex, ID_LA);
+
+               for(wo = main->world.first; wo; wo=wo->id.next)
+                       do_version_mtex_factor_2_50(wo->mtex, ID_WO);
+
+               for(tex = main->tex.first; tex; tex=tex->id.next)
+                       if(tex->vd)
+                               if(tex->vd->extend == 0)
+                                       tex->vd->extend = TEX_CLIP;
+               
+               for(sce= main->scene.first; sce; sce= sce->id.next)
+               {
+                       if(sce->audio.main == 0.0)
+                               sce->audio.main = 1.0;
+
+                       sce->r.ffcodecdata.audio_mixrate = sce->audio.mixrate;
+                       sce->r.ffcodecdata.audio_volume = sce->audio.main;
+                       sce->audio.distance_model = 2.0;
+                       sce->audio.doppler_factor = 1.0;
+                       sce->audio.speed_of_sound = 343.3;
+               }
+
+               /* Add default gravity to scenes */
+               for(sce= main->scene.first; sce; sce= sce->id.next) {
+                       if((sce->physics_settings.flag & PHYS_GLOBAL_GRAVITY) == 0
+                               && VecLength(sce->physics_settings.gravity) == 0.0f) {
+
+                               sce->physics_settings.gravity[0] = sce->physics_settings.gravity[1] = 0.0f;
+                               sce->physics_settings.gravity[2] = -9.81f;
+                               sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
+                               do_gravity = 1;
+                       }
+               }
+
+               /* Assign proper global gravity weights for dynamics (only z-coordinate is taken into account) */
+               if(do_gravity) for(part= main->particle.first; part; part= part->id.next)
+                       part->effector_weights->global_gravity = part->acc[2]/-9.81f;
+
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       ModifierData *md;
+
+                       if(do_gravity) {
+                               for(md= ob->modifiers.first; md; md= md->next) {
+                                       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+                                       if(clmd)
+                                               clmd->sim_parms->effector_weights->global_gravity = clmd->sim_parms->gravity[2]/-9.81;
+                               }
+
+                               if(ob->soft)
+                                       ob->soft->effector_weights->global_gravity = ob->soft->grav/9.81;
+                       }
+
+                       /* Normal wind shape is plane */
+                       if(ob->pd) {
+                               if(ob->pd->forcefield == PFIELD_WIND)
+                                       ob->pd->shape = PFIELD_SHAPE_PLANE;
+                               
+                               if(ob->pd->flag & PFIELD_PLANAR)
+                                       ob->pd->shape = PFIELD_SHAPE_PLANE;
+                               else if(ob->pd->flag & PFIELD_SURFACE)
+                                       ob->pd->shape = PFIELD_SHAPE_SURFACE;
+                       }
+               }
        }
 
        /* put 2.50 compatibility code here until next subversion bump */
-       {
+       if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) {
+               Object *ob;
+               Lamp *la;
+               
+               /* New variables for axis-angle rotations and/or quaternion rotations were added, and need proper initialisation */
+               for (ob= main->object.first; ob; ob= ob->id.next) {
+                       /* new variables for all objects */
+                       ob->quat[0]= 1.0f;
+                       ob->rotAxis[1]= 1.0f;
+                       
+                       /* bones */
+                       if (ob->pose) {
+                               bPoseChannel *pchan;
+                               
+                               for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+                                       /* just need to initalise rotation axis properly... */
+                                       pchan->rotAxis[1]= 1.0f;
+                               }
+                       }
+               }
+
+               for(la = main->lamp.first; la; la=la->id.next)
+                       la->compressthresh= 0.05f;
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -9665,37 +9988,43 @@ static void lib_link_all(FileData *fd, Main *main)
 
 static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
 {
-       Link *link;
+       UserDef *user;
+       wmKeyMap *keymap;
+       wmKeyMapItem *kmi;
 
-       bfd->user= read_struct(fd, bhead, "user def");
-       bfd->user->themes.first= bfd->user->themes.last= NULL;
-       // XXX
-       bfd->user->uifonts.first= bfd->user->uifonts.last= NULL;
-       bfd->user->uistyles.first= bfd->user->uistyles.last= NULL;
-
-       // AUD_XXX
-       if(bfd->user->audiochannels == 0)
-               bfd->user->audiochannels = 2;
-       if(bfd->user->audiodevice == 0)
-               bfd->user->audiodevice = 1;
-       if(bfd->user->audioformat == 0)
-               bfd->user->audioformat = 0x12;
-       if(bfd->user->audiorate == 0)
-               bfd->user->audiorate = 44100;
+       bfd->user= user= read_struct(fd, bhead, "user def");
 
-       bhead = blo_nextbhead(fd, bhead);
+       /* read all data into fd->datamap */
+       bhead= read_data_into_oldnewmap(fd, bhead, "user def");
 
-               /* read all attached data */
-       while(bhead && bhead->code==DATA) {
-               link= read_struct(fd, bhead, "user def data");
-               BLI_addtail(&bfd->user->themes, link);
-               bhead = blo_nextbhead(fd, bhead);
+       link_list(fd, &user->themes);
+       link_list(fd, &user->keymaps);
+
+       for(keymap=user->keymaps.first; keymap; keymap=keymap->next) {
+               keymap->modal_items= NULL;
+               keymap->poll= NULL;
+
+               link_list(fd, &keymap->items);
+               for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
+                       kmi->properties= newdataadr(fd, kmi->properties);
+                       if(kmi->properties)
+                               IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                       kmi->ptr= NULL;
+               }
        }
 
+       // XXX
+       user->uifonts.first= user->uifonts.last= NULL;
+       user->uistyles.first= user->uistyles.last= NULL;
+
+       /* free fd->datamap again */
+       oldnewmap_free_unused(fd->datamap);
+       oldnewmap_clear(fd->datamap);
+
        return bhead;
 }
 
-BlendFileData *blo_read_file_internal(FileData *fd)
+BlendFileData *blo_read_file_internal(FileData *fd, char *file)
 {
        BHead *bhead= blo_firstbhead(fd);
        BlendFileData *bfd;
@@ -9706,6 +10035,9 @@ BlendFileData *blo_read_file_internal(FileData *fd)
 
        bfd->main->versionfile= fd->fileversion;
        
+       bfd->type= BLENFILETYPE_BLEND;
+       strncpy(bfd->main->name, file, sizeof(bfd->main->name)-1);
+
        while(bhead) {
                switch(bhead->code) {
                case DATA:
@@ -10342,6 +10674,9 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
 {
        Bone *curBone;
 
+       if(arm->adt)
+               expand_animdata(fd, mainvar, arm->adt);
+
        for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
                expand_bones(fd, mainvar, curBone);
        }
@@ -10410,6 +10745,8 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
        expand_doit(fd, mainvar, ob->poselib);
        expand_constraints(fd, mainvar, &ob->constraints);
        
+       expand_doit(fd, mainvar, ob->gpd);
+       
 // XXX depreceated - old animation system (for version patching only) 
        expand_doit(fd, mainvar, ob->ipo);
        expand_doit(fd, mainvar, ob->action);
@@ -10488,11 +10825,19 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bObjectActuator *oa= act->data;
                        expand_doit(fd, mainvar, oa->reference);
                }
+               else if(act->type==ACT_ADD_OBJECT) {
+                       bAddObjectActuator *aoa= act->data;
+                       expand_doit(fd, mainvar, aoa->ob);
+               }
                else if(act->type==ACT_SCENE) {
                        bSceneActuator *sa= act->data;
                        expand_doit(fd, mainvar, sa->camera);
                        expand_doit(fd, mainvar, sa->scene);
                }
+               else if(act->type==ACT_2DFILTER) {
+                       bTwoDFilterActuator *tdfa= act->data;
+                       expand_doit(fd, mainvar, tdfa->text);
+               }
                else if(act->type==ACT_ACTION) {
                        bActionActuator *aa= act->data;
                        expand_doit(fd, mainvar, aa->act);
@@ -10509,6 +10854,14 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bMessageActuator *ma= act->data;
                        expand_doit(fd, mainvar, ma->toObject);
                }
+               else if(act->type==ACT_PARENT) {
+                       bParentActuator *pa= act->data;
+                       expand_doit(fd, mainvar, pa->ob);
+               }
+               else if(act->type==ACT_ARMATURE) {
+                       bArmatureActuator *arma= act->data;
+                       expand_doit(fd, mainvar, arma->target);
+               }
                act= act->next;
        }
 
@@ -10545,6 +10898,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
 
        if(sce->r.dometext)
                expand_doit(fd, mainvar, sce->gm.dome.warptext);
+               
+       if(sce->gpd)
+               expand_doit(fd, mainvar, sce->gpd);
 }
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -10705,8 +11061,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
 }
 
 
-static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag)
+static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag)
 {
+       Scene *scene= CTX_data_scene(C);
        Object *ob;
        Base *base;
        BHead *bhead;
@@ -10722,9 +11079,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                
                        if(strcmp(idname+2, name)==0) {
 
-                               id= is_yet_read(fd, mainvar, bhead);
+                               id= is_yet_read(fd, mainl, bhead);
                                if(id==NULL) {
-                                       read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
+                                       read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
                                }
                                else {
                                        printf("append: already linked\n");
@@ -10739,13 +11096,18 @@ 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==NULL) ob= mainvar->object.last;
+                                       if(id==NULL) ob= mainl->object.last;
                                        else ob= (Object *)id;
                                        
-                                       /* XXX use context to find view3d->lay */
-                                       //if((flag & FILE_ACTIVELAY)) {
-                                       //      scene->lay;
-                                       //}
+                                       /* link at active layer (view3d->lay if in context, else scene->lay */
+                                       if((flag & FILE_ACTIVELAY)) {
+                                               View3D *v3d = CTX_wm_view3d(C);
+                                               if (v3d) {
+                                                       ob->lay = v3d->layact;
+                                               } else {
+                                                       ob->lay = scene->lay;
+                                               }
+                                       }
                                        base->lay= ob->lay;
                                        base->object= ob;
                                        ob->id.us++;
@@ -10764,6 +11126,12 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
        }
 }
 
+void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, char *name, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       append_named_part(C, mainl, fd, name, idcode, flag);
+}
+
 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 {
        BHead *bhead;
@@ -10786,11 +11154,10 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
 /* common routine to append/link something from a library */
 
-static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode,
-               int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
+static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
 {
+       Main *mainvar= CTX_data_main(C);
        Main *mainl;
-       Library *curlib;
 
        /* make mains */
        blo_split_main(&(*fd)->mainlist, mainvar);
@@ -10800,19 +11167,69 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        
        mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
        
-       curlib= mainl->curlib;
+       return mainl;
+}
+
+Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir)
+{
+       FileData *fd= (FileData*)(*bh);
+       return library_append_begin(C, &fd, dir);
+}
+
+static void append_do_cursor(Scene *scene, Library *curlib, short flag)
+{
+       Base *centerbase;
+       Object *ob;
+       float *curs, centerloc[3], vec[3], min[3], max[3];
+       int count= 0;
+
+       /* when not linking (appending)... */
+       if(flag & FILE_LINK) 
+               return;
+
+       /* we're not appending at cursor */
+       if((flag & FILE_ATCURSOR) == 0) 
+               return;
        
-       if(totsel==0) {
-               append_named_part(*fd, mainl, scene, file, idcode, flag);
+       /* find the center of everything appended */
+       INIT_MINMAX(min, max);
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       VECCOPY(vec, centerbase->object->loc);
+                       DO_MINMAX(vec, min, max);
+                       count++;
+               }
+               centerbase= centerbase->next;
        }
-       else {
-               int a;
-               for(a=0; a<totfile; a++) {
-                       if(filelist[a].flags & ACTIVE) {
-                               append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
-                       }
+       /* we haven't found any objects to move to cursor */
+       if(!count) 
+               return;
+       
+       /* move from the center of the appended objects to cursor */
+       centerloc[0]= (min[0]+max[0])/2;
+       centerloc[1]= (min[1]+max[1])/2;
+       centerloc[2]= (min[2]+max[2])/2;
+       curs = scene->cursor;
+       VECSUB(centerloc,curs,centerloc);
+       
+       /* now translate the center of the objects */
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       ob= centerbase->object;
+                       ob->loc[0] += centerloc[0];
+                       ob->loc[1] += centerloc[1];
+                       ob->loc[2] += centerloc[2];
                }
+               centerbase= centerbase->next;
        }
+}
+
+static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
+{
+       Main *mainvar= CTX_data_main(C);
+       Scene *scene= CTX_data_scene(C);
 
        /* make main consistant */
        expand_main(*fd, mainl);
@@ -10820,6 +11237,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        /* do this when expand found other libs */
        read_libraries(*fd, &(*fd)->mainlist);
 
+       /* make the lib path relative if required */
        if(flag & FILE_STRINGCODE) {
 
                /* use the full path, this could have been read by other library even */
@@ -10842,7 +11260,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
                        if (flag & FILE_LINK) {
                                give_base_to_objects(mainvar, scene, NULL, 0);
                        } else {
-                               give_base_to_objects(mainvar, scene, curlib, 1);
+                               give_base_to_objects(mainvar, scene, mainl->curlib, 1);
                        }       
                } else {
                        give_base_to_objects(mainvar, scene, NULL, 0);
@@ -10858,14 +11276,23 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
                *fd = NULL;
        }       
 
-       return curlib;
+       append_do_cursor(scene, mainl->curlib, flag);
+}
+
+void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       library_append_end(C, mainl, &fd, idcode, flag);
+       *bh= (BlendHandle*)fd;
 }
 
 /* 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 scene */
 /* this should probably be moved into the Python code anyway */
-
+/* tentatively removed, Python should be able to use the split functions too: */
+/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */
+#if 0 
 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, 
                int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
 {
@@ -10882,88 +11309,7 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
 
        *bh= (BlendHandle*)fd;
 }
-
-/* append to scene */
-void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile, 
-                                                char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports)
-{
-       FileData *fd= (FileData*)(*bh);
-       Library *curlib;
-       Base *centerbase;
-       Object *ob;
-       int a, totsel=0;
-       
-       /* are there files selected? */
-       for(a=0; a<totfile; a++) {
-               if(filelist[a].flags & ACTIVE) {
-                       totsel++;
-               }
-       }
-
-       if(totsel==0) {
-               /* is the indicated file in the filelist? */
-               if(file[0]) {
-                       for(a=0; a<totfile; a++) {
-                               if( strcmp(filelist[a].relname, file)==0) break;
-                       }
-                       if(a==totfile) {
-                               BKE_report(reports, RPT_ERROR, "Wrong indicated name");
-                               return;
-                       }
-               }
-               else {
-                       BKE_report(reports, RPT_ERROR, "Nothing indicated");
-                       return;
-               }
-       }
-       /* now we have or selected, or an indicated file */
-       
-       if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
-
-       fd->reports= reports;
-       curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
-       if(fd) fd->reports= NULL;
-
-       *bh= (BlendHandle*)fd;
-
-       /* when not linking (appending)... */
-       if((flag & FILE_LINK)==0) {
-               if(flag & FILE_ATCURSOR) {
-                       float *curs, centerloc[3], vec[3], min[3], max[3];
-                       int count= 0;
-                       
-                       INIT_MINMAX(min, max);
-                       
-                       centerbase= (scene->base.first);
-                       while(centerbase) {
-                               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                       VECCOPY(vec, centerbase->object->loc);
-                                       DO_MINMAX(vec, min, max);
-                                       count++;
-                               }
-                               centerbase= centerbase->next;
-                       }
-                       if(count) {
-                               centerloc[0]= (min[0]+max[0])/2;
-                               centerloc[1]= (min[1]+max[1])/2;
-                               centerloc[2]= (min[2]+max[2])/2;
-                               curs = scene->cursor;
-                               VECSUB(centerloc,curs,centerloc);
-                       
-                               centerbase= (scene->base.first);
-                               while(centerbase) {
-                                       if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                               ob= centerbase->object;
-                                               ob->loc[0] += centerloc[0];
-                                               ob->loc[1] += centerloc[1];
-                                               ob->loc[2] += centerloc[2];
-                                       }
-                                       centerbase= centerbase->next;
-                               }
-                       }
-               }
-       }
-}
+#endif
 
 /* ************* READ LIBRARY ************** */
 
@@ -11007,9 +11353,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 
                                        printf("read library: lib %s\n", mainptr->curlib->name);
                                        fd= blo_openblenderfile(mainptr->curlib->filename, &reports);
-                                       fd->reports= basefd->reports;
 
                                        if (fd) {
+                                               fd->reports= basefd->reports;
+                                               
                                                if (fd->libmap)
                                                        oldnewmap_free(fd->libmap);
 
@@ -11123,7 +11470,7 @@ BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize,
                return NULL;
 
        fd->reports= reports;
-       bfd= blo_read_file_internal(fd);
+       bfd= blo_read_file_internal(fd, "");
        blo_freefiledata(fd);
 
        return bfd;