Refactor/deduplicate even more make_local code (and fix part of T48907).
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 20 Jul 2016 17:49:45 +0000 (19:49 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 21 Jul 2016 14:54:36 +0000 (16:54 +0200)
Turns out most BKE_foo_make_local datablock-specific functions are actually doing
exactly the same thing, only two currently need special additional operations
(object and brush ones). So added a BKE_id_make_local_generic instead
of copying same code over and over.

Also, changed a bit how make_local works in case we are localizing a whole library.
We need to do the 'remap' step (from old linked ID to new local one) in the second loop,
otherwise we miss some dependencies. This fixes main part of T48907.

36 files changed:
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_camera.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_lamp.h
source/blender/blenkernel/BKE_lattice.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_speaker.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/BKE_world.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/camera.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/lamp.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/node.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

index ac9b0b6fb101dc2ca186f354f89d4025c27e4113..6527ba7f94f54f983d41a19b2acc6c692b9bc79f 100644 (file)
@@ -63,7 +63,7 @@ struct bAction *BKE_action_copy(struct Main *bmain, struct bAction *src);
 /* Deallocate all of the Action's data, but not the Action itself */
 void BKE_action_free(struct bAction *act);
 
-void BKE_action_make_local(struct Main *bmain, struct bAction *act, const bool force_local);
+void BKE_action_make_local(struct Main *bmain, struct bAction *act, const bool lib_local);
 
 
 /* Action API ----------------- */
index bfd4a7e3dd8c459d295d99371a2520ea302d3c52..226cc6aa83de89412094499490a90eb5de67cfde 100644 (file)
@@ -76,7 +76,7 @@ struct bArmature *BKE_armature_from_object(struct Object *ob);
 int  BKE_armature_bonelist_count(struct ListBase *lb);
 void BKE_armature_bonelist_free(struct ListBase *lb);
 void BKE_armature_free(struct bArmature *arm);
-void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool force_local);
+void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool lib_local);
 struct bArmature *BKE_armature_copy(struct Main *bmain, struct bArmature *arm);
 
 /* Bounding box. */
index 4be4d95490bee624a54adca9be2ed73f0f61589f..8bd4bdf89e18d0d911d776bf423e5f571b5380a1 100644 (file)
@@ -45,7 +45,7 @@ void BKE_brush_init(struct Brush *brush);
 struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode);
 struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
 struct Brush *BKE_brush_copy(struct Main *bmain, struct Brush *brush);
-void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool force_local);
+void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
 void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
 void BKE_brush_free(struct Brush *brush);
 
index 3ae0e0e1111700574794ac1af3c34ac270c0a614..31a732cf7e5a7f33e944c1f5c8ff1191b534acee 100644 (file)
@@ -53,7 +53,7 @@ struct GPUFXSettings;
 void BKE_camera_init(struct Camera *cam);
 void *BKE_camera_add(struct Main *bmain, const char *name);
 struct Camera *BKE_camera_copy(struct Main *bmain, struct Camera *cam);
-void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool force_local);
+void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool lib_local);
 void BKE_camera_free(struct Camera *ca);
 
 /* Camera Usage */
index c2a0404e96e38485e30f384d0cd38041477c935c..5558786d254d36e6b257b2681aecd797c21f2249 100644 (file)
@@ -71,7 +71,7 @@ void BKE_curve_editfont_free(struct Curve *cu);
 void BKE_curve_init(struct Curve *cu);
 struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
 struct Curve *BKE_curve_copy(struct Main *bmain, struct Curve *cu);
-void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool force_local);
+void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool lib_local);
 short BKE_curve_type_get(struct Curve *cu);
 void BKE_curve_type_test(struct Object *ob);
 void BKE_curve_curve_dimension_update(struct Curve *cu);
