Revision: 41292
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41292
Author:   z0r
Date:     2011-10-26 10:49:21 +0000 (Wed, 26 Oct 2011)
Log Message:
-----------
Fix [#28772] Filepaths are not remmaped after making a library item local
Added a visitor function to simplify processing of file paths that are attached 
to IDs. This is used for images, and could be used for other ID types in future.
Code reviewed by ideasman_42.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_image.h
    trunk/blender/source/blender/blenkernel/BKE_library.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/brush.c
    trunk/blender/source/blender/blenkernel/intern/curve.c
    trunk/blender/source/blender/blenkernel/intern/image.c
    trunk/blender/source/blender/blenkernel/intern/lattice.c
    trunk/blender/source/blender/blenkernel/intern/library.c
    trunk/blender/source/blender/blenkernel/intern/material.c
    trunk/blender/source/blender/blenkernel/intern/mball.c
    trunk/blender/source/blender/blenkernel/intern/mesh.c
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/speaker.c
    trunk/blender/source/blender/blenkernel/intern/texture.c
    trunk/blender/source/blender/blenkernel/intern/world.c
    trunk/blender/source/blender/blenlib/BLI_bpath.h
    trunk/blender/source/blender/blenlib/intern/bpath.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/space_outliner/outliner_tools.c

Modified: trunk/blender/source/blender/blenkernel/BKE_image.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_image.h 2011-10-26 10:04:10 UTC 
(rev 41291)
+++ trunk/blender/source/blender/blenkernel/BKE_image.h 2011-10-26 10:49:21 UTC 
(rev 41292)
@@ -61,7 +61,9 @@
 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);
 

Modified: trunk/blender/source/blender/blenkernel/BKE_library.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_library.h       2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/BKE_library.h       2011-10-26 
10:49:21 UTC (rev 41292)
@@ -59,6 +59,7 @@
 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 ListBase *lb, struct ID *id);
 
 struct ListBase *which_libbase(struct Main *mainlib, short type);
 

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c     2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/action.c     2011-10-26 
10:49:21 UTC (rev 41292)
@@ -137,19 +137,14 @@
        
        // 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->action, (ID *)act);
                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);
+               id_clear_lib_data(&bmain->action, (ID *)act);
        }
        else if (mlac.local && mlac.lib) {
                mlac.actn= copy_action(act);

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c   2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c   2011-10-26 
10:49:21 UTC (rev 41292)
@@ -141,9 +141,7 @@
 
        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->armature, (ID *)arm);
                return;
        }
 
@@ -155,9 +153,7 @@
        }
 
        if(local && lib==0) {
-               arm->id.lib= NULL;
-               arm->id.flag= LIB_LOCAL;
-               new_id(&bmain->armature, (ID *)arm, NULL);
+               id_clear_lib_data(&bmain->armature, (ID *)arm);
        }
        else if(local && lib) {
                bArmature *armn= copy_armature(arm);

Modified: trunk/blender/source/blender/blenkernel/intern/brush.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/brush.c      2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/brush.c      2011-10-26 
10:49:21 UTC (rev 41292)
@@ -181,6 +181,7 @@
 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)
@@ -198,10 +199,9 @@
        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, (ID *)brush->clone.image);
                extern_local_brush(brush);
        }
 
@@ -213,9 +213,7 @@
        }
 
        if(local && lib==0) {
-               brush->id.lib= NULL;
-               brush->id.flag= LIB_LOCAL;
-               new_id(&bmain->brush, (ID *)brush, NULL);
+               id_clear_lib_data(&bmain->brush, (ID *)brush);
                extern_local_brush(brush);
 
                /* enable fake user by default */

Modified: trunk/blender/source/blender/blenkernel/intern/curve.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/curve.c      2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/curve.c      2011-10-26 
10:49:21 UTC (rev 41292)
@@ -255,10 +255,7 @@
        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->curve, (ID *)cu);
                extern_local_curve(cu);
                return;
        }
@@ -271,10 +268,7 @@
        }
 
        if(local && lib==0) {
-               cu->id.lib= NULL;
-               cu->id.flag= LIB_LOCAL;
-
-               new_id(&bmain->curve, (ID *)cu, NULL);
+               id_clear_lib_data(&bmain->curve, (ID *)cu);
                extern_local_curve(cu);
        }
        else if(local && lib) {

Modified: trunk/blender/source/blender/blenkernel/intern/image.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/image.c      2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/image.c      2011-10-26 
10:49:21 UTC (rev 41292)
@@ -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,132 @@
        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 local=0, lib=0;
+
+       /* - 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->image, (ID *)ima);
+               extern_local_image(ima);
+               return;
+       }
+#endif
+
+       for(tex= bmain->tex.first; tex; tex= tex->id.next) {
+               if(tex->ima == ima) {
+                       if(tex->id.lib) lib= 1;
+                       else local= 1;
+               }
+       }
+       for(brush= bmain->brush.first; brush; brush= brush->id.next) {
+               if(brush->clone.image == ima) {
+                       if(brush->id.lib) lib= 1;
+                       else local= 1;
+               }
+       }
+       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) lib=1;
+                                                       else local= 1;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(local && lib==0) {
+               id_clear_lib_data(&bmain->image, (ID *)ima);
+               extern_local_image(ima);
+       }
+       else if(local && lib) {
+               Image *iman= copy_image(ima);
+               iman->id.us= 0;
+
+               /* Remap paths of new ID using old library as base. */
+               bpath_traverse_id((ID *)iman, bpath_relocate_visitor,
+                                    ((ID *)ima)->lib->filepath);
+
+               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;

Modified: trunk/blender/source/blender/blenkernel/intern/lattice.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/lattice.c    2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/lattice.c    2011-10-26 
10:49:21 UTC (rev 41292)
@@ -255,9 +255,7 @@
        
        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->latt, (ID *)lt);
                return;
        }
        
@@ -269,9 +267,7 @@
        }
        
        if(local && lib==0) {
-               lt->id.lib= NULL;
-               lt->id.flag= LIB_LOCAL;
-               new_id(&bmain->latt, (ID *)lt, NULL);
+               id_clear_lib_data(&bmain->latt, (ID *)lt);
        }
        else if(local && lib) {
                Lattice *ltn= copy_lattice(lt);

Modified: trunk/blender/source/blender/blenkernel/intern/library.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/library.c    2011-10-26 
10:04:10 UTC (rev 41291)
+++ trunk/blender/source/blender/blenkernel/intern/library.c    2011-10-26 
10:49:21 UTC (rev 41292)
@@ -74,8 +74,8 @@
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
 #include "BLI_utildefines.h"
+#include "BLI_bpath.h"
 
-
 #include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_library.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 @@
                        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,16 @@

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to