Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/armature_relations.c
| Show First 20 Lines • Show All 723 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Edit Armature Parenting | /** \name Edit Armature Parenting | ||||
| * \{ */ | * \{ */ | ||||
| /* armature parenting options */ | /* armature parenting options */ | ||||
| #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) | ||||
| { | { | ||||
| bone->flag |= BONE_CONNECTED; | bone->flag |= BONE_CONNECTED; | ||||
| copy_v3_v3(bone->head, bone->parent->tail); | copy_v3_v3(bone->head, bone->parent->tail); | ||||
| bone->rad_head = bone->parent->rad_tail; | bone->rad_head = bone->parent->rad_tail; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | static int armature_parent_set_exec(bContext *C, wmOperator *op) | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int armature_parent_set_invoke(bContext *C, | static int armature_parent_set_invoke(bContext *C, | ||||
| 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; | ||||
| EditBone *actbone = arm->act_edbone; | EditBone *actbone = arm->act_edbone; | ||||
| 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->flag & BONE_CONNECTED)) { | |||||
| par_connect = true; | |||||
| if (ebone->parent != actbone) { | if (ebone->parent != actbone) { | ||||
| all_childbones = true; | par_offset = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| 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); | ||||
| if (par_connect) { | |||||
| uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT); | uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT); | ||||
| if (all_childbones) { | } | ||||
| 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); | ||||
| } | } | ||||
| UI_popup_menu_end(C, pup); | UI_popup_menu_end(C, pup); | ||||
| return OPERATOR_INTERFACE; | return OPERATOR_INTERFACE; | ||||
| } | } | ||||
| Show All 13 Lines | void ARMATURE_OT_parent_set(wmOperatorType *ot) | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| RNA_def_enum( | RNA_def_enum( | ||||
| ot->srna, "type", prop_editarm_make_parent_types, 0, "ParentType", "Type of parenting"); | ot->srna, "type", prop_editarm_make_parent_types, 0, "ParentType", "Type of parenting"); | ||||
| } | } | ||||
| 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}, | ||||
| }; | }; | ||||
| static void editbone_clear_parent(EditBone *ebone, int mode) | static void editbone_clear_parent(EditBone *ebone, int mode) | ||||
| { | { | ||||
| if (ebone->parent) { | if (ebone->parent) { | ||||
| /* for nice selection */ | /* for nice selection */ | ||||
| ebone->parent->flag &= ~(BONE_TIPSEL); | ebone->parent->flag &= ~(BONE_TIPSEL); | ||||
| Show All 39 Lines | for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | ||||
| /* Note, notifier might evolve. */ | /* Note, notifier might evolve. */ | ||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); | ||||
| } | } | ||||
| MEM_freeN(objects); | MEM_freeN(objects); | ||||
| 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; | |||||
sybren: The auto-formatter will cause line wrapping. Better to put the comment above the variable… | |||||
| { | |||||
| Object *ob = CTX_data_edit_object(C); | |||||
| bArmature *arm = ob->data; | |||||
| EditBone *actbone = arm->act_edbone; | |||||
Done Inline Actionsactbone is no longer used and can be removed. sybren: `actbone` is no longer used and can be removed. | |||||
| 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) { | |||||
| par_clear = true; | |||||
| if (ebone->flag & BONE_CONNECTED) { | |||||
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… | |||||
| par_disconnect = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| uiPopupMenu *pup = UI_popup_menu_begin( | |||||
| C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Parent"), ICON_NONE); | |||||
| uiLayout *layout = UI_popup_menu_layout(pup); | |||||
| 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 */ | ||||
| ot->name = "Clear Parent"; | ot->name = "Clear Parent"; | ||||
| ot->idname = "ARMATURE_OT_parent_clear"; | ot->idname = "ARMATURE_OT_parent_clear"; | ||||
| ot->description = | ot->description = | ||||
| "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; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| ot->prop = RNA_def_enum(ot->srna, | ot->prop = RNA_def_enum(ot->srna, | ||||
| "type", | "type", | ||||
| prop_editarm_clear_parent_types, | prop_editarm_clear_parent_types, | ||||
| 0, | 0, | ||||
| "ClearType", | "ClearType", | ||||
| "What way to clear parenting"); | "What way to clear parenting"); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
The auto-formatter will cause line wrapping. Better to put the comment above the variable declaration.
Really nice to have those comments!