index db73b42d894a06278c09ab180d116048958e8ce9..132c73209d15598834f0077fdeb314e3017b35f7 100644 (file)
@@ -108,7 +108,7 @@ struct anim *openanim_noload(const char *name, int flags, int streamindex, char
 
 void    BKE_image_de_interlace(struct Image *ima, int odd);
 
-void    BKE_image_make_local(struct Main *bmain, struct Image *ima, const bool force_local);
+void    BKE_image_make_local(struct Main *bmain, struct Image *ima, const bool lib_local);
 
 void    BKE_image_tag_time(struct Image *ima);
 
index dc977eabbb1f24916fdcf0b1d2385eb6678e4e7e..4d53850c572d8d3ddcc840afb1bfcd478a0c4cea 100644 (file)
@@ -46,7 +46,7 @@ void BKE_lamp_init(struct Lamp *la);
 struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT;
 struct Lamp *BKE_lamp_copy(struct Main *bmain, struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
 struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
-void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool force_local);
+void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool lib_local);
 void BKE_lamp_free(struct Lamp *la);
 
 void lamp_drivers_update(struct Scene *scene, struct Lamp *la, float ctime);
index 4f72bbecff45e46c3b866407c239e8363495c125..226c82da2953a52aaf22f7fdc4143db2ffb29bd8 100644 (file)
@@ -49,7 +49,7 @@ void BKE_lattice_init(struct Lattice *lt);
 struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
 struct Lattice *BKE_lattice_copy(struct Main *bmain, struct Lattice *lt);
 void BKE_lattice_free(struct Lattice *lt);
-void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool force_local);
+void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
 void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
 
 struct LatticeDeformData;
index 3e8ede638ca4917831d53be9d6178db50ef2caec..2ac7e3c97fbada698e944b716dc253fdf11d2a9b 100644 (file)
@@ -80,6 +80,7 @@ void id_us_min(struct ID *id);
 void id_fake_user_set(struct ID *id);
 void id_fake_user_clear(struct ID *id);
 
+void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local);
 bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
 bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
 bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
@@ -88,7 +89,7 @@ void BKE_id_expand_local(struct ID *id);
 
 bool new_id(struct ListBase *lb, struct ID *id, const char *name);
 void id_clear_lib_data(struct Main *bmain, struct ID *id);
-void id_clear_lib_data_ex(struct Main *bmain, struct ID *id, bool id_in_mainlist);
+void id_clear_lib_data_ex(struct Main *bmain, struct ID *id, const bool id_in_mainlist);
 
 struct ListBase *which_libbase(struct Main *mainlib, short type);
 
index ddead79633f03492d609dea8fbeea9bb64b7edc9..df739996c54061b37f079e1988f0c12ec169a810 100644 (file)
@@ -57,7 +57,7 @@ struct Material *BKE_material_add(struct Main *bmain, const char *name);
 struct Material *BKE_material_copy(struct Main *bmain, struct Material *ma);
 struct Material *localize_material(struct Material *ma);
 struct Material *give_node_material(struct Material *ma); /* returns node material or self */
-void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool force_local);
+void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local);
 
 /* UNUSED */
 // void automatname(struct Material *);
index 191e87210995c8c934ea30ba7ca30e9ff0c6d9b1..64320a202816b3bc22ef2995c70564a2253e7056 100644 (file)
@@ -43,7 +43,7 @@ void BKE_mball_init(struct MetaBall *mb);
 struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
 struct MetaBall *BKE_mball_copy(struct Main *bmain, struct MetaBall *mb);
 
-void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool force_local);
+void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local);
 
 bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
 bool BKE_mball_is_basis(struct Object *ob);
index ef8d1c9831891d5ea201f681141578122c158628..d41878825bbfc378995ab303c4508f9887db0807 100644 (file)
@@ -91,7 +91,7 @@ struct Mesh *BKE_mesh_copy(struct Main *bmain, struct Mesh *me);
 void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
 void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
 
-void BKE_mesh_make_local(struct Main *bmain, struct Mesh *me, const bool force_local);
+void BKE_mesh_make_local(struct Main *bmain, struct Mesh *me, const bool lib_local);
 void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
 void BKE_mesh_texspace_calc(struct Mesh *me);
 float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
index 647b96fb9aef7a82bafd7427c4a6ae3603ff6117..95f06e9f6959a0e284aa1f4c3a337281e45a9efd 100644 (file)
@@ -346,7 +346,7 @@ void              ntreeUserDecrefID(struct bNodeTree *ntree);
 
 struct bNodeTree *ntreeFromID(struct ID *id);
 
-void              ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, bool id_in_mainlist, const bool force_local);
+void              ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, bool id_in_mainlist, const bool lib_local);
 struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
