diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-10-27 13:42:03 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-10-27 13:42:03 +0400 |
commit | 75e570b2b71b6d655a71205345752993e1a1cc92 (patch) | |
tree | 923f95b34586e9ff709ade309f9fd5060025c70b /source/blender | |
parent | cfb435e8a52f41bc495c9aa65bae99aaddab1ad7 (diff) | |
parent | 99075b35ed3e5f42f4e652f68b9a5612b54c4cde (diff) |
svn merge -r41287:41310 ^/trunk/blender note, mirror modifier had slow, per vertex name flipping, replaced with flip_map from trunk
Diffstat (limited to 'source/blender')
56 files changed, 1068 insertions, 1270 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 15d3c86c315..84a6517fd52 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -44,7 +44,7 @@ void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2); struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup); struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name); int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg); -int *defgroup_flip_map(struct Object *ob, int use_default); +int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default); int defgroup_flip_index(struct Object *ob, int index, int use_default); int defgroup_name_index(struct Object *ob, const char *name); void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob); @@ -57,9 +57,9 @@ float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert); void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify); -void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, int use_verify); +void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, const int flip_map_len, int use_verify); void defvert_remap (struct MDeformVert *dvert, int *map); -void defvert_flip(struct MDeformVert *dvert, const int *flip_map); +void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len); void defvert_normalize(struct MDeformVert *dvert); /* utility function, note that 32 chars is the maximum string length since its only diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 4db92757969..c7e269a3b75 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -61,7 +61,9 @@ int BKE_imtype_is_movie(int imtype); struct anim *openanim(char * name, int flags, int streamindex); void image_de_interlace(struct Image *ima, int odd); - + +void make_local_image(struct Image *ima); + void tag_image_time(struct Image *ima); void free_old_images(void); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 947eafa9dd3..59ced28d53e 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -59,6 +59,7 @@ int id_copy(struct ID *id, struct ID **newid, int test); int id_unlink(struct ID *id, int test); int new_id(struct ListBase *lb, struct ID *id, const char *name); +void id_clear_lib_data(struct Main *bmain, struct ID *id); struct ListBase *which_libbase(struct Main *mainlib, short type); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index e46e2df8353..8e9d5ee34a8 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,6 +43,7 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" +#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -94,8 +95,8 @@ typedef struct tMakeLocalActionContext { bAction *act; /* original action */ bAction *actn; /* new action */ - int lib; /* some action users were libraries */ - int local; /* some action users were not libraries */ + int is_lib; /* some action users were libraries */ + int is_local; /* some action users were not libraries */ } tMakeLocalActionContext; /* helper function for make_local_action() - local/lib init step */ @@ -104,10 +105,8 @@ static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr) tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr; if (adt->action == mlac->act) { - if (id->lib) - mlac->lib = 1; - else - mlac->local = 1; + if (id->lib) mlac->is_lib= TRUE; + else mlac->is_local= TRUE; } } @@ -129,7 +128,7 @@ static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr) // does copy_fcurve... void make_local_action(bAction *act) { - tMakeLocalActionContext mlac = {act, NULL, 0, 0}; + tMakeLocalActionContext mlac = {act, NULL, FALSE, FALSE}; Main *bmain= G.main; if (act->id.lib==NULL) @@ -137,24 +136,24 @@ void make_local_action(bAction *act) // XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default if ((act->id.flag & LIB_FAKEUSER) && (act->id.us<=1)) { - act->id.lib= NULL; - act->id.flag= LIB_LOCAL; - new_id(&bmain->action, (ID *)act, NULL); + id_clear_lib_data(bmain, &act->id); return; } BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac); - if (mlac.local && mlac.lib==0) { - act->id.lib= NULL; - act->id.flag= LIB_LOCAL; - //make_local_action_channels(act); - new_id(&bmain->action, (ID *)act, NULL); + if (mlac.is_local && mlac.is_lib==FALSE) { + id_clear_lib_data(bmain, &act->id); } - else if (mlac.local && mlac.lib) { + else if (mlac.is_local && mlac.is_lib) { + char *bpath_user_data[2]= {bmain->name, act->id.lib->filepath}; + mlac.actn= copy_action(act); mlac.actn->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &mlac.actn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac); } } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 1149d8eee25..2ebede13d70 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -37,6 +37,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -136,33 +137,33 @@ void free_armature(bArmature *arm) void make_local_armature(bArmature *arm) { Main *bmain= G.main; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; Object *ob; if (arm->id.lib==NULL) return; if (arm->id.us==1) { - arm->id.lib= NULL; - arm->id.flag= LIB_LOCAL; - new_id(&bmain->armature, (ID*)arm, NULL); + id_clear_lib_data(bmain, &arm->id); return; } - for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { if(ob->data == arm) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - arm->id.lib= NULL; - arm->id.flag= LIB_LOCAL; - new_id(&bmain->armature, (ID *)arm, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &arm->id); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, arm->id.lib->filepath}; bArmature *armn= copy_armature(arm); armn->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &armn->id, bpath_relocate_visitor, 0, bpath_user_data); + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data == arm) { if(ob->id.lib==NULL) { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 4063947a5be..ea71b7af2d5 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -161,22 +161,19 @@ static void clear_global(void) G.main= NULL; } +static int clean_paths_visit_cb(void *UNUSED(userdata), char *path_dst, const char *path_src) +{ + strcpy(path_dst, path_src); + BLI_clean(path_dst); + return (strcmp(path_dst, path_src) == 0) ? FALSE : TRUE; +} + /* make sure path names are correct for OS */ static void clean_paths(Main *main) { - struct BPathIterator *bpi; - char filepath_expanded[1024]; Scene *scene; - for(BLI_bpathIterator_init(&bpi, main, main->name, BPATH_USE_PACKED); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) { - BLI_bpathIterator_getPath(bpi, filepath_expanded); - - BLI_clean(filepath_expanded); - - BLI_bpathIterator_setPath(bpi, filepath_expanded); - } - - BLI_bpathIterator_free(bpi); + bpath_traverse_main(main, clean_paths_visit_cb, 0, NULL); for(scene= main->scene.first; scene; scene= scene->id.next) { BLI_clean(scene->r.pic); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index b5cdbc58807..10f056e9b78 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -45,6 +45,7 @@ #include "RNA_access.h" +#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" @@ -181,6 +182,7 @@ void free_brush(Brush *brush) static void extern_local_brush(Brush *brush) { id_lib_extern((ID *)brush->mtex.tex); + id_lib_extern((ID *)brush->clone.image); } void make_local_brush(Brush *brush) @@ -193,29 +195,26 @@ void make_local_brush(Brush *brush) Main *bmain= G.main; Scene *scene; - int local= 0, lib= 0; + int is_local= FALSE, is_lib= FALSE; if(brush->id.lib==NULL) return; if(brush->clone.image) { - /* special case: ima always local immediately */ - brush->clone.image->id.lib= NULL; - brush->clone.image->id.flag= LIB_LOCAL; - new_id(&bmain->brush, (ID *)brush->clone.image, NULL); + /* special case: ima always local immediately. Clone image should only + have one user anyway. */ + id_clear_lib_data(bmain, &brush->clone.image->id); extern_local_brush(brush); } - for(scene= bmain->scene.first; scene && ELEM(0, lib, local); scene=scene->id.next) { + for(scene= bmain->scene.first; scene && ELEM(0, is_lib, is_local); scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { - if(scene->id.lib) lib= 1; - else local= 1; + if(scene->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - brush->id.lib= NULL; - brush->id.flag= LIB_LOCAL; - new_id(&bmain->brush, (ID *)brush, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &brush->id); extern_local_brush(brush); /* enable fake user by default */ @@ -224,10 +223,14 @@ void make_local_brush(Brush *brush) brush->id.us++; } } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, brush->id.lib->filepath}; Brush *brushn= copy_brush(brush); brushn->id.us= 1; /* only keep fake user */ brushn->id.flag |= LIB_FAKEUSER; + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &brushn->id, bpath_relocate_visitor, 0, bpath_user_data); for(scene= bmain->scene.first; scene; scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 022c31c00f6..fd5a329e204 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_bpath.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -246,7 +247,7 @@ void make_local_curve(Curve *cu) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - when there are only lib users: don't do * - when there are only local users: set flag @@ -256,32 +257,31 @@ void make_local_curve(Curve *cu) if(cu->id.lib==NULL) return; if(cu->id.us==1) { - cu->id.lib= NULL; - cu->id.flag= LIB_LOCAL; - - new_id(&bmain->curve, (ID *)cu, NULL); + id_clear_lib_data(bmain, &cu->id); extern_local_curve(cu); return; } - for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { if(ob->data == cu) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - cu->id.lib= NULL; - cu->id.flag= LIB_LOCAL; - - new_id(&bmain->curve, (ID *)cu, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &cu->id); extern_local_curve(cu); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, cu->id.lib->filepath}; Curve *cun= copy_curve(cu); cun->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &cun->id, bpath_relocate_visitor, 0, bpath_user_data); + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==cu) { if(ob->id.lib==NULL) { diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 5cae270d4cc..037e63f1d23 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -115,18 +115,20 @@ void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verif } /* be sure all flip_map values are valid */ -void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, int use_verify) +void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, const int flip_map_len, const int use_verify) { - if(dvert->totweight && dvert_r->totweight) { + if (dvert->totweight && dvert_r->totweight) { int i; MDeformWeight *dw; - for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { - MDeformWeight *dw_r; - if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]); - else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]); - - if(dw_r) { - dw_r->weight= dw->weight; + for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { + if (dw->def_nr < flip_map_len) { + MDeformWeight *dw_r; + if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]); + else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]); + + if(dw_r) { + dw_r->weight= dw->weight; + } } } } @@ -164,14 +166,16 @@ void defvert_normalize (MDeformVert *dvert) } } -void defvert_flip (MDeformVert *dvert, const int *flip_map) +void defvert_flip (MDeformVert *dvert, const int *flip_map, const int flip_map_len) { MDeformWeight *dw; int i; - for(dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) - if(flip_map[dw->def_nr] >= 0) + for(dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) { + if((dw->def_nr < flip_map_len) && (flip_map[dw->def_nr] >= 0)) { dw->def_nr= flip_map[dw->def_nr]; + } + } } @@ -251,17 +255,17 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg) } /* note, must be freed */ -int *defgroup_flip_map(Object *ob, int use_default) +int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) { bDeformGroup *dg; - int totdg= BLI_countlist(&ob->defbase); + int totdg= *flip_map_len= BLI_countlist(&ob->defbase); if(totdg==0) { return NULL; } else { char name[sizeof(dg->name)]; - int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), "get_defgroup_flip_map"); + int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); memset(map, -1, totdg * sizeof(int)); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f16b1e6b4ec..d88cbc33926 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -60,10 +60,14 @@ #include "DNA_camera_types.h" #include "DNA_sequence_types.h" #include "DNA_userdef_types.h" +#include "DNA_brush_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_bpath.h" #include "BKE_bmfont.h" #include "BKE_global.h" @@ -313,6 +317,134 @@ Image *copy_image(Image *ima) return nima; } +static void extern_local_image(Image *UNUSED(ima)) +{ + /* Nothing to do: images don't link to other IDs. This function exists to + match id_make_local pattern. */ +} + +void make_local_image(struct Image *ima) +{ + Main *bmain= G.main; + Tex *tex; + Brush *brush; + Mesh *me; + int is_local= FALSE, is_lib= FALSE; + + /* - only lib users: do nothing + * - only local users: set flag + * - mixed: make copy + */ + + if(ima->id.lib==NULL) return; + + /* Can't take short cut here: must check meshes at least because of bogus + texface ID refs. - z0r */ +#if 0 + if(ima->id.us==1) { + id_clear_lib_data(bmain, &ima->id); + extern_local_image(ima); + return; + } +#endif + + for(tex= bmain->tex.first; tex; tex= tex->id.next) { + if(tex->ima == ima) { + if(tex->id.lib) is_lib= TRUE; + else is_local= TRUE; + } + } + for(brush= bmain->brush.first; brush; brush= brush->id.next) { + if(brush->clone.image == ima) { + if(brush->id.lib) is_lib= TRUE; + else is_local= TRUE; + } + } + for(me= bmain->mesh.first; me; me= me->id.next) { + if(me->mtface) { + MTFace *tface; + int a, i; + + for(i=0; i<me->fdata.totlayer; i++) { + if(me->fdata.layers[i].type == CD_MTFACE) { + tface= (MTFace*)me->fdata.layers[i].data; + + for(a=0; a<me->totface; a++, tface++) { + if(tface->tpage == ima) { + if(me->id.lib) is_lib= TRUE; + else is_local= TRUE; + } + } + } + } + } + } + + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &ima->id); + extern_local_image(ima); + } + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, ima->id.lib->filepath}; + Image *iman= copy_image(ima); + + iman->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &iman->id, bpath_relocate_visitor, 0, bpath_user_data); + + tex= bmain->tex.first; + while(tex) { + if(tex->id.lib==NULL) { + if(tex->ima==ima) { + tex->ima = iman; + iman->id.us++; + ima->id.us--; + } + } + tex= tex->id.next; + } + brush= bmain->brush.first; + while(brush) { + if(brush->id.lib==NULL) { + if(brush->clone.image==ima) { + brush->clone.image = iman; + iman->id.us++; + ima->id.us--; + } + } + brush= brush->id.next; + } + /* Transfer references in texfaces. Texfaces don't add to image ID + user count *unless* there are no other users. See + readfile.c:lib_link_mtface. */ + me= bmain->mesh.first; + while(me) { + if(me->mtface) { + MTFace *tface; + int a, i; + + for(i=0; i<me->fdata.totlayer; i++) { + if(me->fdata.layers[i].type == CD_MTFACE) { + tface= (MTFace*)me->fdata.layers[i].data; + + for(a=0; a<me->totface; a++, tface++) { + if(tface->tpage == ima) { + tface->tpage = iman; + if(iman->id.us == 0) { + tface->tpage->id.us= 1; + } + id_lib_extern((ID*)iman); + } + } + } + } + } + me= me->id.next; + } + } +} + void BKE_image_merge(Image *dest, Image *source) { ImBuf *ibuf; @@ -1816,7 +1948,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) flag = IB_rect|IB_multilayer; if(ima->flag & IMA_DO_PREMUL) flag |= IB_premul; - ibuf = IMB_ibImageFromMemory((unsigned char*)ima->packedfile->data, ima->packedfile->size, flag); + ibuf = IMB_ibImageFromMemory((unsigned char*)ima->packedfile->data, ima->packedfile->size, flag, "<packed data>"); } else { flag= IB_rect|IB_multilayer|IB_metadata; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 349b91ad867..47dd0c50172 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -224,7 +224,7 @@ void make_local_key(Key *key) if(key==NULL) return; key->id.lib= NULL; - new_id(NULL, (ID *)key, NULL); + new_id(NULL, &key->id, NULL); } /* Sort shape keys and Ipo curves after a change. This assumes that at most diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 84f9829a639..9a528b54143 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -39,6 +39,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -246,7 +247,7 @@ void make_local_lattice(Lattice *lt) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -255,28 +256,28 @@ void make_local_lattice(Lattice *lt) if(lt->id.lib==NULL) return; if(lt->id.us==1) { - lt->id.lib= NULL; - lt->id.flag= LIB_LOCAL; - new_id(&bmain->latt, (ID *)lt, NULL); + id_clear_lib_data(bmain, <->id); return; } - for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= bmain->object.first; ob && ELEM(FALSE, is_lib, is_local); ob= ob->id.next) { if(ob->data==lt) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - lt->id.lib= NULL; - lt->id.flag= LIB_LOCAL; - new_id(&bmain->latt, (ID *)lt, NULL); + if(is_local && is_lib==FALSE) { + id_clear_lib_data(bmain, <->id); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bath_user_data[2]= {bmain->name, lt->id.lib->filepath}; Lattice *ltn= copy_lattice(lt); ltn->id.us= 0; + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, <n->id, bpath_relocate_visitor, 0, bath_user_data); + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==lt) { if(ob->id.lib==NULL) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index fd333a0987a..8a557817406 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -74,7 +74,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" - +#include "BLI_bpath.h" #include "BKE_animsys.h" #include "BKE_context.h" @@ -108,6 +108,7 @@ #include "BKE_gpencil.h" #include "BKE_fcurve.h" #include "BKE_speaker.h" +#include "BKE_utildefines.h" #include "RNA_access.h" @@ -194,7 +195,8 @@ int id_make_local(ID *id, int test) if(!test) make_local_texture((Tex*)id); return 1; case ID_IM: - return 0; /* not implemented */ + if(!test) make_local_image((Image*)id); + return 1; case ID_LT: if(!test) { make_local_lattice((Lattice*)id); @@ -1246,6 +1248,17 @@ int new_id(ListBase *lb, ID *id, const char *tname) return result; } +/* Pull an ID out of a library (make it local). Only call this for IDs that + don't have other library users. */ +void id_clear_lib_data(Main *bmain, ID *id) +{ + char *bpath_user_data[2]= {bmain->name, id->lib->filepath}; + bpath_traverse_id(bmain, id, bpath_relocate_visitor, 0, bpath_user_data); + id->lib= NULL; + id->flag= LIB_LOCAL; + new_id(which_libbase(bmain, GS(id->name)), id, NULL); +} + /* next to indirect usage in read/writefile also in editobject.c scene.c */ void clear_id_newpoins(void) { @@ -1464,7 +1477,12 @@ void name_uiprefix_id(char *name, ID *id) void BKE_library_filepath_set(Library *lib, const char *filepath) { - BLI_strncpy(lib->name, filepath, sizeof(lib->name)); + /* in some cases this is used to update the absolute path from the + * relative */ + if (lib->name != filepath) { + BLI_strncpy(lib->name, filepath, sizeof(lib->name)); + } + BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath)); /* not essential but set filepath is an absolute copy of value which diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 190df040bf4..2ad3da9f3a0 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -50,6 +50,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_bpath.h" #include "BKE_animsys.h" #include "BKE_displist.h" @@ -285,8 +286,7 @@ void make_local_material(Material *ma) Mesh *me; Curve *cu; MetaBall *mb; - Material *man; - int a, local=0, lib=0; + int a, is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -294,23 +294,24 @@ void make_local_material(Material *ma) */ if(ma->id.lib==NULL) return; - if(ma->id.us==1) { - ma->id.lib= NULL; - ma->id.flag= LIB_LOCAL; - new_id(&bmain->mat, (ID *)ma, NULL); + /* One local user; set flag and return. */ + if(ma->id.us==1) { + id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); return; } - + + /* Check which other IDs reference this one to determine if it's used by + lib or local */ /* test objects */ ob= bmain->object.first; while(ob) { if(ob->mat) { for(a=0; a<ob->totcol; a++) { if(ob->mat[a]==ma) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } } @@ -322,8 +323,8 @@ void make_local_material(Material *ma) if(me->mat) { for(a=0; a<me->totcol; a++) { if(me->mat[a]==ma) { - if(me->id.lib) lib= 1; - else local= 1; + if(me->id.lib) is_lib= TRUE; + else is_local= TRUE; } } } @@ -335,8 +336,8 @@ void make_local_material(Material *ma) if(cu->mat) { for(a=0; a<cu->totcol; a++) { if(cu->mat[a]==ma) { - if(cu->id.lib) lib= 1; - else local= 1; + if(cu->id.lib) is_lib= TRUE; + else is_local= TRUE; } } } @@ -348,26 +349,29 @@ void make_local_material(Material *ma) if(mb->mat) { for(a=0; a<mb->totcol; a++) { if(mb->mat[a]==ma) { - if(mb->id.lib) lib= 1; - else local= 1; + if(mb->id.lib) is_lib= TRUE; + else is_local= TRUE; } } } mb= mb->id.next; } - - if(local && lib==0) { - ma->id.lib= NULL; - ma->id.flag= LIB_LOCAL; - new_id(&bmain->mat, (ID *)ma, NULL); + /* Only local users. */ + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); } - else if(local && lib) { - - man= copy_material(ma); + /* Both user and local, so copy. */ + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, ma->id.lib->filepath}; + Material *man= copy_material(ma); + man->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &man->id, bpath_relocate_visitor, 0, bpath_user_data); + /* do objects */ ob= bmain->object.first; while(ob) { diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index b9ca6dda4cf..98646bd2faa 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -50,7 +50,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" - +#include "BLI_bpath.h" #include "BKE_global.h" @@ -147,7 +147,7 @@ void make_local_mball(MetaBall *mb) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -156,32 +156,31 @@ void make_local_mball(MetaBall *mb) if(mb->id.lib==NULL) return; if(mb->id.us==1) { - mb->id.lib= NULL; - mb->id.flag= LIB_LOCAL; - new_id(&bmain->mball, (ID *)mb, NULL); + id_clear_lib_data(bmain, &mb->id); extern_local_mball(mb); return; } - for(ob= G.main->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= G.main->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { if(ob->data == mb) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - mb->id.lib= NULL; - mb->id.flag= LIB_LOCAL; - - new_id(&bmain->mball, (ID *)mb, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &mb->id); extern_local_mball(mb); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, mb->id.lib->filepath}; MetaBall *mbn= copy_mball(mb); mbn->id.us= 0; + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &mbn->id, bpath_relocate_visitor, 0, bpath_user_data); + for(ob= G.main->object.first; ob; ob= ob->id.next) { if(ob->data == mb) { if(ob->id.lib==NULL) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 074860c1076..890c08b59a9 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -45,6 +45,7 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BLI_bpath.h" #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_edgehash.h" @@ -575,58 +576,43 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob) return bm; } -static void make_local_tface(Main *bmain, Mesh *me) +static void expand_local_mesh(Mesh *me) { - MTFace *tface; - MTexPoly *txface; - Image *ima; - int a, i; - - for(i=0; i<me->pdata.totlayer; i++) { - if(me->pdata.layers[i].type == CD_MTEXPOLY) { - txface= (MTexPoly*)me->fdata.layers[i].data; - - for(a=0; a<me->totpoly; a++, txface++) { - /* special case: ima always local immediately */ - if(txface->tpage) { - ima= txface->tpage; - if(ima->id.lib) { - ima->id.lib= 0; - ima->id.flag= LIB_LOCAL; - new_id(0, (ID *)ima, 0); + id_lib_extern((ID *)me->texcomesh); + + if(me->mtface) { + int a, i; + + for(i=0; i<me->pdata.totlayer; i++) { + if(me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface= (MTexPoly*)me->fdata.layers[i].data; + + for(a=0; a<me->totpoly; a++, txface++) { + /* special case: ima always local immediately */ + if(txface->tpage) { + if(txface->tpage) { + id_lib_extern((ID *)txface->tpage); + } } } } } - } - for(i=0; i<me->fdata.totlayer; i++) { - if(me->fdata.layers[i].type == CD_MTFACE) { - tface= (MTFace*)me->fdata.layers[i].data; - - for(a=0; a<me->totface; a++, tface++) { - /* special case: ima always local immediately */ - if(tface->tpage) { - ima= tface->tpage; - if(ima->id.lib) { - ima->id.lib= NULL; - ima->id.flag= LIB_LOCAL; - new_id(&bmain->image, (ID *)ima, NULL); + for(i=0; i<me->fdata.totlayer; i++) { + if(me->fdata.layers[i].type == CD_MTFACE) { + MTFace *tface= (MTFace*)me->fdata.layers[i].data; + + for(a=0; a<me->totface; a++, tface++) { + /* special case: ima always local immediately */ + if(tface->tpage) { + if(tface->tpage) { + id_lib_extern((ID *)tface->tpage); + } } } } } } -} - -static void expand_local_mesh(Main *bmain, Mesh *me) -{ - id_lib_extern((ID *)me->texcomesh); - - if(me->mtface) { - /* why is this an exception? - should not really make local when extern'ing - campbell */ - make_local_tface(bmain, me); - } if(me->mat) { extern_local_matarar(me->mat, me->totcol); @@ -650,7 +636,7 @@ void make_local_mesh(Mesh *me) me->id.flag= LIB_LOCAL; new_id(&bmain->mesh, (ID *)me, NULL); - expand_local_mesh(bmain, me); + expand_local_mesh(me); return; } @@ -666,7 +652,7 @@ void make_local_mesh(Mesh *me) me->id.flag= LIB_LOCAL; new_id(&bmain->mesh, (ID *)me, NULL); - expand_local_mesh(bmain, me); + expand_local_mesh(me); } else if(local && lib) { Mesh *men= copy_mesh(me); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index c450b4624d0..824e59a82c5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1039,6 +1039,7 @@ static void ntreeMakeLocal_LinkNew(void *calldata, ID *owner_id, bNodeTree *ntre void ntreeMakeLocal(bNodeTree *ntree) { + Main *bmain= G.main; bNodeTreeType *treetype= ntreeGetType(ntree->type); MakeLocalCallData cd; @@ -1049,9 +1050,7 @@ void ntreeMakeLocal(bNodeTree *ntree) if(ntree->id.lib==NULL) return; if(ntree->id.us==1) { - ntree->id.lib= NULL; - ntree->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ntree, NULL); + id_clear_lib_data(bmain, (ID *)ntree); return; } @@ -1065,9 +1064,7 @@ void ntreeMakeLocal(bNodeTree *ntree) /* if all users are local, we simply make tree local */ if(cd.local && cd.lib==0) { - ntree->id.lib= NULL; - ntree->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ntree, NULL); + id_clear_lib_data(bmain, (ID *)ntree); } else if(cd.local && cd.lib) { /* this is the mixed case, we copy the tree and assign it to local users */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index fcdb39ce3db..2388eaff277 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -56,6 +56,7 @@ #include "DNA_world_types.h" #include "BLI_blenlib.h" +#include "BLI_bpath.h" #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_pbvh.h" @@ -748,7 +749,7 @@ void make_local_camera(Camera *cam) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -757,28 +758,29 @@ void make_local_camera(Camera *cam) if(cam->id.lib==NULL) return; if(cam->id.us==1) { - cam->id.lib= NULL; - cam->id.flag= LIB_LOCAL; - new_id(&bmain->camera, (ID *)cam, NULL); + id_clear_lib_data(bmain, &cam->id); return; } - for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { if(ob->data==cam) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - cam->id.lib= NULL; - cam->id.flag= LIB_LOCAL; - new_id(&bmain->camera, (ID *)cam, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &cam->id); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, cam->id.lib->filepath}; Camera *camn= copy_camera(cam); + camn->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &camn->id, bpath_relocate_visitor, 0, bpath_user_data); + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data == cam) { if(ob->id.lib==NULL) { @@ -912,8 +914,7 @@ void make_local_lamp(Lamp *la) { Main *bmain= G.main; Object *ob; - Lamp *lan; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -922,30 +923,31 @@ void make_local_lamp(Lamp *la) if(la->id.lib==NULL) return; if(la->id.us==1) { - la->id.lib= NULL; - la->id.flag= LIB_LOCAL; - new_id(&bmain->lamp, (ID *)la, NULL); + id_clear_lib_data(bmain, &la->id); return; } ob= bmain->object.first; while(ob) { if(ob->data==la) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } ob= ob->id.next; } - if(local && lib==0) { - la->id.lib= NULL; - la->id.flag= LIB_LOCAL; - new_id(&bmain->lamp, (ID *)la, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &la->id); } - else if(local && lib) { - lan= copy_lamp(la); + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, la->id.lib->filepath}; + Lamp *lan= copy_lamp(la); lan->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &lan->id, bpath_relocate_visitor, 0, bpath_user_data); + ob= bmain->object.first; while(ob) { if(ob->data==la) { @@ -1457,7 +1459,7 @@ void make_local_object(Object *ob) Main *bmain= G.main; Scene *sce; Base *base; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -1469,27 +1471,30 @@ void make_local_object(Object *ob) ob->proxy= ob->proxy_from= NULL; if(ob->id.us==1) { - ob->id.lib= NULL; - ob->id.flag= LIB_LOCAL; - new_id(&bmain->object, (ID *)ob, NULL); + id_clear_lib_data(bmain, &ob->id); + extern_local_object(ob); } else { - for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) { + for(sce= bmain->scene.first; sce && ELEM(0, is_lib, is_local); sce= sce->id.next) { if(object_in_scene(ob, sce)) { - if(sce->id.lib) lib= 1; - else local= 1; + if(sce->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - ob->id.lib= NULL; - ob->id.flag= LIB_LOCAL; - new_id(&bmain->object, (ID *)ob, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &ob->id); + extern_local_object(ob); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, ob->id.lib->filepath}; Object *obn= copy_object(ob); + obn->id.us= 0; + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &obn->id, bpath_relocate_visitor, 0, bpath_user_data); + sce= bmain->scene.first; while(sce) { if(sce->id.lib==NULL) { @@ -1507,8 +1512,6 @@ void make_local_object(Object *ob) } } } - - extern_local_object(ob); } /* diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 680c7479c16..d37b61a2c0c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -53,6 +53,7 @@ #include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_linklist.h" +#include "BLI_bpath.h" #include "BLI_cellalloc.h" #include "BLI_math.h" @@ -3603,7 +3604,7 @@ void make_local_particlesettings(ParticleSettings *part) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -3612,34 +3613,34 @@ void make_local_particlesettings(ParticleSettings *part) if(part->id.lib==0) return; if(part->id.us==1) { - part->id.lib= 0; - part->id.flag= LIB_LOCAL; - new_id(&bmain->particle, (ID *)part, 0); + id_clear_lib_data(bmain, &part->id); expand_local_particlesettings(part); return; } /* test objects */ - for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + for(ob= bmain->object.first; ob && ELEM(FALSE, is_lib, is_local); ob= ob->id.next) { ParticleSystem *psys=ob->particlesystem.first; for(; psys; psys=psys->next){ if(psys->part==part) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } } } - if(local && lib==0) { - part->id.lib= 0; - part->id.flag= LIB_LOCAL; - new_id(&bmain->particle, (ID *)part, 0); + if(is_local && is_lib==FALSE) { + id_clear_lib_data(bmain, &part->id); expand_local_particlesettings(part); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, part->id.lib->filepath}; ParticleSettings *partn= psys_copy_settings(part); partn->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &partn->id, bpath_relocate_visitor, 0, bpath_user_data); + /* do objects */ for(ob= bmain->object.first; ob; ob= ob->id.next) { ParticleSystem *psys; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 2f4c2806826..02e65f7044c 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3853,8 +3853,9 @@ static void update_children(ParticleSimulationData *sim) else if(sim->psys->part->childtype) { if(sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys)) distribute_particles(sim, PART_FROM_CHILD); - else - ; /* Children are up to date, nothing to do. */ + else { + /* Children are up to date, nothing to do. */ + } } else psys_free_children(sim->psys); diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index b743f847bb7..d5788d7a748 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -34,6 +34,8 @@ #include "DNA_speaker_types.h" #include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" @@ -78,7 +80,7 @@ void make_local_speaker(Speaker *spk) { Main *bmain= G.main; Object *ob; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -87,30 +89,30 @@ void make_local_speaker(Speaker *spk) if(spk->id.lib==NULL) return; if(spk->id.us==1) { - spk->id.lib= NULL; - spk->id.flag= LIB_LOCAL; - new_id(&bmain->speaker, (ID *)spk, NULL); + id_clear_lib_data(bmain, &spk->id); return; } ob= bmain->object.first; while(ob) { if(ob->data==spk) { - if(ob->id.lib) lib= 1; - else local= 1; + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; } ob= ob->id.next; } - if(local && lib==0) { - spk->id.lib= NULL; - spk->id.flag= LIB_LOCAL; - new_id(&bmain->speaker, (ID *)spk, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &spk->id); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, spk->id.lib->filepath}; Speaker *spkn= copy_speaker(spk); spkn->id.us= 0; + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &spkn->id, bpath_relocate_visitor, 0, bpath_user_data); + ob= bmain->object.first; while(ob) { if(ob->data==spk) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 42415248bdc..e3713b1e177 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -42,6 +42,7 @@ #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" +#include "BLI_bpath.h" #include "DNA_key_types.h" #include "DNA_object_types.h" @@ -814,16 +815,20 @@ Tex *localize_texture(Tex *tex) /* ------------------------------------------------------------------------- */ +static void extern_local_texture(Tex *tex) +{ + id_lib_extern((ID *)tex->ima); +} + void make_local_texture(Tex *tex) { Main *bmain= G.main; - Tex *texn; Material *ma; World *wrld; Lamp *la; Brush *br; ParticleSettings *pa; - int a, local=0, lib=0; + int a, is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -832,18 +837,9 @@ void make_local_texture(Tex *tex) if(tex->id.lib==NULL) return; - /* special case: ima always local immediately */ - if(tex->ima) { - tex->ima->id.lib= NULL; - tex->ima->id.flag= LIB_LOCAL; - new_id(&bmain->image, (ID *)tex->ima, NULL); - } - if(tex->id.us==1) { - tex->id.lib= NULL; - tex->id.flag= LIB_LOCAL; - new_id(&bmain->tex, (ID *)tex, NULL); - + id_clear_lib_data(bmain, &tex->id); + extern_local_texture(tex); return; } @@ -851,8 +847,8 @@ void make_local_texture(Tex *tex) while(ma) { for(a=0; a<MAX_MTEX; a++) { if(ma->mtex[a] && ma->mtex[a]->tex==tex) { - if(ma->id.lib) lib= 1; - else local= 1; + if(ma->id.lib) is_lib= TRUE; + else is_local= TRUE; } } ma= ma->id.next; @@ -861,8 +857,8 @@ void make_local_texture(Tex *tex) while(la) { for(a=0; a<MAX_MTEX; a++) { if(la->mtex[a] && la->mtex[a]->tex==tex) { - if(la->id.lib) lib= 1; - else local= 1; + if(la->id.lib) is_lib= TRUE; + else is_local= TRUE; } } la= la->id.next; @@ -871,8 +867,8 @@ void make_local_texture(Tex *tex) while(wrld) { for(a=0; a<MAX_MTEX; a++) { if(wrld->mtex[a] && wrld->mtex[a]->tex==tex) { - if(wrld->id.lib) lib= 1; - else local= 1; + if(wrld->id.lib) is_lib= TRUE; + else is_local= TRUE; } } wrld= wrld->id.next; @@ -880,8 +876,8 @@ void make_local_texture(Tex *tex) br= bmain->brush.first; while(br) { if(br->mtex.tex==tex) { - if(br->id.lib) lib= 1; - else local= 1; + if(br->id.lib) is_lib= TRUE; + else is_local= TRUE; } br= br->id.next; } @@ -889,21 +885,25 @@ void make_local_texture(Tex *tex) while(pa) { for(a=0; a<MAX_MTEX; a++) { if(pa->mtex[a] && pa->mtex[a]->tex==tex) { - if(pa->id.lib) lib= 1; - else local= 1; + if(pa->id.lib) is_lib= TRUE; + else is_local= TRUE; } } pa= pa->id.next; } - if(local && lib==0) { - tex->id.lib= NULL; - tex->id.flag= LIB_LOCAL; - new_id(&bmain->tex, (ID *)tex, NULL); + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &tex->id); + extern_local_texture(tex); } - else if(local && lib) { - texn= copy_texture(tex); + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, tex->id.lib->filepath}; + Tex *texn= copy_texture(tex); + texn->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &texn->id, bpath_relocate_visitor, 0, bpath_user_data); ma= bmain->mat.first; while(ma) { diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 5c705c5fe94..4d7a7c9a262 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -40,6 +40,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_bpath.h" #include "BKE_world.h" #include "BKE_library.h" @@ -151,7 +152,7 @@ void make_local_world(World *wrld) { Main *bmain= G.main; Scene *sce; - int local=0, lib=0; + int is_local= FALSE, is_lib= FALSE; /* - only lib users: do nothing * - only local users: set flag @@ -160,28 +161,28 @@ void make_local_world(World *wrld) if(wrld->id.lib==NULL) return; if(wrld->id.us==1) { - wrld->id.lib= NULL; - wrld->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)wrld, NULL); + id_clear_lib_data(bmain, &wrld->id); return; } - for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) { + for(sce= bmain->scene.first; sce && ELEM(FALSE, is_lib, is_local); sce= sce->id.next) { if(sce->world == wrld) { - if(sce->id.lib) lib= 1; - else local= 1; + if(sce->id.lib) is_lib= TRUE; + else is_local= TRUE; } } - if(local && lib==0) { - wrld->id.lib= NULL; - wrld->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)wrld, NULL); + if(is_local && is_lib==FALSE) { + id_clear_lib_data(bmain, &wrld->id); } - else if(local && lib) { + else if(is_local && is_lib) { + char *bpath_user_data[2]= {bmain->name, wrld->id.lib->filepath}; World *wrldn= copy_world(wrld); wrldn->id.us= 0; - + + /* Remap paths of new ID using old library as base. */ + bpath_traverse_id(bmain, &wrldn->id, bpath_relocate_visitor, 0, bpath_user_data); + for(sce= bmain->scene.first; sce; sce= sce->id.next) { if(sce->world == wrld) { if(sce->id.lib==NULL) { diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 6101c94e26f..89ba4b2675e 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -34,22 +34,23 @@ #ifndef BLI_BPATH_H #define BLI_BPATH_H -struct BPathIterator; -struct ReportList; +struct ID; +struct ListBase; struct Main; +struct ReportList; -void BLI_bpathIterator_init (struct BPathIterator **bpi, struct Main *bmain, const char *basedir, const int flag); -void BLI_bpathIterator_free (struct BPathIterator *bpi); -const char* BLI_bpathIterator_getLib (struct BPathIterator *bpi); -const char* BLI_bpathIterator_getName (struct BPathIterator *bpi); -int BLI_bpathIterator_getType (struct BPathIterator *bpi); -unsigned int BLI_bpathIterator_getPathMaxLen (struct BPathIterator *bpi); -const char* BLI_bpathIterator_getBasePath (struct BPathIterator *bpi); -void BLI_bpathIterator_step (struct BPathIterator *bpi); -int BLI_bpathIterator_isDone (struct BPathIterator *bpi); -void BLI_bpathIterator_getPath (struct BPathIterator *bpi, char *path); -void BLI_bpathIterator_getPathExpanded (struct BPathIterator *bpi, char *path_expanded); -void BLI_bpathIterator_setPath (struct BPathIterator *bpi, const char *path); +/* Function that does something with an ID's file path. Should return 1 if the + path has changed, and in that case, should write the result to pathOut. */ +typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src); +/* Executes 'visit' for each path associated with 'id'. */ +void bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); +void bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); +void bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); +int bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); + +#define BPATH_TRAVERSE_ABS (1<<0) /* convert paths to absolute */ +#define BPATH_TRAVERSE_SKIP_LIBRARY (1<<2) /* skip library paths */ +#define BPATH_TRAVERSE_SKIP_PACKED (1<<3) /* skip packed data */ /* high level funcs */ @@ -57,8 +58,6 @@ void BLI_bpathIterator_setPath (struct BPathIterator *bpi, const char *path) void checkMissingFiles(struct Main *bmain, struct ReportList *reports); void makeFilesRelative(struct Main *bmain, const char *basedir, struct ReportList *reports); void makeFilesAbsolute(struct Main *bmain, const char *basedir, struct ReportList *reports); -void findMissingFiles(struct Main *bmain, const char *str); - -#define BPATH_USE_PACKED 1 +void findMissingFiles(struct Main *bmain, const char *searchpath, struct ReportList *reports); #endif // BLI_BPATH_H diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 455b3b91467..e42e02fb24f 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): Campbell barton + * Contributor(s): Campbell barton, Alex Fraser * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,6 +29,12 @@ * \ingroup bli */ +/* TODO, + * currently there are some cases we dont support. + * - passing output paths to the visitor?, like render out. + * - passing sequence strips with many images. + * - passing directory paths - visitors dont know which path is a dir or a file. + * */ #include <sys/stat.h> @@ -46,908 +52,538 @@ #include "MEM_guardedalloc.h" -#include "DNA_mesh_types.h" -#include "DNA_scene_types.h" /* to get the current frame */ +#include "DNA_brush_types.h" #include "DNA_image_types.h" -#include "DNA_texture_types.h" -#include "DNA_text_types.h" -#include "DNA_sound_types.h" +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_fluidsim.h" +#include "DNA_object_force.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" #include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_text_types.h" +#include "DNA_texture_types.h" #include "DNA_vfont_types.h" -#include "DNA_windowmanager_types.h" +#include "DNA_scene_types.h" +#include "DNA_smoke_types.h" #include "BLI_blenlib.h" #include "BLI_bpath.h" #include "BLI_utildefines.h" -#include "BKE_global.h" -#include "BKE_image.h" /* so we can check the image's type */ -#include "BKE_sequencer.h" +#include "BKE_library.h" #include "BKE_main.h" -#include "BKE_utildefines.h" #include "BKE_report.h" +#include "BKE_sequencer.h" +#include "BKE_utildefines.h" +#include "BKE_image.h" /* so we can check the image's type */ -typedef struct BPathIteratorSeqData -{ - int totseq; - int seq; - struct Sequence **seqar; /* Sequence */ - struct Scene *scene; /* Current scene */ -} BPathIteratorSeqData; - -typedef struct BPathIterator -{ - char* _path; /* never access directly, use BLI_bpathIterator_getPath */ - const char* _lib; - const char* _name; - void* data; - int len; - int type; - int flag; /* iterator options */ - - void (*setpath_callback)(struct BPathIterator *, const char *); - void (*getpath_callback)(struct BPathIterator *, char *); - - const char* base_path; /* base path, the directory the blend file is in - normally bmain->name */ - - Main *bmain; - - /* only for seq data */ - struct BPathIteratorSeqData seqdata; -} BPathIterator; - -#define FILE_MAX 240 - - -/* TODO - BPATH_PLUGIN, BPATH_SEQ */ -enum BPathTypes { - BPATH_IMAGE= 0, - BPATH_TEXTURE, - BPATH_TEXT, - BPATH_SOUND, - BPATH_FONT, - BPATH_LIB, - BPATH_SEQ, - BPATH_CDATA, - - BPATH_DONE -}; - -void BLI_bpathIterator_init(struct BPathIterator **bpi_pt, Main *bmain, const char *basedir, const int flag) +static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) { - BPathIterator *bpi; - - bpi= MEM_mallocN(sizeof(BPathIterator), "BLI_bpathIterator_init"); - *bpi_pt= bpi; - - bpi->type= BPATH_IMAGE; - bpi->data= NULL; - - bpi->getpath_callback= NULL; - bpi->setpath_callback= NULL; + ReportList *reports= (ReportList *)userdata; - /* Sequencer specific */ - bpi->seqdata.totseq= 0; - bpi->seqdata.seq= 0; - bpi->seqdata.seqar= NULL; - bpi->seqdata.scene= NULL; - - bpi->flag= flag; - - bpi->base_path= basedir; /* normally bmain->name */ - bpi->bmain= bmain; + if (!BLI_exists(path_src)) { + BKE_reportf(reports, RPT_WARNING, "Path Not Found \"%s\"", path_src); + } - BLI_bpathIterator_step(bpi); + return FALSE; } -#if 0 -static void BLI_bpathIterator_alloc(struct BPathIterator **bpi) +/* high level function */ +void checkMissingFiles(Main *bmain, ReportList *reports) { - *bpi= MEM_mallocN(sizeof(BPathIterator), "BLI_bpathIterator_alloc"); + bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BPATH_TRAVERSE_ABS, reports); } -#endif -void BLI_bpathIterator_free(struct BPathIterator *bpi) +typedef struct BPathRemap_Data { - if (bpi->seqdata.seqar) - MEM_freeN((void *)bpi->seqdata.seqar); - bpi->seqdata.seqar= NULL; - bpi->seqdata.scene= NULL; + const char *basedir; + ReportList *reports; - MEM_freeN(bpi); -} + int count_tot; + int count_changed; + int count_failed; +} BPathRemap_Data; -void BLI_bpathIterator_getPath(struct BPathIterator *bpi, char *path) +static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src) { - if (bpi->getpath_callback) { - bpi->getpath_callback(bpi, path); - } - else { - strcpy(path, bpi->_path); /* warning, we assume 'path' are long enough */ - } -} + BPathRemap_Data *data= (BPathRemap_Data *)userdata; -void BLI_bpathIterator_setPath(struct BPathIterator *bpi, const char *path) -{ - if (bpi->setpath_callback) { - bpi->setpath_callback(bpi, path); + data->count_tot++; + + if(strncmp(path_src, "//", 2)==0) { + return FALSE; /* already relative */ } else { - strcpy(bpi->_path, path); /* warning, we assume 'path' are long enough */ + strcpy(path_dst, path_src); + BLI_path_rel(path_dst, data->basedir); + if (strncmp(path_dst, "//", 2)==0) { + data->count_changed++; + } + else { + BKE_reportf(data->reports, RPT_WARNING, "Path cant be made relative \"%s\"", path_src); + data->count_failed++; + } + return TRUE; } } -void BLI_bpathIterator_getPathExpanded(struct BPathIterator *bpi, char *path_expanded) +void makeFilesRelative(Main *bmain, const char *basedir, ReportList *reports) { - const char *libpath; - - BLI_bpathIterator_getPath(bpi, path_expanded); - libpath= BLI_bpathIterator_getLib(bpi); + BPathRemap_Data data= {0}; - if (libpath) { /* check the files location relative to its library path */ - BLI_path_abs(path_expanded, libpath); - } - else { /* local data, use the blend files path */ - BLI_path_abs(path_expanded, bpi->base_path); + if(basedir[0] == '\0') { + printf("%s: basedir='', this is a bug\n", __func__); + return; } - BLI_cleanup_file(NULL, path_expanded); -} -const char* BLI_bpathIterator_getLib(struct BPathIterator *bpi) -{ - return bpi->_lib; -} -const char* BLI_bpathIterator_getName(struct BPathIterator *bpi) -{ - return bpi->_name; -} -int BLI_bpathIterator_getType(struct BPathIterator *bpi) -{ - return bpi->type; -} -unsigned int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi) -{ - return bpi->len; -} -const char* BLI_bpathIterator_getBasePath(struct BPathIterator *bpi) -{ - return bpi->base_path; -} -/* gets the first or the next image that has a path - not a viewer node or generated image */ -static struct Image *ima_stepdata__internal(struct Image *ima, const int step_next, const int flag) -{ - if (ima==NULL) - return NULL; + data.basedir= basedir; + data.reports= reports; - if (step_next) - ima= ima->id.next; + bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); - while (ima) { - if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - if(ima->packedfile==NULL || (flag & BPATH_USE_PACKED)) { - break; - } - } - /* image is not a image with a path, skip it */ - ima= ima->id.next; - } - return ima; + BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, + "Total files %d|Changed %d|Failed %d", + data.count_tot, data.count_changed, data.count_failed); } -static struct Tex *tex_stepdata__internal(struct Tex *tex, const int step_next, const int UNUSED(flag)) +static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src) { - if (tex==NULL) - return NULL; + BPathRemap_Data *data= (BPathRemap_Data *)userdata; - if (step_next) - tex= tex->id.next; + data->count_tot++; - while (tex) { - if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) - break; - /* image is not a image with a path, skip it */ - tex= tex->id.next; + if(strncmp(path_src, "//", 2)!=0) { + return FALSE; /* already absolute */ + } + else { + strcpy(path_dst, path_src); + BLI_path_abs(path_dst, data->basedir); + if (strncmp(path_dst, "//", 2)!=0) { + data->count_changed++; + } + else { + BKE_reportf(data->reports, RPT_WARNING, "Path cant be made absolute \"%s\"", path_src); + data->count_failed++; + } + return TRUE; } - return tex; } -static struct Text *text_stepdata__internal(struct Text *text, const int step_next, const int UNUSED(flag)) +/* similar to makeFilesRelative - keep in sync! */ +void makeFilesAbsolute(Main *bmain, const char *basedir, ReportList *reports) { - if (text==NULL) - return NULL; + BPathRemap_Data data= {0}; - if (step_next) - text= text->id.next; - - while (text) { - if (text->name) - break; - /* image is not a image with a path, skip it */ - text= text->id.next; + if(basedir[0] == '\0') { + printf("%s: basedir='', this is a bug\n", __func__); + return; } - return text; -} - -static struct VFont *vf_stepdata__internal(struct VFont *vf, const int step_next, const int flag) -{ - if (vf==NULL) - return NULL; - if (step_next) - vf= vf->id.next; + data.basedir= basedir; + data.reports= reports; - while (vf) { - if (strcmp(vf->name, FO_BUILTIN_NAME)!=0) { - if(vf->packedfile==NULL || (flag & BPATH_USE_PACKED)) { - break; - } - } + bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); - /* font with no path, skip it */ - vf= vf->id.next; - } - return vf; + BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, + "Total files %d|Changed %d|Failed %d", + data.count_tot, data.count_changed, data.count_failed); } -static struct bSound *snd_stepdata__internal(struct bSound *snd, int step_next, const int flag) + +/* find this file recursively, use the biggest file so thumbnails dont get used by mistake + - dir: subdir to search + - filename: set this filename + - filesize: filesize for the file +*/ +#define MAX_RECUR 16 +static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth) { - if (snd==NULL) - return NULL; + /* file searching stuff */ + DIR *dir; + struct dirent *de; + struct stat status; + char path[FILE_MAX]; + int size; - if (step_next) - snd= snd->id.next; + dir= opendir(dirname); - while (snd) { - if(snd->packedfile==NULL || (flag & BPATH_USE_PACKED)) { - break; - } + if (dir==NULL) + return 0; - /* font with no path, skip it */ - snd= snd->id.next; - } - return snd; -} + if (*filesize == -1) + *filesize= 0; /* dir opened fine */ -static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int step_next) -{ - Editing *ed; - Sequence *seq; + while ((de= readdir(dir)) != NULL) { - /* Initializing */ - if (bpi->seqdata.scene==NULL) { - bpi->seqdata.scene= bpi->bmain->scene.first; - } + if (strcmp(".", de->d_name)==0 || strcmp("..", de->d_name)==0) + continue; - if (step_next) { - bpi->seqdata.seq++; - } + BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); - while (bpi->seqdata.scene) { - ed= seq_give_editing(bpi->seqdata.scene, 0); - if (ed) { - if (bpi->seqdata.seqar == NULL) { - /* allocate the sequencer array */ - seq_array(ed, &bpi->seqdata.seqar, &bpi->seqdata.totseq, 0); - bpi->seqdata.seq= 0; - } + if (stat(path, &status) != 0) + continue; /* cant stat, dont bother with this file, could print debug info here */ - if (bpi->seqdata.seq >= bpi->seqdata.totseq) { - seq= NULL; - } - else { - seq= bpi->seqdata.seqar[bpi->seqdata.seq]; - while (!SEQ_HAS_PATH(seq) && seq->plugin==NULL) { - bpi->seqdata.seq++; - if (bpi->seqdata.seq >= bpi->seqdata.totseq) { - seq= NULL; - break; - } - seq= bpi->seqdata.seqar[bpi->seqdata.seq]; - } - } - if (seq) { - return seq; - } - else { - /* keep looking through the next scene, reallocate seq array */ - if (bpi->seqdata.seqar) { - MEM_freeN((void *)bpi->seqdata.seqar); - bpi->seqdata.seqar= NULL; + if (S_ISREG(status.st_mode)) { /* is file */ + if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */ + /* open the file to read its size */ + size= status.st_size; + if ((size > 0) && (size > *filesize)) { /* find the biggest file */ + *filesize= size; + BLI_strncpy(filename_new, path, FILE_MAX); } - bpi->seqdata.scene= bpi->seqdata.scene->id.next; } } - else { - /* no seq data in this scene, next */ - bpi->seqdata.scene= bpi->seqdata.scene->id.next; + else if (S_ISDIR(status.st_mode)) { /* is subdir */ + if (*recur_depth <= MAX_RECUR) { + (*recur_depth)++; + findFileRecursive(filename_new, path, filename, filesize, recur_depth); + (*recur_depth)--; + } } } - - return NULL; + closedir(dir); + return 1; } -static void seq_getpath(struct BPathIterator *bpi, char *path) +typedef struct BPathFind_Data { - Sequence *seq= (Sequence *)bpi->data; - - - path[0]= '\0'; /* incase we cant get the path */ - if (seq==NULL) return; - if (SEQ_HAS_PATH(seq)) { - if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) { - BLI_strncpy(path, seq->strip->dir, FILE_MAX); - BLI_add_slash(path); /* incase its missing */ - if (seq->strip->stripdata) { /* should always be true! */ - /* Using the first image is weak for image sequences */ - strcat(path, seq->strip->stripdata->name); - } - } - else { - /* simple case */ - BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir)); - } - } - else if (seq->plugin) { - BLI_strncpy(seq->plugin->name, path, sizeof(seq->plugin->name)); - } -} + const char *basedir; + char searchdir[FILE_MAX]; + ReportList *reports; +} BPathFind_Data; -static void seq_setpath(struct BPathIterator *bpi, const char *path) +static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src) { - Sequence *seq= (Sequence *)bpi->data; - if (seq==NULL) return; + BPathFind_Data *data= (BPathFind_Data *)userdata; + char filename_new[FILE_MAX]; - if (SEQ_HAS_PATH(seq)) { - if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) { - BLI_split_dirfile(path, seq->strip->dir, seq->strip->stripdata->name, sizeof(seq->strip->dir), sizeof(seq->strip->stripdata->name)); - } - else { - /* simple case */ - BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir)); - } + int filesize= -1; + int recur_depth= 0; + + findFileRecursive(filename_new, + data->searchdir, BLI_path_basename((char *)path_src), + &filesize, &recur_depth); + + if (filesize == -1) { /* could not open dir */ + BKE_reportf(data->reports, RPT_WARNING, + "Could not find \"%s\" in \"%s\"", + BLI_path_basename((char *)path_src), data->searchdir); + return FALSE; } - else if (seq->plugin) { - BLI_strncpy(seq->plugin->name, path, sizeof(seq->plugin->name)); + else { + strcpy(path_dst, filename_new); + return TRUE; } } -static void text_getpath(struct BPathIterator *bpi, char *path) +void findMissingFiles(Main *bmain, const char *searchpath, ReportList *reports) { - Text *text= (Text *)bpi->data; - path[0]= '\0'; /* incase we cant get the path */ - if(text->name) { - strcpy(path, text->name); - } + struct BPathFind_Data data= {0}; + + data.reports= reports; + BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir)); + + bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); } -static void text_setpath(struct BPathIterator *bpi, const char *path) +/* Run a visitor on a string, replacing the contents of the string as needed. */ +static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata) { - Text *text= (Text *)bpi->data; - if (text==NULL) return; + char path_src_buf[FILE_MAX]; + const char *path_src; + char path_dst[FILE_MAX]; - if(text->name) { - MEM_freeN(text->name); + if (absbase) { + BLI_strncpy(path_src_buf, path, sizeof(path_src_buf)); + BLI_path_abs(path_src_buf, absbase); + path_src= path_src_buf; + } + else { + path_src= path; } - text->name= BLI_strdup(path); + if (visit_cb(userdata, path_dst, path_src)) { + BLI_strncpy(path, path_dst, FILE_MAX); + return TRUE; + } + else { + return FALSE; + } } -static struct Mesh *cdata_stepdata__internal(struct Mesh *me, int step_next) +static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file[FILE_MAXFILE], BPathVisitor visit_cb, const char *absbase, void *userdata) { - if (me==NULL) - return NULL; + char path_src[FILE_MAX]; + char path_dst[FILE_MAX]; - if (step_next) - me= me->id.next; + BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file); - while (me) { - if (me->fdata.external) { - break; - } + if (absbase) { + BLI_path_abs(path_src, absbase); + } - me= me->id.next; + if (visit_cb(userdata, path_dst, (const char *)path_src)) { + BLI_split_dirfile(path_dst, path_dir, path_file, + sizeof(path_dir), sizeof(path_file)); + return TRUE; + } + else { + return FALSE; } - return me; } -static void bpi_type_step__internal(struct BPathIterator *bpi) +static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata) { - bpi->type++; /* advance to the next type */ - bpi->data= NULL; + char path_src_buf[FILE_MAX]; + const char *path_src; + char path_dst[FILE_MAX]; - switch (bpi->type) { - case BPATH_SEQ: - bpi->getpath_callback= seq_getpath; - bpi->setpath_callback= seq_setpath; - break; - case BPATH_TEXT: /* path is malloc'd */ - bpi->getpath_callback= text_getpath; - bpi->setpath_callback= text_setpath; - break; - default: - bpi->getpath_callback= NULL; - bpi->setpath_callback= NULL; - break; + if (absbase) { + BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf)); + BLI_path_abs(path_src_buf, absbase); + path_src= path_src_buf; + } + else { + path_src= *path; + } + + if (visit_cb(userdata, path_dst, path_src)) { + MEM_freeN((*path)); + (*path)= BLI_strdup(path_dst); + return TRUE; + } + else { + return FALSE; } } -void BLI_bpathIterator_step(struct BPathIterator *bpi) +/* Run visitor function 'visit' on all paths contained in 'id'. */ +void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - while (bpi->type != BPATH_DONE) { + Image *ima; + const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? (id->lib ? id->lib->filepath : bmain->name) : NULL; - if ((bpi->type) == BPATH_IMAGE) { - /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/ - if (bpi->data) bpi->data= ima_stepdata__internal((Image *)bpi->data, 1, bpi->flag); /* must skip images that have no path */ - else bpi->data= ima_stepdata__internal(bpi->bmain->image.first, 0, bpi->flag); - - if (bpi->data) { - /* get the path info from this datatype */ - Image *ima= (Image *)bpi->data; - - bpi->_lib= ima->id.lib ? ima->id.lib->filepath : NULL; - bpi->_path= ima->name; - bpi->_name= ima->id.name+2; - bpi->len= sizeof(ima->name); - - /* we are done, advancing to the next item, this type worked fine */ - break; + if ((flag & BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { + return; + } + switch(GS(id->name)) { + case ID_IM: + ima= (Image *)id; + if (ima->packedfile == NULL || (flag & BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data); } - else { - bpi_type_step__internal(bpi); + } + break; + case ID_BR: + { + Brush *brush= (Brush *)id; + if (brush->icon_filepath[0]) { + rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data); } } + break; + case ID_OB: - if ((bpi->type) == BPATH_TEXTURE) { - /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/ - if (bpi->data) bpi->data= tex_stepdata__internal( (Tex *)bpi->data, 1, bpi->flag); /* must skip images that have no path */ - else bpi->data= tex_stepdata__internal(bpi->bmain->tex.first, 0, bpi->flag); +#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \ + { \ + PointCache *cache; \ + for(cache= (ptcaches).first; cache; cache= cache->next) { \ + if(cache->flag & PTCACHE_DISK_CACHE) { \ + rewrite_path_fixed(cache->path, \ + visit_cb, \ + absbase, \ + bpath_user_data); \ + } \ + } \ + } \ - if (bpi->data) { - /* get the path info from this datatype */ - Tex *tex= (Tex *)bpi->data; - if(tex->type == TEX_VOXELDATA) { - bpi->_lib= tex->id.lib ? tex->id.lib->filepath : NULL; - bpi->_path= tex->vd->source_path; - bpi->_name= tex->id.name+2; - bpi->len= sizeof(tex->vd->source_path); - } - else { - assert(!"Texture has no path, incorrect step 'tex_stepdata__internal'"); - } + { + Object *ob= (Object *)id; + ModifierData *md; + ParticleSystem *psys; - /* we are done, advancing to the next item, this type worked fine */ - break; + /* do via modifiers instead */ +#if 0 + if (ob->fluidsimSettings) { + rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data); } - else { - bpi_type_step__internal(bpi); - } - } - - if ((bpi->type) == BPATH_TEXT) { - /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/ - if (bpi->data) bpi->data= text_stepdata__internal((Text *)bpi->data, 1, bpi->flag); /* must skip images that have no path */ - else bpi->data= text_stepdata__internal(bpi->bmain->text.first, 0, bpi->flag); - - if (bpi->data) { - /* get the path info from this datatype */ - Text *text= (Text *)bpi->data; - - bpi->_lib= text->id.lib ? text->id.lib->filepath : NULL; - bpi->_path= NULL; /* bpi->path= text->name; */ /* get/set functions override. */ - bpi->_name= text->id.name+2; - bpi->len= FILE_MAX; /* malloc'd but limit anyway since large paths may mess up other areas */ +#endif - /* we are done, advancing to the next item, this type worked fine */ - break; + for (md= ob->modifiers.first; md; md= md->next) { + if (md->type == eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd= (FluidsimModifierData *)md; + if (fluidmd->fss) { + rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data); + } + } + else if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd= (SmokeModifierData *)md; + if(smd->type & MOD_SMOKE_TYPE_DOMAIN) { + BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]); + } + } + else if (md->type==eModifierType_Cloth) { + ClothModifierData *clmd= (ClothModifierData*) md; + BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches); + } + } + if (ob->soft) { + BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches); } - else { - bpi_type_step__internal(bpi); + + for (psys= ob->particlesystem.first; psys; psys= psys->next) { + BPATH_TRAVERSE_POINTCACHE(psys->ptcaches); } } - else if ((bpi->type) == BPATH_SOUND) { - if (bpi->data) bpi->data= snd_stepdata__internal((bSound *)bpi->data, 1, bpi->flag); /* must skip images that have no path */ - else bpi->data= snd_stepdata__internal(bpi->bmain->sound.first, 0, bpi->flag); - - if (bpi->data) { - /* get the path info from this datatype */ - bSound *snd= (bSound *)bpi->data; - bpi->_lib= snd->id.lib ? snd->id.lib->filepath : NULL; - bpi->_path= snd->name; - bpi->_name= snd->id.name+2; - bpi->len= sizeof(snd->name); +#undef BPATH_TRAVERSE_POINTCACHE - /* we are done, advancing to the next item, this type worked fine */ - break; + break; + case ID_SO: + { + bSound *sound= (bSound *)id; + if (sound->packedfile == NULL || (flag & BPATH_TRAVERSE_SKIP_PACKED) == 0) { + rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); } - else { - bpi_type_step__internal(bpi); + } + break; + case ID_TXT: + if (((Text*)id)->name) { + rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data); + } + break; + case ID_VF: + { + VFont *vf= (VFont *)id; + if (vf->packedfile == NULL || (flag & BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (strcmp(vf->name, FO_BUILTIN_NAME) != 0) { + rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); + } } } - else if ((bpi->type) == BPATH_FONT) { - - if (bpi->data) bpi->data= vf_stepdata__internal((VFont *)bpi->data, 1, bpi->flag); - else bpi->data= vf_stepdata__internal(bpi->bmain->vfont.first, 0, bpi->flag); - - if (bpi->data) { - /* get the path info from this datatype */ - VFont *vf= (VFont *)bpi->data; - - bpi->_lib= vf->id.lib ? vf->id.lib->filepath : NULL; - bpi->_path= vf->name; - bpi->_name= vf->id.name+2; - bpi->len= sizeof(vf->name); - - /* we are done, advancing to the next item, this type worked fine */ - break; + break; + case ID_TE: + { + Tex *tex = (Tex *)id; + if (tex->plugin) { + /* FIXME: rewrite_path assumes path length of FILE_MAX, but + tex->plugin->name is 160. ... is this field even a path? */ + //rewrite_path(tex->plugin->name, visit_cb, bpath_user_data); } - else { - bpi_type_step__internal(bpi); + if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) { + rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data); } - } - else if ((bpi->type) == BPATH_LIB) { - if (bpi->data) bpi->data= ((ID *)bpi->data)->next; - else bpi->data= bpi->bmain->library.first; - - if (bpi->data) { - /* get the path info from this datatype */ - Library *lib= (Library *)bpi->data; + break; - bpi->_lib= NULL; - bpi->_path= lib->name; - bpi->_name= NULL; - bpi->len= sizeof(lib->name); + case ID_SCE: + { + Scene *scene= (Scene *)id; + if (scene->ed) { + Sequence *seq; + + SEQ_BEGIN(scene->ed, seq) { + if (SEQ_HAS_PATH(seq)) { + if (ELEM(seq->type, SEQ_MOVIE, SEQ_SOUND)) { + rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, absbase, bpath_user_data); + } + else if (seq->type == SEQ_IMAGE) { + /* might want an option not to loop over all strips */ + StripElem *se= seq->strip->stripdata; + int len= MEM_allocN_len(se) / sizeof(*se); + int i; + + for(i= 0; i < len; i++, se++) { + rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); + } + } + else { + /* simple case */ + rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data); + } + } + else if (seq->plugin) { + rewrite_path_fixed(seq->plugin->name, visit_cb, absbase, bpath_user_data); + } - /* we are done, advancing to the next item, this type worked fine */ - break; - } - else { - bpi_type_step__internal(bpi); + } + SEQ_END } } - else if ((bpi->type) == BPATH_SEQ) { - if (bpi->data) bpi->data= seq_stepdata__internal( bpi, 1 ); - else bpi->data= seq_stepdata__internal( bpi, 0 ); - if (bpi->data) { - Sequence *seq= (Sequence *)bpi->data; - bpi->_lib= NULL; - bpi->_name= seq->name+2; - bpi->len= seq->plugin ? sizeof(seq->plugin->name) : sizeof(seq->strip->dir) + sizeof(seq->strip->stripdata->name); - break; - } - else { - bpi_type_step__internal(bpi); + break; + case ID_ME: + { + Mesh *me= (Mesh *)id; + if (me->fdata.external) { + rewrite_path_fixed(me->fdata.external->filename, visit_cb, absbase, bpath_user_data); } } - else if ((bpi->type) == BPATH_CDATA) { - if (bpi->data) bpi->data= cdata_stepdata__internal( bpi->data, 1 ); - else bpi->data= cdata_stepdata__internal( bpi->bmain->mesh.first, 0 ); - - if (bpi->data) { - Mesh *me= (Mesh *)bpi->data; - bpi->_lib= me->id.lib ? me->id.lib->filepath : NULL; - bpi->_path= me->fdata.external->filename; - bpi->_name= me->id.name+2; - bpi->len= sizeof(me->fdata.external->filename); - break; - } - else { - bpi_type_step__internal(bpi); + break; + case ID_LI: + { + Library *lib= (Library *)id; + if(rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) { + BKE_library_filepath_set(lib, lib->name); } } - } -} - -int BLI_bpathIterator_isDone( struct BPathIterator *bpi) -{ - return bpi->type==BPATH_DONE; -} - -/* include the path argument */ -static void bpath_as_report(struct BPathIterator *bpi, const char *message, ReportList *reports) -{ - const char *prefix; - const char *name; - char path_expanded[FILE_MAXDIR*2]; - - if(reports==NULL) - return; - - switch(BLI_bpathIterator_getType(bpi)) { - case BPATH_IMAGE: - prefix= "Image"; - break; - case BPATH_TEXTURE: - prefix= "Texture"; - break; - case BPATH_TEXT: - prefix= "Text"; - break; - case BPATH_SOUND: - prefix= "Sound"; - break; - case BPATH_FONT: - prefix= "Font"; - break; - case BPATH_LIB: - prefix= "Library"; - break; - case BPATH_SEQ: - prefix= "Sequence"; - break; - case BPATH_CDATA: - prefix= "Mesh Data"; break; default: - prefix= "Unknown"; + /* Nothing to do for other IDs that don't contain file paths. */ break; } - - name= BLI_bpathIterator_getName(bpi); - BLI_bpathIterator_getPathExpanded(bpi, path_expanded); - - if(reports) { - if (name) BKE_reportf(reports, RPT_WARNING, "%s \"%s\", \"%s\": %s", prefix, name, path_expanded, message); - else BKE_reportf(reports, RPT_WARNING, "%s \"%s\": %s", prefix, path_expanded, message); - } - } -/* high level function */ -void checkMissingFiles(Main *bmain, ReportList *reports) +void bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - struct BPathIterator *bpi; - - /* be sure there is low chance of the path being too short */ - char filepath_expanded[FILE_MAXDIR*2]; - - BLI_bpathIterator_init(&bpi, bmain, bmain->name, 0); - while (!BLI_bpathIterator_isDone(bpi)) { - BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded); - - if (!BLI_exists(filepath_expanded)) - bpath_as_report(bpi, "file not found", reports); - - BLI_bpathIterator_step(bpi); + ID *id; + for(id= lb->first; id; id= id->next) { + bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); } - BLI_bpathIterator_free(bpi); } -/* dont log any errors at the moment, should probably do this */ -void makeFilesRelative(Main *bmain, const char *basedir, ReportList *reports) +void bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - int tot= 0, changed= 0, failed= 0, linked= 0; - struct BPathIterator *bpi; - char filepath[FILE_MAX]; - const char *libpath; - - /* be sure there is low chance of the path being too short */ - char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE]; - - if(basedir[0] == '\0') { - printf("makeFilesRelative: basedir='', this is a bug\n"); - return; - } - - BLI_bpathIterator_init(&bpi, bmain, basedir, 0); - while (!BLI_bpathIterator_isDone(bpi)) { - BLI_bpathIterator_getPath(bpi, filepath); - libpath= BLI_bpathIterator_getLib(bpi); - - if(strncmp(filepath, "//", 2)) { - if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */ - linked++; - } - else { /* local data, use the blend files path */ - BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative)); - /* Important BLI_cleanup_dir runs before the path is made relative - * because it wont work for paths that start with "//../" */ - BLI_cleanup_file(bpi->base_path, filepath_relative); /* fix any /foo/../foo/ */ - BLI_path_rel(filepath_relative, bpi->base_path); - /* be safe and check the length */ - if (BLI_bpathIterator_getPathMaxLen(bpi) <= strlen(filepath_relative)) { - bpath_as_report(bpi, "couldn't make path relative (too long)", reports); - failed++; - } - else { - if(strncmp(filepath_relative, "//", 2)==0) { - BLI_bpathIterator_setPath(bpi, filepath_relative); - changed++; - } - else { - bpath_as_report(bpi, "couldn't make path relative", reports); - failed++; - } - } - } - } - BLI_bpathIterator_step(bpi); - tot++; - } - BLI_bpathIterator_free(bpi); - - if(reports) - BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + ListBase *lbarray[MAX_LIBARRAY]; + int a= set_listbasepointers(bmain, lbarray); + while(a--) bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); } -/* dont log any errors at the moment, should probably do this - - * Verry similar to makeFilesRelative - keep in sync! */ -void makeFilesAbsolute(Main *bmain, const char *basedir, ReportList *reports) +/* Rewrites a relative path to be relative to the main file - unless the path is + absolute, in which case it is not altered. */ +int bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) { - int tot= 0, changed= 0, failed= 0, linked= 0; - - struct BPathIterator *bpi; - char filepath[FILE_MAX]; - const char *libpath; - /* be sure there is low chance of the path being too short */ - char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE]; - - if(basedir[0] == '\0') { - printf("makeFilesAbsolute: basedir='', this is a bug\n"); - return; + char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + const char *base_new= ((char **)pathbase_v)[0]; + const char *base_old= ((char **)pathbase_v)[1]; + + if (strncmp(base_old, "//", 2) == 0) { + printf("%s: error, old base path '%s' is not absolute.\n", + __func__, base_old); + return FALSE; + } + + /* Make referenced file absolute. This would be a side-effect of + BLI_cleanup_file, but we do it explicitely so we know if it changed. */ + BLI_strncpy(filepath, path_src, FILE_MAX); + if (BLI_path_abs(filepath, base_old)) { + /* Path was relative and is now absolute. Remap. + * Important BLI_cleanup_dir runs before the path is made relative + * because it wont work for paths that start with "//../" */ + BLI_cleanup_file(base_new, filepath); + BLI_path_rel(filepath, base_new); + BLI_strncpy(path_dst, filepath, FILE_MAX); + return TRUE; } - - BLI_bpathIterator_init(&bpi, bmain, basedir, 0); - while (!BLI_bpathIterator_isDone(bpi)) { - BLI_bpathIterator_getPath(bpi, filepath); - libpath= BLI_bpathIterator_getLib(bpi); - - if(strncmp(filepath, "//", 2)==0) { - if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */ - linked++; - } - else { /* get the expanded path and check it is relative or too long */ - BLI_bpathIterator_getPathExpanded(bpi, filepath_absolute); - BLI_cleanup_file(bpi->base_path, filepath_absolute); /* fix any /foo/../foo/ */ - /* to be safe, check the length */ - if (BLI_bpathIterator_getPathMaxLen(bpi) <= strlen(filepath_absolute)) { - bpath_as_report(bpi, "couldn't make absolute (too long)", reports); - failed++; - } - else { - if(strncmp(filepath_absolute, "//", 2)) { - BLI_bpathIterator_setPath(bpi, filepath_absolute); - changed++; - } - else { - bpath_as_report(bpi, "couldn't make absolute", reports); - failed++; - } - } - } - } - BLI_bpathIterator_step(bpi); - tot++; - } - BLI_bpathIterator_free(bpi); - - if(reports) - BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); -} - - -/* find this file recursively, use the biggest file so thumbnails dont get used by mistake - - dir: subdir to search - - filename: set this filename - - filesize: filesize for the file -*/ -#define MAX_RECUR 16 -static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth) -{ - /* file searching stuff */ - DIR *dir; - struct dirent *de; - struct stat status; - char path[FILE_MAX]; - int size; - - dir= opendir(dirname); - - if (dir==NULL) - return 0; - - if (*filesize == -1) - *filesize= 0; /* dir opened fine */ - - while ((de= readdir(dir)) != NULL) { - - if (strcmp(".", de->d_name)==0 || strcmp("..", de->d_name)==0) - continue; - - BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); - - if (stat(path, &status) != 0) - continue; /* cant stat, dont bother with this file, could print debug info here */ - - if (S_ISREG(status.st_mode)) { /* is file */ - if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */ - /* open the file to read its size */ - size= status.st_size; - if ((size > 0) && (size > *filesize)) { /* find the biggest file */ - *filesize= size; - BLI_strncpy(filename_new, path, FILE_MAX); - } - } - } - else if (S_ISDIR(status.st_mode)) { /* is subdir */ - if (*recur_depth <= MAX_RECUR) { - (*recur_depth)++; - findFileRecursive(filename_new, path, filename, filesize, recur_depth); - (*recur_depth)--; - } - } - } - closedir(dir); - return 1; -} - -/* high level function - call from fileselector */ -void findMissingFiles(Main *bmain, const char *str) -{ - struct BPathIterator *bpi; - - /* be sure there is low chance of the path being too short */ - char filepath_expanded[FILE_MAXDIR*2]; - char filepath[FILE_MAX]; - const char *libpath; - int filesize, recur_depth; - - char dirname[FILE_MAX], filename_new[FILE_MAX]; - - //XXX waitcursor( 1 ); - - BLI_split_dir_part(str, dirname, sizeof(dirname)); - - BLI_bpathIterator_init(&bpi, bmain, bmain->name, 0); - - while (!BLI_bpathIterator_isDone(bpi)) { - BLI_bpathIterator_getPath(bpi, filepath); - libpath= BLI_bpathIterator_getLib(bpi); - - /* Check if esc was pressed because searching files can be slow */ - /*XXX if (blender_test_break()) { - break; - }*/ - - if (libpath==NULL) { - - BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded); - - if (!BLI_exists(filepath_expanded)) { - /* can the dir be opened? */ - filesize= -1; - recur_depth= 0; - - findFileRecursive(filename_new, dirname, BLI_path_basename(filepath), &filesize, &recur_depth); - if (filesize == -1) { /* could not open dir */ - printf("Could not open dir \"%s\"\n", dirname); - return; - } - - if (filesize > 0) { - - if (BLI_bpathIterator_getPathMaxLen(bpi) < strlen(filename_new)) { - printf("cannot set path \"%s\" too long!", filename_new); - } - else { - /* copy the found path into the old one */ - if (G.relbase_valid) - BLI_path_rel(filename_new, bpi->base_path); - - BLI_bpathIterator_setPath(bpi, filename_new); - } - } - } - } - BLI_bpathIterator_step(bpi); + else { + /* Path was not relative to begin with. */ + return FALSE; } - BLI_bpathIterator_free(bpi); - - //XXX waitcursor( 0 ); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ce58582d2ca..7f194fd5e53 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3438,6 +3438,9 @@ static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface) MTFace *tf= mtface; int i; + /* Add pseudo-references (not fake users!) to images used by texface. A + little bogus; it would be better if each mesh consistently added one ref + to each image it used. - z0r */ for (i=0; i<totface; i++, tf++) { tf->tpage= newlibadr(fd, me->id.lib, tf->tpage); if(tf->tpage && tf->tpage->id.us==0) diff --git a/source/blender/blenpluginapi/intern/pluginapi.c b/source/blender/blenpluginapi/intern/pluginapi.c index 67d404899b2..b6bd15fd1c3 100644 --- a/source/blender/blenpluginapi/intern/pluginapi.c +++ b/source/blender/blenpluginapi/intern/pluginapi.c @@ -130,7 +130,7 @@ LIBEXPORT short saveiff(struct ImBuf *ib, LIBEXPORT struct ImBuf *loadifffile(int a, int b) { - return IMB_loadifffile(a, b); + return IMB_loadifffile(a, b, "loadifffile"); } LIBEXPORT struct ImBuf *loadiffname(char *n, diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 0f4546968ba..732f84bb33d 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -757,7 +757,9 @@ EnumPropertyItem keyframe_paste_merge_items[] = { {0, NULL, 0, NULL, NULL}}; -/* This function pastes data from the keyframes copy/paste buffer */ +/* This function pastes data from the keyframes copy/paste buffer + * > return status code is whether the method FAILED to do anything + */ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data, const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode) { @@ -773,17 +775,17 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data, /* check if buffer is empty */ if (animcopybuf.first == NULL) { - BKE_report(ac->reports, RPT_WARNING, "No data in buffer to paste"); + BKE_report(ac->reports, RPT_ERROR, "No animation data in buffer to paste"); return -1; } if (anim_data->first == NULL) { - BKE_report(ac->reports, RPT_WARNING, "No FCurves to paste into"); + BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into"); return -1; } /* mathods of offset */ - switch(offset_mode) { + switch (offset_mode) { case KEYFRAME_PASTE_OFFSET_CFRA_START: offset= (float)(CFRA - animcopy_firstframe); break; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 4ec90d210ad..6617ce776b7 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -384,9 +384,10 @@ static short gp_stroke_addpoint (tGPsdata *p, const int mval[2], float pressure) pt->y= mval[1]; pt->pressure= pressure; - /* if there's stroke fir this poly line session add (or replace last) point - to stroke. This allows to draw lines more interactively (see new segment - during mouse slide, i.e.) */ + /* if there's stroke for this poly line session add (or replace last) point + * to stroke. This allows to draw lines more interactively (see new segment + * during mouse slide, i.e.) + */ if (p->flags & GP_PAINTFLAG_STROKEADDED) { bGPDstroke *gps= p->gpf->strokes.last; bGPDspoint *pts; @@ -400,7 +401,8 @@ static short gp_stroke_addpoint (tGPsdata *p, const int mval[2], float pressure) pts = &gps->points[gps->totpoints-1]; /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer, - but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates */ + * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates + */ if (gpencil_project_check(p)) { View3D *v3d= p->sa->spacedata.first; @@ -1121,7 +1123,7 @@ static int gp_session_initdata (bContext *C, tGPsdata *p) p->gpd= *gpd_ptr; } - if(ED_gpencil_session_active()==0) { + if (ED_gpencil_session_active()==0) { /* initialize undo stack, also, existing undo stack would make buffer drawn */ gpencil_undo_init(p->gpd); @@ -1692,9 +1694,11 @@ static int gpencil_area_exists(bContext *C, ScrArea *satest) bScreen *sc= CTX_wm_screen(C); ScrArea *sa; - for(sa= sc->areabase.first; sa; sa= sa->next) - if(sa==satest) + for (sa= sc->areabase.first; sa; sa= sa->next) { + if (sa==satest) return 1; + } + return 0; } @@ -1780,9 +1784,9 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* basically, this should be mouse-button up = end stroke * BUT what happens next depends on whether we 'painting sessions' is enabled */ - sketch|= GPENCIL_SKETCH_SESSIONS_ON(p->scene); - /* polyline drawig is also 'sketching' -- all knots should be added during one session */ - sketch|= p->paintmode == GP_PAINTMODE_DRAW_POLY; + sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene); + /* polyline drawing is also 'sketching' -- all knots should be added during one session */ + sketch |= p->paintmode == GP_PAINTMODE_DRAW_POLY; if (sketch) { /* end stroke only, and then wait to resume painting soon */ @@ -1803,13 +1807,13 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) } else if (event->val == KM_PRESS) { /* not painting, so start stroke (this should be mouse-button down) */ - p= gpencil_stroke_begin(C, op); if (p->status == GP_STATUS_ERROR) { estate = OPERATOR_CANCELLED; } - } else { + } + else { p->status = GP_STATUS_IDLING; } } @@ -1844,7 +1848,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) } /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */ - if(0==gpencil_area_exists(C, p->sa)) + if (0==gpencil_area_exists(C, p->sa)) estate= OPERATOR_CANCELLED; else /* update status indicators - cursor, header, etc. */ diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 39f6cb7b0c2..b35e20bfe31 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -462,10 +462,10 @@ static void vicon_move_down_draw(int x, int y, int w, int h, float UNUSED(alpha) static void init_brush_icons(void) { -#define INIT_BRUSH_ICON(icon_id, name) \ - bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_ ##name## _png, \ - datatoc_ ##name## _png_size, IB_rect); \ - def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \ +#define INIT_BRUSH_ICON(icon_id, name) \ + bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_ ##name## _png, \ + datatoc_ ##name## _png_size, IB_rect, "<brush icon>"); \ + def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \ IMB_freeImBuf(bbuf); // end INIT_BRUSH_ICON @@ -527,7 +527,7 @@ static void init_internal_icons(void) } } if(bbuf==NULL) - bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect); + bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect, "<blender icons>"); if(bbuf) { /* free existing texture if any */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 6280837b0a3..881d6fa28e5 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1530,7 +1530,7 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single) static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, const char sel, const char sel_mirr, - const int *flip_map, + const int *flip_map, const int flip_map_len, const short mirror_weights, const short flip_vgroups) { BLI_assert(sel || sel_mirr); @@ -1540,8 +1540,8 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, if(mirror_weights) SWAP(MDeformVert, *dvert, *dvert_mirr); if(flip_vgroups) { - defvert_flip(dvert, flip_map); - defvert_flip(dvert_mirr, flip_map); + defvert_flip(dvert, flip_map, flip_map_len); + defvert_flip(dvert_mirr, flip_map, flip_map_len); } } else { @@ -1553,14 +1553,14 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, if(mirror_weights) defvert_copy(dvert, dvert_mirr); if(flip_vgroups) { - defvert_flip(dvert, flip_map); + defvert_flip(dvert, flip_map, flip_map_len); } } } void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups) { -#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups) +#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, flip_map_len, mirror_weights, flip_vgroups) #if 0 EditVert *eve, *eve_mirr; @@ -1568,12 +1568,12 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v MDeformVert *dvert, *dvert_mirr; short sel, sel_mirr; - int *flip_map; + int *flip_map, flip_map_len; if(mirror_weights==0 && flip_vgroups==0) return; - flip_map= defgroup_flip_map(ob, 0); + flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); /* only the active group */ if(ob->type == OB_MESH) { diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index bef3e7f0a1a..2f0958371f9 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -187,10 +187,42 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat /* set callbacks, exported to sequence render too. Only call in foreground (UI) renders. */ +static void screen_render_scene_layer_set(wmOperator *op, Main *mainp, Scene **scene, SceneRenderLayer **srl) +{ + /* single layer re-render */ + if(RNA_property_is_set(op->ptr, "scene")) { + Scene *scn; + char scene_name[MAX_ID_NAME-2]; + + RNA_string_get(op->ptr, "scene", scene_name); + scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2); + + if (scn) { + /* camera switch wont have updated */ + scn->r.cfra= (*scene)->r.cfra; + scene_camera_switch_update(scn); + + *scene = scn; + } + } + + if(RNA_property_is_set(op->ptr, "layer")) { + SceneRenderLayer *rl; + char rl_name[RE_MAXNAME]; + + RNA_string_get(op->ptr, "layer", rl_name); + rl = (SceneRenderLayer *)BLI_findstring(&(*scene)->r.layers, rl_name, offsetof(SceneRenderLayer, name)); + + if (rl) + *srl = rl; + } +} + /* executes blocking render */ static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl= NULL; Render *re= RE_NewRender(scene->id.name); Image *ima; View3D *v3d= CTX_wm_view3d(C); @@ -220,10 +252,13 @@ static int screen_render_exec(bContext *C, wmOperator *op) RE_SetReports(re, op->reports); + /* custom scene and single layer re-render */ + screen_render_scene_layer_set(op, mainp, &scene, &srl); + if(is_animation) RE_BlenderAnim(re, mainp, scene, camera_override, lay, scene->r.sfra, scene->r.efra, scene->r.frame_step); else - RE_BlenderFrame(re, mainp, scene, NULL, camera_override, lay, scene->r.cfra, is_write_still); + RE_BlenderFrame(re, mainp, scene, srl, camera_override, lay, scene->r.cfra, is_write_still); RE_SetReports(re, NULL); @@ -518,28 +553,11 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) jobflag= WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS; - /* single layer re-render */ - if(RNA_property_is_set(op->ptr, "layer")) { - SceneRenderLayer *rl; - Scene *scn; - char scene_name[MAX_ID_NAME-2], rl_name[RE_MAXNAME]; - - RNA_string_get(op->ptr, "layer", rl_name); - RNA_string_get(op->ptr, "scene", scene_name); + /* custom scene and single layer re-render */ + screen_render_scene_layer_set(op, mainp, &scene, &srl); - scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2); - rl = (SceneRenderLayer *)BLI_findstring(&scene->r.layers, rl_name, offsetof(SceneRenderLayer, name)); - - if (scn && rl) { - /* camera switch wont have updated */ - scn->r.cfra= scene->r.cfra; - scene_camera_switch_update(scn); - - scene = scn; - srl = rl; - } + if(RNA_property_is_set(op->ptr, "layer")) jobflag |= WM_JOB_SUSPEND; - } /* job custom data */ rj= MEM_callocN(sizeof(RenderJob), "render job"); @@ -611,7 +629,7 @@ void RENDER_OT_render(wmOperatorType *ot) RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene"); RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)"); - RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render"); - RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME-2, "Scene", "Re-render single layer in this scene"); + RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)"); + RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME-2, "Scene", "Scene to render, current scene if not specified"); } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index eb29dfb2ce1..a044651652e 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -492,7 +492,6 @@ void ACTION_OT_copy (wmOperatorType *ot) ot->description= "Copy selected keyframes to the copy/paste buffer"; /* api callbacks */ -// ot->invoke= WM_operator_props_popup; // better wait for graph redo panel ot->exec= actkeys_copy_exec; ot->poll= ED_operator_action_active; @@ -510,10 +509,9 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - - if (ac.reports==NULL) { - ac.reports= op->reports; - } + + /* ac.reports by default will be the global reports list, which won't show warnings */ + ac.reports= op->reports; /* paste keyframes */ if (ac.datatype == ANIMCONT_GPENCIL) { @@ -522,8 +520,8 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { + /* non-zero return means an error occurred while trying to paste */ if (paste_action_keys(&ac, offset_mode, merge_mode)) { - BKE_report(op->reports, RPT_ERROR, "No keyframes to paste"); return OPERATOR_CANCELLED; } } @@ -545,12 +543,14 @@ void ACTION_OT_paste (wmOperatorType *ot) ot->description= "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame"; /* api callbacks */ +// ot->invoke= WM_operator_props_popup; // better wait for action redo panel ot->exec= actkeys_paste_exec; ot->poll= ED_operator_action_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - + + /* props */ RNA_def_enum(ot->srna, "offset", keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys"); RNA_def_enum(ot->srna, "merge", keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing"); } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index bcd35c63a41..e739c5fe22e 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -374,7 +374,7 @@ void filelist_init_icons(void) #ifdef WITH_HEADLESS bbuf = NULL; #else - bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_prvicons, datatoc_prvicons_size, IB_rect); + bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_prvicons, datatoc_prvicons_size, IB_rect, "<splash>"); #endif if (bbuf) { for (y=0; y<SPECIAL_IMG_ROWS; y++) { diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 455b1bc0bdf..460e46fce30 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -727,11 +727,10 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op) if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if(ac.reports==NULL) { - ac.reports= op->reports; - } + /* ac.reports by default will be the global reports list, which won't show warnings */ + ac.reports= op->reports; - /* paste keyframes */ + /* paste keyframes - non-zero return means an error occurred while trying to paste */ if (paste_graph_keys(&ac, offset_mode, merge_mode)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 2b3785e2810..deff1c77912 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -253,10 +253,12 @@ void FILE_OT_make_paths_absolute(wmOperatorType *ot) /********************* report missing files operator *********************/ -static int report_missing_files_exec(bContext *UNUSED(C), wmOperator *op) +static int report_missing_files_exec(bContext *C, wmOperator *op) { + Main *bmain= CTX_data_main(C); + /* run the missing file check */ - checkMissingFiles(G.main, op->reports); + checkMissingFiles(bmain, op->reports); return OPERATOR_FINISHED; } @@ -276,13 +278,12 @@ void FILE_OT_report_missing_files(wmOperatorType *ot) /********************* find missing files operator *********************/ -static int find_missing_files_exec(bContext *UNUSED(C), wmOperator *op) +static int find_missing_files_exec(bContext *C, wmOperator *op) { - char *path; - - path= RNA_string_get_alloc(op->ptr, "filepath", NULL, 0); - findMissingFiles(G.main, path); - MEM_freeN(path); + Main *bmain= CTX_data_main(C); + const char *searchpath= RNA_string_get_alloc(op->ptr, "filepath", NULL, 0); + findMissingFiles(bmain, searchpath, op->reports); + MEM_freeN((void *)searchpath); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 608a3c4c0b2..96b5548a8c5 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -313,13 +313,9 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) Library *lib= (Library *)tselem->id; char expanded[FILE_MAX]; - BLI_strncpy(expanded, lib->name, sizeof(expanded)); - - /* even though we already set the name this syncs the absolute - * path, this is intentionally not already expanded yet to - * avoid copying lib->name to its self. */ - BKE_library_filepath_set(lib, expanded); + BKE_library_filepath_set(lib, lib->name); + BLI_strncpy(expanded, lib->name, sizeof(expanded)); BLI_path_abs(expanded, G.main->name); if (!BLI_exists(expanded)) { BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Library path '%s' does not exist, correct this before saving", expanded); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 78907fbd1ed..a4f67f91763 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -310,9 +310,7 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeSto static void id_local_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { if (tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) { - tselem->id->lib= NULL; - tselem->id->flag= LIB_LOCAL; - new_id(NULL, tselem->id, NULL); + id_clear_lib_data(NULL, tselem->id); } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 18360f8df41..ddfa2fd915f 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -72,7 +72,8 @@ #define SEQ_RIGHTHANDLE 2 -/* Note, Dont use WHILE_SEQ while drawing! - it messes up transform, - Campbell */ +/* Note, Dont use SEQ_BEGIN/SEQ_END while drawing! + * it messes up transform, - Campbell */ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3]) @@ -253,8 +254,10 @@ static void drawmeta_stipple(int value) static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2) { - /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks) - * so for now, just use the meta's immediate children, could be fixed but its only drawing - Campbell */ + /* note: this used to use SEQ_BEGIN/SEQ_END, but it messes up the + * seq->depth value, (needed by transform when doing overlap checks) + * so for now, just use the meta's immediate children, could be fixed but + * its only drawing - campbell */ Sequence *seq; unsigned char col[4]; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index dd9202d96f6..5c31067c284 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -625,9 +625,9 @@ static void editvert_mirror_update(Object *ob, BMVert *eve, int def_nr, int inde if(dvert_dst) { if(def_nr == -1) { /* all vgroups, add groups where neded */ - - int *flip_map= defgroup_flip_map(ob, 1); - defvert_sync_mapped(dvert_dst, dvert_src, flip_map, 1); + int flip_map_len; + int *flip_map= defgroup_flip_map(ob, &flip_map_len, TRUE); + defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, TRUE); MEM_freeN(flip_map); } else { diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 5f03ca9ba28..3ab199625a4 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -94,19 +94,20 @@ void IMB_exit(void); * * @attention Defined in readimage.c */ -struct ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags); +struct ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, + int flags, const char *descr); /** * * @attention Defined in readimage.c */ -struct ImBuf *IMB_testiffname(char *naam,int flags); +struct ImBuf *IMB_testiffname(const char *filepath, int flags); /** * * @attention Defined in readimage.c */ -struct ImBuf *IMB_loadiffname(const char *naam, int flags); +struct ImBuf *IMB_loadiffname(const char *filepath, int flags); /** * @@ -119,7 +120,7 @@ void IMB_freeImBuf(struct ImBuf *ibuf); * @attention Defined in allocimbuf.c */ struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, - unsigned char d, unsigned int flags); + unsigned char d, unsigned int flags); /** * @@ -237,7 +238,7 @@ int IMB_anim_get_fps(struct anim * anim, /** * - * @attention Defined in anim.c + * @attention Defined in anim_movie.c */ struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex); void IMB_close_anim(struct anim *anim); @@ -245,16 +246,16 @@ void IMB_close_anim(struct anim *anim); /** * - * @attention Defined in anim.c + * @attention Defined in anim_movie.c */ -int ismovie(const char *name); +int ismovie(const char *filepath); void IMB_anim_set_preseek(struct anim *anim, int preseek); int IMB_anim_get_preseek(struct anim *anim); /** * - * @attention Defined in anim.c + * @attention Defined in anim_movie.c */ struct ImBuf *IMB_anim_absolute( @@ -264,14 +265,14 @@ struct ImBuf *IMB_anim_absolute( /** * - * @attention Defined in anim.c + * @attention Defined in anim_movie.c * fetches a define previewframe, usually half way into the movie */ struct ImBuf *IMB_anim_previewframe(struct anim *anim); /** * - * @attention Defined in anim.c + * @attention Defined in anim_movie.c */ void IMB_free_anim(struct anim *anim); @@ -419,7 +420,7 @@ struct ImBuf *IMB_loadiffmem(int *mem, int flags); * @deprecated Only here for backwards compatibility of the * @deprecated plugin system. */ -struct ImBuf *IMB_loadifffile(int file, int flags); +struct ImBuf *IMB_loadifffile(int file, int flags, const char *descr); /** * diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 98828c58511..5bbabd84648 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -446,6 +446,7 @@ ImBuf *IMB_dupImBuf(ImBuf *ibuf1) return(ibuf2); } +#if 0 /* remove? - campbell */ /* support for cache limiting */ static void imbuf_cache_destructor(void *data) @@ -461,6 +462,7 @@ static void imbuf_cache_destructor(void *data) ibuf->c_handle = NULL; } + static MEM_CacheLimiterC **get_imbuf_cache_limiter(void) { static MEM_CacheLimiterC *c = NULL; @@ -470,3 +472,4 @@ static MEM_CacheLimiterC **get_imbuf_cache_limiter(void) return &c; } +#endif diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index e1592d221fb..3adb9a3791f 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -1,7 +1,4 @@ /* - * anim.c - * - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -113,7 +110,7 @@ #endif #endif -int ismovie(const char *UNUSED(name)) { +int ismovie(const char *UNUSED(filepath)) { return 0; } @@ -372,7 +369,7 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) { if (anim->pgf) { lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo])); if (lpbi) { - ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect); + ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect, "<avi_fetchibuf>"); //Oh brother... } } diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 794777b21d3..c2f73efa63f 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -43,19 +43,20 @@ #endif #include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_filetype.h" -ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags) +ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, const char *descr) { ImBuf *ibuf; ImFileType *type; if(mem == NULL) { - printf("Error in ibImageFromMemory: NULL pointer\n"); + fprintf(stderr, "%s: NULL pointer\n", __func__); return NULL; } @@ -73,12 +74,12 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags) } } - fprintf(stderr, "Unknown fileformat\n"); - + fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr); + return NULL; } -ImBuf *IMB_loadifffile(int file, int flags) +ImBuf *IMB_loadifffile(int file, int flags, const char *descr) { ImBuf *ibuf; unsigned char *mem; @@ -90,14 +91,14 @@ ImBuf *IMB_loadifffile(int file, int flags) mem= mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0); if(mem==(unsigned char*)-1) { - fprintf(stderr, "Couldn't get mapping\n"); + fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr); return NULL; } - ibuf= IMB_ibImageFromMemory(mem, size, flags); + ibuf= IMB_ibImageFromMemory(mem, size, flags, descr); if(munmap(mem, size)) - fprintf(stderr, "Couldn't unmap file.\n"); + fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr); return ibuf; } @@ -117,24 +118,24 @@ static void imb_cache_filename(char *filename, const char *name, int flags) BLI_strncpy(filename, name, IB_FILENAME_SIZE); } -ImBuf *IMB_loadiffname(const char *name, int flags) +ImBuf *IMB_loadiffname(const char *filepath, int flags) { ImBuf *ibuf; int file, a; - char filename[IB_FILENAME_SIZE]; + char filepath_tx[IB_FILENAME_SIZE]; - imb_cache_filename(filename, name, flags); + imb_cache_filename(filepath_tx, filepath, flags); - file = open(filename, O_BINARY|O_RDONLY); + file = open(filepath_tx, O_BINARY|O_RDONLY); if(file < 0) return NULL; - ibuf= IMB_loadifffile(file, flags); + ibuf= IMB_loadifffile(file, flags, filepath_tx); if(ibuf) { - BLI_strncpy(ibuf->name, name, sizeof(ibuf->name)); - BLI_strncpy(ibuf->cachename, filename, sizeof(ibuf->cachename)); + BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name)); + BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename)); for(a=1; a<ibuf->miptot; a++) - BLI_strncpy(ibuf->mipmap[a-1]->cachename, filename, sizeof(ibuf->cachename)); + BLI_strncpy(ibuf->mipmap[a-1]->cachename, filepath_tx, sizeof(ibuf->cachename)); if(flags & IB_fields) IMB_de_interlace(ibuf); } @@ -143,21 +144,22 @@ ImBuf *IMB_loadiffname(const char *name, int flags) return ibuf; } -ImBuf *IMB_testiffname(char *name, int flags) +ImBuf *IMB_testiffname(const char *filepath, int flags) { ImBuf *ibuf; int file; - char filename[IB_FILENAME_SIZE]; + char filepath_tx[IB_FILENAME_SIZE]; - imb_cache_filename(filename, name, flags); + imb_cache_filename(filepath_tx, filepath, flags); - file = open(filename,O_BINARY|O_RDONLY); + file = open(filepath_tx,O_BINARY|O_RDONLY); if(file < 0) return NULL; - ibuf=IMB_loadifffile(file, flags|IB_test|IB_multilayer); + ibuf=IMB_loadifffile(file, flags|IB_test|IB_multilayer, filepath_tx); + if(ibuf) { - BLI_strncpy(ibuf->name, name, sizeof(ibuf->name)); - BLI_strncpy(ibuf->cachename, filename, sizeof(ibuf->cachename)); + BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name)); + BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename)); } close(file); diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index f2d1578388d..82a7d276817 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -95,15 +95,15 @@ static void rna_Action_groups_remove(bAction *act, ReportList *reports, bActionG static FCurve *rna_Action_fcurve_new(bAction *act, ReportList *reports, const char *data_path, int index, const char *group) { - if(group && group[0]=='\0') group= NULL; + if (group && group[0]=='\0') group= NULL; - if(data_path[0] == '\0') { + if (data_path[0] == '\0') { BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument"); return NULL; } /* annoying, check if this exists */ - if(verify_fcurve(act, group, data_path, index, 0)) { + if (verify_fcurve(act, group, data_path, index, 0)) { BKE_reportf(reports, RPT_ERROR, "F-Curve '%s[%d]' already exists in action '%s'", data_path, index, act->id.name+2); return NULL; } diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index 15facd3606f..f041d3efde4 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -112,7 +112,7 @@ static PointerRNA rna_Context_tool_settings_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_ToolSettings, CTX_data_tool_settings(C)); } -static PointerRNA rna_Context_user_preferences_get(PointerRNA *ptr) +static PointerRNA rna_Context_user_preferences_get(PointerRNA *UNUSED(ptr)) { PointerRNA newptr; RNA_pointer_create(NULL, &RNA_UserPreferences, &U, &newptr); diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index df32359ef91..d2d24e083b1 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -75,7 +75,7 @@ static StructRNA* rna_FluidSettings_refine(struct PointerRNA *ptr) } } -static void rna_fluid_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_fluid_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Object *ob= ptr->id.data; diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index 16d7dd16382..65dcbc66624 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -351,7 +351,7 @@ static char *rna_ShapeKey_path(PointerRNA *ptr) return BLI_sprintfN("key_blocks[\"%s\"]", kb->name); } -static void rna_Key_update_data(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { Key *key= ptr->id.data; Object *ob; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6d9713b659e..968e7264cf7 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1053,7 +1053,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons * is not for general use and only for the few cases where changing scene * settings and NOT for general purpose updates, possibly this should be * given its own notifier. */ -static void rna_Scene_update_active_object_data(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +static void rna_Scene_update_active_object_data(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { Object *ob= OBACT; if(ob) { diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 625a37814cb..f3b158f84fe 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -541,7 +541,7 @@ static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value) BLI_split_file_part(value, elem->name, sizeof(elem->name)); }*/ -static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { Editing *ed= seq_give_editing(scene, FALSE); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 7e2bef9c91f..c7f7fe5feea 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1179,7 +1179,7 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value) else assert(!"setting the bl_description on a non-builtin operator"); } -static void rna_KeyMapItem_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_KeyMapItem_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { wmKeyMapItem *kmi= ptr->data; WM_keyconfig_update_tag(NULL, kmi); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 2825053050e..139e4c21c4b 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -241,29 +241,12 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, /*handle vgroup stuff*/ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) { MDeformVert *dvert = CustomData_get_layer(&cddm->vertData, CD_MDEFORMVERT); + int *flip_map= NULL, flip_map_len= 0; + + flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); for (i=0; i<dm->numVertData; i++, dvert++) { - for(j = 0; j < dvert->totweight; ++j) { - char tmpname[32]; - - if(dvert->dw[j].def_nr < 0 || - dvert->dw[j].def_nr >= vector_size) - continue; - - def = vector_def[dvert->dw[j].def_nr]; - strcpy(tmpname, def->name); - vertgroup_flip_name(tmpname,0); - - for(b = 0, defb = ob->defbase.first; defb; - defb = defb->next, b++) - { - if(!strcmp(defb->name, tmpname)) - { - dvert->dw[j].def_nr = b; - break; - } - } - } + defvert_flip(dvert, flip_map, flip_map_len); } } diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index d9d1c16e11f..dfb7a1e8f75 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -81,53 +81,52 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self)) return ret; } +static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) +{ + PyObject *list= (PyObject *)userdata; + PyObject *item= PyUnicode_DecodeFSDefault(path_src); + PyList_Append(list, item); + Py_DECREF(item); + return FALSE; /* never edits the path */ +} + PyDoc_STRVAR(bpy_blend_paths_doc, -".. function:: blend_paths(absolute=False)\n" +".. function:: blend_paths(absolute=False, packed=False, local=False)\n" "\n" " Returns a list of paths to external files referenced by the loaded .blend file.\n" "\n" " :arg absolute: When true the paths returned are made absolute.\n" " :type absolute: boolean\n" +" :arg packed: When true skip file paths for packed data.\n" +" :type packed: boolean\n" +" :arg local: When true skip linked library paths.\n" +" :type local: boolean\n" " :return: path list.\n" " :rtype: list of strings\n" ); static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { - struct BPathIterator *bpi; - PyObject *list, *st; /* stupidly big string to be safe */ - /* be sure there is low chance of the path being too short */ - char filepath_expanded[1024]; - const char *lib; + int flag= 0; + PyObject *list; - int absolute= 0; - static const char *kwlist[]= {"absolute", NULL}; + int absolute= FALSE; + int packed= FALSE; + int local= FALSE; + static const char *kwlist[]= {"absolute", "packed", "local", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:blend_paths", (char **)kwlist, &absolute)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "|ii:blend_paths", + (char **)kwlist, &absolute, &packed)) + { return NULL; + } - list= PyList_New(0); + if (absolute) flag |= BPATH_TRAVERSE_ABS; + if (!packed) flag |= BPATH_TRAVERSE_SKIP_PACKED; + if (local) flag |= BPATH_TRAVERSE_SKIP_LIBRARY; - for (BLI_bpathIterator_init(&bpi, G.main, G.main->name, 0); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) { - /* build the list */ - if (absolute) { - BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded); - } - else { - lib= BLI_bpathIterator_getLib(bpi); - if (lib && (BLI_path_cmp(lib, BLI_bpathIterator_getBasePath(bpi)))) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */ - BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded); - } - else { - BLI_bpathIterator_getPath(bpi, filepath_expanded); - } - } - st= PyUnicode_DecodeFSDefault(filepath_expanded); - - PyList_Append(list, st); - Py_DECREF(st); - } + list= PyList_New(0); - BLI_bpathIterator_free(bpi); + bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); return list; } @@ -147,10 +146,10 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; /* stupid string compare */ - if (!strcmp(type, "DATAFILES")) folder_id= BLENDER_USER_DATAFILES; - else if (!strcmp(type, "CONFIG")) folder_id= BLENDER_USER_CONFIG; - else if (!strcmp(type, "SCRIPTS")) folder_id= BLENDER_USER_SCRIPTS; - else if (!strcmp(type, "AUTOSAVE")) folder_id= BLENDER_USER_AUTOSAVE; + if (!strcmp(type, "DATAFILES")) folder_id= BLENDER_USER_DATAFILES; + else if (!strcmp(type, "CONFIG")) folder_id= BLENDER_USER_CONFIG; + else if (!strcmp(type, "SCRIPTS")) folder_id= BLENDER_USER_SCRIPTS; + else if (!strcmp(type, "AUTOSAVE")) folder_id= BLENDER_USER_AUTOSAVE; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e1670a674e8..65e65450167 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1953,8 +1953,9 @@ void wm_event_do_handlers(bContext *C) win->eventstate->prevy= event->y; //printf("win->eventstate->prev = %d %d\n", event->x, event->y); } - else - ;//printf("not setting prev to %d %d\n", event->x, event->y); + else { + //printf("not setting prev to %d %d\n", event->x, event->y); + } } /* store last event for this window */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 177a468c008..a817761bd65 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1218,7 +1218,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar extern char datatoc_splash_png[]; extern int datatoc_splash_png_size; - ImBuf *ibuf= IMB_ibImageFromMemory((unsigned char*)datatoc_splash_png, datatoc_splash_png_size, IB_rect); + ImBuf *ibuf= IMB_ibImageFromMemory((unsigned char*)datatoc_splash_png, datatoc_splash_png_size, IB_rect, "<splash screen>"); #else ImBuf *ibuf= NULL; #endif diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 250f431dc9a..fe967bbcd1c 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -648,7 +648,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) // window_handle(win, INPUTCHANGE, win->active); /* bad ghost support for modifier keys... so on activate we set the modifiers again */ - kdata.ascii= 0; + kdata.ascii= '\0'; + kdata.utf8_buf[0]= '\0'; if (win->eventstate->shift && !query_qual(SHIFT)) { kdata.key= GHOST_kKeyLeftShift; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); |