diff options
author | Alexander Romanov <a.romanov@blend4web.com> | 2017-04-13 13:02:39 +0300 |
---|---|---|
committer | Alexander Romanov <a.romanov@blend4web.com> | 2017-04-13 13:02:39 +0300 |
commit | 6f268ac55d834ca9ba098b321dc101fbba93d773 (patch) | |
tree | 6a18624d0c7940af708c69103322fdcaaf5126fc /source/blender/blenkernel | |
parent | 0a62e971b2413dee218f43e8ba01b14c3a005b7f (diff) | |
parent | f5bc8ad4ce87165fc0648f1cd8c0ae1fb5f07281 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_idprop.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_library.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_library_query.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/idprop.c | 117 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 119 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_remap.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 2 |
7 files changed, 212 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 5b10d7ebc06..ab8728faedb 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -60,8 +60,6 @@ typedef union IDPropertyTemplate { IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void IDP_FreeIDPArray(IDProperty *prop); - /* shallow copies item */ void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL(); struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -81,8 +79,8 @@ void IDP_ConcatString(struct IDProperty *str1, struct IDProperty *append) ATTR_N void IDP_FreeString(struct IDProperty *prop) ATTR_NONNULL(); /*-------- ID Type -------*/ -void IDP_LinkID(struct IDProperty *prop, ID *id); -void IDP_UnlinkID(struct IDProperty *prop); + +typedef void(*IDPWalkFunc)(void *userData, IDProperty *idp); /*-------- Group Functions -------*/ @@ -112,11 +110,12 @@ bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) AT struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user); void IDP_FreeProperty(struct IDProperty *prop); void IDP_ClearProperty(IDProperty *prop); -void IDP_UnlinkProperty(struct IDProperty *prop); +void IDP_RelinkProperty(struct IDProperty *prop); #define IDP_Int(prop) ((prop)->data.val) #define IDP_Array(prop) ((prop)->data.pointer) @@ -134,11 +133,15 @@ void IDP_UnlinkProperty(struct IDProperty *prop); # define IDP_IDPArray(prop) _Generic((prop), \ IDProperty *: ((IDProperty *) (prop)->data.pointer), \ const IDProperty *: ((const IDProperty *) (prop)->data.pointer)) +# define IDP_Id(prop) _Generic((prop), \ + IDProperty *: ((ID *) (prop)->data.pointer), \ + const IDProperty *: ((const ID *) (prop)->data.pointer)) #else # define IDP_Float(prop) (*(float *)&(prop)->data.val) # define IDP_Double(prop) (*(double *)&(prop)->data.val) # define IDP_String(prop) ((char *) (prop)->data.pointer) # define IDP_IDPArray(prop) ((IDProperty *) (prop)->data.pointer) +# define IDP_Id(prop) ((ID *) (prop)->data.pointer) #endif #ifndef NDEBUG diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 72ae2cf4efa..6649cfbb585 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -66,7 +66,7 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_ void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL(); void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL(); void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL(); -void BKE_libblock_free_data(struct Main *bmain, struct ID *id) ATTR_NONNULL(); +void BKE_libblock_free_data(struct Main *bmain, struct ID *id, const bool do_id_user) ATTR_NONNULL(); void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL(); void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id); diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h index 1258e2fa72e..68bf9f43fe1 100644 --- a/source/blender/blenkernel/BKE_library_query.h +++ b/source/blender/blenkernel/BKE_library_query.h @@ -87,7 +87,7 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used); -bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used); +bool BKE_library_id_can_use_idtype(struct ID *id_owner, const short id_type_used); bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv); bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv); diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 7c79e13cb01..78a5273f0d0 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -117,14 +117,14 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array) return narray; } -void IDP_FreeIDPArray(IDProperty *prop) +static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user) { int i; BLI_assert(prop->type == IDP_IDPARRAY); for (i = 0; i < prop->len; i++) - IDP_FreeProperty(GETPROP(prop, i)); + IDP_FreeProperty_ex(GETPROP(prop, i), do_id_user); if (prop->data.pointer) MEM_freeN(prop->data.pointer); @@ -437,22 +437,24 @@ void IDP_FreeString(IDProperty *prop) /* -------------------------------------------------------------------- */ -/* ID Type (not in use yet) */ +/* ID Type */ -/** \name IDProperty ID API (unused) +/** \name IDProperty ID API * \{ */ -void IDP_LinkID(IDProperty *prop, ID *id) -{ - if (prop->data.pointer) - id_us_min(((ID *)prop->data.pointer)); - prop->data.pointer = id; - id_us_plus(id); -} -void IDP_UnlinkID(IDProperty *prop) +static IDProperty *IDP_CopyID(const IDProperty *prop) { - id_us_min(((ID *)prop->data.pointer)); + IDProperty *newp; + + BLI_assert(prop->type == IDP_ID); + newp = idp_generic_copy(prop); + + newp->data.pointer = prop->data.pointer; + id_us_plus(IDP_Id(newp)); + + return newp; } + /** \} */ @@ -711,13 +713,13 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con * This is because all ID Property freeing functions free only direct data (not the ID Property * struct itself), but for Groups the child properties *are* considered * direct data. */ -static void IDP_FreeGroup(IDProperty *prop) +static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user) { IDProperty *loop; BLI_assert(prop->type == IDP_GROUP); for (loop = prop->data.group.first; loop; loop = loop->next) { - IDP_FreeProperty(loop); + IDP_FreeProperty_ex(loop, do_id_user); } BLI_freelistN(&prop->data.group); } @@ -734,12 +736,51 @@ IDProperty *IDP_CopyProperty(const IDProperty *prop) switch (prop->type) { case IDP_GROUP: return IDP_CopyGroup(prop); case IDP_STRING: return IDP_CopyString(prop); + case IDP_ID: return IDP_CopyID(prop); case IDP_ARRAY: return IDP_CopyArray(prop); case IDP_IDPARRAY: return IDP_CopyIDPArray(prop); default: return idp_generic_copy(prop); } } +/* Updates ID pointers after an object has been copied */ +/* TODO Nuke this once its only user has been correctly converted to use generic ID management from BKE_library! */ +void IDP_RelinkProperty(struct IDProperty *prop) +{ + if (!prop) + return; + + switch (prop->type) { + case IDP_GROUP: + { + for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + IDP_RelinkProperty(loop); + } + break; + } + case IDP_IDPARRAY: + { + IDProperty *idp_array = IDP_Array(prop); + for (int i = 0; i < prop->len; i++) { + IDP_RelinkProperty(&idp_array[i]); + } + break; + } + case IDP_ID: + { + ID *id = IDP_Id(prop); + if (id && id->newid) { + id_us_min(IDP_Id(prop)); + prop->data.pointer = id->newid; + id_us_plus(IDP_Id(prop)); + } + break; + } + default: + break; /* Nothing to do for other IDProp types. */ + } +} + /** * Get the Group property that contains the id properties for ID id. Set create_if_needed * to create the Group property and attach it to id if it doesn't exist; otherwise @@ -836,6 +877,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is return false; return true; } + case IDP_ID: + return (IDP_Id(prop1) == IDP_Id(prop2)); default: /* should never get here */ BLI_assert(0); @@ -911,6 +954,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * prop->len = prop->totallen = val->array.len; break; } + printf("%s: bad array type.\n",__func__); return NULL; } case IDP_STRING: @@ -957,6 +1001,14 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * /* heh I think all needed values are set properly by calloc anyway :) */ break; } + case IDP_ID: + { + prop = MEM_callocN(sizeof(IDProperty), "IDProperty datablock"); + prop->data.pointer = (void *)val->id; + prop->type = IDP_ID; + id_us_plus(IDP_Id(prop)); + break; + } default: { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); @@ -971,11 +1023,10 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * } /** - * \note this will free all child properties of list arrays and groups! - * Also, note that this does NOT unlink anything! Plus it doesn't free - * the actual struct IDProperty struct either. + * \note This will free allocated data, all child properties of arrays and groups, and unlink IDs! + * But it does not free the actual IDProperty struct itself. */ -void IDP_FreeProperty(IDProperty *prop) +void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user) { switch (prop->type) { case IDP_ARRAY: @@ -985,14 +1036,24 @@ void IDP_FreeProperty(IDProperty *prop) IDP_FreeString(prop); break; case IDP_GROUP: - IDP_FreeGroup(prop); + IDP_FreeGroup(prop, do_id_user); break; case IDP_IDPARRAY: - IDP_FreeIDPArray(prop); + IDP_FreeIDPArray(prop, do_id_user); + break; + case IDP_ID: + if (do_id_user) { + id_us_min(IDP_Id(prop)); + } break; } } +void IDP_FreeProperty(IDProperty *prop) +{ + IDP_FreeProperty_ex(prop, true); +} + void IDP_ClearProperty(IDProperty *prop) { IDP_FreeProperty(prop); @@ -1000,18 +1061,4 @@ void IDP_ClearProperty(IDProperty *prop) prop->len = prop->totallen = 0; } -/** - * Unlinks any struct IDProperty<->ID linkage that might be going on. - * - * \note currently unused - */ -void IDP_UnlinkProperty(IDProperty *prop) -{ - switch (prop->type) { - case IDP_ID: - IDP_UnlinkID(prop); - break; - } -} - /** \} */ diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index c9853f791ce..c6cb336382e 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -33,6 +33,7 @@ #include "DNA_actuator_types.h" #include "DNA_anim_types.h" +#include "DNA_armature_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" #include "DNA_constraint_types.h" @@ -71,10 +72,12 @@ #include "BKE_collection.h" #include "BKE_constraint.h" #include "BKE_fcurve.h" +#include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_main.h" #include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_particle.h" #include "BKE_rigidbody.h" #include "BKE_sca.h" @@ -83,7 +86,9 @@ #define FOREACH_FINALIZE _finalize -#define FOREACH_FINALIZE_VOID FOREACH_FINALIZE: (void)0 +#define FOREACH_FINALIZE_VOID \ + if (0) { goto FOREACH_FINALIZE; } \ + FOREACH_FINALIZE: ((void)0) #define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, _cb_flag) \ CHECK_TYPE(id_pp, ID **); \ @@ -141,6 +146,37 @@ typedef struct LibraryForeachIDData { BLI_LINKSTACK_DECLARE(ids_todo, ID *); } LibraryForeachIDData; +static void library_foreach_idproperty_ID_link(LibraryForeachIDData *data, IDProperty *prop, int flag) +{ + if (!prop) + return; + + switch (prop->type) { + case IDP_GROUP: + { + for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + library_foreach_idproperty_ID_link(data, loop, flag); + } + break; + } + case IDP_IDPARRAY: + { + IDProperty *loop = IDP_Array(prop); + for (int i = 0; i < prop->len; i++) { + library_foreach_idproperty_ID_link(data, &loop[i], flag); + } + break; + } + case IDP_ID: + FOREACH_CALLBACK_INVOKE_ID(data, prop->data.pointer, flag); + break; + default: + break; /* Nothing to do here with other types of IDProperties... */ + } + + FOREACH_FINALIZE_VOID; +} + static void library_foreach_rigidbodyworldSceneLooper( struct RigidBodyWorld *UNUSED(rbw), ID **id_pointer, void *user_data, int cb_flag) { @@ -266,6 +302,17 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint) FOREACH_FINALIZE_VOID; } +static void library_foreach_bone(LibraryForeachIDData *data, Bone *bone) +{ + library_foreach_idproperty_ID_link(data, bone->prop, IDWALK_CB_USER); + + for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) { + library_foreach_bone(data, curbone); + } + + FOREACH_FINALIZE_VOID; +} + static void library_foreach_ID_as_subdata_link( ID **id_pp, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data) { @@ -338,6 +385,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call continue; } + library_foreach_idproperty_ID_link(&data, id->properties, IDWALK_CB_USER); + AnimData *adt = BKE_animdata_from_id(id); if (adt) { library_foreach_animationData(&data, adt); @@ -403,6 +452,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER); CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER); CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER); + library_foreach_idproperty_ID_link(&data, seq->prop, IDWALK_CB_USER); for (SequenceModifierData *smd = seq->modifiers.first; smd; smd = smd->next) { CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER); } @@ -535,6 +585,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call data.cb_flag |= proxy_cb_flag; for (pchan = object->pose->chanbase.first; pchan; pchan = pchan->next) { + library_foreach_idproperty_ID_link(&data, pchan->prop, IDWALK_CB_USER); CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER); BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, &data); } @@ -574,6 +625,16 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call break; } + case ID_AR: + { + bArmature *arm = (bArmature *)id; + + for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) { + library_foreach_bone(&data, bone); + } + break; + } + case ID_ME: { Mesh *mesh = (Mesh *) id; @@ -756,9 +817,27 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call { bNodeTree *ntree = (bNodeTree *) id; bNode *node; + bNodeSocket *sock; + CALLBACK_INVOKE(ntree->gpd, IDWALK_CB_USER); + for (node = ntree->nodes.first; node; node = node->next) { CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER); + + library_foreach_idproperty_ID_link(&data, node->prop, IDWALK_CB_USER); + for (sock = node->inputs.first; sock; sock = sock->next) { + library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + } + for (sock = node->outputs.first; sock; sock = sock->next) { + library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + } + } + + for (sock = ntree->inputs.first; sock; sock = sock->next) { + library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + } + for (sock = ntree->outputs.first; sock; sock = sock->next) { + library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); } break; } @@ -918,7 +997,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_VF: case ID_TXT: case ID_SO: - case ID_AR: case ID_GD: case ID_WM: case ID_PAL: @@ -968,9 +1046,25 @@ void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag) */ /* XXX This has to be fully rethink, basing check on ID type is not really working anymore (and even worth once * IDProps will support ID pointers), we'll have to do some quick checks on IDs themselves... */ -bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used) +bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) { - if (id_type_can_have_animdata(id_type_owner)) { + /* any type of ID can be used in custom props. */ + if (id_owner->properties) { + return true; + } + + const short id_type_owner = GS(id_owner->name); + + /* IDProps of armature bones and nodes, and bNode->id can use virtually any type of ID. */ + if (ELEM(id_type_owner, ID_NT, ID_AR)) { + return true; + } + + if (ntreeFromID(id_owner)) { + return true; + } + + if (BKE_animdata_from_id(id_owner)) { return true; /* AnimationData can use virtually any kind of datablocks, through drivers especially. */ } @@ -979,8 +1073,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id return ELEM(id_type_used, ID_LI); case ID_SCE: return (ELEM(id_type_used, ID_OB, ID_WO, ID_SCE, ID_MC, ID_MA, ID_GR, ID_TXT, - ID_LS, ID_MSK, ID_SO, ID_GD, ID_BR, ID_PAL, ID_IM, ID_NT) || - BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + ID_LS, ID_MSK, ID_SO, ID_GD, ID_BR, ID_PAL, ID_IM, ID_NT)); case ID_OB: /* Could be the following, but simpler to just always say 'yes' here. */ #if 0 @@ -997,13 +1090,13 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id case ID_MB: return ELEM(id_type_used, ID_MA); case ID_MA: - return (ELEM(id_type_used, ID_TE, ID_GR) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + return (ELEM(id_type_used, ID_TE, ID_GR)); case ID_TE: - return (ELEM(id_type_used, ID_IM, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + return (ELEM(id_type_used, ID_IM, ID_OB)); case ID_LT: return ELEM(id_type_used, ID_KE); case ID_LA: - return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + return (ELEM(id_type_used, ID_TE)); case ID_CA: return ELEM(id_type_used, ID_OB); case ID_KE: @@ -1011,7 +1104,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id case ID_SCR: return ELEM(id_type_used, ID_SCE); case ID_WO: - return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + return (ELEM(id_type_used, ID_TE)); case ID_SPK: return ELEM(id_type_used, ID_SO); case ID_GR: @@ -1032,7 +1125,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id case ID_MSK: return ELEM(id_type_used, ID_MC); /* WARNING! mask->parent.id, not typed. */ case ID_LS: - return (ELEM(id_type_used, ID_TE, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + return (ELEM(id_type_used, ID_TE, ID_OB)); case ID_IM: case ID_VF: case ID_TXT: @@ -1138,7 +1231,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked) while (i-- && !is_defined) { ID *id_curr = lb_array[i]->first; - if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(id->name))) { + if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) { continue; } @@ -1190,7 +1283,7 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo while (i-- && !is_defined) { ID *id_curr = lb_array[i]->first; - if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(id->name))) { + if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) { continue; } diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index 1f146ece690..255904841b2 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -472,20 +472,16 @@ ATTR_NONNULL(1) static void libblock_remap_data( * objects actually using given old_id... sounds rather unlikely currently, though, so this will do for now. */ while (i--) { - ID *id_curr = lb_array[i]->first; - - if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(old_id->name))) { - continue; - } - - for (; id_curr; id_curr = id_curr->next) { - /* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for - * the user count handling... - * XXX No more true (except for debug usage of those skipping counters). */ - r_id_remap_data->id = id_curr; - libblock_remap_data_preprocess(r_id_remap_data); - BKE_library_foreach_ID_link( - NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + for (ID *id_curr = lb_array[i]->first; id_curr; id_curr = id_curr->next) { + if (BKE_library_id_can_use_idtype(id_curr, GS(old_id->name))) { + /* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for + * the user count handling... + * XXX No more true (except for debug usage of those skipping counters). */ + r_id_remap_data->id = id_curr; + libblock_remap_data_preprocess(r_id_remap_data); + BKE_library_foreach_ID_link( + NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + } } } } @@ -747,10 +743,10 @@ void BKE_libblock_relink_to_newid(ID *id) BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0); } -void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id) +void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id, const bool do_id_user) { if (id->properties) { - IDP_FreeProperty(id->properties); + IDP_FreeProperty_ex(id->properties, do_id_user); MEM_freeN(id->properties); } } @@ -900,7 +896,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b BLI_remlink(lb, id); - BKE_libblock_free_data(bmain, id); + BKE_libblock_free_data(bmain, id, do_id_user); BKE_main_unlock(bmain); MEM_freeN(id); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 05422a01dbf..60c48bb5dd3 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1828,7 +1828,7 @@ void ntreeFreeTree(bNodeTree *ntree) if (tntree == ntree) break; if (tntree == NULL) { - BKE_libblock_free_data(G.main, &ntree->id); + BKE_libblock_free_data(G.main, &ntree->id, true); } } |