Files
workinf_Blender_Wasm/blender-5.2.0/source/blender/animrig/ANIM_armature.hh
2026-08-12 04:47:48 -04:00

108 lines
3.5 KiB
C++

/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup animrig
*
* \brief Functions to deal with Armatures.
*/
#pragma once
#include "ANIM_bone_collections.hh"
#include "BKE_pose.hh"
#include "DNA_armature_types.h"
namespace blender::animrig {
constexpr char bone_default_name[] = "Bone";
/**
* Returns true if the given Bone is visible. This includes bone collection visibility.
*/
inline bool bone_is_visible(const bArmature *armature, const Bone *bone)
{
const bool bone_itself_visible = (bone->flag & BONE_HIDDEN_P) == 0;
return bone_itself_visible && ANIM_bone_in_visible_collection(armature, bone);
}
inline bool bone_is_visible(const bArmature *armature, const bke::PChanBoneConst pchanbone)
{
const bool bone_itself_visible = (pchanbone.pchan->drawflag & PCHAN_DRAW_HIDDEN) == 0;
return bone_itself_visible && ANIM_bone_in_visible_collection(armature, pchanbone.bone);
}
inline bool bone_is_visible(const bArmature *armature, const EditBone *ebone)
{
const bool bone_itself_visible = (ebone->flag & BONE_HIDDEN_A) == 0;
return bone_itself_visible && ANIM_bonecoll_is_visible_editbone(armature, ebone);
}
/**
* Returns true if the bone is selected. This includes a visibility check
* because invisible bones cannot be selected, no matter their flag.
*/
inline bool bone_is_selected(const bArmature *armature, const Bone *bone)
{
return (bone->flag & BONE_SELECTED) && bone_is_visible(armature, bone);
}
inline bool bone_is_selected(const bArmature *armature, const bke::PChanBoneConst pchanbone)
{
return (pchanbone.pchan->flag & POSE_SELECTED) && bone_is_visible(armature, pchanbone);
}
inline bool bone_is_selected(const bArmature *armature, const EditBone *ebone)
{
return (ebone->flag & BONE_SELECTED) && bone_is_visible(armature, ebone);
}
inline bool bone_is_selectable(const bArmature *armature, const bke::PChanBoneConst pchanbone)
{
return bone_is_visible(armature, pchanbone) && !(pchanbone.bone->flag & BONE_UNSELECTABLE);
}
inline bool bone_is_selectable(const bArmature *armature, const bPoseChannel *pchan)
{
return bone_is_selectable(armature, {pchan, pchan->bone_get(*armature)});
}
inline bool bone_is_selectable(const bArmature *armature, const Bone *bone)
{
return bone_is_visible(armature, bone) && !(bone->flag & BONE_UNSELECTABLE);
}
/**
* Selection and deselection happens with the POSE_SELECTED_ALL flag which includes body tip and
* root. While tip and root are not individually selectable in pose mode, these flags carry over to
* edit mode.
*/
inline void bone_select(bPoseChannel *pchan)
{
pchan->flag |= POSE_SELECTED_ALL;
}
inline void bone_deselect(bPoseChannel *pchan)
{
pchan->flag &= ~POSE_SELECTED_ALL;
}
/**
* Iterates all descendents of the given pose bone including the bone itself. Iterates breadth
* first.
*/
void pose_bone_descendent_iterator(Object &pose_ob,
bPoseChannel &pchan,
FunctionRef<void(bPoseChannel &child_bone)> callback);
/**
* Iterates all descendents of the given pose bone depth first. The traversal for a branch is
* stopped if the callback returns false. Returns true if the iteration completed or false if it
* was stopped before visiting all bones.
*/
bool pose_bone_descendent_depth_iterator(Object &pose_ob,
bPoseChannel &pchan,
FunctionRef<bool(bPoseChannel &child_bone)> callback);
} // namespace blender::animrig