diff --git a/source/blender/animrig/ANIM_pose.hh b/source/blender/animrig/ANIM_pose.hh new file mode 100644 index 00000000000..d414e8630ad --- /dev/null +++ b/source/blender/animrig/ANIM_pose.hh @@ -0,0 +1,37 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup animrig + * + * \brief Functions to work with animation poses. + */ + +#pragma once + +struct AnimationEvalContext; +struct Object; +struct bAction; + +namespace blender::animrig { + +/** + * Evaluate the action and apply it to the pose. If any pose bones are selected, only FCurves that + * relate to those bones are evaluated. + */ +void pose_apply_action_selected_bones(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context); +/** + * Evaluate the action and apply it to the pose. Ignore selection state of the bones. + */ +void pose_apply_action_all_bones(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context); + +void pose_apply_action_blend(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context, + float blend_factor); +} // namespace blender::animrig diff --git a/source/blender/animrig/CMakeLists.txt b/source/blender/animrig/CMakeLists.txt index 83e0999640e..d9b69dc1195 100644 --- a/source/blender/animrig/CMakeLists.txt +++ b/source/blender/animrig/CMakeLists.txt @@ -34,6 +34,7 @@ set(SRC intern/fcurve.cc intern/keyframing.cc intern/keyframing_auto.cc + intern/pose.cc intern/visualkey.cc ANIM_action.hh @@ -48,6 +49,7 @@ set(SRC ANIM_fcurve.hh ANIM_keyframing.hh ANIM_keyingsets.hh + ANIM_pose.hh ANIM_rna.hh ANIM_visualkey.hh intern/action_runtime.hh diff --git a/source/blender/blenkernel/intern/armature_pose.cc b/source/blender/animrig/intern/pose.cc similarity index 63% rename from source/blender/blenkernel/intern/armature_pose.cc rename to source/blender/animrig/intern/pose.cc index fa8fca4ecc3..ee2d42e9987 100644 --- a/source/blender/blenkernel/intern/armature_pose.cc +++ b/source/blender/animrig/intern/pose.cc @@ -1,79 +1,45 @@ -/* SPDX-FileCopyrightText: 2015 Blender Authors +/* SPDX-FileCopyrightText: 2024 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ /** \file - * \ingroup bke + * \ingroup animrig */ +#include "ANIM_pose.hh" #include "BKE_action.hh" #include "BKE_animsys.h" #include "BKE_armature.hh" - -#include "BLI_function_ref.hh" -#include "BLI_set.hh" - -#include "DNA_action_types.h" +#include "BLI_listbase.h" #include "DNA_anim_types.h" -#include "DNA_armature_types.h" #include "DNA_object_types.h" - #include "RNA_access.hh" -using namespace blender::bke; - namespace { using ActionApplier = blender::FunctionRef; -/* Forward declarations. */ -void pose_apply_disable_fcurves_for_unselected_bones(bAction *action, - const BoneNameSet &selected_bone_names); -void pose_apply_restore_fcurves(bAction *action); - -void pose_apply(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context, - ActionApplier applier); - -} // namespace - -void BKE_pose_apply_action_selected_bones(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context) +void pose_apply_restore_fcurves(bAction *action) { - auto evaluate_and_apply = - [](PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context) { - animsys_evaluate_action(ptr, act, anim_eval_context, false); - }; - - pose_apply(ob, action, anim_eval_context, evaluate_and_apply); + /* TODO(Sybren): Restore the FCurve flags, instead of just erasing the 'disabled' flag. */ + LISTBASE_FOREACH (FCurve *, fcu, &action->curves) { + fcu->flag &= ~FCURVE_DISABLED; + } } -void BKE_pose_apply_action_all_bones(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context) +void pose_apply_disable_fcurves_for_unselected_bones( + bAction *action, const blender::bke::BoneNameSet &selected_bone_names) { - PointerRNA pose_owner_ptr = RNA_id_pointer_create(&ob->id); - animsys_evaluate_action(&pose_owner_ptr, action, anim_eval_context, false); -} - -void BKE_pose_apply_action_blend(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context, - const float blend_factor) -{ - auto evaluate_and_blend = [blend_factor](PointerRNA *ptr, - bAction *act, - const AnimationEvalContext *anim_eval_context) { - animsys_blend_in_action(ptr, act, anim_eval_context, blend_factor); + auto disable_unselected_fcurve = [&](FCurve *fcu, const char *bone_name) { + const bool is_bone_selected = selected_bone_names.contains(bone_name); + if (!is_bone_selected) { + fcu->flag |= FCURVE_DISABLED; + } }; - - pose_apply(ob, action, anim_eval_context, evaluate_and_blend); + blender::bke::BKE_action_find_fcurves_with_bones(action, disable_unselected_fcurve); } -namespace { void pose_apply(Object *ob, bAction *action, const AnimationEvalContext *anim_eval_context, @@ -85,7 +51,8 @@ void pose_apply(Object *ob, } const bArmature *armature = (bArmature *)ob->data; - const BoneNameSet selected_bone_names = BKE_armature_find_selected_bone_names(armature); + const blender::bke::BoneNameSet selected_bone_names = + blender::bke::BKE_armature_find_selected_bone_names(armature); const bool limit_to_selected_bones = !selected_bone_names.is_empty(); if (limit_to_selected_bones) { @@ -104,24 +71,42 @@ void pose_apply(Object *ob, } } -void pose_apply_restore_fcurves(bAction *action) -{ - /* TODO(Sybren): Restore the FCurve flags, instead of just erasing the 'disabled' flag. */ - LISTBASE_FOREACH (FCurve *, fcu, &action->curves) { - fcu->flag &= ~FCURVE_DISABLED; - } -} - -void pose_apply_disable_fcurves_for_unselected_bones(bAction *action, - const BoneNameSet &selected_bone_names) -{ - auto disable_unselected_fcurve = [&](FCurve *fcu, const char *bone_name) { - const bool is_bone_selected = selected_bone_names.contains(bone_name); - if (!is_bone_selected) { - fcu->flag |= FCURVE_DISABLED; - } - }; - BKE_action_find_fcurves_with_bones(action, disable_unselected_fcurve); -} - } // namespace + +namespace blender::animrig { + +void pose_apply_action_selected_bones(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context) +{ + auto evaluate_and_apply = + [](PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context) { + animsys_evaluate_action(ptr, act, anim_eval_context, false); + }; + + pose_apply(ob, action, anim_eval_context, evaluate_and_apply); +} + +void pose_apply_action_all_bones(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context) +{ + PointerRNA pose_owner_ptr = RNA_id_pointer_create(&ob->id); + animsys_evaluate_action(&pose_owner_ptr, action, anim_eval_context, false); +} + +void pose_apply_action_blend(Object *ob, + bAction *action, + const AnimationEvalContext *anim_eval_context, + const float blend_factor) +{ + auto evaluate_and_blend = [blend_factor](PointerRNA *ptr, + bAction *act, + const AnimationEvalContext *anim_eval_context) { + animsys_blend_in_action(ptr, act, anim_eval_context, blend_factor); + }; + + pose_apply(ob, action, anim_eval_context, evaluate_and_blend); +} + +} // namespace blender::animrig diff --git a/source/blender/blenkernel/BKE_armature.hh b/source/blender/blenkernel/BKE_armature.hh index 10f343d14c2..a7682b85f4d 100644 --- a/source/blender/blenkernel/BKE_armature.hh +++ b/source/blender/blenkernel/BKE_armature.hh @@ -281,25 +281,6 @@ void BKE_pose_where_is_bone(Depsgraph *depsgraph, */ void BKE_pose_where_is_bone_tail(bPoseChannel *pchan); -/** - * Evaluate the action and apply it to the pose. If any pose bones are selected, only FCurves that - * relate to those bones are evaluated. - */ -void BKE_pose_apply_action_selected_bones(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context); -/** - * Evaluate the action and apply it to the pose. Ignore selection state of the bones. - */ -void BKE_pose_apply_action_all_bones(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context); - -void BKE_pose_apply_action_blend(Object *ob, - bAction *action, - const AnimationEvalContext *anim_eval_context, - float blend_factor); - void vec_roll_to_mat3(const float vec[3], float roll, float r_mat[3][3]); /** diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 12c8554e156..d5960ede11d 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -58,7 +58,6 @@ set(SRC intern/appdir.cc intern/armature.cc intern/armature_deform.cc - intern/armature_pose.cc intern/armature_selection.cc intern/armature_update.cc intern/asset.cc diff --git a/source/blender/editors/armature/pose_lib_2.cc b/source/blender/editors/armature/pose_lib_2.cc index fd1d106c0cc..269046f4876 100644 --- a/source/blender/editors/armature/pose_lib_2.cc +++ b/source/blender/editors/armature/pose_lib_2.cc @@ -49,6 +49,7 @@ #include "ANIM_bone_collections.hh" #include "ANIM_keyframing.hh" #include "ANIM_keyingsets.hh" +#include "ANIM_pose.hh" #include "armature_intern.hh" @@ -193,7 +194,8 @@ static void poselib_blend_apply(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, 0.0f); bAction *to_blend = poselib_action_to_blend(pbd); - BKE_pose_apply_action_blend(pbd->ob, to_blend, &anim_eval_context, pbd->blend_factor); + blender::animrig::pose_apply_action_blend( + pbd->ob, to_blend, &anim_eval_context, pbd->blend_factor); } /* ---------------------------- */ diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt index 942e35e7cc4..5792010ef53 100644 --- a/source/blender/editors/render/CMakeLists.txt +++ b/source/blender/editors/render/CMakeLists.txt @@ -41,6 +41,7 @@ set(LIB PRIVATE bf::dna bf_draw PRIVATE bf::intern::guardedalloc + PRIVATE bf::animrig ) if(WITH_HEADLESS) diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 7ab007414ef..badecb76920 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -97,6 +97,8 @@ #include "UI_interface_icons.hh" +#include "ANIM_pose.hh" + #ifndef NDEBUG /* Used for database init assert(). */ # include "BLI_threads.h" @@ -963,7 +965,7 @@ static PoseBackup *action_preview_render_prepare(IconPreview *preview) /* Apply the Action as pose, so that it can be rendered. This assumes the Action represents a * single pose, and that thus the evaluation time doesn't matter. */ AnimationEvalContext anim_eval_context = {preview->depsgraph, 0.0f}; - BKE_pose_apply_action_all_bones(object, action, &anim_eval_context); + blender::animrig::pose_apply_action_all_bones(object, action, &anim_eval_context); /* Force evaluation of the new pose, before the preview is rendered. */ DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); diff --git a/source/blender/makesrna/intern/rna_pose_api.cc b/source/blender/makesrna/intern/rna_pose_api.cc index 1cbfe50f107..f7db3842fa1 100644 --- a/source/blender/makesrna/intern/rna_pose_api.cc +++ b/source/blender/makesrna/intern/rna_pose_api.cc @@ -34,6 +34,8 @@ # include "BLI_ghash.h" +# include "ANIM_pose.hh" + static float rna_PoseBone_do_envelope(bPoseChannel *chan, const float vec[3]) { Bone *bone = chan->bone; @@ -125,7 +127,7 @@ static void rna_Pose_apply_pose_from_action(ID *pose_owner, Object *pose_owner_ob = (Object *)pose_owner; AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time}; - BKE_pose_apply_action_selected_bones(pose_owner_ob, action, &anim_eval_context); + blender::animrig::pose_apply_action_selected_bones(pose_owner_ob, action, &anim_eval_context); /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */ DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY); @@ -142,7 +144,8 @@ static void rna_Pose_blend_pose_from_action(ID *pose_owner, Object *pose_owner_ob = (Object *)pose_owner; AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time}; - BKE_pose_apply_action_blend(pose_owner_ob, action, &anim_eval_context, blend_factor); + blender::animrig::pose_apply_action_blend( + pose_owner_ob, action, &anim_eval_context, blend_factor); /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */ DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY);