Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/library_remap.c
| Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_ipo.h" | #include "BKE_ipo.h" | ||||
| #include "BKE_key.h" | #include "BKE_key.h" | ||||
| #include "BKE_lamp.h" | #include "BKE_lamp.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_library_override.h" | |||||
| #include "BKE_library_query.h" | #include "BKE_library_query.h" | ||||
| #include "BKE_library_remap.h" | #include "BKE_library_remap.h" | ||||
| #include "BKE_linestyle.h" | #include "BKE_linestyle.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_mask.h" | #include "BKE_mask.h" | ||||
| #include "BKE_mball.h" | #include "BKE_mball.h" | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id_p, int cb_flag) | ||||
| ID *id = id_remap_data->id; | ID *id = id_remap_data->id; | ||||
| if (!old_id) { /* Used to cleanup all IDs used by a specific one. */ | if (!old_id) { /* Used to cleanup all IDs used by a specific one. */ | ||||
| BLI_assert(!new_id); | BLI_assert(!new_id); | ||||
| old_id = *id_p; | old_id = *id_p; | ||||
| } | } | ||||
| if (*id_p && (*id_p == old_id)) { | if (*id_p && (*id_p == old_id)) { | ||||
| const bool is_reference = (cb_flag & IDWALK_CB_STATIC_OVERRIDE_REFERENCE) != 0; | |||||
| const bool is_indirect = (cb_flag & IDWALK_CB_INDIRECT_USAGE) != 0; | const bool is_indirect = (cb_flag & IDWALK_CB_INDIRECT_USAGE) != 0; | ||||
| const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0; | const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0; | ||||
| /* Note: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct, | /* Note: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct, | ||||
| * on the other hand since they get reset to lib data on file open/reload it is indirect too... | * on the other hand since they get reset to lib data on file open/reload it is indirect too... | ||||
| * Edit Mode is also a 'skip direct' case. */ | * Edit Mode is also a 'skip direct' case. */ | ||||
| const bool is_obj = (GS(id->name) == ID_OB); | const bool is_obj = (GS(id->name) == ID_OB); | ||||
| const bool is_obj_proxy = (is_obj && (((Object *)id)->proxy || ((Object *)id)->proxy_group)); | const bool is_obj_proxy = (is_obj && (((Object *)id)->proxy || ((Object *)id)->proxy_group)); | ||||
| const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id)); | const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id)); | ||||
| const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) && | const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) && | ||||
| (id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0); | (id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0); | ||||
| const bool skip_reference = (id_remap_data->flag & ID_REMAP_SKIP_STATIC_OVERRIDE) != 0; | |||||
| const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0; | const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0; | ||||
| #ifdef DEBUG_PRINT | #ifdef DEBUG_PRINT | ||||
| printf("In %s: Remapping %s (%p) to %s (%p) (is_indirect: %d, skip_indirect: %d)\n", | printf("In %s: Remapping %s (%p) to %s (%p) (is_indirect: %d, skip_indirect: %d)\n", | ||||
| id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, is_indirect, skip_indirect); | id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, is_indirect, skip_indirect); | ||||
| #endif | #endif | ||||
| if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_CB_NEVER_NULL)) { | if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_CB_NEVER_NULL)) { | ||||
| id->tag |= LIB_TAG_DOIT; | id->tag |= LIB_TAG_DOIT; | ||||
| } | } | ||||
| /* Special hack in case it's Object->data and we are in edit mode (skipped_direct too). */ | /* Special hack in case it's Object->data and we are in edit mode (skipped_direct too). */ | ||||
| if ((is_never_null && skip_never_null) || | if ((is_never_null && skip_never_null) || | ||||
| (is_obj_editmode && (((Object *)id)->data == *id_p)) || | (is_obj_editmode && (((Object *)id)->data == *id_p)) || | ||||
| (skip_indirect && is_indirect)) | (skip_indirect && is_indirect) || | ||||
| (is_reference && skip_reference)) | |||||
| { | { | ||||
| if (is_indirect) { | if (is_indirect) { | ||||
| id_remap_data->skipped_indirect++; | id_remap_data->skipped_indirect++; | ||||
| if (is_obj) { | if (is_obj) { | ||||
| Object *ob = (Object *)id; | Object *ob = (Object *)id; | ||||
| if (ob->data == *id_p && ob->proxy != NULL) { | if (ob->data == *id_p && ob->proxy != NULL) { | ||||
| /* And another 'Proudly brought to you by Proxy Hell' hack! | /* And another 'Proudly brought to you by Proxy Hell' hack! | ||||
| * This will allow us to avoid clearing 'LIB_EXTERN' flag of obdata of proxies... */ | * This will allow us to avoid clearing 'LIB_EXTERN' flag of obdata of proxies... */ | ||||
| id_remap_data->skipped_direct++; | id_remap_data->skipped_direct++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (is_never_null || is_obj_editmode) { | else if (is_never_null || is_obj_editmode || is_reference) { | ||||
| id_remap_data->skipped_direct++; | id_remap_data->skipped_direct++; | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| if (cb_flag & IDWALK_CB_USER) { | if (cb_flag & IDWALK_CB_USER) { | ||||
| id_remap_data->skipped_refcounted++; | id_remap_data->skipped_refcounted++; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 507 Lines • ▼ Show 20 Lines | |||||
| void BKE_libblock_free_data(ID *id, const bool do_id_user) | void BKE_libblock_free_data(ID *id, const bool do_id_user) | ||||
| { | { | ||||
| if (id->properties) { | if (id->properties) { | ||||
| IDP_FreeProperty_ex(id->properties, do_id_user); | IDP_FreeProperty_ex(id->properties, do_id_user); | ||||
| MEM_freeN(id->properties); | MEM_freeN(id->properties); | ||||
| } | } | ||||
| if (id->override_static) { | |||||
| BKE_override_static_free(&id->override_static); | |||||
| } | |||||
| /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */ | /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */ | ||||
| } | } | ||||
| void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag)) | void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag)) | ||||
| { | { | ||||
| const short type = GS(id->name); | const short type = GS(id->name); | ||||
| switch (type) { | switch (type) { | ||||
| case ID_SCE: | case ID_SCE: | ||||
| ▲ Show 20 Lines • Show All 326 Lines • Show Last 20 Lines | |||||