index 509524a7ce06710fc9286eb47979c4b885c79d15..1b3e05d11aeddf401da0e41f3fe9a893d7668d80 100644 (file)
@@ -107,7 +107,7 @@ struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
 
 struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches);
 struct Object *BKE_object_copy(struct Main *bmain, struct Object *ob);
-void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool force_local);
+void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local);
 bool BKE_object_is_libdata(struct Object *ob);
 bool BKE_object_obdata_is_libdata(struct Object *ob);
 
index b22facd23947c1e34dcc121739c005e4fd1249b4..37831728e6f3d793c10d87fad10149b0101d189c 100644 (file)
@@ -324,7 +324,7 @@ struct ModifierData *object_add_particle_system(struct Scene *scene, struct Obje
 void object_remove_particle_system(struct Scene *scene, struct Object *ob);
 struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
 struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, struct ParticleSettings *part);
-void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool force_local);
+void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local);
 
 void psys_reset(struct ParticleSystem *psys, int mode);
 
index fb730d95b923acccb088af05ecfc5f039290e27c..b91b64c4b741455e2eb8bcce64d6581895ef2358 100644 (file)
@@ -34,7 +34,7 @@ struct Speaker;
 void BKE_speaker_init(struct Speaker *spk);
 void *BKE_speaker_add(struct Main *bmain, const char *name);
 struct Speaker *BKE_speaker_copy(struct Main *bmain, struct Speaker *spk);
-void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool force_local);
+void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool lib_local);
 void BKE_speaker_free(struct Speaker *spk);
 
 #endif
index eef02f633500b5d5803a76a54f1e37b542a96b37..1c5ea946f59ad60b310a3f3d3fa140716b32083e 100644 (file)
@@ -72,7 +72,7 @@ void         BKE_texture_default(struct Tex *tex);
 struct Tex  *BKE_texture_copy(struct Main *bmain, struct Tex *tex);
 struct Tex  *BKE_texture_add(struct Main *bmain, const char *name);
 struct Tex  *BKE_texture_localize(struct Tex *tex);
-void         BKE_texture_make_local(struct Main *bmain, struct Tex *tex, const bool force_local);
+void         BKE_texture_make_local(struct Main *bmain, struct Tex *tex, const bool lib_local);
 void         BKE_texture_type_set(struct Tex *tex, int type);
 
 void         BKE_texture_mtex_default(struct MTex *mtex);
index 8b8dac4ab2201b9627ad43ddb13f6ccab6d3baa3..23bf9ec3d22f71d0fe0c4b84751103a5e0ac2879 100644 (file)
@@ -41,7 +41,7 @@ void BKE_world_init(struct World *wrld);
 struct World *add_world(struct Main *bmian, const char *name);
 struct World *BKE_world_copy(struct Main *bmain, struct World *wrld);
 struct World *localize_world(struct World *wrld);
-void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool force_local);
+void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
 
 #endif
 
index fa49797126d87c892fcea494a04baad6740f9d60..8f82610a8bbf2e660c3e4d80eb01330f98905f2d 100644 (file)
@@ -95,34 +95,9 @@ bAction *add_empty_action(Main *bmain, const char name[])
 /* .................................. */
 
 // does copy_fcurve...
-void BKE_action_make_local(Main *bmain, bAction *act, const bool force_local)
+void BKE_action_make_local(Main *bmain, bAction *act, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(act)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, act, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &act->id);
-                       BKE_id_expand_local(&act->id);
-               }
-               else {
-                       bAction *act_new = BKE_action_copy(bmain, act);
-
-                       act_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, act, act_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &act->id, true, lib_local);
 }
 
 /* .................................. */
index 53e28177bdffea3f9be01e7ad8446b7ba2734146..b618eb5561e06c3f90a4b862aa2d6dfdbc5da2bc 100644 (file)
@@ -144,34 +144,9 @@ void BKE_armature_free(bArmature *arm)
        }
 }
 
-void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool force_local)
+void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(arm)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, arm, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &arm->id);
-                       BKE_id_expand_local(&arm->id);
-               }
-               else {
-                       bArmature *arm_new = BKE_armature_copy(bmain, arm);
-
-                       arm_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, arm, arm_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &arm->id, true, lib_local);
 }
 
 static void copy_bonechildren(Bone *newBone, Bone *oldBone, Bone *actBone, Bone **newActBone)
