diff options
Diffstat (limited to 'source/blender/blenkernel/intern/library.c')
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 5f7bded4262..978f1acefba 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -141,7 +141,7 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id) void id_lib_extern(ID *id) { - if (id) { + if (id && ID_IS_LINKED_DATABLOCK(id)) { BLI_assert(BKE_idcode_is_linkable(GS(id->name))); if (id->tag & LIB_TAG_INDIRECT) { id->tag -= LIB_TAG_INDIRECT; @@ -250,9 +250,27 @@ void id_fake_user_clear(ID *id) } } +static int id_expand_local_callback( + void *UNUSED(user_data), struct ID *UNUSED(id_self), struct ID **id_pointer, int UNUSED(cd_flag)) +{ + if (*id_pointer) { + id_lib_extern(*id_pointer); + } + + return IDWALK_RET_NOP; +} + +/** + * Expand ID usages of given id as 'extern' (and no more indirect) linked data. Used by ID copy/make_local functions. + */ +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(ID *id, bool test) +bool id_make_local(Main *bmain, ID *id, bool test) { if (id->tag & LIB_TAG_INDIRECT) return false; @@ -263,54 +281,45 @@ bool id_make_local(ID *id, bool test) case ID_LI: return false; /* can't be linked */ case ID_OB: - if (!test) BKE_object_make_local((Object *)id); + if (!test) BKE_object_make_local(bmain, (Object *)id); return true; case ID_ME: - if (!test) { - BKE_mesh_make_local((Mesh *)id); - BKE_key_make_local(((Mesh *)id)->key); - } + if (!test) BKE_mesh_make_local(bmain, (Mesh *)id); return true; case ID_CU: - if (!test) { - BKE_curve_make_local((Curve *)id); - BKE_key_make_local(((Curve *)id)->key); - } + if (!test) BKE_curve_make_local(bmain, (Curve *)id); return true; case ID_MB: - if (!test) BKE_mball_make_local((MetaBall *)id); + if (!test) BKE_mball_make_local(bmain, (MetaBall *)id); return true; case ID_MA: - if (!test) BKE_material_make_local((Material *)id); + if (!test) BKE_material_make_local(bmain, (Material *)id); return true; case ID_TE: - if (!test) BKE_texture_make_local((Tex *)id); + if (!test) BKE_texture_make_local(bmain, (Tex *)id); return true; case ID_IM: - if (!test) BKE_image_make_local((Image *)id); + if (!test) BKE_image_make_local(bmain, (Image *)id); return true; case ID_LT: - if (!test) { - BKE_lattice_make_local((Lattice *)id); - BKE_key_make_local(((Lattice *)id)->key); - } + if (!test) BKE_lattice_make_local(bmain, (Lattice *)id); return true; case ID_LA: - if (!test) BKE_lamp_make_local((Lamp *)id); + if (!test) BKE_lamp_make_local(bmain, (Lamp *)id); return true; case ID_CA: - if (!test) BKE_camera_make_local((Camera *)id); + if (!test) BKE_camera_make_local(bmain, (Camera *)id); return true; case ID_SPK: - if (!test) BKE_speaker_make_local((Speaker *)id); + if (!test) BKE_speaker_make_local(bmain, (Speaker *)id); return true; case ID_IP: return false; /* deprecated */ case ID_KE: - if (!test) BKE_key_make_local((Key *)id); + if (!test) BKE_key_make_local(bmain, (Key *)id); return true; case ID_WO: - if (!test) BKE_world_make_local((World *)id); + if (!test) BKE_world_make_local(bmain, (World *)id); return true; case ID_SCR: return false; /* can't be linked */ @@ -323,16 +332,16 @@ bool id_make_local(ID *id, bool test) case ID_GR: return false; /* not implemented */ case ID_AR: - if (!test) BKE_armature_make_local((bArmature *)id); + if (!test) BKE_armature_make_local(bmain, (bArmature *)id); return true; case ID_AC: - if (!test) BKE_action_make_local((bAction *)id); + if (!test) BKE_action_make_local(bmain, (bAction *)id); return true; case ID_NT: - if (!test) ntreeMakeLocal((bNodeTree *)id, true); + if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true); return true; case ID_BR: - if (!test) BKE_brush_make_local((Brush *)id); + if (!test) BKE_brush_make_local(bmain, (Brush *)id); return true; case ID_WM: return false; /* can't be linked */ @@ -349,9 +358,11 @@ bool id_make_local(ID *id, bool test) * Invokes the appropriate copy method for the block and returns the result in * newid, unless test. Returns true if the block can be copied. */ -bool id_copy(ID *id, ID **newid, bool test) +bool id_copy(Main *bmain, ID *id, ID **newid, bool test) { - if (!test) *newid = NULL; + if (!test) { + *newid = NULL; + } /* conventions: * - make shallow copy, only this ID block @@ -362,80 +373,80 @@ bool id_copy(ID *id, ID **newid, bool test) case ID_LI: return false; /* can't be copied from here */ case ID_OB: - if (!test) *newid = (ID *)BKE_object_copy((Object *)id); + if (!test) *newid = (ID *)BKE_object_copy(bmain, (Object *)id); return true; case ID_ME: - if (!test) *newid = (ID *)BKE_mesh_copy((Mesh *)id); + if (!test) *newid = (ID *)BKE_mesh_copy(bmain, (Mesh *)id); return true; case ID_CU: - if (!test) *newid = (ID *)BKE_curve_copy((Curve *)id); + if (!test) *newid = (ID *)BKE_curve_copy(bmain, (Curve *)id); return true; case ID_MB: - if (!test) *newid = (ID *)BKE_mball_copy((MetaBall *)id); + if (!test) *newid = (ID *)BKE_mball_copy(bmain, (MetaBall *)id); return true; case ID_MA: - if (!test) *newid = (ID *)BKE_material_copy((Material *)id); + if (!test) *newid = (ID *)BKE_material_copy(bmain, (Material *)id); return true; case ID_TE: - if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id); + if (!test) *newid = (ID *)BKE_texture_copy(bmain, (Tex *)id); return true; case ID_IM: - if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id); + if (!test) *newid = (ID *)BKE_image_copy(bmain, (Image *)id); return true; case ID_LT: - if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id); + if (!test) *newid = (ID *)BKE_lattice_copy(bmain, (Lattice *)id); return true; case ID_LA: - if (!test) *newid = (ID *)BKE_lamp_copy((Lamp *)id); + if (!test) *newid = (ID *)BKE_lamp_copy(bmain, (Lamp *)id); return true; case ID_SPK: - if (!test) *newid = (ID *)BKE_speaker_copy((Speaker *)id); + if (!test) *newid = (ID *)BKE_speaker_copy(bmain, (Speaker *)id); return true; case ID_CA: - if (!test) *newid = (ID *)BKE_camera_copy((Camera *)id); + if (!test) *newid = (ID *)BKE_camera_copy(bmain, (Camera *)id); return true; case ID_IP: return false; /* deprecated */ case ID_KE: - if (!test) *newid = (ID *)BKE_key_copy((Key *)id); + if (!test) *newid = (ID *)BKE_key_copy(bmain, (Key *)id); return true; case ID_WO: - if (!test) *newid = (ID *)BKE_world_copy((World *)id); + if (!test) *newid = (ID *)BKE_world_copy(bmain, (World *)id); return true; case ID_SCR: return false; /* can't be copied from here */ case ID_VF: return false; /* not implemented */ case ID_TXT: - if (!test) *newid = (ID *)BKE_text_copy(G.main, (Text *)id); + if (!test) *newid = (ID *)BKE_text_copy(bmain, (Text *)id); return true; case ID_SO: return false; /* not implemented */ case ID_GR: - if (!test) *newid = (ID *)BKE_group_copy((Group *)id); + if (!test) *newid = (ID *)BKE_group_copy(bmain, (Group *)id); return true; case ID_AR: - if (!test) *newid = (ID *)BKE_armature_copy((bArmature *)id); + if (!test) *newid = (ID *)BKE_armature_copy(bmain, (bArmature *)id); return true; case ID_AC: - if (!test) *newid = (ID *)BKE_action_copy((bAction *)id); + if (!test) *newid = (ID *)BKE_action_copy(bmain, (bAction *)id); return true; case ID_NT: - if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id); + if (!test) *newid = (ID *)ntreeCopyTree(bmain, (bNodeTree *)id); return true; case ID_BR: - if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id); + if (!test) *newid = (ID *)BKE_brush_copy(bmain, (Brush *)id); return true; case ID_WM: return false; /* can't be copied from here */ case ID_GD: - if (!test) *newid = (ID *)gpencil_data_duplicate((bGPdata *)id, false); + if (!test) *newid = (ID *)gpencil_data_duplicate(bmain, (bGPdata *)id, false); return true; case ID_MSK: - if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id); + if (!test) *newid = (ID *)BKE_mask_copy(bmain, (Mask *)id); return true; case ID_LS: - if (!test) *newid = (ID *)BKE_linestyle_copy(G.main, (FreestyleLineStyle *)id); + if (!test) *newid = (ID *)BKE_linestyle_copy(bmain, (FreestyleLineStyle *)id); return true; } @@ -450,7 +461,7 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop) if (id) { /* if property isn't editable, we're going to have an extra block hanging around until we save */ if (RNA_property_editable(ptr, prop)) { - if (id_copy(id, &newid, false) && newid) { + if (id_copy(CTX_data_main(C), id, &newid, false) && newid) { /* copy animation actions too */ BKE_animdata_copy_id_action(id); /* us is 1 by convention, but RNA_property_pointer_set @@ -621,7 +632,7 @@ void BKE_main_lib_objects_recalc_all(Main *bmain) /* flag for full recalc */ for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->id.lib) { + if (ID_IS_LINKED_DATABLOCK(ob)) { DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } } @@ -969,7 +980,7 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action) } /* used everywhere in blenkernel */ -void *BKE_libblock_copy_ex(Main *bmain, ID *id) +void *BKE_libblock_copy(Main *bmain, ID *id) { ID *idn; size_t idn_len; @@ -1021,11 +1032,6 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action) return idn; } -void *BKE_libblock_copy(ID *id) -{ - return BKE_libblock_copy_ex(G.main, id); -} - static int id_relink_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag) { ID *id = *id_pointer; @@ -1045,7 +1051,7 @@ static int id_relink_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **i void BKE_libblock_relink(ID *id) { - if (id->lib) + if (ID_IS_LINKED_DATABLOCK(id)) return; BKE_library_foreach_ID_link(id, id_relink_looper, NULL, 0); @@ -1259,7 +1265,7 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name) for (idtest = lb->first; idtest; idtest = idtest->next) { /* if idtest is not a lib */ - if (id != idtest && idtest->lib == NULL) { + if (id != idtest && !ID_IS_LINKED_DATABLOCK(idtest)) { /* do not test alphabetic! */ /* optimized */ if (idtest->name[2] == name[0]) { @@ -1319,7 +1325,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name) for (idtest = lb->first; idtest; idtest = idtest->next) { int nrtest; if ( (id != idtest) && - (idtest->lib == NULL) && + !ID_IS_LINKED_DATABLOCK(idtest) && (*name == *(idtest->name + 2)) && STREQLEN(name, idtest->name + 2, left_len) && (BLI_split_name_num(leftest, &nrtest, idtest->name + 2, '.') == left_len) @@ -1401,7 +1407,7 @@ bool new_id(ListBase *lb, ID *id, const char *tname) char name[MAX_ID_NAME - 2]; /* if library, don't rename */ - if (id->lib) + if (ID_IS_LINKED_DATABLOCK(id)) return false; /* if no libdata given, look up based on ID */ @@ -1465,7 +1471,7 @@ void id_clear_lib_data_ex(Main *bmain, ID *id, bool id_in_mainlist) ntree = ntreeFromID(id); if (ntree) { - ntreeMakeLocal(ntree, false); + ntreeMakeLocal(bmain, ntree, false); } if (GS(id->name) == ID_OB) { @@ -1506,7 +1512,7 @@ static void lib_indirect_test_id(ID *id, const Library *lib) #define LIBTAG(a) \ if (a && a->id.lib) { a->id.tag &= ~LIB_TAG_INDIRECT; a->id.tag |= LIB_TAG_EXTERN; } (void)0 - if (id->lib) { + if (ID_IS_LINKED_DATABLOCK(id)) { /* datablocks that were indirectly related are now direct links * without this, appending data that has a link to other data will fail to write */ if (lib && id->lib->parent == lib) { |