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:
Diffstat (limited to 'source/blender/editors/armature/armature_add.c')
-rw-r--r--source/blender/editors/armature/armature_add.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 59453f0ac71..218f215a350 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -38,6 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_ghash.h"
#include "BKE_action.h"
#include "BKE_constraint.h"
@@ -287,6 +288,66 @@ void preEditBoneDuplicate(ListBase *editbones)
ED_armature_ebone_listbase_temp_clear(editbones);
}
+/**
+ * Helper function for #postEditBoneDuplicate,
+ * return the destination pchan from the original.
+ *
+ * \param use_orig_fallback: return the input value if no new channel is found.
+ */
+static bPoseChannel *pchan_duplicate_map(
+ const bPose *pose, GHash *name_map,
+ bPoseChannel *pchan_src, bool use_orig_fallback)
+{
+ bPoseChannel *pchan_dst = NULL;
+ const char *name_src = pchan_src->name;
+ const char *name_dst = BLI_ghash_lookup(name_map, name_src);
+ if (name_dst) {
+ pchan_dst = BKE_pose_channel_find_name(pose, name_dst);
+ }
+
+ if ((pchan_dst == NULL) && use_orig_fallback) {
+ pchan_dst = pchan_src;
+ }
+
+ return pchan_dst;
+}
+
+void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
+{
+ if (ob->pose == NULL) {
+ return;
+ }
+
+ BKE_pose_channels_hash_free(ob->pose);
+ BKE_pose_channels_hash_make(ob->pose);
+
+ GHash *name_map = BLI_ghash_str_new(__func__);
+
+ for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) {
+ EditBone *ebone_dst = ebone_src->temp.ebone;
+ if (ebone_dst) {
+ BLI_ghash_insert(name_map, ebone_src->name, ebone_dst->name);
+ }
+ }
+
+ for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) {
+ EditBone *ebone_dst = ebone_src->temp.ebone;
+ if (ebone_dst) {
+ bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name);
+ if (pchan_src) {
+ bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name);
+ if (pchan_dst) {
+ if (pchan_src->custom_tx) {
+ pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx, true);
+ }
+ }
+ }
+ }
+ }
+
+ BLI_ghash_free(name_map, NULL, NULL);
+}
+
/*
* Note: When duplicating cross objects, editbones here is the list of bones
* from the SOURCE object but ob is the DESTINATION object
@@ -490,6 +551,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ postEditBoneDuplicate(arm->edbo, obedit);
+
ED_armature_validate_active(arm);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
@@ -687,6 +750,8 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
arm->act_edbone = arm->act_edbone->temp.ebone;
}
+ postEditBoneDuplicate(arm->edbo, obedit);
+
ED_armature_validate_active(arm);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
@@ -697,7 +762,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
/* following conventions from #MESH_OT_symmetrize */
void ARMATURE_OT_symmetrize(wmOperatorType *ot)
{
- /* subset of 'symmetrize_direction_items' */
+ /* subset of 'rna_enum_symmetrize_direction_items' */
static EnumPropertyItem arm_symmetrize_direction_items[] = {
{-1, "NEGATIVE_X", 0, "-X to +X", ""},
{+1, "POSITIVE_X", 0, "+X to -X", ""},