From f041d2f1163c36d9831b223d61e5740f43c00a13 Mon Sep 17 00:00:00 2001 From: Demeter Dzadik Date: Wed, 21 Aug 2019 09:59:11 +0200 Subject: Fix T65671: Armature X-Mirror inconsistencies This fixes bendy bone properties not being mirrored correctly Reviewed By: Brecht Differential Revision: http://developer.blender.org/D5408 --- source/blender/editors/armature/armature_utils.c | 42 +++++++++++++++------- source/blender/editors/include/ED_armature.h | 4 +-- source/blender/editors/transform/transform.h | 1 + .../editors/transform/transform_conversions.c | 2 ++ source/blender/makesrna/intern/rna_armature.c | 30 +++++++++++++--- 5 files changed, 59 insertions(+), 20 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index d8777b7e0b7..63b55a3f1b8 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -381,23 +381,33 @@ void armature_tag_unselect(bArmature *arm) void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bool check_select) { + /* TODO When this function is called by property updates, cancelling the value change will not restore mirrored bone correctly. */ + /* Currently check_select==true when this function is called from a transform operator, eg. from 3d viewport. */ /* no layer check, correct mirror is more important */ if (!check_select || ebo->flag & (BONE_TIPSEL | BONE_ROOTSEL)) { EditBone *eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo); if (eboflip) { - /* we assume X-axis flipping for now */ - if (check_select && ebo->flag & BONE_TIPSEL) { - EditBone *children; + /* We assume X-axis flipping for now. */ + + /* Always mirror roll, since it can be changed by moving either head or tail. */ + eboflip->roll = -ebo->roll; + + if (!check_select || ebo->flag & BONE_TIPSEL) { + /* Mirror tail properties. */ eboflip->tail[0] = -ebo->tail[0]; eboflip->tail[1] = ebo->tail[1]; eboflip->tail[2] = ebo->tail[2]; eboflip->rad_tail = ebo->rad_tail; - eboflip->roll = -ebo->roll; eboflip->curve_out_x = -ebo->curve_out_x; + eboflip->curve_out_y = ebo->curve_out_y; + eboflip->scale_out_x = ebo->scale_out_x; + eboflip->scale_out_y = ebo->scale_out_y; + eboflip->ease2 = ebo->ease2; eboflip->roll2 = -ebo->roll2; - /* Also move connected children, in case children's name aren't mirrored properly */ + /* Also move connected children, in case children's name aren't mirrored properly. */ + EditBone *children; for (children = arm->edbo->first; children; children = children->next) { if (children->parent == eboflip && children->flag & BONE_CONNECTED) { copy_v3_v3(children->head, eboflip->tail); @@ -405,32 +415,38 @@ void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bo } } } + if (!check_select || ebo->flag & BONE_ROOTSEL) { + /* Mirror head properties. */ eboflip->head[0] = -ebo->head[0]; eboflip->head[1] = ebo->head[1]; eboflip->head[2] = ebo->head[2]; eboflip->rad_head = ebo->rad_head; - eboflip->roll = -ebo->roll; + eboflip->curve_in_x = -ebo->curve_in_x; + eboflip->curve_in_y = ebo->curve_in_y; + eboflip->scale_in_x = ebo->scale_in_x; + eboflip->scale_in_y = ebo->scale_in_y; + eboflip->ease1 = ebo->ease1; eboflip->roll1 = -ebo->roll1; - /* Also move connected parent, in case parent's name isn't mirrored properly */ + /* Also move connected parent, in case parent's name isn't mirrored properly. */ if (eboflip->parent && eboflip->flag & BONE_CONNECTED) { EditBone *parent = eboflip->parent; copy_v3_v3(parent->tail, eboflip->head); parent->rad_tail = ebo->rad_head; } } + if (!check_select || ebo->flag & BONE_SELECTED) { + /* Mirror bone body properties (both head and tail are selected). */ + /* TODO: These values can also be changed from pose mode, so only mirroring them in edit mode is not ideal. */ eboflip->dist = ebo->dist; - eboflip->roll = -ebo->roll; + eboflip->weight = ebo->weight; + + eboflip->segments = ebo->segments; eboflip->xwidth = ebo->xwidth; eboflip->zwidth = ebo->zwidth; - - eboflip->curve_in_x = -ebo->curve_in_x; - eboflip->curve_out_x = -ebo->curve_out_x; - eboflip->roll1 = -ebo->roll1; - eboflip->roll2 = -ebo->roll2; } } } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 6629eed8328..76be0e82aa4 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -75,12 +75,14 @@ typedef struct EditBone { int flag; int layer; + /* Envelope distance & weight */ float dist, weight; /** put them in order! transform uses this as scale */ float xwidth, length, zwidth; float rad_head, rad_tail; /* Bendy-Bone parameters */ + short segments; float roll1, roll2; float curve_in_x, curve_in_y; float curve_out_x, curve_out_y; @@ -91,8 +93,6 @@ typedef struct EditBone { /** for envelope scaling */ float oldlength; - short segments; - /** Type of next/prev bone handles */ char bbone_prev_type; char bbone_next_type; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index b023199fa1b..a2195c97823 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -375,6 +375,7 @@ typedef struct VertSlideParams { typedef struct BoneInitData { struct EditBone *bone; float tail[3]; + float rad_head; float rad_tail; float roll; float head[3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 2fb9e2b9591..2684b6e279d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1517,6 +1517,7 @@ void restoreBones(TransDataContainer *tc) ebo = bid->bone; ebo->dist = bid->dist; + ebo->rad_head = bid->rad_head; ebo->rad_tail = bid->rad_tail; ebo->roll = bid->roll; ebo->xwidth = bid->xwidth; @@ -1782,6 +1783,7 @@ static void createTransArmatureVerts(TransInfo *t) if (eboflip) { bid[i].bone = eboflip; bid[i].dist = eboflip->dist; + bid[i].rad_head = eboflip->rad_head; bid[i].rad_tail = eboflip->rad_tail; bid[i].roll = eboflip->roll; bid[i].xwidth = eboflip->xwidth; diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 59e5c584811..bc6d3b6e743 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -621,7 +621,7 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone) RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); \ } \ else { \ - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); \ + RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); \ } \ } \ ((void)0) @@ -871,11 +871,16 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) /* Number values */ /* envelope deform settings */ prop = RNA_def_property(srna, "envelope_distance", PROP_FLOAT, PROP_DISTANCE); + if (editbone) { + RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); + } + else { + RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + } RNA_def_property_float_sdna(prop, NULL, "dist"); RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text( prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only)"); - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); prop = RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "weight"); @@ -914,23 +919,38 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) /* b-bones deform settings */ prop = RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE); + if (editbone) { + RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); + } + else { + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); + } RNA_def_property_int_sdna(prop, NULL, "segments"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text( prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only)"); - RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); prop = RNA_def_property(srna, "bbone_x", PROP_FLOAT, PROP_NONE); + if (editbone) { + RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); + } + else { + RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + } RNA_def_property_float_sdna(prop, NULL, "xwidth"); RNA_def_property_ui_range(prop, 0.0f, 1000.0f, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "B-Bone Display X Width", "B-Bone X size"); - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); prop = RNA_def_property(srna, "bbone_z", PROP_FLOAT, PROP_NONE); + if (editbone) { + RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); + } + else { + RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + } RNA_def_property_float_sdna(prop, NULL, "zwidth"); RNA_def_property_ui_range(prop, 0.0f, 1000.0f, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "B-Bone Display Z Width", "B-Bone Z size"); - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); prop = RNA_def_property(srna, "bbone_handle_type_start", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "bbone_prev_type"); -- cgit v1.2.3