diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_bone.py | 35 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender_version.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 50 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 49 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_add.c | 16 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_utils.c | 60 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature_retarget.c | 4 | ||||
-rw-r--r-- | source/blender/editors/include/ED_armature.h | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 13 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_armature.c | 79 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 28 |
15 files changed, 287 insertions, 69 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 3fc0c66b0b4..bdee55666fd 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -130,6 +130,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): bone = context.bone # arm = context.armature pchan = None + edit = False if ob and bone: pchan = ob.pose.bones[bone.name] @@ -137,6 +138,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): elif bone is None: bone = context.edit_bone bbone = bone + edit = True else: bbone = bone @@ -169,24 +171,27 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easein", text="Ease In") col.prop(bbone, "bbone_easeout", text="Out") - if pchan: - topcol.separator() - - col = topcol.column() - col.use_property_split = False - col.prop(pchan, "use_bbone_custom_handles") + col = topcol.column(align=True) + col.prop(bone, "bbone_handle_type_start", text="Start Handle") - col = topcol.column(align=True) - col.active = pchan.use_bbone_custom_handles - col.use_property_split = True + col = col.column(align=True) + col.active = (bone.bbone_handle_type_start != "AUTO") + if edit: + col.prop_search(bone, "bbone_custom_handle_start", ob.data, "edit_bones", text="Custom") + else: + # read-only + col.prop(bbone, "bbone_custom_handle_start", text="Custom") - sub = col.column() - sub.prop_search(pchan, "bbone_custom_handle_start", ob.pose, "bones", text="Custom Handle Start") - sub.prop_search(pchan, "bbone_custom_handle_end", ob.pose, "bones", text="End") + col = topcol.column(align=True) + col.prop(bone, "bbone_handle_type_end", text="End Handle") - sub = col.column(align=True) - sub.prop(pchan, "use_bbone_relative_start_handle", text="Relative Handle Start") - sub.prop(pchan, "use_bbone_relative_end_handle", text="End") + col = col.column(align=True) + col.active = (bone.bbone_handle_type_end != "AUTO") + if edit: + col.prop_search(bone, "bbone_custom_handle_end", ob.data, "edit_bones", text="Custom") + else: + # read-only + col.prop(bbone, "bbone_custom_handle_end", text="Custom") class BONE_PT_relations(BoneButtonsPanel, Panel): diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 7ac59d6c9d4..84451fe31d4 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -28,7 +28,7 @@ * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 24 +#define BLENDER_SUBVERSION 25 /* Several breakages with 280, e.g. collections vs layers */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 9c407d27c29..68029ea72f6 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -887,7 +887,6 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f pchan->iklinweight = pchan_from->iklinweight; /* bbone settings (typically not animated) */ - pchan->bboneflag = pchan_from->bboneflag; pchan->bbone_next = pchan_from->bbone_next; pchan->bbone_prev = pchan_from->bbone_prev; @@ -1356,7 +1355,6 @@ void BKE_pose_copyesult_pchan_result(bPoseChannel *pchanto, const bPoseChannel * pchanto->rotmode = pchanfrom->rotmode; pchanto->flag = pchanfrom->flag; pchanto->protectflag = pchanfrom->protectflag; - pchanto->bboneflag = pchanfrom->bboneflag; } /* both poses should be in sync */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e2a41f46e69..61472068399 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -433,23 +433,31 @@ void equalize_bbone_bezier(float *data, int desired) copy_qt_qt(fp, temp[MAX_BBONE_SUBDIV]); } -/* get "next" and "prev" bones - these are used for handle calculations */ +/* Get "next" and "prev" bones - these are used for handle calculations. */ void BKE_pchan_get_bbone_handles(bPoseChannel *pchan, bPoseChannel **r_prev, bPoseChannel **r_next) { - if (pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) { - /* use the provided bones as the next/prev - leave blank to eliminate this effect altogether */ - *r_prev = pchan->bbone_prev; - *r_next = pchan->bbone_next; - } - else { - /* evaluate next and prev bones */ - if (pchan->bone->flag & BONE_CONNECTED) + if (pchan->bone->bbone_prev_type == BBONE_HANDLE_AUTO) { + /* Use connected parent. */ + if (pchan->bone->flag & BONE_CONNECTED) { *r_prev = pchan->parent; - else + } + else { *r_prev = NULL; + } + } + else { + /* Use the provided bone as prev - leave blank to eliminate this effect altogether. */ + *r_prev = pchan->bbone_prev; + } + if (pchan->bone->bbone_next_type == BBONE_HANDLE_AUTO) { + /* Use connected child. */ *r_next = pchan->child; } + else { + /* Use the provided bone as next - leave blank to eliminate this effect altogether. */ + *r_next = pchan->bbone_next; + } } /* returns pointer to static array, filled with desired amount of bone->segments elements */ @@ -499,8 +507,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB float difmat[4][4], result[3][3], imat3[3][3]; /* transform previous point inside this bone space */ - if ((pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) && - (pchan->bboneflag & PCHAN_BBONE_CUSTOM_START_REL)) + if (bone->bbone_prev_type == BBONE_HANDLE_RELATIVE) { /* Use delta movement (from restpose), and apply this relative to the current bone's head */ if (rest) { @@ -555,8 +562,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB float difmat[4][4], result[3][3], imat3[3][3]; /* transform next point inside this bone space */ - if ((pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) && - (pchan->bboneflag & PCHAN_BBONE_CUSTOM_END_REL)) + if (bone->bbone_next_type == BBONE_HANDLE_RELATIVE) { /* Use delta movement (from restpose), and apply this relative to the current bone's tail */ if (rest) { @@ -2019,6 +2025,22 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_ BKE_pose_channels_hash_free(pose); BLI_freelinkN(&pose->chanbase, pchan); } + else { + /* Find the custom B-Bone handles. */ + if (pchan->bone->bbone_prev) { + pchan->bbone_prev = BKE_pose_channel_find_name(pose, pchan->bone->bbone_prev->name); + } + else { + pchan->bbone_prev = NULL; + } + + if (pchan->bone->bbone_next) { + pchan->bbone_next = BKE_pose_channel_find_name(pose, pchan->bone->bbone_next->name); + } + else { + pchan->bbone_next = NULL; + } + } } /* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 005e2c62b85..275d14dbca3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3546,7 +3546,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) bool rebuild = false; if (fd->memfile == NULL) { - if (ob->proxy || (ob->id.lib==NULL && arm->id.lib)) { + if (ob->proxy || ob->id.lib != arm->id.lib) { rebuild = true; } } @@ -3628,6 +3628,9 @@ static void direct_link_bones(FileData *fd, Bone *bone) bone->prop = newdataadr(fd, bone->prop); IDP_DirectLinkGroup_OrFree(&bone->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + bone->bbone_next = newdataadr(fd, bone->bbone_next); + bone->bbone_prev = newdataadr(fd, bone->bbone_prev); + bone->flag &= ~BONE_DRAW_ACTIVE; link_list(fd, &bone->childbase); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 1e2ae48ccb1..5392e1dd4e8 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -60,7 +60,9 @@ #include "DNA_workspace_types.h" #include "DNA_key_types.h" #include "DNA_curve_types.h" +#include "DNA_armature_types.h" +#include "BKE_action.h" #include "BKE_collection.h" #include "BKE_constraint.h" #include "BKE_customdata.h" @@ -87,6 +89,8 @@ #include "BKE_key.h" #include "BKE_unit.h" +#include "DEG_depsgraph.h" + #include "BLT_translation.h" #include "BLO_readfile.h" @@ -860,6 +864,51 @@ void do_versions_after_linking_280(Main *bmain) } } } + + /* Move B-Bone custom handle settings from bPoseChannel to Bone. */ + if (!MAIN_VERSION_ATLEAST(bmain, 280, 25)) { + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + bArmature *arm = ob->data; + + /* If it is an armature from the same file. */ + if (ob->pose && arm && arm->id.lib == ob->id.lib) { + bool rebuild = false; + + for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + /* If the 2.7 flag is enabled, processing is needed. */ + if (pchan->bone && (pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES)) { + /* If the settings in the Bone are not set, copy. */ + if (pchan->bone->bbone_prev_type == BBONE_HANDLE_AUTO && + pchan->bone->bbone_next_type == BBONE_HANDLE_AUTO && + pchan->bone->bbone_prev == NULL && pchan->bone->bbone_next == NULL) + { + pchan->bone->bbone_prev_type = (pchan->bboneflag & PCHAN_BBONE_CUSTOM_START_REL) ? BBONE_HANDLE_RELATIVE : BBONE_HANDLE_ABSOLUTE; + pchan->bone->bbone_next_type = (pchan->bboneflag & PCHAN_BBONE_CUSTOM_END_REL) ? BBONE_HANDLE_RELATIVE : BBONE_HANDLE_ABSOLUTE; + + if (pchan->bbone_prev) { + pchan->bone->bbone_prev = pchan->bbone_prev->bone; + } + if (pchan->bbone_next) { + pchan->bone->bbone_next = pchan->bbone_next->bone; + } + } + + rebuild = true; + pchan->bboneflag = 0; + } + } + + /* Tag pose rebuild for all objects that use this armature. */ + if (rebuild) { + for (Object *ob2 = bmain->object.first; ob2; ob2 = ob2->id.next) { + if (ob2->pose && ob2->data == arm) { + ob2->pose->flag |= POSE_RECALC; + } + } + } + } + } + } } /* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already. diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index cf0b2457eca..a636e19faa2 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -561,6 +561,14 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) ebone->flag &= ~BONE_CONNECTED; } + /* Update custom handle links. */ + if (ebone_iter->bbone_prev && ebone_iter->bbone_prev->temp.ebone) { + ebone_iter->bbone_prev = ebone_iter->bbone_prev->temp.ebone; + } + if (ebone_iter->bbone_next && ebone_iter->bbone_next->temp.ebone) { + ebone_iter->bbone_next = ebone_iter->bbone_next->temp.ebone; + } + /* Lets try to fix any constraint subtargets that might * have been duplicated */ @@ -751,6 +759,14 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) ebone->parent = ebone_parent; } + /* Update custom handle links. */ + if (ebone_iter->bbone_prev && ebone_iter->bbone_prev->temp.ebone) { + ebone_iter->bbone_prev = ebone_iter->bbone_prev->temp.ebone; + } + if (ebone_iter->bbone_next && ebone_iter->bbone_next->temp.ebone) { + ebone_iter->bbone_next = ebone_iter->bbone_next->temp.ebone; + } + /* Lets try to fix any constraint subtargets that might * have been duplicated */ diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index e28e9877eba..e5efb3315d0 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -213,7 +213,7 @@ void POSE_OT_propagate(struct wmOperatorType *ot); * within each file, but some tools still have a bit of overlap which makes things messy -- Feb 2013 */ -EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent, struct Bone *actBone); +EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct Bone *actBone); /* duplicate method */ void preEditBoneDuplicate(struct ListBase *editbones); diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 2b28b76bcf6..339f0306779 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -131,6 +131,16 @@ void bone_free(bArmature *arm, EditBone *bone) MEM_freeN(bone->prop); } + /* Clear references from other edit bones. */ + for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (ebone->bbone_next == bone) { + ebone->bbone_next = NULL; + } + if (ebone->bbone_prev == bone) { + ebone->bbone_prev = NULL; + } + } + BLI_freelinkN(arm->edbo, bone); } @@ -426,7 +436,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit) /* Armature EditMode Conversions */ /* converts Bones to EditBone list, used for tools as well */ -EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone) +static EditBone *make_boneList_rec(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone) { EditBone *eBone; EditBone *eBoneAct = NULL; @@ -435,6 +445,7 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone for (curBone = bones->first; curBone; curBone = curBone->next) { eBone = MEM_callocN(sizeof(EditBone), "make_editbone"); + eBone->temp.bone = curBone; /* Copy relevant data from bone to eBone * Keep selection logic in sync with ED_armature_edit_sync_selection. @@ -490,6 +501,9 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone eBone->scaleIn = curBone->scaleIn; eBone->scaleOut = curBone->scaleOut; + eBone->bbone_prev_type = curBone->bbone_prev_type; + eBone->bbone_next_type = curBone->bbone_next_type; + if (curBone->prop) eBone->prop = IDP_CopyProperty(curBone->prop); @@ -497,7 +511,7 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone /* Add children if necessary */ if (curBone->childbase.first) { - eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone); + eBoneTest = make_boneList_rec(edbo, &curBone->childbase, eBone, actBone); if (eBoneTest) eBoneAct = eBoneTest; } @@ -509,6 +523,36 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone return eBoneAct; } +static EditBone *find_ebone_link(ListBase *edbo, Bone *link) +{ + if (link != NULL) { + for (EditBone *ebone = edbo->first; ebone; ebone = ebone->next) { + if (ebone->temp.bone == link) { + return ebone; + } + } + } + + return NULL; +} + +EditBone *make_boneList(ListBase *edbo, ListBase *bones, struct Bone *actBone) +{ + BLI_assert(!edbo->first && !edbo->last); + + EditBone *active = make_boneList_rec(edbo, bones, NULL, actBone); + + for (EditBone *ebone = edbo->first; ebone; ebone = ebone->next) { + Bone *bone = ebone->temp.bone; + + /* Convert custom B-Bone handle links. */ + ebone->bbone_prev = find_ebone_link(edbo, bone->bbone_prev); + ebone->bbone_next = find_ebone_link(edbo, bone->bbone_next); + } + + return active; +} + /* This function: * - sets local head/tail rest locations using parent bone's arm_mat. * - calls BKE_armature_where_is_bone() which uses parent's transform (arm_mat) to define this bone's transform. @@ -655,6 +699,8 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) newBone->scaleIn = eBone->scaleIn; newBone->scaleOut = eBone->scaleOut; + newBone->bbone_prev_type = eBone->bbone_prev_type; + newBone->bbone_next_type = eBone->bbone_next_type; if (eBone->prop) newBone->prop = IDP_CopyProperty(eBone->prop); @@ -673,6 +719,14 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) else { BLI_addtail(&arm->bonebase, newBone); } + + /* Also transfer B-Bone custom handles. */ + if (eBone->bbone_prev) { + newBone->bbone_prev = eBone->bbone_prev->temp.bone; + } + if (eBone->bbone_next) { + newBone->bbone_next = eBone->bbone_next->temp.bone; + } } /* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */ @@ -715,7 +769,7 @@ void ED_armature_to_edit(bArmature *arm) { ED_armature_edit_free(arm); arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature"); - arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone); + arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, arm->act_bone); } /* *************************************************************** */ diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 89e510e6f3e..0c770bcbcc4 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -1348,7 +1348,7 @@ RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm) } else { rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); - make_boneList(rg->editbones, &arm->bonebase, NULL, NULL); + make_boneList(rg->editbones, &arm->bonebase, NULL); rg->flag |= RIG_FREE_BONELIST; } @@ -1396,7 +1396,7 @@ static RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm } else { rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); - make_boneList(rg->editbones, &arm->bonebase, NULL, NULL); + make_boneList(rg->editbones, &arm->bonebase, NULL); rg->flag |= RIG_FREE_BONELIST; } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 3044543795c..9347d2037b0 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -90,6 +90,11 @@ typedef struct EditBone { short segments; + char bbone_prev_type; /* Type of next/prev bone handles */ + char bbone_next_type; + struct EditBone *bbone_prev; /* Next/prev bones to use as handle references when calculating bbones (optional) */ + struct EditBone *bbone_next; + /* Used for display */ float disp_mat[4][4]; /* in Armature space, rest pos matrix */ float disp_tail_mat[4][4]; /* in Armature space, rest pos matrix */ diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 55e1a43925d..d6991041ec6 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -224,7 +224,7 @@ typedef struct bPoseChannel { char constflag; /* for quick detecting which constraints affect this channel */ char selectflag; /* copy of bone flag, so you can work with library armatures, not for runtime use */ char drawflag; - char bboneflag; + char bboneflag DNA_DEPRECATED; char pad0[4]; struct Bone *bone; /* set on read file or rebuild pose */ @@ -278,7 +278,7 @@ typedef struct bPoseChannel { float ease1, ease2; float scaleIn, scaleOut; - struct bPoseChannel *bbone_prev; /* next/prev bones to use as handle references when calculating bbones (optional) */ + struct bPoseChannel *bbone_prev; /* B-Bone custom handles; set on read file or rebuild pose based on pchan->bone data */ struct bPoseChannel *bbone_next; void *temp; /* use for outliner */ @@ -361,6 +361,7 @@ typedef enum ePchan_DrawFlag { #define PCHAN_CUSTOM_DRAW_SIZE(pchan) \ (pchan)->custom_scale * (((pchan)->drawflag & PCHAN_DRAW_NO_CUSTOM_BONE_SIZE) ? 1.0f : (pchan)->bone->length) +#ifdef DNA_DEPRECATED_ALLOW /* PoseChannel->bboneflag */ typedef enum ePchan_BBoneFlag { /* Use custom reference bones (for roll and handle alignment), instead of immediate neighbors */ @@ -370,6 +371,7 @@ typedef enum ePchan_BBoneFlag { /* Evaluate end handle as being "relative" */ PCHAN_BBONE_CUSTOM_END_REL = (1 << 3), } ePchan_BBoneFlag; +#endif /* PoseChannel->rotmode and Object->rotmode */ typedef enum eRotationModes { diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 937caffb71e..141ad7c3ce0 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -78,8 +78,10 @@ typedef struct Bone { int layer; /* layers that bone appears on */ short segments; /* for B-bones */ - short pad1; - + char bbone_prev_type; /* Type of next/prev bone handles */ + char bbone_next_type; + struct Bone *bbone_prev; /* Next/prev bones to use as handle references when calculating bbones (optional) */ + struct Bone *bbone_next; } Bone; typedef struct bArmature { @@ -214,6 +216,13 @@ typedef enum eBone_Flag { } eBone_Flag; +/* bone->bbone_prev_type, bbone_next_type */ +typedef enum eBone_BBoneHandleType { + BBONE_HANDLE_AUTO = 0, /* Default mode based on parents & children. */ + BBONE_HANDLE_ABSOLUTE, /* Custom handle in absolute position mode. */ + BBONE_HANDLE_RELATIVE, /* Custom handle in relative position mode. */ +} eBone_BBoneHandleType; + #define MAXBONENAME 64 #endif diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index d557714d228..4fd42a97568 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -449,6 +449,40 @@ static void rna_EditBone_matrix_set(PointerRNA *ptr, const float *values) ED_armature_ebone_from_mat4(ebone, (float(*)[4])values); } +static PointerRNA rna_EditBone_bbone_prev_get(PointerRNA *ptr) +{ + EditBone *data = (EditBone *)(ptr->data); + return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_prev); +} + +static void rna_EditBone_bbone_prev_set(PointerRNA *ptr, PointerRNA value) +{ + EditBone *ebone = (EditBone *)(ptr->data); + EditBone *hbone = (EditBone *)value.data; + + /* Within the same armature? */ + if (hbone == NULL || value.id.data == ptr->id.data) { + ebone->bbone_prev = hbone; + } +} + +static PointerRNA rna_EditBone_bbone_next_get(PointerRNA *ptr) +{ + EditBone *data = (EditBone *)(ptr->data); + return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_next); +} + +static void rna_EditBone_bbone_next_set(PointerRNA *ptr, PointerRNA value) +{ + EditBone *ebone = (EditBone *)(ptr->data); + EditBone *hbone = (EditBone *)value.data; + + /* Within the same armature? */ + if (hbone == NULL || value.id.data == ptr->id.data) { + ebone->bbone_next = hbone; + } +} + static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bArmature *arm = (bArmature *)ptr->id.data; @@ -617,6 +651,13 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone) static void rna_def_bone_common(StructRNA *srna, int editbone) { + static const EnumPropertyItem prop_bbone_handle_type[] = { + {BBONE_HANDLE_AUTO, "AUTO", 0, "Automatic", "Use connected parent and children to compute the handle"}, + {BBONE_HANDLE_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Use the position of the specified bone to compute the handle"}, + {BBONE_HANDLE_RELATIVE, "RELATIVE", 0, "Relative", "Use the offset of the specified bone from rest pose to compute the handle"}, + {0, NULL, 0, NULL, NULL} + }; + PropertyRNA *prop; /* strings */ @@ -745,6 +786,44 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_range(prop, 0.0f, 1000.0f); 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"); + RNA_def_property_enum_items(prop, prop_bbone_handle_type); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "B-Bone Start Handle Type", "Selects how the start handle of the B-Bone is computed"); + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); + + prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev"); + RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone"); + if (editbone) { + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_EditBone_bbone_prev_get", "rna_EditBone_bbone_prev_set", NULL, NULL); + } + RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); + RNA_def_property_ui_text(prop, "B-Bone Start Handle", + "Bone that serves as the start handle for the B-Bone curve"); + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); + + prop = RNA_def_property(srna, "bbone_handle_type_end", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "bbone_next_type"); + RNA_def_property_enum_items(prop, prop_bbone_handle_type); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "B-Bone End Handle Type", "Selects how the end handle of the B-Bone is computed"); + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); + + prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "bbone_next"); + RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone"); + if (editbone) { + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_EditBone_bbone_next_get", "rna_EditBone_bbone_next_set", NULL, NULL); + } + RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); + RNA_def_property_ui_text(prop, "B-Bone End Handle", + "Bone that serves as the end handle for the B-Bone curve"); + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); } /* err... bones should not be directly edited (only editbones should be...) */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index d263e02d3f8..56ba29d277c 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -965,46 +965,22 @@ static void rna_def_pose_channel(BlenderRNA *brna) rna_def_bone_curved_common(srna, true); /* Custom BBone next/prev sources */ - prop = RNA_def_property(srna, "use_bbone_custom_handles", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_HANDLES); - RNA_def_property_ui_text(prop, "Use Custom Handle References", - "Use custom reference bones as handles for B-Bones instead of next/previous bones, " - "leave these blank to use only B-Bone offset properties to control the shape"); - RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); - prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev"); RNA_def_property_struct_type(prop, "PoseBone"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP); + RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); RNA_def_property_ui_text(prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve"); - RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); - prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL); - RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle", - "Treat custom start handle position as a relative value"); - RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); - prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bbone_next"); RNA_def_property_struct_type(prop, "PoseBone"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP); + RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); RNA_def_property_ui_text(prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve"); - RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); - prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL); - RNA_def_property_ui_text(prop, "Relative B-Bone End Handle", - "Treat custom end handle position as a relative value"); - RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); - /* transform matrices - should be read-only since these are set directly by AnimSys evaluation */ prop = RNA_def_property(srna, "matrix_channel", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "chan_mat"); |