index 3d9cabdc15dff7368c1f9355d526a2f0905ea19e..9027287a457213b587c1ff8de7c3b5aa99283a61 100644 (file)
@@ -219,7 +219,7 @@ void BKE_brush_free(Brush *brush)
        BKE_previewimg_free(&(brush->preview));
 }
 
-void BKE_brush_make_local(Main *bmain, Brush *brush, const bool force_local)
+void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
 {
        bool is_local = false, is_lib = false;
 
@@ -239,7 +239,7 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool force_local)
 
        BKE_library_ID_test_usages(bmain, brush, &is_local, &is_lib);
 
-       if (force_local || is_local) {
+       if (lib_local || is_local) {
                if (!is_lib) {
                        id_clear_lib_data(bmain, &brush->id);
                        BKE_id_expand_local(&brush->id);
@@ -252,7 +252,9 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool force_local)
 
                        brush_new->id.us = 0;
 
-                       BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+                       if (!lib_local) {
+                               BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+                       }
                }
        }
 }
index cd085816b4d1bba8d4b93a014e908e35e2c39048..b7e6e409999a0ff1bddc7d6790ba40b4250b0dcd 100644 (file)
@@ -107,34 +107,9 @@ Camera *BKE_camera_copy(Main *bmain, Camera *cam)
        return camn;
 }
 
-void BKE_camera_make_local(Main *bmain, Camera *cam, const bool force_local)
+void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(cam)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, cam, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &cam->id);
-                       BKE_id_expand_local(&cam->id);
-               }
-               else {
-                       Camera *cam_new = BKE_camera_copy(bmain, cam);
-
-                       cam_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, cam, cam_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &cam->id, true, lib_local);
 }
 
 /** Free (or release) any data used by this camera (does not free the camera itself). */
index 693e7eb0c80041e17fdc59a68ab18771f56a1ecd..07f4e4f16107ec94935b6c9043a081709b1728d3 100644 (file)
@@ -215,34 +215,9 @@ Curve *BKE_curve_copy(Main *bmain, Curve *cu)
        return cun;
 }
 
-void BKE_curve_make_local(Main *bmain, Curve *cu, const bool force_local)
+void BKE_curve_make_local(Main *bmain, Curve *cu, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - when there are only local users: set flag
-        * - mixed: do a copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(cu)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, cu, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &cu->id);
-                       BKE_id_expand_local(&cu->id);
-               }
-               else {
-                       Curve *cu_new = BKE_curve_copy(bmain, cu);
-
-                       cu_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, cu, cu_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &cu->id, true, lib_local);
 }
 
 /* Get list of nurbs from editnurbs structure */
index 0032eb35d3a776f51d3792779175191e92d0f152..44bea5c81382bdcc41a170e436bedede756d10d8 100644 (file)
@@ -469,34 +469,9 @@ Image *BKE_image_copy(Main *bmain, Image *ima)
        return nima;
 }
 
-void BKE_image_make_local(Main *bmain, Image *ima, const bool force_local)
+void BKE_image_make_local(Main *bmain, Image *ima, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(ima)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, ima, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &ima->id);
-                       BKE_id_expand_local(&ima->id);
-               }
-               else {
-                       Image *ima_new = BKE_image_copy(bmain, ima);
-
-                       ima_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, ima, ima_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &ima->id, true, lib_local);
 }
 
 void BKE_image_merge(Image *dest, Image *source)
index 81bcdbde1dc57f3fed0d55d157db1b59020201b9..35fcf211b0506e0a694e1a41d64f6abfb91a4b80 100644 (file)
@@ -172,34 +172,9 @@ Lamp *localize_lamp(Lamp *la)
        return lan;
 }
 
-void BKE_lamp_make_local(Main *bmain, Lamp *la, const bool force_local)
+void BKE_lamp_make_local(Main *bmain, Lamp *la, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-       
-       if (!ID_IS_LINKED_DATABLOCK(la)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, la, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &la->id);
-                       BKE_id_expand_local(&la->id);
-               }
-               else {
-                       Lamp *la_new = BKE_lamp_copy(bmain, la);
-
-                       la_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, la, la_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &la->id, true, lib_local);
 }
 
 void BKE_lamp_free(Lamp *la)
