diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-11-24 15:12:24 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-11-27 09:31:34 +0300 |
commit | a58f0eea4f1e9b04e519e123eb656009cf718f9e (patch) | |
tree | d3459d3c43d9602fe1f0c2e1678bb565601144d6 /source/blender/makesrna/intern/rna_pose_api.c | |
parent | fe65867c3dd99f33c1b2a8f509027021d43063bf (diff) |
RNA: expose access to B-Bone shape data from Python.
B-Bone shape is a non-trivial computation, so access to
the results would be useful for Python scripts working with
B-Bones, e.g. rig generation.
This exposes both final segment matrices, and the tangent
vectors computed from the custom handle bones.
Since the handle tangents use the axis+roll orientation math
of edit bones, add matrix conversion static methods to Bone.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D3983
Diffstat (limited to 'source/blender/makesrna/intern/rna_pose_api.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_pose_api.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c index 04ecdd497f6..f4463e0f7d8 100644 --- a/source/blender/makesrna/intern/rna_pose_api.c +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -59,6 +59,45 @@ static float rna_PoseBone_do_envelope(bPoseChannel *chan, float *vec) return distfactor_to_bone(vec, chan->pose_head, chan->pose_tail, bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale); } + +static void rna_PoseBone_bbone_segment_matrix(bPoseChannel *pchan, ReportList *reports, float mat_ret[16], int index, bool rest) +{ + if (!pchan->bone || pchan->bone->segments <= 1) { + BKE_reportf(reports, RPT_ERROR, "Bone '%s' is not a B-Bone!", pchan->name); + return; + } + if (pchan->runtime.bbone_segments != pchan->bone->segments) { + BKE_reportf(reports, RPT_ERROR, "Bone '%s' has out of date B-Bone segment data!", pchan->name); + return; + } + if (index < 0 || index >= pchan->runtime.bbone_segments) { + BKE_reportf(reports, RPT_ERROR, "Invalid index %d for B-Bone segments of '%s'!", index, pchan->name); + return; + } + + if (rest) { + copy_m4_m4((float (*)[4])mat_ret, pchan->runtime.bbone_rest_mats[index].mat); + } + else { + copy_m4_m4((float (*)[4])mat_ret, pchan->runtime.bbone_pose_mats[index].mat); + } +} + +static void rna_PoseBone_compute_bbone_handles( + bPoseChannel *pchan, ReportList *reports, + float ret_h1[3], float *ret_roll1, float ret_h2[3], float *ret_roll2, + bool rest, bool ease, bool offsets) +{ + if (!pchan->bone || pchan->bone->segments <= 1) { + BKE_reportf(reports, RPT_ERROR, "Bone '%s' is not a B-Bone!", pchan->name); + return; + } + + BBoneSplineParameters params; + + BKE_pchan_get_bbone_spline_parameters(pchan, rest, ¶ms); + BKE_compute_b_bone_handles(¶ms, ret_h1, ret_roll1, ret_h2, ret_roll2, ease || offsets, offsets); +} #else void RNA_api_pose(StructRNA *UNUSED(srna)) @@ -80,6 +119,38 @@ void RNA_api_pose_channel(StructRNA *srna) /* return value */ parm = RNA_def_float(func, "factor", 0, -FLT_MAX, FLT_MAX, "Factor", "Envelope factor", -FLT_MAX, FLT_MAX); RNA_def_function_return(func, parm); + + /* B-Bone segment matrices */ + func = RNA_def_function(srna, "bbone_segment_matrix", "rna_PoseBone_bbone_segment_matrix"); + RNA_def_function_ui_description(func, "Retrieve the matrix of the B-Bone segment if available"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_property(func, "matrix_return", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The resulting matrix in bone local space"); + RNA_def_function_output(func, parm); + parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the segment", 0, 10000); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_boolean(func, "rest", false, "", "Return the rest pose matrix"); + + /* B-Bone custom handle positions */ + func = RNA_def_function(srna, "compute_bbone_handles", "rna_PoseBone_compute_bbone_handles"); + RNA_def_function_ui_description(func, "Retrieve the vectors and rolls coming from B-Bone custom handles"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_property(func, "handle1", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + RNA_def_property_ui_text(parm, "", "The direction vector of the start handle in bone local space"); + RNA_def_function_output(func, parm); + parm = RNA_def_float(func, "roll1", 0, -FLT_MAX, FLT_MAX, "", "Roll of the start handle", -FLT_MAX, FLT_MAX); + RNA_def_function_output(func, parm); + parm = RNA_def_property(func, "handle2", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + RNA_def_property_ui_text(parm, "", "The direction vector of the end handle in bone local space"); + RNA_def_function_output(func, parm); + parm = RNA_def_float(func, "roll2", 0, -FLT_MAX, FLT_MAX, "", "Roll of the end handle", -FLT_MAX, FLT_MAX); + RNA_def_function_output(func, parm); + parm = RNA_def_boolean(func, "rest", false, "", "Return the rest pose state"); + parm = RNA_def_boolean(func, "ease", false, "", "Apply scale from ease values"); + parm = RNA_def_boolean(func, "offsets", false, "", "Apply roll and curve offsets from bone properties"); } |