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
This commit is contained in:
Demeter Dzadik
2019-08-21 09:59:11 +02:00
committed by Sebastian Parborg
parent 3d8f158697
commit f041d2f116
5 changed files with 59 additions and 20 deletions

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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];

View File

@@ -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;

View File

@@ -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");