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:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-08-05 18:48:05 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-10-04 19:55:44 +0300
commit61a24c799b2882c22a43591138a113d7f09be0ed (patch)
treeea85047e68ff64bf7e25329a7e7048f1b9dbfeb1 /source/blender
parent6932eaa2bcaff0649c82f6b31a205319c966bd15 (diff)
Move B-Bone custom handle settings to Edit mode.
Custom handle settings actually affect the B-Bone rest shape, so they should be changed in Edit mode rather than Pose mode. This is necessary to be able to display the correct rest shape of the bone in Edit Mode. Also, instead of flags, introduce an enum to specify the handle operation modes, so that new ones could be added later. Differential Revision: https://developer.blender.org/D3588
Diffstat (limited to 'source/blender')
-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
14 files changed, 267 insertions, 54 deletions
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");