Blender V4.3
rna_pose_api.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10#include <cstdlib>
11#include <cstring>
12#include <ctime>
13
14#include "BLI_math_matrix.h"
15#include "BLI_utildefines.h"
16
17#include "RNA_define.hh"
18
19#include "DNA_object_types.h"
20
21/* #include "BLI_sys_types.h" */
22
23#include "rna_internal.hh" /* own include */
24
25using namespace blender;
26
27#ifdef RNA_RUNTIME
28
29# include "BKE_animsys.h"
30# include "BKE_armature.hh"
31# include "BKE_context.hh"
32# include "BKE_pose_backup.h"
33
34# include "DNA_action_types.h"
35# include "DNA_anim_types.h"
36
37# include "BLI_ghash.h"
38
39# include "ANIM_action.hh"
40# include "ANIM_pose.hh"
41
42static float rna_PoseBone_do_envelope(bPoseChannel *chan, const float vec[3])
43{
44 Bone *bone = chan->bone;
45
46 float scale = (bone->flag & BONE_MULT_VG_ENV) == BONE_MULT_VG_ENV ? bone->weight : 1.0f;
47
48 return distfactor_to_bone(vec,
49 chan->pose_head,
50 chan->pose_tail,
51 bone->rad_head * scale,
52 bone->rad_tail * scale,
53 bone->dist * scale);
54}
55
56static void rna_PoseBone_bbone_segment_index(
57 bPoseChannel *pchan, ReportList *reports, const float pt[3], int *r_index, float *r_blend_next)
58{
59 if (!pchan->bone || pchan->bone->segments <= 1) {
60 BKE_reportf(reports, RPT_ERROR, "Bone '%s' is not a B-Bone!", pchan->name);
61 return;
62 }
63 if (pchan->runtime.bbone_segments != pchan->bone->segments) {
64 BKE_reportf(reports,
66 "Bone '%s' has out of date B-Bone segment data - depsgraph update required!",
67 pchan->name);
68 return;
69 }
70
71 BKE_pchan_bbone_deform_segment_index(pchan, pt, r_index, r_blend_next);
72}
73
74static void rna_PoseBone_bbone_segment_matrix(
75 bPoseChannel *pchan, ReportList *reports, float mat_ret[16], int index, bool rest)
76{
77 if (!pchan->bone || pchan->bone->segments <= 1) {
78 BKE_reportf(reports, RPT_ERROR, "Bone '%s' is not a B-Bone!", pchan->name);
79 return;
80 }
81 if (pchan->runtime.bbone_segments != pchan->bone->segments) {
82 BKE_reportf(reports,
84 "Bone '%s' has out of date B-Bone segment data - depsgraph update required!",
85 pchan->name);
86 return;
87 }
88 if (index < 0 || index > pchan->runtime.bbone_segments) {
90 reports, RPT_ERROR, "Invalid index %d for B-Bone segments of '%s'!", index, pchan->name);
91 return;
92 }
93
94 if (rest) {
95 copy_m4_m4((float(*)[4])mat_ret, pchan->runtime.bbone_rest_mats[index].mat);
96 }
97 else {
98 copy_m4_m4((float(*)[4])mat_ret, pchan->runtime.bbone_pose_mats[index].mat);
99 }
100}
101
102static void rna_PoseBone_compute_bbone_handles(bPoseChannel *pchan,
103 ReportList *reports,
104 float ret_h1[3],
105 float *ret_roll1,
106 float ret_h2[3],
107 float *ret_roll2,
108 bool rest,
109 bool ease,
110 bool offsets)
111{
112 if (!pchan->bone || pchan->bone->segments <= 1) {
113 BKE_reportf(reports, RPT_ERROR, "Bone '%s' is not a B-Bone!", pchan->name);
114 return;
115 }
116
118
121 &params, ret_h1, ret_roll1, ret_h2, ret_roll2, ease || offsets, offsets);
122}
123
124static void rna_Pose_apply_pose_from_action(ID *pose_owner,
125 bContext *C,
126 bAction *action,
127 const float evaluation_time)
128{
129 BLI_assert(GS(pose_owner->name) == ID_OB);
130 Object *pose_owner_ob = (Object *)pose_owner;
131
132 const animrig::slot_handle_t slot_handle = animrig::first_slot_handle(*action);
133
134 AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time};
136 pose_owner_ob, action, slot_handle, &anim_eval_context);
137
138 /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */
140 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner);
141}
142
143static void rna_Pose_blend_pose_from_action(ID *pose_owner,
144 bContext *C,
145 bAction *action,
146 const float blend_factor,
147 const float evaluation_time)
148{
149 BLI_assert(GS(pose_owner->name) == ID_OB);
150 Object *pose_owner_ob = (Object *)pose_owner;
151
153
154 AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time};
156 pose_owner_ob, action, slot_handle, &anim_eval_context, blend_factor);
157
158 /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */
160 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner);
161}
162
163static void rna_Pose_backup_create(ID *pose_owner, bAction *action)
164{
165 BLI_assert(GS(pose_owner->name) == ID_OB);
166 Object *pose_owner_ob = (Object *)pose_owner;
167
168 BKE_pose_backup_create_on_object(pose_owner_ob, action);
169}
170
171static bool rna_Pose_backup_restore(ID *pose_owner, bContext *C)
172{
173 BLI_assert(GS(pose_owner->name) == ID_OB);
174 Object *pose_owner_ob = (Object *)pose_owner;
175
176 const bool success = BKE_pose_backup_restore_on_object(pose_owner_ob);
177 if (!success) {
178 return false;
179 }
180
181 /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */
183 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner);
184
185 return true;
186}
187
188static void rna_Pose_backup_clear(ID *pose_owner)
189{
190 BLI_assert(GS(pose_owner->name) == ID_OB);
191 Object *pose_owner_ob = (Object *)pose_owner;
192
193 BKE_pose_backup_clear(pose_owner_ob);
194}
195
196#else
197
199{
200 FunctionRNA *func;
201 PropertyRNA *parm;
202
203 func = RNA_def_function(srna, "apply_pose_from_action", "rna_Pose_apply_pose_from_action");
206 func,
207 "Apply the given action to this pose by evaluating it at a specific time. Only updates the "
208 "pose of selected bones, or all bones if none are selected.");
209 parm = RNA_def_pointer(func, "action", "Action", "Action", "The Action containing the pose");
211 parm = RNA_def_float(func,
212 "evaluation_time",
213 0.0f,
214 -FLT_MAX,
215 FLT_MAX,
216 "Evaluation Time",
217 "Time at which the given action is evaluated to obtain the pose",
218 -FLT_MAX,
219 FLT_MAX);
220
221 func = RNA_def_function(srna, "blend_pose_from_action", "rna_Pose_blend_pose_from_action");
224 "Blend the given action into this pose by evaluating it at a "
225 "specific time. Only updates the "
226 "pose of selected bones, or all bones if none are selected.");
227 parm = RNA_def_pointer(func, "action", "Action", "Action", "The Action containing the pose");
229 RNA_def_float(func,
230 "blend_factor",
231 1.0f,
232 0.0f,
233 1.0f,
234 "Blend Factor",
235 "How much the given Action affects the final pose",
236 0.0f,
237 1.0f);
238 RNA_def_float(func,
239 "evaluation_time",
240 0.0f,
241 -FLT_MAX,
242 FLT_MAX,
243 "Evaluation Time",
244 "Time at which the given action is evaluated to obtain the pose",
245 -FLT_MAX,
246 FLT_MAX);
247
248 func = RNA_def_function(srna, "backup_create", "rna_Pose_backup_create");
250 func,
251 "Create a backup of the current pose. Only those bones that are animated in the Action are "
252 "backed up. The object owns the backup, and each object can have only one backup at a time. "
253 "When you no longer need it, it must be freed use `backup_clear()`.");
255 parm = RNA_def_pointer(func,
256 "action",
257 "Action",
258 "Action",
259 "An Action with animation data for the bones. "
260 "Only the animated bones will be included in the backup.");
262
263 func = RNA_def_function(srna, "backup_restore", "rna_Pose_backup_restore");
266 func,
267 "Restore the previously made pose backup. "
268 "This can be called multiple times. See `Pose.backup_create()` for more info.");
269 /* return value */
270 parm = RNA_def_boolean(
271 func,
272 "success",
273 false,
274 "",
275 "`True` when the backup was restored, `False` if there was no backup to restore");
276 RNA_def_function_return(func, parm);
277
278 func = RNA_def_function(srna, "backup_clear", "rna_Pose_backup_clear");
280 func, "Free a previously made pose backup. See `Pose.backup_create()` for more info.");
282}
283
285{
286 PropertyRNA *parm;
287 FunctionRNA *func;
288
289 func = RNA_def_function(srna, "evaluate_envelope", "rna_PoseBone_do_envelope");
290 RNA_def_function_ui_description(func, "Calculate bone envelope at given point");
291 parm = RNA_def_float_vector_xyz(func,
292 "point",
293 3,
294 nullptr,
295 -FLT_MAX,
296 FLT_MAX,
297 "Point",
298 "Position in 3d space to evaluate",
299 -FLT_MAX,
300 FLT_MAX);
302 /* return value */
303 parm = RNA_def_float(
304 func, "factor", 0, -FLT_MAX, FLT_MAX, "Factor", "Envelope factor", -FLT_MAX, FLT_MAX);
305 RNA_def_function_return(func, parm);
306
307 /* B-Bone segment index from point */
308 func = RNA_def_function(srna, "bbone_segment_index", "rna_PoseBone_bbone_segment_index");
311 func, "Retrieve the index and blend factor of the B-Bone segments based on vertex position");
312 parm = RNA_def_float_vector_xyz(func,
313 "point",
314 3,
315 nullptr,
316 -FLT_MAX,
317 FLT_MAX,
318 "Point",
319 "Vertex position in armature pose space",
320 -FLT_MAX,
321 FLT_MAX);
323 /* outputs */
324 parm = RNA_def_property(func, "index", PROP_INT, PROP_NONE);
325 RNA_def_property_ui_text(parm, "", "The index of the first segment joint affecting the point");
326 RNA_def_function_output(func, parm);
327 parm = RNA_def_property(func, "blend_next", PROP_FLOAT, PROP_NONE);
328 RNA_def_property_ui_text(parm, "", "The blend factor between the given and the following joint");
329 RNA_def_function_output(func, parm);
330
331 /* B-Bone segment matrices */
332 func = RNA_def_function(srna, "bbone_segment_matrix", "rna_PoseBone_bbone_segment_matrix");
334 func, "Retrieve the matrix of the joint between B-Bone segments if available");
336 parm = RNA_def_property(func, "matrix_return", PROP_FLOAT, PROP_MATRIX);
338 RNA_def_property_ui_text(parm, "", "The resulting matrix in bone local space");
339 RNA_def_function_output(func, parm);
340 parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the segment endpoint", 0, 10000);
342 parm = RNA_def_boolean(func, "rest", false, "", "Return the rest pose matrix");
343
344 /* B-Bone custom handle positions */
345 func = RNA_def_function(srna, "compute_bbone_handles", "rna_PoseBone_compute_bbone_handles");
347 func, "Retrieve the vectors and rolls coming from B-Bone custom handles");
349 parm = RNA_def_property(func, "handle1", PROP_FLOAT, PROP_XYZ);
350 RNA_def_property_array(parm, 3);
352 parm, "", "The direction vector of the start handle in bone local space");
353 RNA_def_function_output(func, parm);
354 parm = RNA_def_float(
355 func, "roll1", 0, -FLT_MAX, FLT_MAX, "", "Roll of the start handle", -FLT_MAX, FLT_MAX);
356 RNA_def_function_output(func, parm);
357 parm = RNA_def_property(func, "handle2", PROP_FLOAT, PROP_XYZ);
358 RNA_def_property_array(parm, 3);
359 RNA_def_property_ui_text(parm, "", "The direction vector of the end handle in bone local space");
360 RNA_def_function_output(func, parm);
361 parm = RNA_def_float(
362 func, "roll2", 0, -FLT_MAX, FLT_MAX, "", "Roll of the end handle", -FLT_MAX, FLT_MAX);
363 RNA_def_function_output(func, parm);
364 parm = RNA_def_boolean(func, "rest", false, "", "Return the rest pose state");
365 parm = RNA_def_boolean(func, "ease", false, "", "Apply scale from ease values");
366 parm = RNA_def_boolean(
367 func, "offsets", false, "", "Apply roll and curve offsets from bone properties");
368}
369
370#endif
Functions and classes to work with Actions.
Functions to work with animation poses.
void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan, const float *co, int *r_index, float *r_blend_next)
Definition armature.cc:1970
void BKE_pchan_bbone_spline_params_get(bPoseChannel *pchan, bool rest, BBoneSplineParameters *param)
Definition armature.cc:1087
float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist)
void BKE_pchan_bbone_handles_compute(const BBoneSplineParameters *param, float h1[3], float *r_roll1, float h2[3], float *r_roll2, bool ease, bool offsets)
Definition armature.cc:1346
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
void BKE_pose_backup_create_on_object(struct Object *ob, const struct bAction *action)
void BKE_pose_backup_clear(struct Object *ob)
bool BKE_pose_backup_restore_on_object(struct Object *ob)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:50
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_OB
@ BONE_MULT_VG_ENV
Object is a sort of wrapper for general info.
@ PARM_REQUIRED
Definition RNA_types.hh:397
@ FUNC_USE_REPORTS
Definition RNA_types.hh:680
@ FUNC_NO_SELF
Definition RNA_types.hh:673
@ FUNC_USE_CONTEXT
Definition RNA_types.hh:679
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:667
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_INT
Definition RNA_types.hh:66
PropertyFlag
Definition RNA_types.hh:201
@ PROP_MATRIX
Definition RNA_types.hh:168
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_NONE
Definition RNA_types.hh:136
#define ND_POSE
Definition WM_types.hh:425
#define NC_OBJECT
Definition WM_types.hh:346
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition iris.cc:202
slot_handle_t first_slot_handle(const ::bAction &dna_action)
void pose_apply_action_selected_bones(Object *ob, bAction *action, slot_handle_t slot_handle, const AnimationEvalContext *anim_eval_context)
decltype(::ActionSlot::handle) slot_handle_t
void pose_apply_action_blend(Object *ob, bAction *action, slot_handle_t slot_handle, const AnimationEvalContext *anim_eval_context, float blend_factor)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
PropertyRNA * RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
void RNA_def_property_array(PropertyRNA *prop, int length)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
const int rna_matrix_dimsize_4x4[]
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_function_flag(FunctionRNA *func, int flag)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_function_output(FunctionRNA *, PropertyRNA *ret)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_api_pose(StructRNA *srna)
void RNA_api_pose_channel(StructRNA *srna)
#define FLT_MAX
Definition stdcycles.h:14
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
float mat[4][4]
struct Mat4 * bbone_pose_mats
struct Mat4 * bbone_rest_mats
struct Bone * bone
struct bPoseChannel_Runtime runtime
void WM_event_add_notifier(const bContext *C, uint type, void *reference)