42#include "RNA_prototypes.hh"
92 ob =
static_cast<Object *
>(ob->id.next))
95 if ((ob->parent == armob) && (ob->partype ==
PARBONE)) {
108 const float pose_mat[4][4],
109 const float new_tail[3],
110 float r_new_arm_mat[4][4])
121 float premat[3][3], pmat[3][3];
176 pchan->
size[0] = pchan->
size[1] = pchan->
size[2] = 1.0f;
182 const float delta_mat[4][4],
183 float r_new_arm_mat[4][4])
186 float delta[3], new_tail[3], premat[3][3], new_pose[4][4];
221 if (!pchan || !pchan_eval) {
226 new_pstate.
bone = bone;
228 if (std::find_if(selected.begin(), selected.end(), [&](
const PointerRNA &
ptr) {
229 return ptr.data == pchan;
230 }) != selected.end())
245 float offs_bone[4][4];
276 mul_m4_v3(new_pstate.new_rest_mat, new_tail);
279 curbone, new_pstate.new_rest_mat, new_tail, new_pstate.new_arm_mat);
282 pstate = &new_pstate;
295 float offs_bone[4][4], delta[4][4], old_chan_loc[3];
306 unit_m4(new_pstate.new_rest_mat);
314 mul_m4_m4m4(delta, new_pstate.new_rest_mat, delta);
321 float inv_parent_arm[4][4];
325 mul_m4_m4m4(offs_bone, inv_parent_arm, new_pstate.new_arm_mat);
338 pstate = &new_pstate;
352 switch (constraint->
type) {
379 if (use_selected && (pchan->bone->flag &
BONE_SELECTED) == 0) {
415 "Actions on this armature will be destroyed by this new rest pose as the "
416 "transforms stored are relative to the old rest pose");
438 arm, pose, ob_eval->
pose, bone, selected_bones,
nullptr);
485 ot->
name =
"Apply Pose as Rest Pose";
486 ot->
idname =
"POSE_OT_armature_apply";
487 ot->
description =
"Apply the current pose as the new rest pose";
501 "Only apply the selected bones (with propagation to children)");
531 } *pchan_xform_array =
static_cast<XFormArray *
>(
532 MEM_mallocN(
sizeof(*pchan_xform_array) * chanbase_len, __func__));
533 bool changed =
false;
538 pchan_xform_array[i].is_set =
false;
552 pchan_xform_array[i].is_set =
true;
559 if (!pchan_xform_array[i].is_set) {
581 ot->
name =
"Apply Visual Transform to Pose";
582 ot->
idname =
"POSE_OT_visual_transform_apply";
583 ot->
description =
"Apply final constrained position of pose bones to their transform";
608 Bone *bone = chan->bone;
613 chan->flag &= ~POSE_KEY;
649 if (pchan ==
nullptr) {
795 PartialWriteContext::IDAddOperations::MAKE_LOCAL |
796 PartialWriteContext::IDAddOperations::SET_FAKE_USER |
797 PartialWriteContext::IDAddOperations::SET_CLIPBOARD_MARK)},
801 if (*(cb_data->id_pointer) == ob->data) {
802 return PartialWriteContext::IDAddOperations(
803 PartialWriteContext::IDAddOperations::MAKE_LOCAL |
804 PartialWriteContext::IDAddOperations::ADD_DEPENDENCIES);
806 return PartialWriteContext::IDAddOperations::CLEAR_DEPENDENCIES;
811 copybuffer.write(filepath, *op->reports);
823 ot->
description =
"Copy the current pose of the selected bones to the internal clipboard";
874 if (pose_from ==
nullptr) {
897 if (pchan !=
nullptr) {
926 ot->
description =
"Paste the stored pose on to the current pose";
940 "Paste the stored pose flipped on to current pose");
947 "Only paste the stored pose on to selected bones in the current pose");
960 pchan->
size[0] = 1.0f;
963 pchan->
size[1] = 1.0f;
966 pchan->
size[2] = 1.0f;
981 if (pchan_mirror !=
nullptr) {
992 pchan->
loc[0] = 0.0f;
995 pchan->
loc[1] = 0.0f;
998 pchan->
loc[2] = 0.0f;
1007 if (pchan_mirror !=
nullptr) {
1045 pchan->
quat[0] = 1.0f;
1048 pchan->
quat[1] = 0.0f;
1051 pchan->
quat[2] = 0.0f;
1054 pchan->
quat[3] = 0.0f;
1060 pchan->
eul[0] = 0.0f;
1063 pchan->
eul[1] = 0.0f;
1066 pchan->
eul[2] = 0.0f;
1072 float eul[3], oldeul[3], quat1[4] = {0};
1086 eul[0] = eul[1] = eul[2] = 0.0f;
1105 if ((quat1[0] < 0.0f && pchan->
quat[0] > 0.0f) ||
1106 (quat1[0] > 0.0f && pchan->
quat[0] < 0.0f))
1134 pchan->
roll1 = 0.0f;
1135 pchan->
roll2 = 0.0f;
1148 if (pchan_mirror !=
nullptr) {
1169 const char default_ksName[])
1173 bool changed_multi =
false;
1176 if (
ELEM(
nullptr, clear_func, default_ksName)) {
1179 "Programming error: missing clear transform function or keying set name");
1190 bool changed =
false;
1194 clear_func(ob_iter->pose, pchan);
1204 clear_func(ob_iter->pose, pchan_eval);
1211 changed_multi =
true;
1254 ot->
name =
"Clear Pose Scale";
1255 ot->
idname =
"POSE_OT_scale_clear";
1256 ot->
description =
"Reset scaling of selected bones to their default values";
1281 ot->
name =
"Clear Pose Rotation";
1283 ot->
description =
"Reset rotations of selected bones to their default values";
1308 ot->
name =
"Clear Pose Location";
1310 ot->
description =
"Reset locations of selected bones to their default values";
1335 ot->
name =
"Clear Pose Transforms";
1336 ot->
idname =
"POSE_OT_transforms_clear";
1338 "Reset location, rotation, and scaling of selected bones to their default values";
1365 if ((ob->adt) && (ob->adt->action)) {
1369 bPose *dummyPose =
nullptr;
1375 STRNCPY(workob.id.name,
"OB<ClearTfmWorkOb>");
1377 workob.data = ob->data;
1378 workob.adt = ob->adt;
1379 workob.pose = dummyPose;
1417 ot->
name =
"Clear User Transforms";
1418 ot->
idname =
"POSE_OT_user_transforms_clear";
1419 ot->
description =
"Reset pose bone transforms to keyframed state";
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bone_in_visible_collection(const bArmature *armature, const Bone *bone)
Functions to insert, delete or modify keyframes.
Functionality to interact with keying sets.
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bPoseChannel * BKE_pose_channel_get_mirrored(const bPose *pose, const char *name) ATTR_WARN_UNUSED_RESULT
void BKE_pose_copy_data(bPose **dst, const bPose *src, bool copy_constraints)
void BKE_pose_rest(bPose *pose, bool selected_bones_only)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, bool flush_to_original)
const char * BKE_tempdir_base() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
bArmature * BKE_armature_from_object(Object *ob)
void BKE_bone_parent_transform_clear(BoneParentTransform *bpt)
void BKE_bone_parent_transform_combine(const BoneParentTransform *in1, const BoneParentTransform *in2, BoneParentTransform *result)
void BKE_bone_parent_transform_invert(BoneParentTransform *bpt)
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
void BKE_pchan_apply_mat4(bPoseChannel *pchan, const float mat[4][4], bool use_compat)
void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END
#define PBONE_VISIBLE(arm, bone)
void BKE_bone_parent_transform_apply(const BoneParentTransform *bpt, const float inmat[4][4], float outmat[4][4])
void vec_roll_to_mat3(const float vec[3], float roll, float r_mat[3][3])
void BKE_pose_where_is(Depsgraph *depsgraph, Scene *scene, Object *ob)
void BKE_bone_parent_transform_calc_from_matrices(int bone_flag, int inherit_scale_mode, const float offs_bone[4][4], const float parent_arm_mat[4][4], const float parent_pose_mat[4][4], BoneParentTransform *r_bpt)
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan)
void BKE_bone_offset_matrix_get(const Bone *bone, float offs_bone[4][4])
bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports, uint64_t id_types_mask)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
#define CTX_DATA_COUNT(C, member)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
bool CTX_data_selected_pose_bones(const bContext *C, blender::Vector< PointerRNA > *list)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void IDP_FreeProperty(IDProperty *prop)
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src) ATTR_NONNULL()
#define FOREACH_OBJECT_IN_MODE_END
#define FOREACH_OBJECT_IN_MODE_BEGIN(_scene, _view_layer, _v3d, _object_type, _object_mode, _instance)
Main * BKE_main_new(void)
void BKE_main_free(Main *bmain)
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
const char * BKE_main_blendfile_path_from_global()
General operations, lookup, etc. for blender objects.
blender::float4x4 BKE_object_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *ob)
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
Object * BKE_object_pose_armature_get(Object *ob)
bool BKE_object_obdata_is_libdata(const Object *ob)
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
void unit_m4(float m[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
bool invert_m4(float mat[4][4])
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void quat_to_eulO(float e[3], short order, const float q[4])
float normalize_qt(float q[4])
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order)
void mul_qt_fl(float q[4], float f)
void eulO_to_quat(float q[4], const float e[3], short order)
void eul_to_quat(float quat[4], const float eul[3])
void quat_to_eul(float eul[3], const float quat[4])
float normalize_qt_qt(float r[4], const float q[4])
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle)
void unit_axis_angle(float axis[3], float *angle)
void copy_qt_qt(float q[4], const float a[4])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
#define BLI_path_join(...)
#define STRNCPY(dst, src)
size_t BLI_string_flip_side_name(char *name_dst, const char *name_src, bool strip_number, size_t name_dst_maxncpy) ATTR_NONNULL(1
void DEG_id_tag_update(ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ MOTIONPATH_BAKE_HAS_PATHS
@ CONSTRAINT_TYPE_STRETCHTO
Object is a sort of wrapper for general info.
@ POSE_PATH_CALC_RANGE_FULL
#define ANIM_KS_LOC_ROT_SCALE_ID
#define ANIM_KS_LOCATION_ID
#define ANIM_KS_WHOLE_CHARACTER_ID
#define ANIM_KS_SCALING_ID
#define ANIM_KS_ROTATION_ID
bool ED_operator_posemode(bContext *C)
Read Guarded memory(de)allocation.
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
void ED_armature_edit_free(bArmature *arm)
void ED_armature_from_edit(Main *bmain, bArmature *arm)
void ED_armature_to_edit(bArmature *arm)
ID * id_add(const ID *id, IDAddOptions options, blender::FunctionRef< IDAddOperations(LibraryIDLinkCallbackData *cb_data, IDAddOptions options)> dependencies_filter_cb=nullptr)
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void ANIM_relative_keyingset_add_source(blender::Vector< PointerRNA > &sources, ID *id, StructRNA *srna, void *data)
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
int ANIM_apply_keyingset(bContext *C, blender::Vector< PointerRNA > *sources, KeyingSet *keyingset, const blender::animrig::ModifyKeyMode mode, const float cfra)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathCalcRange range)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
struct bPoseChannel * parent
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* ui)(bContext *C, wmOperator *op)
struct ReportList * reports
struct wmOperatorType * type
void WM_event_add_notifier(const bContext *C, uint type, void *reference)