added path traversal flag - BPATH_TRAVERSE_SKIP_MULTIFILE,
authorCampbell Barton <ideasman42@gmail.com>
Tue, 1 Nov 2011 06:26:55 +0000 (06:26 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 1 Nov 2011 06:26:55 +0000 (06:26 +0000)
so path manipulation functions dont run multiple times on the same path in the case of sequence strips where the one directory is used as the base for many images.

19 files changed:
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/speaker.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/world.c
source/blender/blenlib/BLI_bpath.h
source/blender/blenlib/intern/bpath.c

index e203391..9130cac 100644 (file)
@@ -49,6 +49,7 @@ void *alloc_libblock(struct ListBase *lb, short type, const char *name);
 void *copy_libblock(void *rt);
 void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
 
 void *copy_libblock(void *rt);
 void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
 
+void BKE_id_lib_local_paths(struct Main *bmain, struct ID *id);
 void id_lib_extern(struct ID *id);
 void BKE_library_filepath_set(struct Library *lib, const char *filepath);
 void id_us_plus(struct ID *id);
 void id_lib_extern(struct ID *id);
 void BKE_library_filepath_set(struct Library *lib, const char *filepath);
 void id_us_plus(struct ID *id);
index 2a1794f..944f7c6 100644 (file)
@@ -146,13 +146,10 @@ void make_local_action(bAction *act)
                id_clear_lib_data(bmain, &act->id);
        }
        else if (mlac.is_local && mlac.is_lib) {
                id_clear_lib_data(bmain, &act->id);
        }
        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;
 
                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_id_lib_local_paths(bmain, &mlac.actn->id);
 
                BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
        }
 
                BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
        }
