Anim: Store pose bone visibility flag on pose bone
This PR adds a flag to the pose bone that determines its visibility. Doing so allows to hide a pose bone and * don't affect other instances of the same armature * save the visibility even if the rig is linked The visibility of the bone in object mode is now also determined by the pose bone whereas before it was the `Bone`. **This breaks backwards compatibility** on the Python API since the visibility property, on the `Bone` behaves differently now as it hides the edit bone instead of the pose bone. In order to remove all active uses of `BONE_HIDDEN_P` the changes in `armature_skinning.cc` are required. Part of #138482 Pull Request: https://projects.blender.org/blender/blender/pulls/139167
This commit is contained in:
committed by
Christoph Lendenfeld
parent
6f57268e9a
commit
a43359eb88
@@ -323,17 +323,18 @@ class BONE_PT_display(BoneButtonsPanel, Panel):
|
||||
bone = context.bone
|
||||
|
||||
col = layout.column()
|
||||
col.prop(bone, "hide", text="Hide", toggle=False)
|
||||
# Figure out the pose bone.
|
||||
ob = context.object
|
||||
pose_bone = ob and ob.pose.bones[bone.name]
|
||||
hide_select_sub = col.column()
|
||||
hide_select_sub.active = not bone.hide
|
||||
if pose_bone:
|
||||
col.prop(pose_bone, "hide", text="Hide", toggle=False)
|
||||
hide_select_sub.active = not pose_bone.hide
|
||||
hide_select_sub.prop(bone, "hide_select", invert_checkbox=True)
|
||||
col.prop(bone, "display_type", text="Display As")
|
||||
|
||||
# Figure out the pose bone.
|
||||
ob = context.object
|
||||
if not ob:
|
||||
if not pose_bone:
|
||||
return
|
||||
pose_bone = ob.pose.bones[bone.name]
|
||||
|
||||
# Allow the layout to use the space normally occupied by the 'set a key' diamond.
|
||||
layout.use_property_decorate = False
|
||||
|
||||
@@ -27,7 +27,8 @@ inline bool bone_is_visible(const bArmature *armature, const Bone *bone)
|
||||
|
||||
inline bool bone_is_visible_pchan(const bArmature *armature, const bPoseChannel *pchan)
|
||||
{
|
||||
return bone_is_visible(armature, pchan->bone);
|
||||
const bool bone_itself_visible = (pchan->drawflag & PCHAN_DRAW_HIDDEN) == 0;
|
||||
return bone_itself_visible && ANIM_bone_in_visible_collection(armature, pchan->bone);
|
||||
}
|
||||
|
||||
inline bool bone_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
|
||||
@@ -55,4 +56,12 @@ inline bool bone_is_selected(const bArmature *armature, const EditBone *ebone)
|
||||
return (ebone->flag & BONE_SELECTED) && bone_is_visible_editbone(armature, ebone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates all descendents of the given pose bone including the bone itself. Iterates breadth
|
||||
* first.
|
||||
*/
|
||||
void pose_bone_descendent_iterator(bPose &pose,
|
||||
bPoseChannel &pose_bone,
|
||||
FunctionRef<void(bPoseChannel &child_bone)> callback);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
@@ -24,6 +24,7 @@ set(SRC
|
||||
intern/action_selection.cc
|
||||
intern/anim_rna.cc
|
||||
intern/animdata.cc
|
||||
intern/armature.cc
|
||||
intern/bone_collections.cc
|
||||
intern/bonecolor.cc
|
||||
intern/driver.cc
|
||||
|
||||
41
source/blender/animrig/intern/armature.cc
Normal file
41
source/blender/animrig/intern/armature.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*/
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include "ANIM_armature.hh"
|
||||
#include "BKE_action.hh"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
void pose_bone_descendent_iterator(bPose &pose,
|
||||
bPoseChannel &pose_bone,
|
||||
FunctionRef<void(bPoseChannel &child_bone)> callback)
|
||||
{
|
||||
/* Needed for fast name lookups. */
|
||||
BKE_pose_channels_hash_ensure(&pose);
|
||||
|
||||
std::deque<bPoseChannel *> to_visit = {&pose_bone};
|
||||
while (!to_visit.empty()) {
|
||||
bPoseChannel *descendant = to_visit.front();
|
||||
to_visit.pop_front();
|
||||
callback(*descendant);
|
||||
LISTBASE_FOREACH (Bone *, child_bone, &descendant->bone->childbase) {
|
||||
bPoseChannel *child_pose_bone = BKE_pose_channel_find_name(&pose, child_bone->name);
|
||||
if (!child_pose_bone) {
|
||||
/* Can happen if the pose is not rebuilt. */
|
||||
BLI_assert_unreachable();
|
||||
continue;
|
||||
}
|
||||
to_visit.push_back(child_pose_bone);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::animrig
|
||||
@@ -576,7 +576,7 @@ void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan,
|
||||
for (bPoseChannel *_pchan = (bPoseChannel *)(_ob)->pose->chanbase.first; _pchan; \
|
||||
_pchan = _pchan->next) \
|
||||
{ \
|
||||
if (blender::animrig::bone_is_visible(((bArmature *)(_ob)->data), (_pchan)->bone) && \
|
||||
if (blender::animrig::bone_is_visible_pchan(((bArmature *)(_ob)->data), _pchan) && \
|
||||
((_pchan)->bone->flag & BONE_SELECTED)) \
|
||||
{
|
||||
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END \
|
||||
@@ -588,7 +588,7 @@ void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan,
|
||||
for (bPoseChannel *_pchan = (bPoseChannel *)(_ob)->pose->chanbase.first; _pchan; \
|
||||
_pchan = _pchan->next) \
|
||||
{ \
|
||||
if (blender::animrig::bone_is_visible(((bArmature *)(_ob)->data), (_pchan)->bone)) {
|
||||
if (blender::animrig::bone_is_visible_pchan(((bArmature *)(_ob)->data), _pchan)) {
|
||||
#define FOREACH_PCHAN_VISIBLE_IN_OBJECT_END \
|
||||
} \
|
||||
} \
|
||||
|
||||
@@ -1585,6 +1585,22 @@ void do_versions_after_linking_500(FileData *fd, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 54)) {
|
||||
LISTBASE_FOREACH (Object *, object, &bmain->objects) {
|
||||
if (object->type != OB_ARMATURE) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (bPoseChannel *, pose_bone, &object->pose->chanbase) {
|
||||
if (pose_bone->bone->flag & BONE_HIDDEN_P) {
|
||||
pose_bone->drawflag |= PCHAN_DRAW_HIDDEN;
|
||||
}
|
||||
else {
|
||||
pose_bone->drawflag &= ~PCHAN_DRAW_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -2022,11 +2022,11 @@ void Armatures::draw_armature_pose(Armatures::DrawContext *ctx)
|
||||
for (bPoseChannel *pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan;
|
||||
pchan = pchan->next, index += 0x10000)
|
||||
{
|
||||
Bone *bone = pchan->bone;
|
||||
if (!blender::animrig::bone_is_visible(&arm, bone)) {
|
||||
if (!blender::animrig::bone_is_visible_pchan(&arm, pchan)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Bone *bone = pchan->bone;
|
||||
const bool draw_dofs = !is_pose_select && ctx->show_relations &&
|
||||
(ctx->draw_mode == ARM_DRAW_MODE_POSE) &&
|
||||
(bone->flag & BONE_SELECTED) &&
|
||||
@@ -2042,7 +2042,7 @@ void Armatures::draw_armature_pose(Armatures::DrawContext *ctx)
|
||||
}
|
||||
|
||||
eBone_Flag boneflag = eBone_Flag(bone->flag);
|
||||
if (bone->parent && !blender::animrig::bone_is_visible(&arm, bone->parent)) {
|
||||
if (pchan->parent && !blender::animrig::bone_is_visible_pchan(&arm, pchan->parent)) {
|
||||
/* Avoid drawing connection line to hidden parent. */
|
||||
boneflag &= ~BONE_CONNECTED;
|
||||
}
|
||||
|
||||
@@ -76,11 +76,14 @@ static int bone_skinnable_cb(Object * /*ob*/, Bone *bone, void *datap)
|
||||
bool is_weight_paint;
|
||||
} *data = static_cast<Arg *>(datap);
|
||||
|
||||
if (!(data->is_weight_paint) || !(bone->flag & BONE_HIDDEN_P)) {
|
||||
bPoseChannel *pose_bone = BKE_pose_channel_find_name(data->armob->pose, bone->name);
|
||||
if (!pose_bone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(data->is_weight_paint) || !(pose_bone->drawflag & PCHAN_DRAW_HIDDEN)) {
|
||||
if (!(bone->flag & BONE_NO_DEFORM)) {
|
||||
if (data->heat && data->armob->pose &&
|
||||
BKE_pose_channel_find_name(data->armob->pose, bone->name))
|
||||
{
|
||||
if (data->heat && data->armob->pose && pose_bone) {
|
||||
segments = bone->segments;
|
||||
}
|
||||
else {
|
||||
@@ -149,43 +152,49 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
|
||||
int heat;
|
||||
bool is_weight_paint;
|
||||
} *data = static_cast<Arg *>(datap);
|
||||
|
||||
if (bone->flag & BONE_NO_DEFORM) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bArmature *arm = static_cast<bArmature *>(data->armob->data);
|
||||
const bPoseChannel *pose_bone = BKE_pose_channel_find_name(data->armob->pose, bone->name);
|
||||
if (!pose_bone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data->is_weight_paint || !(bone->flag & BONE_HIDDEN_P)) {
|
||||
if (!(bone->flag & BONE_NO_DEFORM)) {
|
||||
if (data->heat && data->armob->pose &&
|
||||
BKE_pose_channel_find_name(data->armob->pose, bone->name))
|
||||
{
|
||||
segments = bone->segments;
|
||||
}
|
||||
else {
|
||||
segments = 1;
|
||||
}
|
||||
if (data->is_weight_paint && (pose_bone->drawflag & PCHAN_DRAW_HIDDEN)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data->is_weight_paint ||
|
||||
(ANIM_bone_in_visible_collection(arm, bone) && (bone->flag & BONE_SELECTED)))
|
||||
{
|
||||
if (!(defgroup = BKE_object_defgroup_find_name(ob, bone->name))) {
|
||||
defgroup = BKE_object_defgroup_add_name(ob, bone->name);
|
||||
}
|
||||
else if (defgroup->flag & DG_LOCK_WEIGHT) {
|
||||
/* In case vgroup already exists and is locked, do not modify it here. See #43814. */
|
||||
defgroup = nullptr;
|
||||
}
|
||||
}
|
||||
if (data->heat) {
|
||||
segments = bone->segments;
|
||||
}
|
||||
else {
|
||||
segments = 1;
|
||||
}
|
||||
|
||||
if (data->list != nullptr) {
|
||||
hgroup = (bDeformGroup ***)&data->list;
|
||||
|
||||
for (a = 0; a < segments; a++) {
|
||||
**hgroup = defgroup;
|
||||
(*hgroup)++;
|
||||
}
|
||||
}
|
||||
return segments;
|
||||
if (!data->is_weight_paint ||
|
||||
(ANIM_bone_in_visible_collection(arm, bone) && (bone->flag & BONE_SELECTED)))
|
||||
{
|
||||
if (!(defgroup = BKE_object_defgroup_find_name(ob, bone->name))) {
|
||||
defgroup = BKE_object_defgroup_add_name(ob, bone->name);
|
||||
}
|
||||
else if (defgroup->flag & DG_LOCK_WEIGHT) {
|
||||
/* In case vgroup already exists and is locked, do not modify it here. See #43814. */
|
||||
defgroup = nullptr;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (data->list != nullptr) {
|
||||
hgroup = (bDeformGroup ***)&data->list;
|
||||
|
||||
for (a = 0; a < segments; a++) {
|
||||
**hgroup = defgroup;
|
||||
(*hgroup)++;
|
||||
}
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
static void envelope_bone_weighting(Object *ob,
|
||||
@@ -305,6 +314,10 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
looper_data.list = nullptr;
|
||||
looper_data.is_weight_paint = wpmode;
|
||||
|
||||
if (!par->pose) {
|
||||
BKE_pose_rebuild(nullptr, par, arm, false);
|
||||
}
|
||||
BKE_pose_channels_hash_ensure(par->pose);
|
||||
/* count the number of skinnable bones */
|
||||
numbones = bone_looper(
|
||||
ob, static_cast<Bone *>(arm->bonebase.first), &looper_data, bone_skinnable_cb);
|
||||
|
||||
@@ -663,22 +663,6 @@ void POSE_OT_rotation_mode_set(wmOperatorType *ot)
|
||||
/* ********************************************** */
|
||||
/* Show/Hide Bones */
|
||||
|
||||
static int hide_pose_bone_fn(Object *ob, Bone *bone, void *ptr)
|
||||
{
|
||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||
const bool hide_select = bool(POINTER_AS_INT(ptr));
|
||||
int count = 0;
|
||||
if (ANIM_bone_in_visible_collection(arm, bone)) {
|
||||
if (((bone->flag & BONE_SELECTED) != 0) == hide_select) {
|
||||
bone->flag |= BONE_HIDDEN_P;
|
||||
/* only needed when 'hide_select' is true, but harmless. */
|
||||
bone->flag &= ~BONE_SELECTED;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* active object is armature in posemode, poll checked */
|
||||
static wmOperatorStatus pose_hide_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
@@ -688,15 +672,22 @@ static wmOperatorStatus pose_hide_exec(bContext *C, wmOperator *op)
|
||||
bool changed_multi = false;
|
||||
|
||||
const int hide_select = !RNA_boolean_get(op->ptr, "unselected");
|
||||
void *hide_select_p = POINTER_FROM_INT(hide_select);
|
||||
|
||||
for (Object *ob_iter : objects) {
|
||||
bool changed = false;
|
||||
bArmature *arm = static_cast<bArmature *>(ob_iter->data);
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) {
|
||||
if (!ANIM_bone_in_visible_collection(arm, pchan->bone)) {
|
||||
continue;
|
||||
}
|
||||
if (((pchan->bone->flag & BONE_SELECTED) != 0) != hide_select) {
|
||||
continue;
|
||||
}
|
||||
pchan->drawflag |= PCHAN_DRAW_HIDDEN;
|
||||
pchan->bone->flag &= ~BONE_SELECTED;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
bool changed = bone_looper(ob_iter,
|
||||
static_cast<Bone *>(arm->bonebase.first),
|
||||
hide_select_p,
|
||||
hide_pose_bone_fn) != 0;
|
||||
if (changed) {
|
||||
changed_multi = true;
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob_iter);
|
||||
@@ -725,25 +716,6 @@ void POSE_OT_hide(wmOperatorType *ot)
|
||||
RNA_def_boolean(ot->srna, "unselected", false, "Unselected", "");
|
||||
}
|
||||
|
||||
static int show_pose_bone_cb(Object *ob, Bone *bone, void *data)
|
||||
{
|
||||
const bool select = POINTER_AS_INT(data);
|
||||
|
||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||
int count = 0;
|
||||
if (ANIM_bone_in_visible_collection(arm, bone)) {
|
||||
if (bone->flag & BONE_HIDDEN_P) {
|
||||
if (!(bone->flag & BONE_UNSELECTABLE)) {
|
||||
SET_FLAG_FROM_TEST(bone->flag, select, BONE_SELECTED);
|
||||
}
|
||||
bone->flag &= ~BONE_HIDDEN_P;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* active object is armature in posemode, poll checked */
|
||||
static wmOperatorStatus pose_reveal_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
@@ -752,13 +724,25 @@ static wmOperatorStatus pose_reveal_exec(bContext *C, wmOperator *op)
|
||||
Vector<Object *> objects = BKE_object_pose_array_get_unique(scene, view_layer, CTX_wm_view3d(C));
|
||||
bool changed_multi = false;
|
||||
const bool select = RNA_boolean_get(op->ptr, "select");
|
||||
void *select_p = POINTER_FROM_INT(select);
|
||||
|
||||
for (Object *ob_iter : objects) {
|
||||
bArmature *arm = static_cast<bArmature *>(ob_iter->data);
|
||||
|
||||
bool changed = bone_looper(
|
||||
ob_iter, static_cast<Bone *>(arm->bonebase.first), select_p, show_pose_bone_cb);
|
||||
bool changed = false;
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) {
|
||||
if (!ANIM_bone_in_visible_collection(arm, pchan->bone)) {
|
||||
continue;
|
||||
}
|
||||
if ((pchan->drawflag & PCHAN_DRAW_HIDDEN) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (!(pchan->bone->flag & BONE_UNSELECTABLE)) {
|
||||
SET_FLAG_FROM_TEST(pchan->bone->flag, select, BONE_SELECTED);
|
||||
}
|
||||
pchan->drawflag &= ~PCHAN_DRAW_HIDDEN;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
changed_multi = true;
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob_iter);
|
||||
|
||||
@@ -624,7 +624,9 @@ static wmOperatorStatus pose_select_parent_exec(bContext *C, wmOperator * /*op*/
|
||||
pchan = CTX_data_active_pose_bone(C);
|
||||
if (pchan) {
|
||||
parent = pchan->parent;
|
||||
if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE))) {
|
||||
if ((parent) && !(parent->drawflag & PCHAN_DRAW_HIDDEN) &&
|
||||
!(parent->bone->flag & BONE_UNSELECTABLE))
|
||||
{
|
||||
parent->bone->flag |= BONE_SELECTED;
|
||||
arm->act_bone = parent->bone;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ bool jump_to_bone(bContext *C, Object *ob, const char *bone_name, const bool rev
|
||||
if (pchan != nullptr) {
|
||||
if (reveal_hidden) {
|
||||
/* Unhide the bone. */
|
||||
pchan->bone->flag &= ~BONE_HIDDEN_P;
|
||||
pchan->drawflag &= ~PCHAN_DRAW_HIDDEN;
|
||||
ANIM_armature_bonecoll_show_from_pchan(arm, pchan);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
@@ -49,6 +50,7 @@
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
#include "ANIM_armature.hh"
|
||||
#include "ANIM_bone_collections.hh"
|
||||
#include "ANIM_keyframing.hh"
|
||||
|
||||
@@ -177,12 +179,20 @@ static void restrictbutton_r_lay_fn(bContext *C, void *poin, void * /*poin2*/)
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
|
||||
}
|
||||
|
||||
static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void * /*poin2*/)
|
||||
static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *poin2)
|
||||
{
|
||||
Bone *bone = (Bone *)poin;
|
||||
|
||||
const Object *ob = (Object *)poin;
|
||||
bPoseChannel *pchan = (bPoseChannel *)poin2;
|
||||
if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
|
||||
restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
|
||||
blender::animrig::pose_bone_descendent_iterator(
|
||||
*ob->pose, *pchan, [&](bPoseChannel &descendent) {
|
||||
if (pchan->drawflag & PCHAN_DRAW_HIDDEN) {
|
||||
descendent.drawflag |= PCHAN_DRAW_HIDDEN;
|
||||
}
|
||||
else {
|
||||
descendent.drawflag &= ~PCHAN_DRAW_HIDDEN;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1135,7 +1145,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
||||
|
||||
props.constraint_enable = RNA_struct_type_find_property(&RNA_Constraint, "mute");
|
||||
|
||||
props.bone_hide_viewport = RNA_struct_type_find_property(&RNA_Bone, "hide");
|
||||
props.bone_hide_viewport = RNA_struct_type_find_property(&RNA_PoseBone, "hide");
|
||||
|
||||
props.initialized = true;
|
||||
}
|
||||
@@ -1401,7 +1411,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
||||
Object *ob = (Object *)tselem->id;
|
||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||
|
||||
PointerRNA ptr = RNA_pointer_create_discrete(&arm->id, &RNA_Bone, bone);
|
||||
PointerRNA ptr = RNA_pointer_create_discrete(&arm->id, &RNA_PoseBone, pchan);
|
||||
|
||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
|
||||
bt = uiDefIconButR_prop(block,
|
||||
@@ -1419,7 +1429,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
||||
0,
|
||||
TIP_("Restrict visibility in the 3D View\n"
|
||||
" \u2022 Shift to set children"));
|
||||
UI_but_func_set(bt, restrictbutton_bone_visibility_fn, bone, nullptr);
|
||||
UI_but_func_set(bt, restrictbutton_bone_visibility_fn, ob, pchan);
|
||||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
|
||||
}
|
||||
|
||||
@@ -577,7 +577,7 @@ static void tree_element_posechannel_activate(bContext *C,
|
||||
pchan->bone->flag &= ~BONE_SELECTED;
|
||||
}
|
||||
else {
|
||||
if (blender::animrig::bone_is_visible(arm, pchan->bone)) {
|
||||
if (blender::animrig::bone_is_visible_pchan(arm, pchan)) {
|
||||
pchan->bone->flag |= BONE_SELECTED;
|
||||
}
|
||||
arm->act_bone = pchan->bone;
|
||||
|
||||
@@ -2096,11 +2096,11 @@ static void pchan_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, voi
|
||||
pchan->bone->flag &= ~BONE_SELECTED;
|
||||
}
|
||||
else if (event == OL_DOP_HIDE) {
|
||||
pchan->bone->flag |= BONE_HIDDEN_P;
|
||||
pchan->drawflag |= PCHAN_DRAW_HIDDEN;
|
||||
pchan->bone->flag &= ~BONE_SELECTED;
|
||||
}
|
||||
else if (event == OL_DOP_UNHIDE) {
|
||||
pchan->bone->flag &= ~BONE_HIDDEN_P;
|
||||
pchan->drawflag &= ~PCHAN_DRAW_HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -504,6 +504,7 @@ typedef enum ePchan_IkFlag {
|
||||
/* PoseChannel->drawflag */
|
||||
typedef enum ePchan_DrawFlag {
|
||||
PCHAN_DRAW_NO_CUSTOM_BONE_SIZE = (1 << 0),
|
||||
PCHAN_DRAW_HIDDEN = (1 << 1),
|
||||
} ePchan_DrawFlag;
|
||||
|
||||
/* NOTE: It doesn't take custom_scale_xyz into account. */
|
||||
|
||||
@@ -720,11 +720,9 @@ static void rna_Bone_hide_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA
|
||||
{
|
||||
bArmature *arm = (bArmature *)ptr->owner_id;
|
||||
Bone *bone = (Bone *)ptr->data;
|
||||
|
||||
if (bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE)) {
|
||||
if (bone->flag & (BONE_HIDDEN_A | BONE_UNSELECTABLE)) {
|
||||
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE, arm);
|
||||
DEG_id_tag_update(&arm->id, ID_RECALC_SYNC_TO_EVAL);
|
||||
}
|
||||
@@ -1778,16 +1776,11 @@ static void rna_def_bone(BlenderRNA *brna)
|
||||
|
||||
RNA_define_lib_overridable(true);
|
||||
|
||||
/* XXX should we define this in PoseChannel wrapping code instead?
|
||||
* But PoseChannels directly get some of their flags from here... */
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_HIDDEN_P);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Hide",
|
||||
"Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes)");
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_HIDDEN_A);
|
||||
RNA_def_property_ui_text(prop, "Hide", "Bone is not visible when it is in Edit Mode");
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
|
||||
RNA_def_property_update(prop, 0, "rna_Bone_hide_update");
|
||||
RNA_def_property_update(prop, 0, "rna_EditBone_hide_update");
|
||||
|
||||
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_SELECTED);
|
||||
|
||||
@@ -95,6 +95,14 @@ static void rna_Pose_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE, ptr->owner_id);
|
||||
}
|
||||
|
||||
static void rna_PoseBone_visibility_update(Main * /* bmain */,
|
||||
Scene * /* scene */,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE, ptr->owner_id);
|
||||
}
|
||||
|
||||
static void rna_Pose_dependency_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
|
||||
{
|
||||
DEG_relations_tag_update(bmain);
|
||||
@@ -1169,6 +1177,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
|
||||
prop, "Scale to Bone Length", "Scale the custom object by the bone length");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
|
||||
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "drawflag", PCHAN_DRAW_HIDDEN);
|
||||
RNA_def_property_ui_text(prop, "Hide", "Bone is not visible except for Edit Mode");
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_PoseBone_visibility_update");
|
||||
|
||||
prop = RNA_def_property(srna, "custom_shape_transform", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, nullptr, "custom_tx");
|
||||
RNA_def_property_struct_type(prop, "PoseBone");
|
||||
|
||||
Reference in New Issue
Block a user