Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/armature_edit.c
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_ghash.h" | #include "BLI_ghash.h" | ||||
| #include "BKE_action.h" | #include "BKE_action.h" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_constraint.h" | #include "BKE_constraint.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_layer.h" | |||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| ▲ Show 20 Lines • Show All 566 Lines • ▼ Show 20 Lines | if (found == 0) { | ||||
| BLI_addtail(points, ebp); | BLI_addtail(points, ebp); | ||||
| } | } | ||||
| } | } | ||||
| /* bone adding between selected joints */ | /* bone adding between selected joints */ | ||||
| static int armature_fill_bones_exec(bContext *C, wmOperator *op) | static int armature_fill_bones_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Object *obedit = CTX_data_edit_object(C); | Object *obedit_active = CTX_data_edit_object(C); | ||||
| bArmature *arm = (obedit) ? obedit->data : NULL; | |||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| ListBase points = {NULL, NULL}; | ListBase points = {NULL, NULL}; | ||||
| EditBone *newbone = NULL; | EditBone *newbone = NULL; | ||||
| int count; | int count; | ||||
| bool mixed_object_error = false; | |||||
| /* sanity checks */ | /* sanity checks */ | ||||
| if (ELEM(NULL, obedit, arm)) | if (ELEM(NULL, obedit_active, obedit_active->data)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | |||||
| /* loop over all bones, and only consider if visible */ | /* loop over all bones, and only consider if visible */ | ||||
| CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) | bArmature *arm = NULL; | ||||
| CTX_DATA_BEGIN_WITH_ID(C, EditBone *, ebone, visible_bones, bArmature *, arm_iter) | |||||
| { | { | ||||
| if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) | bool check = false; | ||||
| if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) { | |||||
| fill_add_joint(ebone, 0, &points); | fill_add_joint(ebone, 0, &points); | ||||
| if (ebone->flag & BONE_TIPSEL) | check = true; | ||||
| } | |||||
| if (ebone->flag & BONE_TIPSEL) { | |||||
| fill_add_joint(ebone, 1, &points); | fill_add_joint(ebone, 1, &points); | ||||
| check = true; | |||||
| } | |||||
| if (check) { | |||||
| if (arm && (arm != arm_iter)) { | |||||
| mixed_object_error = true; | |||||
| } | |||||
| arm = arm_iter; | |||||
| } | |||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* the number of joints determines how we fill: | /* the number of joints determines how we fill: | ||||
| * 1) between joint and cursor (joint=head, cursor=tail) | * 1) between joint and cursor (joint=head, cursor=tail) | ||||
| * 2) between the two joints (order is dependent on active-bone/hierarchy) | * 2) between the two joints (order is dependent on active-bone/hierarchy) | ||||
| * 3+) error (a smarter method involving finding chains needs to be worked out | * 3+) error (a smarter method involving finding chains needs to be worked out | ||||
| */ | */ | ||||
| count = BLI_listbase_count(&points); | count = BLI_listbase_count(&points); | ||||
| if (count == 0) { | if (count == 0) { | ||||
| BKE_report(op->reports, RPT_ERROR, "No joints selected"); | BKE_report(op->reports, RPT_ERROR, "No joints selected"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| else if (count == 1) { | else if (mixed_object_error) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Bones for different objects selected"); | |||||
| BLI_freelistN(&points); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| Object *obedit = NULL; | |||||
| { | |||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_EDIT, ob_iter) { | |||||
| if (ob_iter->data == arm) { | |||||
| obedit = ob_iter; | |||||
| } | |||||
| } | |||||
| FOREACH_OBJECT_IN_MODE_END; | |||||
| } | |||||
| BLI_assert(obedit != NULL); | |||||
| if (count == 1) { | |||||
| EditBonePoint *ebp; | EditBonePoint *ebp; | ||||
| float curs[3]; | float curs[3]; | ||||
| /* Get Points - selected joint */ | /* Get Points - selected joint */ | ||||
| ebp = points.first; | ebp = points.first; | ||||
| /* Get points - cursor (tail) */ | /* Get points - cursor (tail) */ | ||||
| invert_m4_m4(obedit->imat, obedit->obmat); | invert_m4_m4(obedit->imat, obedit->obmat); | ||||
| ▲ Show 20 Lines • Show All 621 Lines • ▼ Show 20 Lines | static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p) | ||||
| ebone = ED_armature_ebone_find_name(arm->edbo, bone_name); | ebone = ED_armature_ebone_find_name(arm->edbo, bone_name); | ||||
| return (ebone && (ebone->flag & BONE_SELECTED) && (arm->layer & ebone->layer)); | return (ebone && (ebone->flag & BONE_SELECTED) && (arm->layer & ebone->layer)); | ||||
| } | } | ||||
| /* previously delete_armature */ | /* previously delete_armature */ | ||||
| /* only editmode! */ | /* only editmode! */ | ||||
| static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) | static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| bArmature *arm; | |||||
| EditBone *curBone, *ebone_next; | EditBone *curBone, *ebone_next; | ||||
| Object *obedit = CTX_data_edit_object(C); | bool changed_multi = false; | ||||
| bool changed = false; | |||||
| arm = obedit->data; | |||||
| /* cancel if nothing selected */ | /* cancel if nothing selected */ | ||||
| if (CTX_DATA_COUNT(C, selected_bones) == 0) | if (CTX_DATA_COUNT(C, selected_bones) == 0) | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| uint objects_len = 0; | |||||
| Object **objects = BKE_view_layer_array_from_objects_in_mode( | |||||
| view_layer, &objects_len, { | |||||
| .object_mode = OB_MODE_EDIT, | |||||
| .no_dup_data = true}); | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| bArmature *arm = obedit->data; | |||||
| bool changed = false; | |||||
| armature_select_mirrored(arm); | armature_select_mirrored(arm); | ||||
| BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm); | BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm); | ||||
| for (curBone = arm->edbo->first; curBone; curBone = ebone_next) { | for (curBone = arm->edbo->first; curBone; curBone = ebone_next) { | ||||
| ebone_next = curBone->next; | ebone_next = curBone->next; | ||||
| if (arm->layer & curBone->layer) { | if (arm->layer & curBone->layer) { | ||||
| if (curBone->flag & BONE_SELECTED) { | if (curBone->flag & BONE_SELECTED) { | ||||
| if (curBone == arm->act_edbone) arm->act_edbone = NULL; | if (curBone == arm->act_edbone) arm->act_edbone = NULL; | ||||
| ED_armature_ebone_remove(arm, curBone); | ED_armature_ebone_remove(arm, curBone); | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!changed) | if (changed) { | ||||
| return OPERATOR_CANCELLED; | changed_multi = true; | ||||
| ED_armature_edit_sync_selection(arm->edbo); | ED_armature_edit_sync_selection(arm->edbo); | ||||
| BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose); | BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose); | ||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); | WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); | ||||
| } | |||||
| } /* no indent */ | |||||
| if (!changed_multi) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void ARMATURE_OT_delete(wmOperatorType *ot) | void ARMATURE_OT_delete(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Delete Selected Bone(s)"; | ot->name = "Delete Selected Bone(s)"; | ||||
| ▲ Show 20 Lines • Show All 264 Lines • Show Last 20 Lines | |||||