Refactor/deduplicate even more make_local code (and fix part of T48907).

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.
This commit is contained in:
Bastien Montagne 2016-07-20 19:49:45 +02:00
parent 2977dcf2f7
commit d8d4bef6cc
Notes: blender-bot 2023-02-14 09:09:43 +01:00
Referenced by issue #48907, Appending breaks parent relations and groups
36 changed files with 140 additions and 462 deletions

View 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 ----------------- */

View 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. */

View 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);

View 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 */

View 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);

View 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);

View 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);

View 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;

View 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);

View 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 *);

View 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);

View 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];

View 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);

View 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);

View 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);

View 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

View 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);

View 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

View 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);
}
/* .................................. */

View 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)

View 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);
}
}
}
}

View 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). */

View 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 */

View 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)

View 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)

View 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 {

View 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);
}
}
}

View 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)

View 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

View 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,

View 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)

View 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);
}
}
}
}

View 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);
}
/************************************************/

View 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)

View 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)

View 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);
}