index 9fba18d..e9a19b5 100644 (file)
@@ -157,12 +157,11 @@ void make_local_armature(bArmature *arm)
                id_clear_lib_data(bmain, &arm->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &arm->id);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &armn->id);
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data == arm) {
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data == arm) {
index 6e343e8..d68b0b3 100644 (file)
@@ -172,7 +172,7 @@ static void clean_paths(Main *main)
 {
        Scene *scene;
 
 {
        Scene *scene;
 
-       bpath_traverse_main(main, clean_paths_visit_cb, 0, NULL);
+       bpath_traverse_main(main, clean_paths_visit_cb, BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
 
        for(scene= main->scene.first; scene; scene= scene->id.next) {
                BLI_clean(scene->r.pic);
 
        for(scene= main->scene.first; scene; scene= scene->id.next) {
                BLI_clean(scene->r.pic);
index 10f056e..e78b894 100644 (file)
@@ -224,13 +224,12 @@ void make_local_brush(Brush *brush)
                }
        }
        else if(is_local && is_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. */
                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);
+               BKE_id_lib_local_paths(bmain, &brush->id);
                
                for(scene= bmain->scene.first; scene; scene=scene->id.next) {
                        if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
                
                for(scene= bmain->scene.first; scene; scene=scene->id.next) {
                        if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
index 13b1da2..5d2180f 100644 (file)
@@ -273,13 +273,10 @@ void make_local_curve(Curve *cu)
                extern_local_curve(cu);
        }
        else if(is_local && is_lib) {
                extern_local_curve(cu);
        }
        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;
 
                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);
+               BKE_id_lib_local_paths(bmain, &cun->id);
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==cu) {
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==cu) {
index 9aeacb9..0844084 100644 (file)
@@ -385,13 +385,12 @@ void make_local_image(struct Image *ima)
                extern_local_image(ima);
        }
        else if(is_local && is_lib) {
                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. */
                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);
+               BKE_id_lib_local_paths(bmain, &iman->id);
 
                tex= bmain->tex.first;
                while(tex) {
 
                tex= bmain->tex.first;
                while(tex) {
index 9a528b5..4787824 100644 (file)
@@ -271,12 +271,11 @@ void make_local_lattice(Lattice *lt)
                id_clear_lib_data(bmain, &lt->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &lt->id);
        }
        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. */
                Lattice *ltn= copy_lattice(lt);
                ltn->id.us= 0;
 
                /* Remap paths of new ID using old library as base. */
-               bpath_traverse_id(bmain, &ltn->id, bpath_relocate_visitor, 0, bath_user_data);
+               BKE_id_lib_local_paths(bmain, &ltn->id);
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==lt) {
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==lt) {
index 9d8acc4..35b5073 100644 (file)
 
 /* ************* general ************************ */
 
 
 /* ************* general ************************ */
 
+
+/* this has to be called from each make_local_* func, we could call
+ * from id_make_local() but then the make local functions would not be self
+ * contained.
+ * also note that the id _must_ have a library - campbell */
+void BKE_id_lib_local_paths(Main *bmain, ID *id)
+{
+       char *bpath_user_data[2]= {bmain->name, (id)->lib->filepath};
+
+       bpath_traverse_id(bmain, id,
+                                         bpath_relocate_visitor,
+                                         BPATH_TRAVERSE_SKIP_MULTIFILE,
+                                         bpath_user_data);
+}
+
 void id_lib_extern(ID *id)
 {
        if(id) {
 void id_lib_extern(ID *id)
 {
        if(id) {
@@ -1252,8 +1267,8 @@ int new_id(ListBase *lb, ID *id, const char *tname)
    don't have other library users. */
 void id_clear_lib_data(Main *bmain, ID *id)
 {
    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);
+       BKE_id_lib_local_paths(bmain, id);
+
        id->lib= NULL;
        id->flag= LIB_LOCAL;
        new_id(which_libbase(bmain, GS(id->name)), id, NULL);
        id->lib= NULL;
        id->flag= LIB_LOCAL;
        new_id(which_libbase(bmain, GS(id->name)), id, NULL);
index 2ad3da9..7be3514 100644 (file)
@@ -364,13 +364,12 @@ void make_local_material(Material *ma)
        }
        /* Both user and local, so copy. */
        else if(is_local && is_lib) {
        }
        /* 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. */
                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);
+               BKE_id_lib_local_paths(bmain, &man->id);
 
                /* do objects */
                ob= bmain->object.first;
 
                /* do objects */
                ob= bmain->object.first;
index 98646bd..327306b 100644 (file)
@@ -174,12 +174,11 @@ void make_local_mball(MetaBall *mb)
                extern_local_mball(mb);
        }
        else if(is_local && is_lib) {
                extern_local_mball(mb);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &mbn->id);
 
                for(ob= G.main->object.first; ob; ob= ob->id.next) {
                        if(ob->data == mb) {
 
                for(ob= G.main->object.first; ob; ob= ob->id.next) {
                        if(ob->data == mb) {
index 6f66e18..4a8bc34 100644 (file)
@@ -298,13 +298,12 @@ void make_local_mesh(Mesh *me)
                expand_local_mesh(me);
        }
        else if(is_local && is_lib) {
                expand_local_mesh(me);
        }
        else if(is_local && is_lib) {
-               char *bpath_user_data[2]= {bmain->name, me->id.lib->filepath};
                Mesh *men= copy_mesh(me);
                men->id.us= 0;
 
 
                /* Remap paths of new ID using old library as base. */
                Mesh *men= copy_mesh(me);
                men->id.us= 0;
 
 
                /* Remap paths of new ID using old library as base. */
-               bpath_traverse_id(bmain, &men->id, bpath_relocate_visitor, 0, bpath_user_data);
+               BKE_id_lib_local_paths(bmain, &men->id);
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(me == ob->data) {
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(me == ob->data) {
index 0d0552c..635e074 100644 (file)
@@ -772,13 +772,12 @@ void make_local_camera(Camera *cam)
                id_clear_lib_data(bmain, &cam->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &cam->id);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &camn->id);
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data == cam) {
 
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data == cam) {
@@ -939,13 +938,11 @@ void make_local_lamp(Lamp *la)
                id_clear_lib_data(bmain, &la->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &la->id);
        }
        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;
                Lamp *lan= copy_lamp(la);
                lan->id.us= 0;
-               
 
                /* Remap paths of new ID using old library as base. */
 
                /* Remap paths of new ID using old library as base. */
-               bpath_traverse_id(bmain, &lan->id, bpath_relocate_visitor, 0, bpath_user_data);
+               BKE_id_lib_local_paths(bmain, &lan->id);
 
                ob= bmain->object.first;
                while(ob) {
 
                ob= bmain->object.first;
                while(ob) {
@@ -1486,13 +1483,12 @@ void make_local_object(Object *ob)
                        extern_local_object(ob);
                }
                else if(is_local && is_lib) {
                        extern_local_object(ob);
                }
                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. */
                        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);
+                       BKE_id_lib_local_paths(bmain, &obn->id);
 
                        sce= bmain->scene.first;
                        while(sce) {
 
                        sce= bmain->scene.first;
                        while(sce) {
index a1ed086..7678da1 100644 (file)
@@ -3632,13 +3632,12 @@ void make_local_particlesettings(ParticleSettings *part)
                expand_local_particlesettings(part);
        }
        else if(is_local && is_lib) {
                expand_local_particlesettings(part);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &partn->id);
 
                /* do objects */
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
 
                /* do objects */
                for(ob= bmain->object.first; ob; ob= ob->id.next) {
index d5788d7..018c7a1 100644 (file)
@@ -106,12 +106,11 @@ void make_local_speaker(Speaker *spk)
                id_clear_lib_data(bmain, &spk->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &spk->id);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &spkn->id);
 
                ob= bmain->object.first;
                while(ob) {
 
                ob= bmain->object.first;
                while(ob) {
index e3713b1..d3bd7d7 100644 (file)
@@ -897,13 +897,12 @@ void make_local_texture(Tex *tex)
                extern_local_texture(tex);
        }
        else if(is_local && is_lib) {
                extern_local_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. */
                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);
+               BKE_id_lib_local_paths(bmain, &texn->id);
                
                ma= bmain->mat.first;
                while(ma) {
                
                ma= bmain->mat.first;
                while(ma) {
index 4d7a7c9..5797c6c 100644 (file)
@@ -176,12 +176,11 @@ void make_local_world(World *wrld)
                id_clear_lib_data(bmain, &wrld->id);
        }
        else if(is_local && is_lib) {
                id_clear_lib_data(bmain, &wrld->id);
        }
        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. */
                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);
+               BKE_id_lib_local_paths(bmain, &wrldn->id);
 
                for(sce= bmain->scene.first; sce; sce= sce->id.next) {
                        if(sce->world == wrld) {
 
                for(sce= bmain->scene.first; sce; sce= sce->id.next) {
                        if(sce->world == wrld) {
index 89ba4b2..e850db5 100644 (file)
@@ -48,9 +48,13 @@ void bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisito
 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);
 
 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 */
+#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 */
+#define BPATH_TRAVERSE_SKIP_MULTIFILE  (1<<4) /* skip paths where a single dir is used with an array of files, eg.
+                                               * sequence strip images and pointcache. in this case only use the first
+                                               * file, this is needed for directory manipulation functions which might
+                                               * otherwise modify the same directory multiple times */
 
 /* high level funcs */
 
 
 /* high level funcs */
 
index b7fe7ef..259b25e 100644 (file)
@@ -499,6 +499,11 @@ void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int fla
                                                        int len= MEM_allocN_len(se) / sizeof(*se);
                                                        int i;
 
                                                        int len= MEM_allocN_len(se) / sizeof(*se);
                                                        int i;
 
+                                                       if (flag & BPATH_TRAVERSE_SKIP_MULTIFILE) {
+                                                               /* only operate on one path */
+                                                               len= MIN2(1, len);
+                                                       }
+
                                                        for(i= 0; i < len; i++, se++) {
                                                                rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
                                                        }
                                                        for(i= 0; i < len; i++, se++) {
                                                                rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
                                                        }