index c2675fabe3b580fe1b286d2e49b7b1122f3f8f3c..82b179d4f1cbb5529b5762a77349ea78d9693907 100644 (file)
@@ -330,34 +330,9 @@ void BKE_lattice_free(Lattice *lt)
 }
 
 
-void BKE_lattice_make_local(Main *bmain, Lattice *lt, const bool force_local)
+void BKE_lattice_make_local(Main *bmain, Lattice *lt, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(lt)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, lt, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &lt->id);
-                       BKE_id_expand_local(&lt->id);
-               }
-               else {
-                       Lattice *lt_new = BKE_lattice_copy(bmain, lt);
-
-                       lt_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, lt, lt_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &lt->id, true, lib_local);
 }
 
 typedef struct LatticeDeformData {
index 2e066528f56d549194f5dbbfcf2f1a3aa75196d8..0ecc223de71b07063647bd63fdb0e2a7217eb9c5 100644 (file)
@@ -96,6 +96,7 @@
 #include "BKE_lattice.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
+#include "BKE_library_remap.h"
 #include "BKE_linestyle.h"
 #include "BKE_mesh.h"
 #include "BKE_material.h"
@@ -269,9 +270,54 @@ void BKE_id_expand_local(ID *id)
        BKE_library_foreach_ID_link(id, id_expand_local_callback, NULL, 0);
 }
 
-/* calls the appropriate make_local method for the block, unless test. Returns true
- * if the block can be made local. */
-bool id_make_local(Main *bmain, ID *id, const bool test, const bool force_local)
+/**
+ * Generic 'make local' function, works for most of datablock types...
+ */
+void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, const bool lib_local)
+{
+       bool is_local = false, is_lib = false;
+
+       /* - only lib users: do nothing (unless force_local is set)
+        * - only local users: set flag
+        * - mixed: make copy
+        * In case we make a whole lib's content local, we always want to localize, and we skip remapping (done later).
+        */
+
+       if (!ID_IS_LINKED_DATABLOCK(id)) {
+               return;
+       }
+
+       BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
+
+       if (lib_local || is_local) {
+               if (!is_lib) {
+                       id_clear_lib_data_ex(bmain, id, id_in_mainlist);
+                       BKE_id_expand_local(id);
+               }
+               else {
+                       ID *id_new;
+
+                       /* Should not fail in expected usecases, but id_copy does not copy Scene e.g. */
+                       if (id_copy(bmain, id, &id_new, false)) {
+                               id_new->us = 0;
+
+                               if (!lib_local) {
+                                       BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+                               }
+                       }
+               }
+       }
+
+}
+
+/**
+ * Calls the appropriate make_local method for the block, unless test is set.
+ *
+ * \param lib_local Special flag used when making a whole library's content local, it needs specific handling.
+ *
+ * \return true if the block can be made local.
+ */
+bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
 {
        if (id->tag & LIB_TAG_INDIRECT)
                return false;
@@ -282,44 +328,44 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool force_local)
                case ID_LI:
                        return false; /* can't be linked */
                case ID_OB:
-                       if (!test) BKE_object_make_local(bmain, (Object *)id, force_local);
+                       if (!test) BKE_object_make_local(bmain, (Object *)id, lib_local);
                        return true;
                case ID_ME:
-                       if (!test) BKE_mesh_make_local(bmain, (Mesh *)id, force_local);
+                       if (!test) BKE_mesh_make_local(bmain, (Mesh *)id, lib_local);
                        return true;
                case ID_CU:
-                       if (!test) BKE_curve_make_local(bmain, (Curve *)id, force_local);
+                       if (!test) BKE_curve_make_local(bmain, (Curve *)id, lib_local);
                        return true;
                case ID_MB:
-                       if (!test) BKE_mball_make_local(bmain, (MetaBall *)id, force_local);
+                       if (!test) BKE_mball_make_local(bmain, (MetaBall *)id, lib_local);
                        return true;
                case ID_MA:
-                       if (!test) BKE_material_make_local(bmain, (Material *)id, force_local);
+                       if (!test) BKE_material_make_local(bmain, (Material *)id, lib_local);
                        return true;
                case ID_TE:
-                       if (!test) BKE_texture_make_local(bmain, (Tex *)id, force_local);
+                       if (!test) BKE_texture_make_local(bmain, (Tex *)id, lib_local);
                        return true;
                case ID_IM:
-                       if (!test) BKE_image_make_local(bmain, (Image *)id, force_local);
+                       if (!test) BKE_image_make_local(bmain, (Image *)id, lib_local);
                        return true;
                case ID_LT:
-                       if (!test) BKE_lattice_make_local(bmain, (Lattice *)id, force_local);
+                       if (!test) BKE_lattice_make_local(bmain, (Lattice *)id, lib_local);
                        return true;
                case ID_LA:
-                       if (!test) BKE_lamp_make_local(bmain, (Lamp *)id, force_local);
+                       if (!test) BKE_lamp_make_local(bmain, (Lamp *)id, lib_local);
                        return true;
                case ID_CA:
-                       if (!test) BKE_camera_make_local(bmain, (Camera *)id, force_local);
+                       if (!test) BKE_camera_make_local(bmain, (Camera *)id, lib_local);
                        return true;
                case ID_SPK:
-                       if (!test) BKE_speaker_make_local(bmain, (Speaker *)id, force_local);
+                       if (!test) BKE_speaker_make_local(bmain, (Speaker *)id, lib_local);
                        return true;
                case ID_IP:
                        return false; /* deprecated */
                case ID_KE:
                        return false; /* can't be linked */
                case ID_WO:
-                       if (!test) BKE_world_make_local(bmain, (World *)id, force_local);
+                       if (!test) BKE_world_make_local(bmain, (World *)id, lib_local);
                        return true;
                case ID_SCR:
                        return false; /* can't be linked */
@@ -332,19 +378,19 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool force_local)
                case ID_GR:
                        return false; /* not implemented */
                case ID_AR:
-                       if (!test) BKE_armature_make_local(bmain, (bArmature *)id, force_local);
+                       if (!test) BKE_armature_make_local(bmain, (bArmature *)id, lib_local);
                        return true;
                case ID_AC:
-                       if (!test) BKE_action_make_local(bmain, (bAction *)id, force_local);
+                       if (!test) BKE_action_make_local(bmain, (bAction *)id, lib_local);
                        return true;
                case ID_NT:
-                       if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true, force_local);
+                       if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true, lib_local);
                        return true;
                case ID_BR:
-                       if (!test) BKE_brush_make_local(bmain, (Brush *)id, force_local);
+                       if (!test) BKE_brush_make_local(bmain, (Brush *)id, lib_local);
                        return true;
                case ID_PA:
-                       if (!test) BKE_particlesettings_make_local(bmain, (ParticleSettings *)id, force_local);
+                       if (!test) BKE_particlesettings_make_local(bmain, (ParticleSettings *)id, lib_local);
                        return true;
                case ID_WM:
                        return false; /* can't be linked */
@@ -1467,7 +1513,7 @@ bool new_id(ListBase *lb, ID *id, const char *tname)
  * 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_ex(Main *bmain, ID *id, bool id_in_mainlist)
