diff options
Diffstat (limited to 'source/blender/editors/armature/armature_edit.c')
-rw-r--r-- | source/blender/editors/armature/armature_edit.c | 119 |
1 files changed, 82 insertions, 37 deletions
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 0f382f07671..ccc1eefd9dc 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -48,9 +48,11 @@ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_context.h" +#include "BKE_layer.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_report.h" +#include "BKE_object.h" #include "RNA_access.h" #include "RNA_define.h" @@ -139,17 +141,16 @@ void ED_armature_transform(Main *bmain, bArmature *arm, float mat[4][4], const b /* exported for use in editors/object/ */ /* 0 == do center, 1 == center new, 2 == center cursor */ -void ED_armature_origin_set(Main *bmain, Scene *scene, Object *ob, float cursor[3], int centermode, int around) +void ED_armature_origin_set(Main *bmain, Object *ob, float cursor[3], int centermode, int around) { - Object *obedit = scene->obedit; // XXX get from context + const bool is_editmode = BKE_object_is_in_editmode(ob); EditBone *ebone; bArmature *arm = ob->data; float cent[3]; /* Put the armature into editmode */ - if (ob != obedit) { + if (is_editmode == false) { ED_armature_to_edit(arm); - obedit = NULL; /* we cant use this so behave as if there is no obedit */ } /* Find the centerpoint */ @@ -189,13 +190,13 @@ void ED_armature_origin_set(Main *bmain, Scene *scene, Object *ob, float cursor[ } /* Turn the list into an armature */ - if (obedit == NULL) { + if (is_editmode == false) { ED_armature_from_edit(bmain, arm); ED_armature_edit_free(arm); } /* Adjust object location for new centerpoint */ - if (centermode && obedit == NULL) { + if (centermode && (is_editmode == false)) { mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */ add_v3_v3(ob->loc, cent); } @@ -318,10 +319,10 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; - const float *cursor = ED_view3d_cursor3d_get(scene, v3d); + const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d); invert_m4_m4(ob->imat, ob->obmat); - copy_v3_v3(cursor_local, cursor); + copy_v3_v3(cursor_local, cursor->location); mul_m4_v3(ob->imat, cursor_local); @@ -631,25 +632,39 @@ static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points) /* bone adding between selected joints */ static int armature_fill_bones_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); - bArmature *arm = (obedit) ? obedit->data : NULL; + Object *obedit_active = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); ListBase points = {NULL, NULL}; EditBone *newbone = NULL; int count; + bool mixed_object_error = false; /* sanity checks */ - if (ELEM(NULL, obedit, arm)) + if (ELEM(NULL, obedit_active, obedit_active->data)) { return OPERATOR_CANCELLED; + } /* 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); - if (ebone->flag & BONE_TIPSEL) + check = true; + } + if (ebone->flag & BONE_TIPSEL) { 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; @@ -664,7 +679,25 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "No joints selected"); 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; float curs[3]; @@ -673,7 +706,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* Get points - cursor (tail) */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location); /* Create a bone */ newbone = add_points_bone(obedit, ebp->vec, curs); @@ -711,7 +744,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* get cursor location */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location); /* get distances */ dist_sq_a = len_squared_v3v3(ebp_a->vec, curs); @@ -1302,38 +1335,50 @@ static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p) /* only editmode! */ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) { - bArmature *arm; EditBone *curBone, *ebone_next; - Object *obedit = CTX_data_edit_object(C); - bool changed = false; - arm = obedit->data; + bool changed_multi = false; /* cancel if nothing selected */ if (CTX_DATA_COUNT(C, selected_bones) == 0) return OPERATOR_CANCELLED; - armature_select_mirrored(arm); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + 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); + + BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm); + + for (curBone = arm->edbo->first; curBone; curBone = ebone_next) { + ebone_next = curBone->next; + if (arm->layer & curBone->layer) { + if (curBone->flag & BONE_SELECTED) { + if (curBone == arm->act_edbone) arm->act_edbone = NULL; + ED_armature_ebone_remove(arm, curBone); + changed = true; + } + } + } + + if (changed) { + changed_multi = true; - BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm); + ED_armature_edit_sync_selection(arm->edbo); + BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose); - for (curBone = arm->edbo->first; curBone; curBone = ebone_next) { - ebone_next = curBone->next; - if (arm->layer & curBone->layer) { - if (curBone->flag & BONE_SELECTED) { - if (curBone == arm->act_edbone) arm->act_edbone = NULL; - ED_armature_ebone_remove(arm, curBone); - changed = true; - } + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); } } + MEM_freeN(objects); - if (!changed) + if (!changed_multi) { return OPERATOR_CANCELLED; - - ED_armature_edit_sync_selection(arm->edbo); - BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose); - - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + } return OPERATOR_FINISHED; } |