Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomoaki Kawada <i@yvt.jp>2019-04-28 16:19:45 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-04-28 17:05:37 +0300
commit9e3246ce6e9767148e4394dc7acbec04a7d69163 (patch)
tree0145ddd31683391866bd62c93d7e00831de57bf0
parent91bb8da59fe16e711e44d8fb0ff6422277b2d742 (diff)
Fix T63794: duplicating an armature clears B-Bones' custom handle references.
This patch fixes T63794 by updating duplicated bones' custom handle references to point to the new armature's bones. The problem occurs because B-Bones of a duplicated armature keep pointing to the old armature's bones. The references are cleared upon entering Edit Mode because there are no matching `EditBone` for such bones, and `find_ebone_link` just returns `NULL` in such cases. Reviewers: mont29, angavrilov Maniphest Tasks: T63794 Differential Revision: https://developer.blender.org/D4726
-rw-r--r--source/blender/blenkernel/intern/armature.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 97238020f29..7f374c1d66e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -169,6 +169,28 @@ static void copy_bonechildren(Bone *bone_dst,
}
}
+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 == NULL) {
+ *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.
@@ -202,6 +224,17 @@ void BKE_armature_copy_data(Main *UNUSED(bmain),
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->act_edbone = NULL;
}