fix [#27178] Material links lost when making mesh data local
authorCampbell Barton <ideasman42@gmail.com>
Tue, 26 Apr 2011 07:17:21 +0000 (07:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 26 Apr 2011 07:17:21 +0000 (07:17 +0000)
- making local object data - Curve/Mesh/MBall lost references to linked materials.
- joining a linked mesh object into a local one lost the link.

As well as these reported bugs, checked all local functions for consistency/correctness and found other cases which would also fail.
- making local metaball didn't ensure unique ID name.
- make_local_armature() was missing check for object users - main body of code would never run.
- local particles didn't set the dupli-group or textures to extern.

checked all local functions for consistency/correctness.

16 files changed:
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/lattice.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/texture.c
source/blender/blenkernel/intern/world.c
source/blender/editors/mesh/meshtools.c

index 523a67e..c445408 100644 (file)
@@ -55,6 +55,7 @@ struct Material *copy_material(struct Material *ma);
 struct Material *localize_material(struct Material *ma);
 struct Material *give_node_material(struct Material *ma); /* returns node material or self */
 void make_local_material(struct Material *ma);
+void extern_local_matarar(struct Material **matar, short totcol);
 
 void automatname(struct Material *);
 
index ae7ac0d..08c150e 100644 (file)
@@ -66,7 +66,6 @@ void free_mesh(struct Mesh *me);
 struct Mesh *add_mesh(const char *name);
 struct Mesh *copy_mesh(struct Mesh *me);
 void mesh_update_customdata_pointers(struct Mesh *me);
-void make_local_tface(struct Mesh *me);
 void make_local_mesh(struct Mesh *me);
 void boundbox_mesh(struct Mesh *me, float *loc, float *size);
 void tex_space_mesh(struct Mesh *me);
index fe757b6..3a98f89 100644 (file)
@@ -91,7 +91,6 @@ struct Object *add_only_object(int type, const char *name);
 struct Object *add_object(struct Scene *scene, int type);
 
 struct Object *copy_object(struct Object *ob);
-void expand_local_object(struct Object *ob);
 void make_local_object(struct Object *ob);
 int object_is_libdata(struct Object *ob);
 int object_data_is_libdata(struct Object *ob);
index 5b42948..058227e 100644 (file)
@@ -95,6 +95,7 @@ bAction *add_empty_action(const char name[])
 void make_local_action(bAction *act)
 {
        // Object *ob;
+       Main *bmain= G.main;
        bAction *actn;
        int local=0, lib=0;
        
@@ -102,7 +103,7 @@ void make_local_action(bAction *act)
        if (act->id.us==1) {
                act->id.lib= NULL;
                act->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)act, NULL);
+               new_id(&bmain->action, (ID *)act, NULL);
                return;
        }
        
@@ -121,7 +122,7 @@ void make_local_action(bAction *act)
                act->id.lib= NULL;
                act->id.flag= LIB_LOCAL;
                //make_local_action_channels(act);
-               new_id(NULL, (ID *)act, NULL);
+               new_id(&bmain->action, (ID *)act, NULL);
        }
        else if(local && lib) {
                actn= copy_action(act);
index a79637e..fd25ebe 100644 (file)
@@ -137,39 +137,42 @@ void free_armature(bArmature *arm)
 
 void make_local_armature(bArmature *arm)
 {
+       Main *bmain= G.main;
        int local=0, lib=0;
        Object *ob;
-       bArmature *newArm;
-       
-       if (arm->id.lib==NULL)
-               return;
+
+       if (arm->id.lib==NULL) return;
        if (arm->id.us==1) {
                arm->id.lib= NULL;
                arm->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID*)arm, NULL);
+               new_id(&bmain->armature, (ID*)arm, NULL);
                return;
        }
-       
+
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(ob->data == arm) {
+                       if(ob->id.lib) lib= 1;
+                       else local= 1;
+               }
+       }
+
        if(local && lib==0) {
                arm->id.lib= NULL;
                arm->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)arm, NULL);