+void id_clear_lib_data_ex(Main *bmain, ID *id, const bool id_in_mainlist)
 {
        bNodeTree *ntree = NULL;
        Key *key = NULL;
@@ -1581,16 +1627,13 @@ static void lib_indirect_test_id(ID *id, const Library *lib)
 void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged_only, const bool set_fake)
 {
        ListBase *lbarray[MAX_LIBARRAY];
-       ID *id, *idn;
+       ID *id, *id_next;
        int a;
 
-       a = set_listbasepointers(bmain, lbarray);
-       while (a--) {
-               id = lbarray[a]->first;
-               
-               while (id) {
+       for (a = set_listbasepointers(bmain, lbarray); a--; ) {
+               for (id = lbarray[a]->first; id; id = id_next) {
                        id->newid = NULL;
-                       idn = id->next;      /* id is possibly being inserted again */
+                       id_next = id->next;  /* id is possibly being inserted again */
                        
                        /* The check on the second line (LIB_TAG_PRE_EXISTING) is done so its
                         * possible to tag data you don't want to be made local, used for
@@ -1617,15 +1660,19 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged
                                        }
                                }
                        }
-
-                       id = idn;
                }
        }
 
-       a = set_listbasepointers(bmain, lbarray);
-       while (a--) {
-               for (id = lbarray[a]->first; id; id = id->next)
+       /* We have to remap local usages of old (linked) ID to new (local) id in a second loop, as lbarray ordering is not
+        * enough to ensure us we did catch all dependencies (e.g. if making local a parent object before its child...).
+        * See T48907. */
+       for (a = set_listbasepointers(bmain, lbarray); a--; ) {
+               for (id = lbarray[a]->first; id; id = id->next) {
+                       if (id->newid) {
+                               BKE_libblock_remap(bmain, id, id->newid, ID_REMAP_SKIP_INDIRECT_USAGE);
+                       }
                        lib_indirect_test_id(id, lib);
+               }
        }
 }
 
index 340eab8341409458dad619a6760a030abe88fd71..62aba1af694296f25e25e2ae07e53a8c9cc19134 100644 (file)
@@ -285,34 +285,9 @@ Material *localize_material(Material *ma)
        return man;
 }
 
-void BKE_material_make_local(Main *bmain, Material *ma, const bool force_local)
+void BKE_material_make_local(Main *bmain, Material *ma, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(ma)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, ma, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &ma->id);
-                       BKE_id_expand_local(&ma->id);
-               }
-               else {
-                       Material *ma_new = BKE_material_copy(bmain, ma);
-
-                       ma_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, ma, ma_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &ma->id, true, lib_local);
 }
 
 Material ***give_matarar(Object *ob)
index aeb38b3bd1d0cb18d4ef003ee36e5f8f1e821efe..7e363e5600f07f308cec2b24c1f0a6752fd70307 100644 (file)
@@ -127,34 +127,9 @@ MetaBall *BKE_mball_copy(Main *bmain, MetaBall *mb)
        return mbn;
 }
 
-void BKE_mball_make_local(Main *bmain, MetaBall *mb, const bool force_local)
+void BKE_mball_make_local(Main *bmain, MetaBall *mb, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(mb)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, mb, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &mb->id);
-                       BKE_id_expand_local(&mb->id);
-               }
-               else {
-                       MetaBall *mb_new = BKE_mball_copy(bmain, mb);
-
-                       mb_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, mb, mb_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &mb->id, true, lib_local);
 }
 
 /* most simple meta-element adding function
index 99b1e96cf20c79e86ea3c41d902721ecbae9ea95..2b35cdc9d6490040f5e1e08906a243e73e74ab3b 100644 (file)
@@ -556,34 +556,9 @@ BMesh *BKE_mesh_to_bmesh(
        return bm;
 }
 
-void BKE_mesh_make_local(Main *bmain, Mesh *me, const bool force_local)
+void BKE_mesh_make_local(Main *bmain, Mesh *me, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(me)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, me, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &me->id);
-                       BKE_id_expand_local(&me->id);
-               }
-               else {
-                       Mesh *me_new = BKE_mesh_copy(bmain, me);
-
-                       me_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, me, me_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &me->id, true, lib_local);
 }
 
 bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index,
index eec09973a824c207a0c3328ead968683ceda7b21..8bae04849202b1ecd2b18d36b68ef6ce339ffe7c 100644 (file)
@@ -1950,34 +1950,9 @@ bNodeTree *ntreeFromID(ID *id)
        }
 }
 
-void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist, const bool force_local)
+void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist, const bool lib_local)
 {
-       bool is_lib = false, is_local = false;
-       
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(ntree)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, ntree, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist);
-                       BKE_id_expand_local(&ntree->id);
-               }
-               else {
-                       bNodeTree *ntree_new = ntreeCopyTree(bmain, ntree);
-
-                       ntree_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, ntree, ntree_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &ntree->id, id_in_mainlist, lib_local);
 }
 
 int ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
index 4bdcec51360a6c24045e5fee03c4c179b0788f95..9c48fdfbf0877ace5ea64294d38963cb2d03a4f0 100644 (file)
@@ -1186,13 +1186,14 @@ Object *BKE_object_copy(Main *bmain, Object *ob)
        return BKE_object_copy_ex(bmain, ob, false);
 }
 
-void BKE_object_make_local(Main *bmain, Object *ob, const bool force_local)
+void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local)
 {
        bool is_local = false, is_lib = false;
 
        /* - only lib users: do nothing (unless force_local is set)
         * - only local users: set flag
         * - mixed: make copy
+        * In case we make a whole lib's content local, we always want to localize, and we skip remapping (done later).
         */
 
        if (!ID_IS_LINKED_DATABLOCK(ob)) {
@@ -1201,7 +1202,7 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool force_local)
 
        BKE_library_ID_test_usages(bmain, ob, &is_local, &is_lib);
 
