Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/armature_relations.c
| Context not available. | |||||
| #define ARM_PAR_CONNECT 1 | #define ARM_PAR_CONNECT 1 | ||||
| #define ARM_PAR_OFFSET 2 | #define ARM_PAR_OFFSET 2 | ||||
| /* armature un-parenting options */ | |||||
| #define ARM_PAR_CLEAR_OFFSET 1 | |||||
| #define ARM_PAR_CLEAR_DISCONNECT 2 | |||||
| /* check for null, before calling! */ | /* check for null, before calling! */ | ||||
| static void bone_connect_to_existing_parent(EditBone *bone) | static void bone_connect_to_existing_parent(EditBone *bone) | ||||
| { | { | ||||
| Context not available. | |||||
| wmOperator *UNUSED(op), | wmOperator *UNUSED(op), | ||||
| const wmEvent *UNUSED(event)) | const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| bool all_childbones = false; | bool par_offset = false; | ||||
| bool par_connect = false; | |||||
| { | { | ||||
| Object *ob = CTX_data_edit_object(C); | Object *ob = CTX_data_edit_object(C); | ||||
| bArmature *arm = ob->data; | bArmature *arm = ob->data; | ||||
| Context not available. | |||||
| for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) { | for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) { | ||||
| if (EBONE_EDITABLE(ebone) && (ebone->flag & BONE_SELECTED)) { | if (EBONE_EDITABLE(ebone) && (ebone->flag & BONE_SELECTED)) { | ||||
| if (ebone != actbone) { | if (ebone != actbone) { | ||||
| if (ebone->parent != actbone) { | if (!(ebone->flag & BONE_CONNECTED)) { | ||||
| all_childbones = true; | par_connect = true; | ||||
| break; | if (ebone->parent != actbone) { | ||||
| par_offset = true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| uiPopupMenu *pup = UI_popup_menu_begin( | uiPopupMenu *pup = UI_popup_menu_begin( | ||||
| C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE); | C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE); | ||||
| uiLayout *layout = UI_popup_menu_layout(pup); | uiLayout *layout = UI_popup_menu_layout(pup); | ||||
| uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT); | if (par_connect) { | ||||
| if (all_childbones) { | uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT); | ||||
| } | |||||
| if (par_offset) { | |||||
| /* Object becomes parent, make the associated menus. */ | /* Object becomes parent, make the associated menus. */ | ||||
| uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET); | uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET); | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| static const EnumPropertyItem prop_editarm_clear_parent_types[] = { | static const EnumPropertyItem prop_editarm_clear_parent_types[] = { | ||||
| {1, "CLEAR", 0, "Clear Parent", ""}, | {ARM_PAR_CLEAR_OFFSET, "CLEAR", 0, "Clear Parent", ""}, | ||||
| {2, "DISCONNECT", 0, "Disconnect Bone", ""}, | {ARM_PAR_CLEAR_DISCONNECT, "DISCONNECT", 0, "Disconnect Bone", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| Context not available. | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int armature_parent_clear_invoke(bContext *C, | |||||
| wmOperator *UNUSED(op), | |||||
| const wmEvent *UNUSED(event)) | |||||
| { | |||||
| bool par_disconnect = false; | |||||
| bool par_clear = false; | |||||
| { | |||||
| Object *ob = CTX_data_edit_object(C); | |||||
| bArmature *arm = ob->data; | |||||
| EditBone *actbone = arm->act_edbone; | |||||
| for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) { | |||||
| if (EBONE_EDITABLE(ebone) && (ebone->flag & BONE_SELECTED)) { | |||||
| /* It is possible for a bone to not have a parent, but have the connected option enabled. */ | |||||
| if (ebone->flag & BONE_CONNECTED) { | |||||
| par_disconnect = true; | |||||
| } | |||||
| if (ebone->parent != NULL) { | |||||
sybren: The auto-formatter will cause line wrapping. Better to put the comment above the variable… | |||||
| par_clear = true; | |||||
| if (ebone->flag & BONE_CONNECTED) { | |||||
| par_disconnect = true; | |||||
| break; | |||||
Done Inline Actionsactbone is no longer used and can be removed. sybren: `actbone` is no longer used and can be removed. | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| uiPopupMenu *pup = UI_popup_menu_begin( | |||||
| C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Parent"), ICON_NONE); | |||||
| uiLayout *layout = UI_popup_menu_layout(pup); | |||||
Done Inline ActionsNesting can be heavily reduced here, by flipping conditions and continueing early. if (!EBONE_EDITABLE(ebone) || !(ebone->flag & BONE_SELECTED)) { continue; } if (ebone->parent == NULL) { continue; } enable_clear = true; if (ebone->flag & BONE_CONNECTED) { enable_disconnect = true; break; } And yes, this is inconsistent with the above function that this was copied from -- I'm stricter for new code than for modifications on already-existing code ;-) sybren: Nesting can be heavily reduced here, by flipping conditions and `continue`ing early.
```lang=C… | |||||
| if (par_clear){ | |||||
| uiItemEnumO(layout, "ARMATURE_OT_parent_clear", NULL, 0, "type", ARM_PAR_CLEAR_OFFSET); | |||||
| } | |||||
| if (par_disconnect) { | |||||
| /* Object becomes parent, make the associated menus. */ | |||||
| uiItemEnumO(layout, "ARMATURE_OT_parent_clear", NULL, 0, "type", ARM_PAR_CLEAR_DISCONNECT); | |||||
| } | |||||
| UI_popup_menu_end(C, pup); | |||||
| return OPERATOR_INTERFACE; | |||||
| } | |||||
| void ARMATURE_OT_parent_clear(wmOperatorType *ot) | void ARMATURE_OT_parent_clear(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| Context not available. | |||||
| "Remove the parent-child relationship between selected bones and their parents"; | "Remove the parent-child relationship between selected bones and their parents"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->invoke = WM_menu_invoke; | ot->invoke = armature_parent_clear_invoke; | ||||
| ot->exec = armature_parent_clear_exec; | ot->exec = armature_parent_clear_exec; | ||||
| ot->poll = ED_operator_editarmature; | ot->poll = ED_operator_editarmature; | ||||
| Context not available. | |||||
The auto-formatter will cause line wrapping. Better to put the comment above the variable declaration.
Really nice to have those comments!