Merge remote-tracking branch 'origin/blender-v4.0-release'
This commit is contained in:
@@ -247,6 +247,44 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
|
||||
sub.prop(bone, "inherit_scale")
|
||||
|
||||
|
||||
class BONE_PT_collections(BoneButtonsPanel, Panel):
|
||||
bl_label = "Bone Collections"
|
||||
bl_parent_id = "BONE_PT_relations"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.bone or context.edit_bone
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = False
|
||||
|
||||
bone = context.bone or context.edit_bone
|
||||
|
||||
if not bone.collections:
|
||||
layout.active = False
|
||||
layout.label(text="Not assigned to any bone collection.")
|
||||
return
|
||||
|
||||
box = layout.box()
|
||||
sub = box.column(align=True)
|
||||
for bcoll in bone.collections:
|
||||
bcoll_row = sub.row()
|
||||
bcoll_row.emboss = 'NONE'
|
||||
|
||||
# Name & visibility of bcoll. Safe things, so aligned together.
|
||||
row = bcoll_row.row(align=True)
|
||||
row.label(text=bcoll.name)
|
||||
row.prop(bcoll, "is_visible", text="",
|
||||
icon='HIDE_OFF' if bcoll.is_visible else 'HIDE_ON')
|
||||
|
||||
# Unassignment operator, less safe so with a bit of spacing.
|
||||
props = bcoll_row.operator("armature.collection_unassign_named",
|
||||
text="", icon='X')
|
||||
props.name = bcoll.name
|
||||
props.bone_name = bone.name
|
||||
|
||||
|
||||
class BONE_PT_display(BoneButtonsPanel, Panel):
|
||||
bl_label = "Viewport Display"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -514,6 +552,7 @@ classes = (
|
||||
BONE_PT_transform,
|
||||
BONE_PT_curved,
|
||||
BONE_PT_relations,
|
||||
BONE_PT_collections,
|
||||
BONE_PT_inverse_kinematics,
|
||||
BONE_PT_deform,
|
||||
BONE_PT_display,
|
||||
|
||||
@@ -77,6 +77,7 @@ void ARMATURE_OT_collection_remove(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_move(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_assign(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_unassign(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_unassign_named(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_select(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_collection_deselect(struct wmOperatorType *ot);
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ void ED_operatortypes_armature()
|
||||
WM_operatortype_append(ARMATURE_OT_collection_move);
|
||||
WM_operatortype_append(ARMATURE_OT_collection_assign);
|
||||
WM_operatortype_append(ARMATURE_OT_collection_unassign);
|
||||
WM_operatortype_append(ARMATURE_OT_collection_unassign_named);
|
||||
WM_operatortype_append(ARMATURE_OT_collection_select);
|
||||
WM_operatortype_append(ARMATURE_OT_collection_deselect);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_report.h"
|
||||
@@ -290,7 +291,11 @@ static void bone_collection_assign_editbones(bContext *C,
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
/* Returns whether the current mode is actually supported. */
|
||||
/**
|
||||
* Assign or unassign all selected bones to/from the given bone collection.
|
||||
*
|
||||
* \return whether the current mode is actually supported.
|
||||
*/
|
||||
static bool bone_collection_assign_mode_specific(bContext *C,
|
||||
Object *ob,
|
||||
BoneCollection *bcoll,
|
||||
@@ -327,6 +332,58 @@ static bool bone_collection_assign_mode_specific(bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign or unassign the named bone to/from the given bone collection.
|
||||
*
|
||||
* \return whether the current mode is actually supported.
|
||||
*/
|
||||
static bool bone_collection_assign_named_mode_specific(bContext *C,
|
||||
Object *ob,
|
||||
BoneCollection *bcoll,
|
||||
const char *bone_name,
|
||||
assign_bone_func assign_bone_func,
|
||||
assign_ebone_func assign_ebone_func,
|
||||
bool *made_any_changes,
|
||||
bool *had_bones_to_assign)
|
||||
{
|
||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||
|
||||
switch (CTX_data_mode_enum(C)) {
|
||||
case CTX_MODE_POSE: {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
|
||||
if (!pchan) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*had_bones_to_assign = true;
|
||||
*made_any_changes |= assign_bone_func(bcoll, pchan->bone);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_COLLECTION, ob);
|
||||
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT); /* Recreate the draw buffers. */
|
||||
return true;
|
||||
}
|
||||
|
||||
case CTX_MODE_EDIT_ARMATURE: {
|
||||
EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
|
||||
if (!ebone) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*had_bones_to_assign = true;
|
||||
*made_any_changes |= assign_ebone_func(bcoll, ebone);
|
||||
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_COLLECTION, ob);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool bone_collection_assign_poll(bContext *C)
|
||||
{
|
||||
Object *ob = ED_object_context(C);
|
||||
@@ -484,6 +541,82 @@ void ARMATURE_OT_collection_unassign(wmOperatorType *ot)
|
||||
"the active bone collection");
|
||||
}
|
||||
|
||||
static int bone_collection_unassign_named_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_context(C);
|
||||
if (ob == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BoneCollection *bcoll = get_bonecoll_named_or_active(C, op, ob, FAIL_IF_MISSING);
|
||||
if (bcoll == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
char bone_name[MAX_NAME];
|
||||
RNA_string_get(op->ptr, "bone_name", bone_name);
|
||||
if (!bone_name[0]) {
|
||||
WM_report(RPT_ERROR, "Missing bone name");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
bool made_any_changes = false;
|
||||
bool had_bones_to_unassign = false;
|
||||
const bool mode_is_supported = bone_collection_assign_named_mode_specific(
|
||||
C,
|
||||
ob,
|
||||
bcoll,
|
||||
bone_name,
|
||||
ANIM_armature_bonecoll_unassign,
|
||||
ANIM_armature_bonecoll_unassign_editbone,
|
||||
&made_any_changes,
|
||||
&had_bones_to_unassign);
|
||||
|
||||
if (!mode_is_supported) {
|
||||
WM_report(RPT_ERROR, "This operator only works in pose mode and armature edit mode");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (!had_bones_to_unassign) {
|
||||
WM_reportf(RPT_WARNING, "Could not find bone '%s'", bone_name);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (!made_any_changes) {
|
||||
WM_reportf(
|
||||
RPT_WARNING, "Bone '%s' was not assigned to collection '%s'", bone_name, bcoll->name);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void ARMATURE_OT_collection_unassign_named(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Remove Bone from Bone collections";
|
||||
ot->idname = "ARMATURE_OT_collection_unassign_named";
|
||||
ot->description = "Unassign the bone from this bone collection";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = bone_collection_unassign_named_exec;
|
||||
ot->poll = bone_collection_assign_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_string(ot->srna,
|
||||
"name",
|
||||
nullptr,
|
||||
MAX_NAME,
|
||||
"Bone Collection",
|
||||
"Name of the bone collection to unassign this bone from; empty to unassign from "
|
||||
"the active bone collection");
|
||||
RNA_def_string(ot->srna,
|
||||
"bone_name",
|
||||
nullptr,
|
||||
MAX_NAME,
|
||||
"Bone Name",
|
||||
"Name of the bone to unassign from the collection; empty to use the active bone");
|
||||
}
|
||||
|
||||
static bool editbone_is_member(const EditBone *ebone, const BoneCollection *bcoll)
|
||||
{
|
||||
LISTBASE_FOREACH (BoneCollectionReference *, ref, &ebone->bone_collections) {
|
||||
|
||||
Reference in New Issue
Block a user