diff --git a/scripts/startup/bl_ui/properties_data_armature.py b/scripts/startup/bl_ui/properties_data_armature.py index 9520d8f28b3..6df04ae2340 100644 --- a/scripts/startup/bl_ui/properties_data_armature.py +++ b/scripts/startup/bl_ui/properties_data_armature.py @@ -81,6 +81,9 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel): sub.active = arm.show_axes sub.prop(arm, "axes_position", text="Position") + sub = col.row(align=True) + sub.prop(arm, "relation_line_position", text="Relations", expand=True) + class DATA_MT_bone_group_context_menu(Menu): bl_label = "Bone Group Specials" diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 250f9725526..77073ce2b3f 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -3639,7 +3639,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { - arm->flag &= ~(ARM_FLAG_UNUSED_1 | ARM_FLAG_UNUSED_5 | ARM_FLAG_UNUSED_6 | + arm->flag &= ~(ARM_FLAG_UNUSED_1 | ARM_DRAW_RELATION_FROM_HEAD | ARM_FLAG_UNUSED_6 | ARM_FLAG_UNUSED_7 | ARM_FLAG_UNUSED_12); } diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index eda023000f9..20a9cde5310 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -2023,6 +2023,20 @@ static void pchan_draw_ik_lines(ArmatureDrawContext *ctx, } } +static void draw_bone_bone_relationship_line(ArmatureDrawContext *ctx, + const float bone_head[3], + const float parent_head[3], + const float parent_tail[3], + const eArmature_Flag armature_flags) +{ + if (armature_flags & ARM_DRAW_RELATION_FROM_HEAD) { + drw_shgroup_bone_relationship_lines(ctx, bone_head, parent_head); + } + else { + drw_shgroup_bone_relationship_lines(ctx, bone_head, parent_tail); + } +} + static void draw_bone_relations(ArmatureDrawContext *ctx, EditBone *ebone, bPoseChannel *pchan, @@ -2036,7 +2050,8 @@ static void draw_bone_relations(ArmatureDrawContext *ctx, * since riggers will want to know about the links between bones */ if ((boneflag & BONE_CONNECTED) == 0) { - drw_shgroup_bone_relationship_lines(ctx, ebone->head, ebone->parent->tail); + draw_bone_bone_relationship_line( + ctx, ebone->head, ebone->parent->head, ebone->parent->tail, eArmature_Flag(arm->flag)); } } } @@ -2047,7 +2062,11 @@ static void draw_bone_relations(ArmatureDrawContext *ctx, if ((boneflag & BONE_SELECTED) || (pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED))) { if ((boneflag & BONE_CONNECTED) == 0) { - drw_shgroup_bone_relationship_lines(ctx, pchan->pose_head, pchan->parent->pose_tail); + draw_bone_bone_relationship_line(ctx, + pchan->pose_head, + pchan->parent->pose_head, + pchan->parent->pose_tail, + eArmature_Flag(arm->flag)); } } } diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index f0ffb608942..cc8dfbcbccb 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -154,9 +154,12 @@ typedef enum eArmature_Flag { ARM_DRAWAXES = (1 << 2), ARM_DRAWNAMES = (1 << 3), ARM_POSEMODE = (1 << 4), - ARM_FLAG_UNUSED_5 = (1 << 5), /* cleared */ - ARM_FLAG_UNUSED_6 = (1 << 6), /* cleared */ - ARM_FLAG_UNUSED_7 = (1 << 7), + /** Position of the parent-child relation lines on the bone (cleared = drawn + * from the tail, set = drawn from the head). Only controls the parent side of + * the line; the child side is always drawn to the head of the bone. */ + ARM_DRAW_RELATION_FROM_HEAD = (1 << 5), /* Cleared in versioning of pre-2.80 files. */ + ARM_FLAG_UNUSED_6 = (1 << 6), /* cleared */ + ARM_FLAG_UNUSED_7 = (1 << 7), /* cleared */ ARM_MIRROR_EDIT = (1 << 8), ARM_FLAG_UNUSED_9 = (1 << 9), /** Made option negative, for backwards compatibility. */ diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index a2386205013..b11595bb8b9 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -653,6 +653,30 @@ static void rna_Armature_transform(bArmature *arm, float mat[16]) ED_armature_transform(arm, (const float(*)[4])mat, true); } +static int rna_Armature_relation_line_position_get(PointerRNA *ptr) +{ + bArmature *arm = (bArmature *)ptr->data; + /* Translate the bitflag to an EnumPropertyItem prop_relation_lines_items item ID. */ + return (arm->flag & ARM_DRAW_RELATION_FROM_HEAD) ? 1 : 0; +} + +static void rna_Armature_relation_line_position_set(PointerRNA *ptr, const int value) +{ + bArmature *arm = (bArmature *)ptr->data; + + /* Translate the EnumPropertyItem prop_relation_lines_items item ID to a bitflag */ + switch (value) { + case 0: + arm->flag &= ~ARM_DRAW_RELATION_FROM_HEAD; + break; + case 1: + arm->flag |= ARM_DRAW_RELATION_FROM_HEAD; + break; + default: + return; + } +} + #else void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone, bool is_editbone) @@ -1460,6 +1484,11 @@ static void rna_def_armature(BlenderRNA *brna) "Show Armature in binding pose state (no posing possible)"}, {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem prop_relation_lines_items[] = { + {0, "TAIL", 0, "Tail", "Draw the relationship line from the parent tail to the child head"}, + {1, "HEAD", 0, "Head", "Draw the relationship line from the parent head to the child head"}, + {0, NULL, 0, NULL, NULL}, + }; srna = RNA_def_struct(brna, "Armature", "ID"); RNA_def_struct_ui_text( @@ -1554,6 +1583,20 @@ static void rna_def_armature(BlenderRNA *brna) "closer to the tip; decreasing moves it closer to the root"); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + RNA_define_verify_sdna(false); /* This property does not live in DNA. */ + prop = RNA_def_property(srna, "relation_line_position", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_relation_lines_items); + RNA_def_property_ui_text(prop, + "Relation Line Position", + "The start position of the relation lines from parent to child bones"); + RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + RNA_def_property_enum_funcs(prop, + "rna_Armature_relation_line_position_get", + "rna_Armature_relation_line_position_set", + /*item function*/ NULL); + RNA_define_verify_sdna(true); /* Restore default. */ + prop = RNA_def_property(srna, "show_names", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWNAMES); RNA_def_property_ui_text(prop, "Display Names", "Display bone names");