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:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py35
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/armature.c50
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/blenloader/intern/versioning_280.c49
-rw-r--r--source/blender/editors/armature/armature_add.c16
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_utils.c60
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c4
-rw-r--r--source/blender/editors/include/ED_armature.h5
-rw-r--r--source/blender/makesdna/DNA_action_types.h6
-rw-r--r--source/blender/makesdna/DNA_armature_types.h13
-rw-r--r--source/blender/makesrna/intern/rna_armature.c79
-rw-r--r--source/blender/makesrna/intern/rna_pose.c28
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");