+               new_id(&bmain->armature, (ID *)arm, NULL);
        }
        else if(local && lib) {
-               newArm= copy_armature(arm);
-               newArm->id.us= 0;
+               bArmature *armn= copy_armature(arm);
+               armn->id.us= 0;
                
-               ob= G.main->object.first;
-               while(ob) {
-                       if(ob->data==arm) {
-                               
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
+                       if(ob->data == arm) {
                                if(ob->id.lib==NULL) {
-                                       ob->data= newArm;
-                                       newArm->id.us++;
+                                       ob->data= armn;
+                                       armn->id.us++;
                                        arm->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index ac532cc..fa3b756 100644 (file)
@@ -180,14 +180,20 @@ void free_brush(Brush *brush)
        curvemapping_free(brush->curve);
 }
 
+static void extern_local_brush(Brush *brush)
+{
+       id_lib_extern((ID *)brush->mtex.tex);
+}
+
 void make_local_brush(Brush *brush)
 {
+
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
-       
-       Brush *brushn;
+        * - only local users: set flag
+        * - mixed: make copy
+        */
+
+       Main *bmain= G.main;
        Scene *scene;
        int local= 0, lib= 0;
 
@@ -197,19 +203,22 @@ void make_local_brush(Brush *brush)
                /* special case: ima always local immediately */
                brush->clone.image->id.lib= NULL;
                brush->clone.image->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)brush->clone.image, NULL);
+               new_id(&bmain->brush, (ID *)brush->clone.image, NULL);
+               extern_local_brush(brush);
        }
 
-       for(scene= G.main->scene.first; scene; scene=scene->id.next)
+       for(scene= bmain->scene.first; scene && ELEM(0, lib, local); scene=scene->id.next) {
                if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
                        if(scene->id.lib) lib= 1;
                        else local= 1;
                }
+       }
 
        if(local && lib==0) {
                brush->id.lib= NULL;
                brush->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)brush, NULL);
+               new_id(&bmain->brush, (ID *)brush, NULL);
+               extern_local_brush(brush);
 
                /* enable fake user by default */
                if (!(brush->id.flag & LIB_FAKEUSER)) {
@@ -218,17 +227,19 @@ void make_local_brush(Brush *brush)
                }
        }
        else if(local && lib) {
-               brushn= copy_brush(brush);
+               Brush *brushn= copy_brush(brush);
                brushn->id.us= 1; /* only keep fake user */
                brushn->id.flag |= LIB_FAKEUSER;
                
-               for(scene= G.main->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) {
                                if(scene->id.lib==NULL) {
                                        paint_brush_set(&scene->toolsettings->imapaint.paint, brushn);
                                        brushn->id.us++;
                                        brush->id.us--;
                                }
+                       }
+               }
        }
 }
 
index 34e5fef..b104c6c 100644 (file)
@@ -63,7 +63,8 @@
 #include "BKE_key.h"  
 #include "BKE_library.h"  
 #include "BKE_main.h"  
-#include "BKE_object.h"  
+#include "BKE_object.h"
+#include "BKE_material.h"
 
 
 #include "ED_curve.h"
@@ -216,10 +217,22 @@ Curve *copy_curve(Curve *cu)
        return cun;
 }
 