-       if (force_local || is_local) {
+       if (lib_local || is_local) {
                if (!is_lib) {
                        id_clear_lib_data(bmain, &ob->id);
                        BKE_id_expand_local(&ob->id);
@@ -1212,7 +1213,9 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool force_local)
                        ob_new->id.us = 0;
                        ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
 
-                       BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+                       if (!lib_local) {
+                               BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+                       }
                }
        }
 }
index 2ff6c6c8b659355463a7c793c6d9c027c6932cd9..9fef220bcc9e8091100b04ccd2423fd18e850d64 100644 (file)
@@ -3343,34 +3343,9 @@ ParticleSettings *BKE_particlesettings_copy(Main *bmain, ParticleSettings *part)
        return partn;
 }
 
-void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const bool force_local)
+void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(part)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, part, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &part->id);
-                       BKE_id_expand_local(&part->id);
-               }
-               else {
-                       ParticleSettings *part_new = BKE_particlesettings_copy(bmain, part);
-
-                       part_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, part, part_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &part->id, true, lib_local);
 }
 
 /************************************************/
index c027f3b38ca80f6902c0d89d50f06f9a41a0653c..80ee6d50d7e0013c47546ccc8bfc1879f4fba109 100644 (file)
@@ -85,34 +85,9 @@ Speaker *BKE_speaker_copy(Main *bmain, Speaker *spk)
        return spkn;
 }
 
-void BKE_speaker_make_local(Main *bmain, Speaker *spk, const bool force_local)
+void BKE_speaker_make_local(Main *bmain, Speaker *spk, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(spk)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, spk, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &spk->id);
-                       BKE_id_expand_local(&spk->id);
-               }
-               else {
-                       Speaker *spk_new = BKE_speaker_copy(bmain, spk);
-
-                       spk_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, spk, spk_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &spk->id, true, lib_local);
 }
 
 void BKE_speaker_free(Speaker *spk)
index ecc169077cdcda40a81df83eaddfabe7038751d8..ed7f32b938f3ab8f6acc9ee65326aa3e8ff158a2 100644 (file)
@@ -917,34 +917,9 @@ Tex *BKE_texture_localize(Tex *tex)
 
 /* ------------------------------------------------------------------------- */
 
-void BKE_texture_make_local(Main *bmain, Tex *tex, const bool force_local)
+void BKE_texture_make_local(Main *bmain, Tex *tex, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(tex)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, tex, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &tex->id);
-                       BKE_id_expand_local(&tex->id);
-               }
-               else {
-                       Tex *tex_new = BKE_texture_copy(bmain, tex);
-
-                       tex_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, tex, tex_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &tex->id, true, lib_local);
 }
 
 Tex *give_current_object_texture(Object *ob)
index f926e29ea84867ebe7096e29818b9f51e9cc4e36..78342e9919aae2ccc945e77d55451c35f355b2a7 100644 (file)
@@ -176,32 +176,7 @@ World *localize_world(World *wrld)
        return wrldn;
 }
 
-void BKE_world_make_local(Main *bmain, World *wrld, const bool force_local)
+void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
 {
-       bool is_local = false, is_lib = false;
-
-       /* - only lib users: do nothing (unless force_local is set)
-        * - only local users: set flag
-        * - mixed: make copy
-        */
-
-       if (!ID_IS_LINKED_DATABLOCK(wrld)) {
-               return;
-       }
-
-       BKE_library_ID_test_usages(bmain, wrld, &is_local, &is_lib);
-
-       if (force_local || is_local) {
-               if (!is_lib) {
-                       id_clear_lib_data(bmain, &wrld->id);
-                       BKE_id_expand_local(&wrld->id);
-               }
-               else {
-                       World *wrld_new = BKE_world_copy(bmain, wrld);
-
-                       wrld_new->id.us = 0;
-
-                       BKE_libblock_remap(bmain, wrld, wrld_new, ID_REMAP_SKIP_INDIRECT_USAGE);
-               }
-       }
+       BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
 }