Fix #21577: incorrect camera selected when loading file without UI.
[blender.git] / source / blender / blenloader / intern / readfile.c
index b28610fe6a23ff0b4604864d5af850b608c6fcea..1f6d36dc95710cacf469cbd93e4ee0ff988f2e29 100644 (file)
 #include "BKE_group.h"
 #include "BKE_image.h"
 #include "BKE_lattice.h"
-#include "BKE_library.h" // for wich_libbase
+#include "BKE_library.h" // for which_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_mesh.h" // for ME_ defines (patching)
 #include "BKE_modifier.h"
@@ -429,7 +429,7 @@ static void split_libdata(ListBase *lb, Main *first)
                        mainvar= first;
                        while(mainvar) {
                                if(mainvar->curlib==id->lib) {
-                                       lbn= wich_libbase(mainvar, GS(id->name));
+                                       lbn= which_libbase(mainvar, GS(id->name));
                                        BLI_remlink(lb, id);
                                        BLI_addtail(lbn, id);
                                        break;
@@ -1183,6 +1183,7 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
 {
        Image *ima= oldmain->image.first;
        Scene *sce= oldmain->scene.first;
+       int a;
        
        fd->imamap= oldnewmap_new();
        
@@ -1192,6 +1193,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
                        oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
                if(ima->gputexture)
                        oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
+               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+                       if(ima->renders[a])
+                               oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1209,7 +1213,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
        OldNew *entry= fd->imamap->entries;
        Image *ima= oldmain->image.first;
        Scene *sce= oldmain->scene.first;
-       int i;
+       int i, a;
        
        /* used entries were restored, so we put them to zero */
        for (i=0; i<fd->imamap->nentries; i++, entry++) {
@@ -1231,6 +1235,8 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                }
 
                ima->gputexture= newimaadr(fd, ima->gputexture);
+               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+                       ima->renders[a]= newimaadr(fd, ima->renders[a]);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -2653,7 +2659,8 @@ static void direct_link_image(FileData *fd, Image *ima)
        ima->anim= NULL;
        ima->rr= NULL;
        ima->repbind= NULL;
-       ima->render_text= newdataadr(fd, ima->render_text);
+       memset(ima->renders, 0, sizeof(ima->renders));
+       ima->last_render_slot= ima->render_slot;
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
        ima->preview = direct_link_preview_image(fd, ima->preview);
@@ -3031,6 +3038,7 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
        link_list(fd, &part->dupliweights);
 
        part->boids= newdataadr(fd, part->boids);
+       part->fluid= newdataadr(fd, part->fluid);
 
        if(part->boids) {
                BoidState *state;
@@ -3065,6 +3073,7 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase
                                 * pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
                                psys->clmd->point_cache= psys->pointcache;
                                psys->clmd->ptcaches.first= psys->clmd->ptcaches.last= NULL;
+                               psys->clmd->coll_parms->group= newlibadr(fd, id->lib, psys->clmd->coll_parms->group);
                        }
                }
                else {
@@ -3430,7 +3439,11 @@ static void lib_link_object(FileData *fd, Main *main)
                                if(ob->proxy->id.lib==NULL) {
                                        ob->proxy->proxy_from= NULL;
                                        ob->proxy= NULL;
-                                       printf("Proxy lost from  object %s lib %s\n", ob->id.name+2, ob->id.lib->name);
+                                       
+                                       if (ob->id.lib)
+                                               printf("Proxy lost from  object %s lib %s\n", ob->id.name+2, ob->id.lib->name);
+                                       else
+                                               printf("Proxy lost from  object %s lib <NONE>\n", ob->id.name+2);
                                }
                                else {
                                        /* this triggers object_update to always use a copy */
@@ -3621,6 +3634,7 @@ static void lib_link_object(FileData *fd, Main *main)
                                if(clmd) 
                                {
                                        clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
+                                       clmd->coll_parms->group= newlibadr(fd, ob->id.lib, clmd->coll_parms->group);
                                }
                        }
                        
@@ -3652,6 +3666,8 @@ static void direct_link_pose(FileData *fd, bPose *pose)
        link_list(fd, &pose->chanbase);
        link_list(fd, &pose->agroups);
 
+       pose->chanhash= NULL;
+
        for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
                pchan->bone= NULL;
                pchan->parent= newdataadr(fd, pchan->parent);
@@ -3727,6 +3743,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
                        
                        fluidmd->fss= newdataadr(fd, fluidmd->fss);
+                       fluidmd->fss->fmd= fluidmd;
                        fluidmd->fss->meshSurfNormals = 0;
                }
                else if (md->type==eModifierType_Smoke) {
@@ -4597,6 +4614,11 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                SpaceImage *sima= (SpaceImage *)sl;
 
                                                sima->image= newlibadr_us(fd, sc->id.lib, sima->image);
+                                               
+                                               /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+                                                * so fingers crossed this works fine!
+                                                */
+                                               sima->gpd= newlibadr_us(fd, sc->id.lib, sima->gpd);
                                        }
                                        else if(sl->spacetype==SPACE_NLA){
                                                SpaceNla *snla= (SpaceNla *)sl;
@@ -4672,7 +4694,7 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
 {
                
        if(id) {
-               ListBase *lb= wich_libbase(mainp, GS(id->name));
+               ListBase *lb= which_libbase(mainp, GS(id->name));
                
                if(lb) {        // there's still risk of checking corrupt mem (freed Ids in oops)
                        ID *idn= lb->first;
@@ -4735,7 +4757,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                        View3D *v3d= (View3D*) sl;
                                        BGpic *bgpic;
                                        
-                                       v3d->camera= restore_pointer_by_name(newmain, (ID *)v3d->camera, 1);
+                                       if(v3d->scenelock)
+                                               v3d->camera= NULL; /* always get from scene */
+                                       else
+                                               v3d->camera= restore_pointer_by_name(newmain, (ID *)v3d->camera, 1);
                                        if(v3d->camera==NULL)
                                                v3d->camera= sc->scene->camera;
                                        v3d->ob_centre= restore_pointer_by_name(newmain, (ID *)v3d->ob_centre, 1);
@@ -4811,6 +4836,11 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                        SpaceImage *sima= (SpaceImage *)sl;
 
                                        sima->image= restore_pointer_by_name(newmain, (ID *)sima->image, 1);
+                                       
+                                       /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+                                        * so assume that here we're doing for undo only...
+                                        */
+                                       sima->gpd= restore_pointer_by_name(newmain, (ID *)sima->gpd, 1);
                                }
                                else if(sl->spacetype==SPACE_NLA){
                                        SpaceNla *snla= (SpaceNla *)sl;
@@ -5073,13 +5103,18 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                SpaceImage *sima= (SpaceImage *)sl;
                                
                                sima->cumap= newdataadr(fd, sima->cumap);
-                               sima->gpd= newdataadr(fd, sima->gpd);
-                               if (sima->gpd)
-                                       direct_link_gpencil(fd, sima->gpd);
                                if(sima->cumap)
                                        direct_link_curvemapping(fd, sima->cumap);
+                               
                                sima->iuser.scene= NULL;
                                sima->iuser.ok= 1;
+                               
+                               /* WARNING: gpencil data is no longer stored directly in sima after 2.5 
+                                * so sacrifice a few old files for now to avoid crashes with new files!
+                                */
+                               //sima->gpd= newdataadr(fd, sima->gpd);
+                               //if (sima->gpd)
+                               //      direct_link_gpencil(fd, sima->gpd);
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
@@ -5365,10 +5400,10 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        
        /* do after read_struct, for dna reconstruct */
        if(bhead->code==ID_ID) {
-               lb= wich_libbase(main, GS(id->name));
+               lb= which_libbase(main, GS(id->name));
        }
        else {
-               lb= wich_libbase(main, bhead->code);
+               lb= which_libbase(main, bhead->code);
        }
        
        BLI_addtail(lb, id);
@@ -6425,6 +6460,25 @@ static void do_version_constraints_radians_degrees_250(ListBase *lb)
        }
 }
 
+/* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already */
+static void do_version_old_trackto_to_constraints(Object *ob)
+{
+       /* create new trackto constraint from the relationship */
+       if (ob->track)
+       {
+               bConstraint *con= add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+               bTrackToConstraint *data = con->data;
+               
+               /* copy tracking settings from the object */
+               data->tar = ob->track;
+               data->reserved1 = ob->trackflag;
+               data->reserved2 = ob->upflag;
+       }
+       
+       /* clear old track setting */
+       ob->track = NULL;
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7247,36 +7301,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
 
                        /* Change Ob->Track in real TrackTo constraint */
-
-                       if (ob->track){
-                               bConstraint *con;
-                               bConstraintTypeInfo *cti;
-                               bTrackToConstraint *data;
-                               void *cdata;
-
-                               list = &ob->constraints;
-                               if (list)
-                               {
-                                       con = MEM_callocN(sizeof(bConstraint), "constraint");
-                                       strcpy (con->name, "AutoTrack");
-                                       unique_constraint_name(con, list);
-                                       con->flag |= CONSTRAINT_EXPAND;
-                                       con->enforce=1.0F;
-                                       con->type = CONSTRAINT_TYPE_TRACKTO;
-                                       
-                                       cti= get_constraint_typeinfo(CONSTRAINT_TYPE_TRACKTO);
-                                       cdata= MEM_callocN(cti->size, cti->structName);
-                                       cti->new_data(cdata);
-                                       data = (bTrackToConstraint *)cdata;
-                                       
-                                       data->tar = ob->track;
-                                       data->reserved1 = ob->trackflag;
-                                       data->reserved2 = ob->upflag;
-                                       con->data= (void*) data;
-                                       BLI_addtail(list, con);
-                               }
-                               ob->track = 0;
-                       }
+                       do_version_old_trackto_to_constraints(ob);
                        
                        ob = ob->id.next;
                }
@@ -9480,7 +9505,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                /* check if top parent has compound shape set and if yes, set this object
                                   to compound shaper as well (was the behaviour before, now it's optional) */
                                Object *parent= newlibadr(fd, lib, ob->parent);
-                               while (parent && parent->parent != NULL) {
+                               while (parent && parent != ob &&  parent->parent != NULL) {
                                        parent = newlibadr(fd, lib, parent->parent);
                                }
                                if(parent) {
@@ -9747,7 +9772,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                void *olddata = ob->data;
                                ob->data = me;
 
-                               if(me && me->id.lib==NULL && me->mr) /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid -  Campbell */
+                               if(me && me->id.lib==NULL && me->mr && me->mr->level_count > 1) /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid -  Campbell */
                                        multires_load_old(ob, me);
 
                                ob->data = olddata;
@@ -10642,13 +10667,71 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                } /* sequencer changes */
        }
 
-       /* put 2.50 compatibility code here until next subversion bump */
-       {
+       if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 1)) {
                Brush *brush;
+               Object *ob;
+               Scene *scene;
+               bNodeTree *ntree;
                
                for (brush= main->brush.first; brush; brush= brush->id.next) {
                        if (brush->curve) brush->curve->preset = CURVE_PRESET_SMOOTH;
                }
+               
+               /* properly initialise active flag for fluidsim modifiers */
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       ModifierData *md;
+                       for(md= ob->modifiers.first; md; md= md->next) {
+                               if (md->type == eModifierType_Fluidsim) {
+                                       FluidsimModifierData *fmd = (FluidsimModifierData *)md;
+                                       fmd->fss->flag |= OB_FLUIDSIM_ACTIVE; 
+                                       fmd->fss->flag |= OB_FLUIDSIM_OVERRIDE_TIME;
+                               }
+                       }
+               }
+               
+               /* adjustment to color balance node values */
+               for(scene= main->scene.first; scene; scene= scene->id.next) {
+                       if(scene->nodetree) {
+                               bNode *node=scene->nodetree->nodes.first;
+                               
+                               while(node) {
+                                       if (node->type == CMP_NODE_COLORBALANCE) {
+                                               NodeColorBalance *n= (NodeColorBalance *)node->storage;
+                                               n->lift[0] += 1.f;
+                                               n->lift[1] += 1.f;
+                                               n->lift[2] += 1.f;
+                                       }
+                                       node= node->next;
+                               }
+                       }
+               }
+               /* check inside node groups too */
+               for (ntree= main->nodetree.first; ntree; ntree=ntree->id.next) {
+                       bNode *node=ntree->nodes.first;
+                       
+                       while(node) {
+                               if (node->type == CMP_NODE_COLORBALANCE) {
+                                       NodeColorBalance *n= (NodeColorBalance *)node->storage;
+                                       n->lift[0] += 1.f;
+                                       n->lift[1] += 1.f;
+                                       n->lift[2] += 1.f;
+                               }
+                               node= node->next;
+                       }
+               }
+       }
+       
+       /* old-track -> constraints (this time we're really doing it!) */
+       if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 2)) {
+               Object *ob;
+               
+               for (ob = main->object.first; ob; ob = ob->id.next)
+                       do_version_old_trackto_to_constraints(ob);
+       }
+       
+       /* put 2.50 compatibility code here until next subversion bump */
+       {
+               
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -10899,8 +10982,8 @@ char *bhead_id_name(FileData *fd, BHead *bhead)
 static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
 {
        const char *idname= bhead_id_name(fd, bhead);
-       /* wich_libbase can be NULL, intentionally not using idname+2 */
-       return BLI_findstring(wich_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
+       /* which_libbase can be NULL, intentionally not using idname+2 */
+       return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
 }
 
 static void expand_doit(FileData *fd, Main *mainvar, void *old)
@@ -12070,8 +12153,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                if(fd==NULL) {
 
                                        /* printf and reports for now... its important users know this */
-                                       printf("read library: %s\n", mainptr->curlib->name);
-                                       BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s'\n", mainptr->curlib->name);
+                                       printf("read library: '%s', '%s'\n", mainptr->curlib->filename, mainptr->curlib->name);
+                                       BKE_reportf(basefd->reports, RPT_INFO, "read library:  '%s', '%s'\n", mainptr->curlib->filename, mainptr->curlib->name);
 
                                        fd= blo_openblenderfile(mainptr->curlib->filename, basefd->reports);