diff options
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 407 |
1 files changed, 240 insertions, 167 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9ff30916eff..1099823a8b1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -76,6 +76,7 @@ #include "DNA_node_types.h" #include "DNA_object_fluidsim.h" // NT #include "DNA_packedFile_types.h" +#include "DNA_particle_types.h" #include "DNA_property_types.h" #include "DNA_text_types.h" #include "DNA_view3d_types.h" @@ -138,7 +139,6 @@ //XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo #include "BLO_readfile.h" #include "BLO_undofile.h" -#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory #include "readfile.h" @@ -489,13 +489,13 @@ static void read_file_version(FileData *fd, Main *main) } -static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, const char *relabase) +static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *filepath, const char *relabase) { Main *m; Library *lib; char name1[FILE_MAXDIR+FILE_MAXFILE]; - strncpy(name1, name, sizeof(name1)-1); + BLI_strncpy(name1, filepath, sizeof(name1)); cleanup_path(relabase, name1); // printf("blo_find_main: original in %s\n", name); // printf("blo_find_main: converted to %s\n", name1); @@ -513,14 +513,14 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, c BLI_addtail(mainlist, m); lib= alloc_libblock(&m->library, ID_LI, "lib"); - strncpy(lib->name, name, sizeof(lib->name)-1); + strncpy(lib->name, filepath, sizeof(lib->name)-1); BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath)); m->curlib= lib; read_file_version(fd, m); - if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", name); + if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", filepath); return m; } @@ -946,14 +946,14 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports) /* cannot be called with relative paths anymore! */ /* on each new library added, it now checks for the current FileData and expands relativeness */ -FileData *blo_openblenderfile(const char *name, ReportList *reports) +FileData *blo_openblenderfile(const char *filepath, ReportList *reports) { gzFile gzfile; errno= 0; - gzfile= gzopen(name, "rb"); + gzfile= gzopen(filepath, "rb"); if (gzfile == (gzFile)Z_NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", name, errno ? strerror(errno) : "Unknown error reading file"); + BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file"); return NULL; } else { FileData *fd = filedata_new(); @@ -961,7 +961,7 @@ FileData *blo_openblenderfile(const char *name, ReportList *reports) fd->read = fd_read_gzip_from_file; /* needed for library_append and read_libraries */ - BLI_strncpy(fd->relabase, name, sizeof(fd->relabase)); + BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase)); return blo_decode_and_check(fd, reports); } @@ -1084,7 +1084,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group) /* 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) + if (strcmp("Screen", gp)!=0) BLI_strncpy(group, gp, GROUP_MAX); } return 1; @@ -1585,7 +1585,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p if (prv) { int i; - for (i=0; i < PREVIEW_MIPMAPS; ++i) { + for (i=0; i < NUM_ICON_SIZES; ++i) { if (prv->rect[i]) { prv->rect[i] = newdataadr(fd, prv->rect[i]); } @@ -1738,6 +1738,12 @@ static void direct_link_fmodifiers(FileData *fd, ListBase *list) FMod_Generator *data= (FMod_Generator *)fcm->data; data->coefficients= newdataadr(fd, data->coefficients); + + if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) { + unsigned int a; + for(a = 0; a < data->arraysize; a++) + SWITCH_INT(data->coefficients[a]); + } } break; case FMODIFIER_TYPE_ENVELOPE: @@ -2089,7 +2095,7 @@ static void lib_nodetree_do_versions_group(bNodeTree *ntree) for (node=ntree->nodes.first; node; node=node->next) { if (node->type==NODE_GROUP) { bNodeTree *ngroup= (bNodeTree*)node->id; - if (ngroup->flag & NTREE_DO_VERSIONS) + if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS)) lib_node_do_versions_group(node); } } @@ -2117,7 +2123,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open)) } { - int has_old_groups=0; + /*int has_old_groups=0;*/ /*UNUSED*/ /* XXX this should actually be part of do_versions, but since we need * finished library linking, it is not possible there. Instead in do_versions * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the @@ -2127,7 +2133,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open)) if (ntree->flag & NTREE_DO_VERSIONS) { /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */ nodeGroupExposeAllSockets(ntree); - has_old_groups = 1; + /*has_old_groups = 1;*/ /*UNUSED*/ } } /* now verify all types in material trees, groups are set OK now */ @@ -3157,9 +3163,37 @@ static void lib_link_particlesettings(FileData *fd, Main *main) 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->dupliweights.first) { + int index_ok = 0; + /* check for old files without indices (all indexes 0) */ + dw = part->dupliweights.first; + if(part->dupliweights.first == part->dupliweights.last) { + /* special case for only one object in the group */ + index_ok = 1; + } + else { + for(; dw; dw=dw->next) { + if(dw->index > 0) { + index_ok = 1; + break; + } + } + } + + if(index_ok) { + /* if we have indexes, let's use them */ + dw = part->dupliweights.first; + for(; dw; dw=dw->next) { + GroupObject *go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index); + dw->ob = go ? go->ob : NULL; + } + } + else { + /* otherwise try to get objects from own library (won't work on library linked groups) */ + for(; dw; dw=dw->next) + dw->ob = newlibadr(fd, part->id.lib, dw->ob); + } + } if(part->boids) { BoidState *state = part->boids->states.first; @@ -3534,6 +3568,18 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases); mesh->mr->verts = newdataadr(fd, mesh->mr->verts); + + /* If mesh has the same number of vertices as the + highest multires level, load the current mesh verts + into multires and discard the old data. Needed + because some saved files either do not have a verts + array, or the verts array contains out-of-date + data. */ + if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert) { + if(mesh->mr->verts) + MEM_freeN(mesh->mr->verts); + mesh->mr->verts = MEM_dupallocN(mesh->mvert); + } for(; lvl; lvl= lvl->next) { lvl->verts= newdataadr(fd, lvl->verts); @@ -3543,16 +3589,11 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) } } - /* Gracefully handle corrupted mesh */ + /* if multires is present but has no valid vertex data, + there's no way to recover it; silently remove multires */ if(mesh->mr && !mesh->mr->verts) { - /* If totals match, simply load the current mesh verts into multires */ - if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert) - mesh->mr->verts = MEM_dupallocN(mesh->mvert); - else { - /* Otherwise, we can't recover the data, silently remove multires */ - multires_free(mesh->mr); - mesh->mr = NULL; - } + multires_free(mesh->mr); + mesh->mr = NULL; } if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) { @@ -3839,26 +3880,10 @@ static void lib_link_object(FileData *fd, Main *main) if(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain) { - 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); - smd->domain->flags |= MOD_SMOKE_FILE_LOAD; /* flag for refreshing the simulation after loading */ } } - { - 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); - clmd->coll_parms->group= newlibadr(fd, ob->id.lib, clmd->coll_parms->group); - } - } - /* texture field */ if(ob->pd) lib_link_partdeflect(fd, &ob->id, ob->pd); @@ -3969,7 +3994,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) fluidmd->fss= newdataadr(fd, fluidmd->fss); fluidmd->fss->fmd= fluidmd; - fluidmd->fss->meshSurfNormals = NULL; + fluidmd->fss->meshVelocities = NULL; } else if (md->type==eModifierType_Smoke) { SmokeModifierData *smd = (SmokeModifierData*) md; @@ -4142,9 +4167,8 @@ static void direct_link_object(FileData *fd, Object *ob) bActuator *act; PythonComponent *pc; ComponentProperty *cprop; - int a; - /* weak weak... this was only meant as draw flag, now is used in give_base too */ + /* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */ ob->flag &= ~OB_FROMGROUP; /* loading saved files with editmode enabled works, but for undo we like @@ -4242,6 +4266,7 @@ static void direct_link_object(FileData *fd, Object *ob) sb->keys= newdataadr(fd, sb->keys); test_pointer_array(fd, (void **)&sb->keys); if(sb->keys) { + int a; for(a=0; a<sb->totkey; a++) { sb->keys[a]= newdataadr(fd, sb->keys[a]); } @@ -4349,6 +4374,7 @@ static void direct_link_object(FileData *fd, Object *ob) MEM_freeN(hook); } + ob->customdata_mask= 0; ob->bb= NULL; ob->derivedDeform= NULL; ob->derivedFinal= NULL; @@ -4856,7 +4882,6 @@ static void lib_link_screen(FileData *fd, Main *main) else if(sl->spacetype==SPACE_FILE) { SpaceFile *sfile= (SpaceFile *)sl; sfile->files= NULL; - sfile->params= NULL; sfile->op= NULL; sfile->layout= NULL; sfile->folders_prev= NULL; @@ -5469,7 +5494,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sfile->files= NULL; sfile->layout= NULL; sfile->op= NULL; - sfile->params= NULL; + sfile->params= newdataadr(fd, sfile->params); } } @@ -5529,20 +5554,31 @@ static void lib_link_library(FileData *UNUSED(fd), Main *main) } } -/* Always call this once you havbe loaded new library data to set the relative paths correctly in relation to the blend file */ +/* Always call this once you have loaded new library data to set the relative paths correctly in relation to the blend file */ static void fix_relpaths_library(const char *basepath, Main *main) { Library *lib; /* BLO_read_from_memory uses a blank filename */ - if (basepath==NULL || basepath[0] == '\0') - return; - - for(lib= main->library.first; lib; lib= lib->id.next) { - /* Libraries store both relative and abs paths, recreate relative paths, - * relative to the blend file since indirectly linked libs will be relative to their direct linked library */ - if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */ - strncpy(lib->name, lib->filepath, sizeof(lib->name)); - BLI_path_rel(lib->name, basepath); + if (basepath==NULL || basepath[0] == '\0') { + for(lib= main->library.first; lib; lib= lib->id.next) { + /* when loading a linked lib into a file which has not been saved, + * there is nothing we can be relative to, so instead we need to make + * it absolute. This can happen when appending an object with a relative + * link into an unsaved blend file. See [#27405]. + * The remap relative option will make it relative again on save - campbell */ + if (strncmp(lib->name, "//", 2)==0) { + strncpy(lib->name, lib->filepath, sizeof(lib->name)); + } + } + } + else { + for(lib= main->library.first; lib; lib= lib->id.next) { + /* Libraries store both relative and abs paths, recreate relative paths, + * relative to the blend file since indirectly linked libs will be relative to their direct linked library */ + if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */ + strncpy(lib->name, lib->filepath, sizeof(lib->name)); + BLI_path_rel(lib->name, basepath); + } } } } @@ -5659,11 +5695,10 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a while(bhead && bhead->code==DATA) { void *data; #if 0 - /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ + /* 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); - + allocname = fd->filesdna->types[ sp[0] ]; strcpy(tmp, allocname); data= read_struct(fd, bhead, tmp); #else @@ -6281,7 +6316,7 @@ static void area_add_header_region(ScrArea *sa, ListBase *lb) BLI_addtail(lb, ar); ar->regiontype= RGN_TYPE_HEADER; - if(sa->headertype==1) + if(sa->headertype==HEADERDOWN) ar->alignment= RGN_ALIGN_BOTTOM; else ar->alignment= RGN_ALIGN_TOP; @@ -8385,7 +8420,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ArmatureModifierData *amd = (ArmatureModifierData*) md; if(amd->object && amd->deformflag==0) { Object *oba= newlibadr(fd, lib, amd->object); - bArmature *arm= newlibadr(fd, lib, oba->data); + arm= newlibadr(fd, lib, oba->data); amd->deformflag= arm->deformflag; } } @@ -8532,7 +8567,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) int a; for(a=0; a<MAX_MTEX; a++) { if(ma->mtex[a] && ma->mtex[a]->tex) { - Tex *tex= newlibadr(fd, lib, ma->mtex[a]->tex); + tex= newlibadr(fd, lib, ma->mtex[a]->tex); if(tex && tex->type==TEX_STUCCI) ma->mtex[a]->mapto &= ~(MAP_COL|MAP_SPEC|MAP_REF); } @@ -8724,7 +8759,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* now, subversion control! */ if(main->subversionfile < 3) { - bScreen *sc; Image *ima; Tex *tex; @@ -9641,7 +9675,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) fluidmd->fss->lastgoodframe = INT_MAX; fluidmd->fss->flag = 0; - fluidmd->fss->meshSurfNormals = NULL; + fluidmd->fss->meshVelocities = NULL; } } } @@ -9700,7 +9734,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) nu->radius_interp = 3; /* resolu and resolv are now used differently for surfaces - * rather then using the resolution to define the entire number of divisions, + * rather than using the resolution to define the entire number of divisions, * use it for the number of divisions per segment */ if (nu->pntsv > 1) { @@ -10140,7 +10174,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ToolSettings *ts; //PTCacheID *pid; //ListBase pidlist; - int a; for(ob = main->object.first; ob; ob = ob->id.next) { //BKE_ptcache_ids_from_object(&pidlist, ob); @@ -10179,6 +10212,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } for(ma = main->mat.first; ma; ma = ma->id.next) { + int a; if(ma->mode & MA_WIRE) { ma->material_type= MA_TYPE_WIRE; ma->mode &= ~MA_WIRE; @@ -10264,8 +10298,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->gm.attrib = sce->r.attrib; //Stereo - sce->gm.xsch = sce->r.xsch; - sce->gm.ysch = sce->r.ysch; sce->gm.stereomode = sce->r.stereomode; /* reassigning stereomode NO_STEREO and DOME to a separeted flag*/ if (sce->gm.stereomode == 1){ //1 = STEREO_NOSTEREO @@ -11505,7 +11537,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) do_version_bone_roll_256(bone); /* fix for objects which have zero dquat's - * since this is multiplied with the quat rather then added */ + * since this is multiplied with the quat rather than added */ for(ob= main->object.first; ob; ob= ob->id.next) { if(is_zero_v4(ob->dquat)) { unit_qt(ob->dquat); @@ -11612,9 +11644,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* put compatibility code here until next subversion bump */ - - { + if (main->versionfile < 258 || (main->versionfile == 258 && main->subversionfile < 1)){ /* screen view2d settings were not properly initialized [#27164] * v2d->scroll caused the bug but best reset other values too which are in old blend files only. * need to make less ugly - possibly an iterator? */ @@ -11666,6 +11696,35 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + + { + /* add default value for behind strength of camera actuator */ + Object *ob; + bActuator *act; + for(ob = main->object.first; ob; ob= ob->id.next) { + for(act= ob->actuators.first; act; act= act->next) { + if (act->type == ACT_CAMERA) { + bCameraActuator *ba= act->data; + + ba->damping = 1.0/32.0; + } + } + } + } + + { + ParticleSettings *part; + for(part = main->particle.first; part; part = part->id.next) { + /* Initialize particle billboard scale */ + part->bb_size[0] = part->bb_size[1] = 1.0f; + } + } + } + + /* put compatibility code here until next subversion bump */ + + { + } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ @@ -11748,7 +11807,8 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) // XXX user->uifonts.first= user->uifonts.last= NULL; - user->uistyles.first= user->uistyles.last= NULL; + + link_list(fd, &user->uistyles); /* free fd->datamap again */ oldnewmap_free_unused(fd->datamap); @@ -11757,7 +11817,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) return bhead; } -BlendFileData *blo_read_file_internal(FileData *fd, const char *filename) +BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) { BHead *bhead= blo_firstbhead(fd); BlendFileData *bfd; @@ -11769,7 +11829,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filename) bfd->main->versionfile= fd->fileversion; bfd->type= BLENFILETYPE_BLEND; - strncpy(bfd->main->name, filename, sizeof(bfd->main->name)-1); + strncpy(bfd->main->name, filepath, sizeof(bfd->main->name)-1); while(bhead) { switch(bhead->code) { @@ -12208,6 +12268,9 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) if(ma->nodetree) expand_nodetree(fd, mainvar, ma->nodetree); + + if(ma->group) + expand_doit(fd, mainvar, ma->group); } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) @@ -12722,11 +12785,11 @@ static int object_in_any_scene(Main *mainvar, Object *ob) return 0; } -/* when *lib set, it also does objects that were in the appended group */ -static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is_group_append) +static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const short is_link) { Object *ob; Base *base; + const short is_group_append= (is_link==FALSE && idcode==ID_GR); /* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */ for(ob= mainvar->object.first; ob; ob= ob->id.next) { @@ -12742,12 +12805,32 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is int do_it= 0; - if(ob->id.us==0) + if(ob->id.us==0) { do_it= 1; - else if(ob->id.us==1 && lib) - if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) - do_it= 1; - + } + else if(idcode==ID_GR) { + if(ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) { + if((ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) { + do_it= 1; + } + } + } + else { + /* when appending, make sure any indirectly loaded objects + * get a base else they cant be accessed at all [#27437] */ + if(ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) { + + /* we may be appending from a scene where we already + * have a linked object which is not in any scene [#27616] */ + if((ob->id.flag & LIB_PRE_EXISTING)==0) { + + if(object_in_any_scene(mainvar, ob)==0) { + do_it= 1; + } + } + } + } + if(do_it) { base= MEM_callocN( sizeof(Base), "add_ext_base"); BLI_addtail(&(sce->base), base); @@ -12764,7 +12847,6 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is } } -/* when *lib set, it also does objects that were in the appended group */ static void give_base_to_groups(Main *mainvar, Scene *scene) { Group *group; @@ -12796,29 +12878,22 @@ static void give_base_to_groups(Main *mainvar, Scene *scene) } /* returns true if the item was found - * but it may already have already been appended/linked */ -static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag) +* but it may already have already been appended/linked */ +static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, const short idcode) { - Scene *scene= CTX_data_scene(C); - Object *ob; - Base *base; BHead *bhead; - ID *id; - int endloop=0; + ID *id= NULL; int found=0; - bhead = blo_firstbhead(fd); - while(bhead && endloop==0) { + for(bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) { + if(bhead->code==idcode) { + const char *idname_test= bhead_id_name(fd, bhead); - if(bhead->code==ENDB) endloop= 1; - else if(bhead->code==idcode) { - char *idname= bhead_id_name(fd, bhead); - - if(strcmp(idname+2, name)==0) { + if(strcmp(idname_test + 2, idname)==0) { found= 1; id= is_yet_read(fd, mainl, bhead); if(id==NULL) { - read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL); + read_libblock(fd, mainl, bhead, LIB_TESTEXT, &id); } else { printf("append: already linked\n"); @@ -12829,47 +12904,67 @@ static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const } } - if(idcode==ID_OB && scene) { /* loose object: give a base */ - base= MEM_callocN( sizeof(Base), "app_nam_part"); - BLI_addtail(&scene->base, base); - - if(id==NULL) ob= mainl->object.last; - else ob= (Object *)id; - - /* 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; - } - } - ob->mode= 0; - base->lay= ob->lay; - base->object= ob; - ob->id.us++; - - if(flag & FILE_AUTOSELECT) { - base->flag |= SELECT; - base->object->flag = base->flag; - /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ - } - } - endloop= 1; + break; } } + else if(bhead->code==ENDB) { + break; + } + } - bhead = blo_nextbhead(fd, bhead); + /* if we found the id but the id is NULL, this is really bad */ + BLI_assert((found != 0) == (id != NULL)); + + return found ? id : NULL; +} + +static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag) +{ + ID *id= append_named_part(mainl, fd, idname, idcode); + + if(id && (GS(id->name) == ID_OB)) { /* loose object: give a base */ + Scene *scene= CTX_data_scene(C); /* can be NULL */ + if(scene) { + Base *base; + Object *ob; + + base= MEM_callocN( sizeof(Base), "app_nam_part"); + BLI_addtail(&scene->base, base); + + ob= (Object *)id; + + /* link at active layer (view3d->lay if in context, else scene->lay */ + if((flag & FILE_ACTIVELAY)) { + View3D *v3d = CTX_wm_view3d(C); + ob->lay = v3d ? v3d->layact : scene->lay; + } + + ob->mode= 0; + base->lay= ob->lay; + base->object= ob; + ob->id.us++; + + if(flag & FILE_AUTOSELECT) { + base->flag |= SELECT; + base->object->flag = base->flag; + /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ + } + } } - return found; + return id; +} + +ID *BLO_library_append_named_part(Main *mainl, BlendHandle** bh, const char *idname, const int idcode) +{ + FileData *fd= (FileData*)(*bh); + return append_named_part(mainl, fd, idname, idcode); } -int BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag) +ID *BLO_library_append_named_part_ex(const bContext *C, Main *mainl, BlendHandle** bh, const char *idname, const int idcode, const short flag) { FileData *fd= (FileData*)(*bh); - return append_named_part(C, mainl, fd, name, idcode, flag); + return append_named_part_ex(C, mainl, fd, idname, idcode, flag); } static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) @@ -12878,8 +12973,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)) { - - if (BLI_streq(id->name, bhead_id_name(fd, bhead))) { + + if (strcmp(id->name, bhead_id_name(fd, bhead))==0) { id->flag &= ~LIB_READ; id->flag |= LIB_TEST; // printf("read lib block %s\n", id->name); @@ -12894,7 +12989,7 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) /* common routine to append/link something from a library */ -static Main* library_append_begin(const bContext *C, FileData **fd, char *dir) +static Main* library_append_begin(const bContext *C, FileData **fd, const char *filepath) { Main *mainvar= CTX_data_main(C); Main *mainl; @@ -12903,7 +12998,7 @@ static Main* library_append_begin(const bContext *C, FileData **fd, char *dir) blo_split_main(&(*fd)->mainlist, mainvar); /* which one do we need? */ - mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.main->name); + mainl = blo_find_main(*fd, &(*fd)->mainlist, filepath, G.main->name); /* needed for do_version */ mainl->versionfile= (*fd)->fileversion; @@ -12912,10 +13007,10 @@ static Main* library_append_begin(const bContext *C, FileData **fd, char *dir) return mainl; } -Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir) +Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, const char *filepath) { FileData *fd= (FileData*)(*bh); - return library_append_begin(C, &fd, dir); + return library_append_begin(C, &fd, filepath); } static void append_do_cursor(Scene *scene, Library *curlib, short flag) @@ -13000,23 +13095,21 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in /* give a base to loose objects. If group append, do it for objects too */ if(scene) { + const short is_link= (flag & FILE_LINK) != 0; if(idcode==ID_SCE) { /* dont instance anything when linking in scenes, assume the scene its self instances the data */ } - else if(idcode==ID_GR) { - if (flag & FILE_LINK) { - give_base_to_objects(mainvar, scene, NULL, 0); - } else { - give_base_to_objects(mainvar, scene, curlib, 1); - } + else { + give_base_to_objects(mainvar, scene, curlib, idcode, is_link); if (flag & FILE_GROUP_INSTANCE) { give_base_to_groups(mainvar, scene); } - } else { - give_base_to_objects(mainvar, scene, NULL, 0); } } + else { + printf("library_append_end, scene is NULL (objects wont get bases)\n"); + } /* 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) */ @@ -13037,30 +13130,10 @@ void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** *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, const char *name, - int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports) +void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname) { - FileData *fd= (FileData*)(*bh); - - /* try to append the requested object */ - fd->reports= reports; - library_append(mainvar, scene, name, dir, idcode, 0, &fd, NULL, 0, flag ); - if(fd) fd->reports= NULL; - - /* do we need to do this? */ - if(scene) - DAG_scene_sort(bmain, scene); - - *bh= (BlendHandle*)fd; + return read_struct(fd, bh, blockname); } -#endif /* ************* READ LIBRARY ************** */ |