Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/armature.c
| Show First 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | static void copy_bonechildren(Bone *bone_dst, | ||||
| for (bone_src_child = bone_src->childbase.first, bone_dst_child = bone_dst->childbase.first; | for (bone_src_child = bone_src->childbase.first, bone_dst_child = bone_dst->childbase.first; | ||||
| bone_src_child; | bone_src_child; | ||||
| bone_src_child = bone_src_child->next, bone_dst_child = bone_dst_child->next) { | bone_src_child = bone_src_child->next, bone_dst_child = bone_dst_child->next) { | ||||
| bone_dst_child->parent = bone_dst; | bone_dst_child->parent = bone_dst; | ||||
| copy_bonechildren(bone_dst_child, bone_src_child, bone_src_act, r_bone_dst_act, flag); | copy_bonechildren(bone_dst_child, bone_src_child, bone_src_act, r_bone_dst_act, flag); | ||||
| } | } | ||||
| } | } | ||||
| static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst, GHash **bone_hash) | |||||
| { | |||||
| Bone *bone_dst_child; | |||||
| /* Lazily create the name -> bone hashtable */ | |||||
| if ((bone_dst->bbone_prev || bone_dst->bbone_next) && !*bone_hash) { | |||||
angavrilov: Maybe it's better to use BKE_armature_bone_from_name_map to create a hash table for lookup? In… | |||||
Done Inline ActionsYou are right, updated the code. yvt: You are right, updated the code. | |||||
| *bone_hash = BKE_armature_bone_from_name_map(arm_dst); | |||||
| } | |||||
| if (bone_dst->bbone_prev) { | |||||
| bone_dst->bbone_prev = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_prev->name); | |||||
| } | |||||
| if (bone_dst->bbone_next) { | |||||
| bone_dst->bbone_next = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_next->name); | |||||
| } | |||||
| for (bone_dst_child = bone_dst->childbase.first; bone_dst_child; | |||||
| bone_dst_child = bone_dst_child->next) { | |||||
| copy_bonechildren_custom_handles(bone_dst_child, arm_dst, bone_hash); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Only copy internal data of Armature ID from source to already allocated/initialized destination. | * Only copy internal data of Armature ID from source to already allocated/initialized destination. | ||||
| * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs. | * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs. | ||||
| * | * | ||||
| * WARNING! This function will not handle ID user count! | * WARNING! This function will not handle ID user count! | ||||
| * | * | ||||
| * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). | * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). | ||||
| */ | */ | ||||
| Show All 15 Lines | void BKE_armature_copy_data(Main *UNUSED(bmain), | ||||
| for (bone_src = arm_src->bonebase.first; bone_src; bone_src = bone_src->next) { | for (bone_src = arm_src->bonebase.first; bone_src; bone_src = bone_src->next) { | ||||
| bone_dst->parent = NULL; | bone_dst->parent = NULL; | ||||
| copy_bonechildren(bone_dst, bone_src, arm_src->act_bone, &bone_dst_act, flag_subdata); | copy_bonechildren(bone_dst, bone_src, arm_src->act_bone, &bone_dst_act, flag_subdata); | ||||
| bone_dst = bone_dst->next; | bone_dst = bone_dst->next; | ||||
| } | } | ||||
| arm_dst->act_bone = bone_dst_act; | arm_dst->act_bone = bone_dst_act; | ||||
| /* Fix custom handle references */ | |||||
| GHash *bone_hash = NULL; /* lazily created */ | |||||
| for (bone_dst = arm_dst->bonebase.first; bone_dst; bone_dst = bone_dst->next) { | |||||
| copy_bonechildren_custom_handles(bone_dst, arm_dst, &bone_hash); | |||||
| } | |||||
| if (bone_hash) { | |||||
| BLI_ghash_free(bone_hash, NULL, NULL); | |||||
| } | |||||
| arm_dst->edbo = NULL; | arm_dst->edbo = NULL; | ||||
| arm_dst->act_edbone = NULL; | arm_dst->act_edbone = NULL; | ||||
| } | } | ||||
| bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm) | bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm) | ||||
| { | { | ||||
| bArmature *arm_copy; | bArmature *arm_copy; | ||||
| BKE_id_copy(bmain, &arm->id, (ID **)&arm_copy); | BKE_id_copy(bmain, &arm->id, (ID **)&arm_copy); | ||||
| ▲ Show 20 Lines • Show All 2,508 Lines • Show Last 20 Lines | |||||
Maybe it's better to use BKE_armature_bone_from_name_map to create a hash table for lookup? In a big rig with many B-Bones this is effectively quadratic complexity, and this copying code is used internally by depsgraph for copy-on-write.