53 if (armature ==
nullptr) {
59 "Cannot add bone collections to a linked Armature without an "
60 "override on the Armature Data");
66 "Cannot add bone collections to a linked Armature with a system "
67 "override; explicitly create an override on the Armature Data");
78 if (armature ==
nullptr) {
84 "Cannot update a linked Armature with a system override; "
85 "explicitly create an override on the Armature Data");
90 if (bcoll ==
nullptr) {
97 C,
"Cannot edit bone collections that are linked from another blend file");
131 ot->name =
"Add Bone Collection";
132 ot->idname =
"ARMATURE_OT_collection_add";
133 ot->description =
"Add a new bone collection";
159 ot->name =
"Remove Bone Collection";
160 ot->idname =
"ARMATURE_OT_collection_remove";
161 ot->description =
"Remove the active bone collection";
193 {-1,
"UP", 0,
"Up",
""},
194 {1,
"DOWN", 0,
"Down",
""},
195 {0,
nullptr, 0,
nullptr,
nullptr},
199 ot->name =
"Move Bone Collection";
200 ot->idname =
"ARMATURE_OT_collection_move";
201 ot->description =
"Change position of active Bone Collection in list of Bone collections";
215 "Direction to move the active Bone Collection towards");
225 if (bcoll_name[0] ==
'\0') {
248 bool *made_any_changes,
249 bool *had_bones_to_assign)
253 *made_any_changes |= assign_func(bcoll, pchan->bone);
254 *had_bones_to_assign =
true;
268 bool *made_any_changes,
269 bool *had_bones_to_assign)
278 *made_any_changes |= assign_func(bcoll, ebone);
279 *had_bones_to_assign =
true;
297 bool *made_any_changes,
298 bool *had_bones_to_assign)
328 const char *bone_name,
331 bool *made_any_changes,
332 bool *had_bones_to_assign)
343 *had_bones_to_assign =
true;
358 *had_bones_to_assign =
true;
392 C,
"Cannot edit bone collections on linked Armatures without override");
397 "Cannot edit bone collections on a linked Armature with a system "
398 "override; explicitly create an override on the Armature Data");
418 if (bcoll ==
nullptr) {
428 bool made_any_changes =
false;
429 bool had_bones_to_assign =
false;
437 &had_bones_to_assign);
439 if (!mode_is_supported) {
441 op->
reports,
RPT_ERROR,
"This operator only works in pose mode and armature edit mode");
444 if (!had_bones_to_assign) {
449 if (!made_any_changes) {
462 ot->name =
"Add Selected Bones to Collection";
463 ot->idname =
"ARMATURE_OT_collection_assign";
464 ot->description =
"Add selected bones to the chosen bone collection";
479 "Name of the bone collection to assign this bone to; empty to assign to the "
480 "active bone collection");
498 C,
"Cannot edit bone collections on linked Armatures without override");
503 "Cannot edit bone collections on a linked Armature with a system "
504 "override; explicitly create an override on the Armature Data");
528 bool made_any_changes =
false;
529 bool had_bones_to_assign =
false;
537 &had_bones_to_assign);
539 if (!mode_is_supported) {
541 op->
reports,
RPT_ERROR,
"This operator only works in pose mode and armature edit mode");
545 if (!had_bones_to_assign) {
561 ot->name =
"Add Selected Bones to New Collection";
562 ot->idname =
"ARMATURE_OT_collection_create_and_assign";
563 ot->description =
"Create a new bone collection and assign all selected bones";
578 "Name of the bone collection to create");
589 if (bcoll ==
nullptr) {
593 bool made_any_changes =
false;
594 bool had_bones_to_unassign =
false;
602 &had_bones_to_unassign);
604 if (!mode_is_supported) {
606 op->
reports,
RPT_ERROR,
"This operator only works in pose mode and armature edit mode");
609 if (!had_bones_to_unassign) {
611 op->
reports,
RPT_WARNING,
"No bones selected, nothing to unassign from bone collection");
614 if (!made_any_changes) {
616 op->
reports,
RPT_WARNING,
"None of the selected bones were assigned to this collection");
625 ot->name =
"Remove Selected from Bone collections";
626 ot->idname =
"ARMATURE_OT_collection_unassign";
627 ot->description =
"Remove selected bones from the active bone collection";
641 "Name of the bone collection to unassign this bone from; empty to unassign from "
642 "the active bone collection");
653 if (bcoll ==
nullptr) {
664 bool made_any_changes =
false;
665 bool had_bones_to_unassign =
false;
674 &had_bones_to_unassign);
676 if (!mode_is_supported) {
678 op->
reports,
RPT_ERROR,
"This operator only works in pose mode and armature edit mode");
681 if (!had_bones_to_unassign) {
685 if (!made_any_changes) {
688 "Bone '%s' was not assigned to collection '%s'",
699 ot->name =
"Remove Bone from Bone Collection";
700 ot->idname =
"ARMATURE_OT_collection_unassign_named";
701 ot->description =
"Unassign the named bone from this bone collection";
715 "Name of the bone collection to unassign this bone from; empty to unassign from "
716 "the active bone collection");
722 "Name of the bone to unassign from the collection; empty to use the active bone");
728 if (ref->bcoll == bcoll) {
744 C,
"Cannot (de)select bones on linked object, that would need an override");
750 if (armature ==
nullptr) {
766 const bool is_editmode = armature->
edbo !=
nullptr;
781 Bone *bone = member->bone;
812 if (armature ==
nullptr) {
817 if (bcoll ==
nullptr) {
828 ot->name =
"Select Bones of Bone Collection";
829 ot->idname =
"ARMATURE_OT_collection_select";
830 ot->description =
"Select bones in active Bone Collection";
843 if (armature ==
nullptr) {
848 if (bcoll ==
nullptr) {
859 ot->name =
"Deselect Bone Collection";
860 ot->idname =
"ARMATURE_OT_collection_deselect";
861 ot->description =
"Deselect bones of active Bone Collection";
875 const int collection_index =
RNA_int_get(op->
ptr,
"collection_index");
882 (collection_index < 0))
889 "It should always be possible to create a new bone collection on an armature");
896 "Bone collection with index %d not found on Armature %s",
907 "Bone collection %s is not editable, maybe add an override on the armature Data?",
936 bool made_any_changes =
false;
937 bool had_bones_to_assign =
false;
944 &had_bones_to_assign);
946 if (!mode_is_supported) {
948 op->
reports,
RPT_ERROR,
"This operator only works in pose mode and armature edit mode");
951 if (!had_bones_to_assign) {
956 if (!made_any_changes) {
1003 "Cannot update a linked Armature with a system override; "
1004 "explicitly create an override on the Armature Data");
1028 const uintptr_t index_and_move_bit = ((bcoll_index + 1) << 1) | (is_move_operation << 0);
1029 return reinterpret_cast<void *
>(index_and_move_bit);
1039 const uintptr_t index_and_move_bit =
reinterpret_cast<intptr_t
>(menu_custom_data);
1040 const bool is_move_operation = (index_and_move_bit & 1) == 1;
1041 const int bcoll_index = int(index_and_move_bit >> 1) - 1;
1042 return std::make_pair(bcoll_index, is_move_operation);
1047 return collection_contains_active_bone ? ICON_REMOVE : ICON_ADD;
1053 const int bcoll_index,
1054 const bool is_move_operation)
1056 if (is_move_operation) {
1058 RNA_int_set(&op_ptr,
"collection_index", bcoll_index);
1065 if (contains_active_bone) {
1088 int parent_bcoll_index;
1089 bool is_move_operation;
1099 is_move_operation ?
"ARMATURE_OT_move_to_collection" :
"ARMATURE_OT_assign_to_collection",
1102 RNA_int_set(&op_ptr,
"collection_index", parent_bcoll_index);
1110 int child_index, child_count;
1111 if (parent_bcoll_index == -1) {
1121 layout, arm, parent, parent_bcoll_index, is_move_operation);
1130 for (
int index = child_index; index < child_index + child_count; index++) {
1160 const bool is_move_operation =
STREQ(op->
type->
idname,
"ARMATURE_OT_move_to_collection");
1172 C, op, 200,
IFACE_(
"Move to New Bone Collection"),
IFACE_(
"Create"));
1194 ot->name =
"Move to Collection";
1195 ot->description =
"Move bones to a collection";
1196 ot->idname =
"ARMATURE_OT_move_to_collection";
1216 "Index of the collection to move selected bones to. When the operator should create a new "
1217 "bone collection, do not include this parameter and pass new_collection_name",
1224 "new_collection_name",
1228 "Name of a to-be-added bone collection. Only pass this if you want to create a new bone "
1229 "collection and move the selected bones to it. To move to an existing collection, do not "
1230 "include this parameter and use collection_index");
1240 ot->name =
"Assign to Collection";
1242 "Assign all selected bones to a collection, or unassign them, depending on whether the "
1243 "active bone is already assigned or not";
1244 ot->idname =
"ARMATURE_OT_assign_to_collection";
1264 "Index of the collection to assign selected bones to. When the operator should create a new "
1265 "bone collection, use new_collection_name to define the collection name, and set this "
1266 "parameter to the parent index of the new bone collection",
1273 "new_collection_name",
1277 "Name of a to-be-added bone collection. Only pass this if you want to create a new bone "
1278 "collection and assign the selected bones to it. To assign to an existing collection, do "
1279 "not include this parameter and use collection_index");
Functions to deal with Armatures.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_armature_bonecoll_assign_and_move(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_active_set(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_is_editable(const bArmature *armature, const BoneCollection *bcoll)
bool ANIM_armature_bonecoll_assign_and_move_editbone(BoneCollection *bcoll, EditBone *ebone)
bool ANIM_armature_bonecoll_unassign_editbone(BoneCollection *bcoll, EditBone *ebone)
bool ANIM_armature_bonecoll_assign(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_remove(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_unassign(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_active_runtime_refresh(bArmature *armature)
bool ANIM_armature_bonecoll_move(bArmature *armature, BoneCollection *bcoll, int step)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, int parent_index=-1)
bool ANIM_armature_bonecoll_contains_active_bone(const bArmature *armature, const BoneCollection *bcoll)
BoneCollection * ANIM_armature_bonecoll_get_by_name(bArmature *armature, const char *name) ATTR_WARN_UNUSED_RESULT
bool ANIM_armature_bonecoll_assign_editbone(BoneCollection *bcoll, EditBone *ebone)
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_msg(a, msg)
#define LISTBASE_FOREACH(type, var, list)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
ID and Library types, which are fundamental for SDNA.
Object is a sort of wrapper for general info.
#define EBONE_SELECTABLE(arm, ebone)
#define EBONE_EDITABLE(ebone)
void ED_outliner_select_sync_from_edit_bone_tag(bContext *C)
void ED_outliner_select_sync_from_pose_bone_tag(bContext *C)
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
#define ND_BONE_COLLECTION
bArmature * ED_armature_context(const bContext *C)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
void ED_armature_edit_sync_selection(ListBase *edbo)
void ED_armature_ebone_select_set(EditBone *ebone, bool select)
static bool active_bone_collection_poll(bContext *C)
static wmOperatorStatus move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *)
void ARMATURE_OT_assign_to_collection(wmOperatorType *ot)
void ARMATURE_OT_collection_create_and_assign(wmOperatorType *ot)
static wmOperatorStatus bone_collection_deselect_exec(bContext *C, wmOperator *)
static bool bone_collection_create_and_assign_poll(bContext *C)
static wmOperatorStatus bone_collection_unassign_named_exec(bContext *C, wmOperator *op)
static wmOperatorStatus bone_collection_create_and_assign_exec(bContext *C, wmOperator *op)
static wmOperatorStatus bone_collection_select_exec(bContext *C, wmOperator *)
static void bone_collection_select(bContext *C, bArmature *armature, BoneCollection *bcoll, const bool select)
static wmOperatorStatus move_to_new_collection_invoke(bContext *C, wmOperator *op)
bool(*)(BoneCollection *bcoll, Bone *bone) assign_bone_func
void ARMATURE_OT_collection_deselect(wmOperatorType *ot)
void ARMATURE_OT_collection_remove(wmOperatorType *ot)
void ARMATURE_OT_collection_unassign_named(wmOperatorType *ot)
static void bone_collection_assign_pchans(bContext *C, Object *ob, BoneCollection *bcoll, assign_bone_func assign_func, bool *made_any_changes, bool *had_bones_to_assign)
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)
static void * menu_custom_data_encode(const int bcoll_index, const bool is_move_operation)
static wmOperatorStatus bone_collection_move_exec(bContext *C, wmOperator *op)
static bool bone_collection_assign_poll(bContext *C)
static BoneCollection * add_or_move_to_collection_bcoll(wmOperator *op, bArmature *arm)
static wmOperatorStatus move_to_collection_exec(bContext *C, wmOperator *op)
static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *menu_custom_data)
static wmOperatorStatus bone_collection_remove_exec(bContext *C, wmOperator *)
void ARMATURE_OT_collection_assign(wmOperatorType *ot)
void ARMATURE_OT_collection_add(wmOperatorType *ot)
static wmOperatorStatus bone_collection_unassign_exec(bContext *C, wmOperator *op)
void ARMATURE_OT_collection_move(wmOperatorType *ot)
static bool armature_bone_select_poll(bContext *C)
static void menu_add_item_for_move_assign_unassign(uiLayout *layout, const bArmature *arm, const BoneCollection *bcoll, const int bcoll_index, const bool is_move_operation)
static BoneCollection * get_bonecoll_named_or_active(bContext *, wmOperator *op, Object *ob)
static wmOperatorStatus add_or_move_to_collection_exec(bContext *C, wmOperator *op, const assign_bone_func assign_func_bone, const assign_ebone_func assign_func_ebone)
static std::pair< int, bool > menu_custom_data_decode(void *menu_custom_data)
static wmOperatorStatus assign_to_collection_exec(bContext *C, wmOperator *op)
void ARMATURE_OT_move_to_collection(wmOperatorType *ot)
static void bone_collection_assign_editbones(bContext *C, Object *ob, BoneCollection *bcoll, assign_ebone_func assign_func, bool *made_any_changes, bool *had_bones_to_assign)
static int icon_for_bone_collection(const bool collection_contains_active_bone)
static bool editbone_is_member(const EditBone *ebone, const BoneCollection *bcoll)
static bool bone_collection_assign_mode_specific(bContext *C, Object *ob, BoneCollection *bcoll, assign_bone_func assign_bone_func, assign_ebone_func assign_ebone_func, bool *made_any_changes, bool *had_bones_to_assign)
static bool bone_collection_add_poll(bContext *C)
static wmOperatorStatus move_to_collection_regular_invoke(bContext *C, wmOperator *op)
bool(*)(BoneCollection *bcoll, EditBone *ebone) assign_ebone_func
static wmOperatorStatus bone_collection_add_exec(bContext *C, wmOperator *)
static bool move_to_collection_poll(bContext *C)
void ARMATURE_OT_collection_unassign(wmOperatorType *ot)
static wmOperatorStatus bone_collection_assign_exec(bContext *C, wmOperator *op)
void ARMATURE_OT_collection_select(wmOperatorType *ot)
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
bool bone_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
bool bone_is_visible(const bArmature *armature, const Bone *bone)
int armature_bonecoll_child_number_find(const bArmature *armature, const ::BoneCollection *bcoll)
bool bonecoll_has_children(const BoneCollection *bcoll)
int armature_bonecoll_find_parent_index(const bArmature *armature, int bcoll_index)
int armature_bonecoll_child_number_set(bArmature *armature, ::BoneCollection *bcoll, int new_child_number)
Object * context_object(const bContext *C)
Object * context_active_object(const bContext *C)
Object * ED_pose_object_from_context(bContext *C)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
ListBase bone_collections
int active_collection_index
struct BoneCollection * active_collection
int collection_root_count
struct BoneCollection ** collection_array
struct bArmature_Runtime runtime
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void menu_fn(blender::StringRefNull name, int icon, uiMenuCreateFunc func, void *arg)
uiLayout & row(bool align)
const char * translation_context
struct ReportList * reports
struct wmOperatorType * type
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorStatus WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)