+static void extern_local_curve(Curve *cu)
+{      
+       id_lib_extern((ID *)cu->vfont);
+       id_lib_extern((ID *)cu->vfontb);        
+       id_lib_extern((ID *)cu->vfonti);
+       id_lib_extern((ID *)cu->vfontbi);
+       
+       if(cu->mat) {
+               extern_local_matarar(cu->mat, cu->totcol);
+       }
+}
+
 void make_local_curve(Curve *cu)
 {
-       Object *ob = NULL;
-       Curve *cun;
+       Main *bmain= G.main;
+       Object *ob;
        int local=0, lib=0;
        
        /* - when there are only lib users: don't do
@@ -229,47 +242,41 @@ void make_local_curve(Curve *cu)
        
        if(cu->id.lib==NULL) return;
 
-       if(cu->vfont) cu->vfont->id.lib= NULL;
-       if(cu->vfontb) cu->vfontb->id.lib= NULL;
-       if(cu->vfonti) cu->vfonti->id.lib= NULL;
-       if(cu->vfontbi) cu->vfontbi->id.lib= NULL;
-
        if(cu->id.us==1) {
                cu->id.lib= NULL;
                cu->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)cu, NULL);
+
+               new_id(&bmain->curve, (ID *)cu, NULL);
+               extern_local_curve(cu);
                return;
        }
-       
-       ob= G.main->object.first;
-       while(ob) {
-               if(ob->data==cu) {
+
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(ob->data == cu) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
-       
+
        if(local && lib==0) {
                cu->id.lib= NULL;
                cu->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)cu, NULL);
+
+               new_id(&bmain->curve, (ID *)cu, NULL);
+               extern_local_curve(cu);
        }
        else if(local && lib) {
-               cun= copy_curve(cu);
+               Curve *cun= copy_curve(cu);
                cun->id.us= 0;
-               
-               ob= G.main->object.first;
-               while(ob) {
+
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==cu) {
-                               
                                if(ob->id.lib==NULL) {
                                        ob->data= cun;
                                        cun->id.us++;
                                        cu->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index d308ccb..f0ac704 100644 (file)
@@ -249,8 +249,8 @@ void free_lattice(Lattice *lt)
 
 void make_local_lattice(Lattice *lt)
 {
+       Main *bmain= G.main;
        Object *ob;
-       Lattice *ltn;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
@@ -262,39 +262,34 @@ void make_local_lattice(Lattice *lt)
        if(lt->id.us==1) {
                lt->id.lib= NULL;
                lt->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)lt, NULL);
+               new_id(&bmain->latt, (ID *)lt, NULL);
                return;
        }
        
-       ob= G.main->object.first;
-       while(ob) {
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
                if(ob->data==lt) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
        
        if(local && lib==0) {
                lt->id.lib= NULL;
                lt->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)lt, NULL);
+               new_id(&bmain->latt, (ID *)lt, NULL);
        }
        else if(local && lib) {
-               ltn= copy_lattice(lt);
+               Lattice *ltn= copy_lattice(lt);
                ltn->id.us= 0;
-               
-               ob= G.main->object.first;
-               while(ob) {
+
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==lt) {
-                               
                                if(ob->id.lib==NULL) {
                                        ob->data= ltn;
                                        ltn->id.us++;
                                        lt->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index 130bc79..fd58dc2 100644 (file)
@@ -267,6 +267,14 @@ Material *localize_material(Material *ma)
        return man;
 }
 
+static void extern_local_material(Material *ma)
+{
+       int i;
+       for(i=0; i < MAX_MTEX; i++) {
+               if(ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex);
+       }
+}
+
 void make_local_material(Material *ma)
 {
        Main *bmain= G.main;
@@ -286,11 +294,9 @@ void make_local_material(Material *ma)
        if(ma->id.us==1) {
                ma->id.lib= NULL;
                ma->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)ma, NULL);
-               for(a=0; a<MAX_MTEX; a++) {
-                       if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
-               }
-               
+
+               new_id(&bmain->mat, (ID *)ma, NULL);
+               extern_local_material(ma);
                return;
        }
        
@@ -350,12 +356,9 @@ void make_local_material(Material *ma)
        if(local && lib==0) {
                ma->id.lib= NULL;
                ma->id.flag= LIB_LOCAL;
-               
-               for(a=0; a<MAX_MTEX; a++) {
-                       if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
-               }
-               
-               new_id(NULL, (ID *)ma, NULL);
+
+               new_id(&bmain->mat, (ID *)ma, NULL);
+               extern_local_material(ma);
        }
        else if(local && lib) {
                
@@ -429,6 +432,15 @@ void make_local_material(Material *ma)
        }
 }
 
+/* for curve, mball, mesh types */
+void extern_local_matarar(struct Material **matar, short totcol)
+{
+       short i;
+       for(i= 0; i < totcol; i++) {
+               id_lib_extern((ID *)matar[i]);
+       }
+}
+
 Material ***give_matarar(Object *ob)
 {
        Mesh *me;
index e19a508..555d357 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_displist.h"
 #include "BKE_mball.h"
 #include "BKE_object.h"
+#include "BKE_material.h"
 
 /* Global variables */
 
@@ -139,10 +140,17 @@ MetaBall *copy_mball(MetaBall *mb)
        return mbn;
 }
 
+static void extern_local_mball(MetaBall *mb)
+{
+       if(mb->mat) {
+               extern_local_matarar(mb->mat, mb->totcol);
+       }
+}
+
 void make_local_mball(MetaBall *mb)
 {
+       Main *bmain= G.main;
        Object *ob;
-       MetaBall *mbn;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
@@ -154,37 +162,38 @@ void make_local_mball(MetaBall *mb)
        if(mb->id.us==1) {
                mb->id.lib= NULL;
                mb->id.flag= LIB_LOCAL;
+               new_id(&bmain->mball, (ID *)mb, NULL);
+               extern_local_mball(mb);
+               
                return;
        }
-       
-       ob= G.main->object.first;
-       while(ob) {
-               if(ob->data==mb) {
+
+       for(ob= G.main->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(ob->data == mb) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
        
        if(local && lib==0) {
                mb->id.lib= NULL;
                mb->id.flag= LIB_LOCAL;
+
+               new_id(&bmain->mball, (ID *)mb, NULL);
+               extern_local_mball(mb);
        }
        else if(local && lib) {
-               mbn= copy_mball(mb);
+               MetaBall *mbn= copy_mball(mb);
                mbn->id.us= 0;
-               
-               ob= G.main->object.first;
-               while(ob) {
-                       if(ob->data==mb) {
-                               
+
+               for(ob= G.main->object.first; ob; ob= ob->id.next) {
+                       if(ob->data == mb) {
                                if(ob->id.lib==NULL) {
                                        ob->data= mbn;
                                        mbn->id.us++;
                                        mb->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index 532e96f..45a60b8 100644 (file)
@@ -247,7 +247,7 @@ Mesh *copy_mesh(Mesh *me)
        return men;
 }
 
-void make_local_tface(Mesh *me)
+static void make_local_tface(Main *bmain, Mesh *me)
 {
        MTFace *tface;
        Image *ima;
@@ -264,7 +264,7 @@ void make_local_tface(Mesh *me)
                                        if(ima->id.lib) {
                                                ima->id.lib= NULL;
                                                ima->id.flag= LIB_LOCAL;
-                                               new_id(NULL, (ID *)ima, NULL);
+                                               new_id(&bmain->image, (ID *)ima, NULL);
                                        }
                                }
                        }
@@ -272,58 +272,65 @@ void make_local_tface(Mesh *me)
        }
 }
 
+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);
+       }
+}
+
 void make_local_mesh(Mesh *me)
 {
        Main *bmain= G.main;
        Object *ob;
-       Mesh *men;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
-       
+        * - only local users: set flag
+        * - mixed: make copy
+        */
+
        if(me->id.lib==NULL) return;
        if(me->id.us==1) {
                me->id.lib= NULL;
                me->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)me, NULL);
-               
-               if(me->mtface) make_local_tface(me);
-               
+
+               new_id(&bmain->mesh, (ID *)me, NULL);
+               expand_local_mesh(bmain, me);
                return;
        }
-       
-       ob= bmain->object.first;
-       while(ob) {
-               if( me==get_mesh(ob) ) {
+
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(me == ob->data) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
-       
+
        if(local && lib==0) {
                me->id.lib= NULL;
                me->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)me, NULL);
-               
-               if(me->mtface) make_local_tface(me);
-               
+
+               new_id(&bmain->mesh, (ID *)me, NULL);
+               expand_local_mesh(bmain, me);
        }
        else if(local && lib) {
-               men= copy_mesh(me);
+               Mesh *men= copy_mesh(me);
                men->id.us= 0;
-               
-               ob= bmain->object.first;
-               while(ob) {
-                       if( me==get_mesh(ob) ) {                                
+
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
+                       if(me == ob->data) {
                                if(ob->id.lib==NULL) {
                                        set_mesh(ob, men);
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index 488ede5..29fa731 100644 (file)
@@ -97,6 +97,7 @@
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
 #include "BKE_softbody.h"
+#include "BKE_material.h"
 
 #include "LBM_fluidsim.h"
 
@@ -736,51 +737,45 @@ void make_local_camera(Camera *cam)
 {
        Main *bmain= G.main;
        Object *ob;
-       Camera *camn;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
+        * - only local users: set flag
+        * - mixed: make copy
+        */
        
        if(cam->id.lib==NULL) return;
        if(cam->id.us==1) {
                cam->id.lib= NULL;
                cam->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)cam, NULL);
+               new_id(&bmain->camera, (ID *)cam, NULL);
                return;
        }
        
-       ob= bmain->object.first;
-       while(ob) {
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
                if(ob->data==cam) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
        
        if(local && lib==0) {
                cam->id.lib= NULL;
                cam->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)cam, NULL);
+               new_id(&bmain->camera, (ID *)cam, NULL);
        }
        else if(local && lib) {
-               camn= copy_camera(cam);
+               Camera *camn= copy_camera(cam);
                camn->id.us= 0;
                
-               ob= bmain->object.first;
-               while(ob) {
-                       if(ob->data==cam) {
-                               
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
+                       if(ob->data == cam) {
                                if(ob->id.lib==NULL) {
                                        ob->data= camn;
                                        camn->id.us++;
                                        cam->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
@@ -897,7 +892,7 @@ void make_local_lamp(Lamp *la)
        if(la->id.us==1) {
                la->id.lib= NULL;
                la->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)la, NULL);
+               new_id(&bmain->lamp, (ID *)la, NULL);
                return;
        }
        
@@ -913,7 +908,7 @@ void make_local_lamp(Lamp *la)
        if(local && lib==0) {
                la->id.lib= NULL;
                la->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)la, NULL);
+               new_id(&bmain->lamp, (ID *)la, NULL);
        }
        else if(local && lib) {
                lan= copy_lamp(la);
@@ -1366,11 +1361,10 @@ Object *copy_object(Object *ob)
        return obn;
 }
 
-void expand_local_object(Object *ob)
+static void extern_local_object(Object *ob)
 {
        //bActionStrip *strip;
        ParticleSystem *psys;
-       int a;
 
 #if 0 // XXX old animation system
        id_lib_extern((ID *)ob->action);
@@ -1378,10 +1372,11 @@ void expand_local_object(Object *ob)
 #endif // XXX old animation system
        id_lib_extern((ID *)ob->data);
        id_lib_extern((ID *)ob->dup_group);
-       
-       for(a=0; a<ob->totcol; a++) {
-               id_lib_extern((ID *)ob->mat[a]);
-       }
+       id_lib_extern((ID *)ob->poselib);
+       id_lib_extern((ID *)ob->gpd);
+
+       extern_local_matarar(ob->mat, ob->totcol);
+
 #if 0 // XXX old animation system
        for (strip=ob->nlastrips.first; strip; strip=strip->next) {
                id_lib_extern((ID *)strip->act);
@@ -1394,16 +1389,15 @@ void expand_local_object(Object *ob)
 void make_local_object(Object *ob)
 {
        Main *bmain= G.main;
-       Object *obn;
        Scene *sce;
        Base *base;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
-       
+        * - only local users: set flag
+        * - mixed: make copy
+        */
+
        if(ob->id.lib==NULL) return;
        
        ob->proxy= ob->proxy_from= NULL;
@@ -1411,31 +1405,23 @@ void make_local_object(Object *ob)
        if(ob->id.us==1) {
                ob->id.lib= NULL;
                ob->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)ob, NULL);
-
+               new_id(&bmain->object, (ID *)ob, NULL);
        }
        else {
-               sce= bmain->scene.first;
-               while(sce) {
-                       base= sce->base.first;
-                       while(base) {
-                               if(base->object==ob) {
-                                       if(sce->id.lib) lib++;
-                                       else local++;
-                                       break;
-                               }
-                               base= base->next;
+               for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) {
+                       if(object_in_scene(ob, sce)) {
+                               if(sce->id.lib) lib= 1;
+                               else local= 1;
                        }
-                       sce= sce->id.next;
                }
-               
+
                if(local && lib==0) {
                        ob->id.lib= NULL;
                        ob->id.flag= LIB_LOCAL;
-                       new_id(NULL, (ID *)ob, NULL);
+                       new_id(&bmain->object, (ID *)ob, NULL);
                }
                else if(local && lib) {
-                       obn= copy_object(ob);
+                       Object *obn= copy_object(ob);
                        obn->id.us= 0;
                        
                        sce= bmain->scene.first;
@@ -1456,7 +1442,7 @@ void make_local_object(Object *ob)
                }
        }
        
-       expand_local_object(ob);
+       extern_local_object(ob);
 }
 
 /*
index e80289c..5b58372 100644 (file)
@@ -3589,28 +3589,38 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part)
        return partn;
 }
 
+static void expand_local_particlesettings(ParticleSettings *part)
+{
+       int i;
+       id_lib_extern((ID *)part->dup_group);
+
+       for(i=0; i<MAX_MTEX; i++) {
+               if(part->mtex[i]) id_lib_extern((ID *)part->mtex[i]->tex);
+       }
+}
+
 void make_local_particlesettings(ParticleSettings *part)
 {
+       Main *bmain= G.main;
        Object *ob;
-       ParticleSettings *par;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-               * - only local users: set flag
-               * - mixed: make copy
-               */
+        * - only local users: set flag
+        * - mixed: make copy
+        */
        
        if(part->id.lib==0) return;
        if(part->id.us==1) {
                part->id.lib= 0;
                part->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)part, 0);
+               new_id(&bmain->particle, (ID *)part, 0);
+               expand_local_particlesettings(part);
                return;
        }
-       
+
        /* test objects */
-       ob= G.main->object.first;
-       while(ob) {
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
                ParticleSystem *psys=ob->particlesystem.first;
                for(; psys; psys=psys->next){
                        if(psys->part==part) {
@@ -3618,31 +3628,28 @@ void make_local_particlesettings(ParticleSettings *part)
                                else local= 1;
                        }
                }
-               ob= ob->id.next;
        }
        
        if(local && lib==0) {
                part->id.lib= 0;
                part->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)part, 0);
+               new_id(&bmain->particle, (ID *)part, 0);
+               expand_local_particlesettings(part);
        }
        else if(local && lib) {
-               
-               par= psys_copy_settings(part);
-               par->id.us= 0;
+               ParticleSettings *partn= psys_copy_settings(part);
+               partn->id.us= 0;
                
                /* do objects */
-               ob= G.main->object.first;
-               while(ob) {
-                       ParticleSystem *psys=ob->particlesystem.first;
-                       for(; psys; psys=psys->next){
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
+                       ParticleSystem *psys;
+                       for(psys= ob->particlesystem.first; psys; psys=psys->next){
                                if(psys->part==part && ob->id.lib==0) {
-                                       psys->part= par;
-                                       par->id.us++;
+                                       psys->part= partn;
+                                       partn->id.us++;
                                        part->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
index a5412c6..672fd06 100644 (file)
@@ -843,13 +843,13 @@ void make_local_texture(Tex *tex)
        if(tex->ima) {
                tex->ima->id.lib= NULL;
                tex->ima->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)tex->ima, NULL);
+               new_id(&bmain->image, (ID *)tex->ima, NULL);
        }
 
        if(tex->id.us==1) {
                tex->id.lib= NULL;
                tex->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)tex, NULL);
+               new_id(&bmain->tex, (ID *)tex, NULL);
 
                return;
        }
@@ -906,7 +906,7 @@ void make_local_texture(Tex *tex)
        if(local && lib==0) {
                tex->id.lib= NULL;
                tex->id.flag= LIB_LOCAL;
-               new_id(NULL, (ID *)tex, NULL);
+               new_id(&bmain->tex, (ID *)tex, NULL);
        }
        else if(local && lib) {
                texn= copy_texture(tex);
index ff58e8b..7a76e61 100644 (file)
@@ -43,6 +43,8 @@
 #include "DNA_scene_types.h"
 #include "DNA_texture_types.h"
 
+#include "BLI_utildefines.h"
+
 #include "BKE_world.h"
 #include "BKE_library.h"
 #include "BKE_animsys.h"
@@ -134,7 +136,6 @@ void make_local_world(World *wrld)
 {
        Main *bmain= G.main;
        Scene *sce;
-       World *wrldn;
        int local=0, lib=0;
 
        /* - only lib users: do nothing
@@ -150,34 +151,30 @@ void make_local_world(World *wrld)
                return;
        }
        
-       sce= bmain->scene.first;
-       while(sce) {
-               if(sce->world==wrld) {
+       for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) {
+               if(sce->world == wrld) {
                        if(sce->id.lib) lib= 1;
                        else local= 1;
                }
-               sce= sce->id.next;
        }
-       
+
        if(local && lib==0) {
                wrld->id.lib= NULL;
                wrld->id.flag= LIB_LOCAL;
                new_id(NULL, (ID *)wrld, NULL);
        }
        else if(local && lib) {
-               wrldn= copy_world(wrld);
+               World *wrldn= copy_world(wrld);
                wrldn->id.us= 0;
                
-               sce= bmain->scene.first;
-               while(sce) {
-                       if(sce->world==wrld) {
+               for(sce= bmain->scene.first; sce; sce= sce->id.next) {
+                       if(sce->world == wrld) {
                                if(sce->id.lib==NULL) {
                                        sce->world= wrldn;
                                        wrldn->id.us++;
                                        wrld->id.us--;
                                }
                        }
-                       sce= sce->id.next;
                }
        }
 }
index cf3ad26..763e82b 100644 (file)
@@ -226,8 +226,9 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                                                }
                                                if(b==totcol) {
                                                        matar[b]= ma;
-                                                       if(ma)
-                                                               ma->id.us++;
+                                                       if(ma) {
+                                                               id_us_plus(&ma->id);
+                                                       }
                                                        totcol++;
                                                }
                                                if(totcol>=MAXMAT-1)