diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-12-24 07:55:35 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-12-24 07:55:35 +0300 |
commit | c1f6a49ae4cc01dff68a8d5fba01ab518bba67aa (patch) | |
tree | 78ce4202a7f42a4a026f42591f03fbda8f640b83 | |
parent | 0bc964c93d44e6cf15213fbc7a0855eb2f4c6c82 (diff) |
Fix snapping pose mode bugs
- Object/pose checks were performed in same loop,
so selected pose bones were moved instead of the object.
- Snap selected to cursor/active incorrectly used unique object-data.
-rw-r--r-- | source/blender/editors/space_view3d/view3d_snap.c | 161 |
1 files changed, 84 insertions, 77 deletions
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 07e5b20db75..13e6ea5c35a 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -70,7 +70,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph); - Object *obedit = CTX_data_edit_object(C); + Object *obact = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); RegionView3D *rv3d = CTX_wm_region_data(C); View3D *v3d = CTX_wm_view3d(C); @@ -81,13 +81,13 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL); - if (obedit) { + if (OBEDIT_FROM_OBACT(obact)) { 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, CTX_wm_view3d(C), &objects_len); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { - obedit = objects[ob_index]; + Object *obedit = objects[ob_index]; if (obedit->type == OB_MESH) { BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -124,89 +124,96 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) } MEM_freeN(objects); } - else { + else if (OBPOSE_FROM_OBACT(obact)) { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); - - FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN (view_layer_eval, v3d, ob_eval) { + uint objects_len = 0; + Object **objects_eval = BKE_object_pose_array_get(view_layer_eval, v3d, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob_eval = objects_eval[ob_index]; Object *ob = DEG_get_original_object(ob_eval); - if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan_eval; - bArmature *arm_eval = ob_eval->data; - - invert_m4_m4(ob_eval->imat, ob_eval->obmat); - - for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval; - pchan_eval = pchan_eval->next) { - if (pchan_eval->bone->flag & BONE_SELECTED) { - if (pchan_eval->bone->layer & arm_eval->layer) { - if ((pchan_eval->bone->flag & BONE_CONNECTED) == 0) { - float nLoc[3]; - - /* get nearest grid point to snap to */ - copy_v3_v3(nLoc, pchan_eval->pose_mat[3]); - /* We must operate in world space! */ - mul_m4_v3(ob_eval->obmat, nLoc); - vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf); - vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf); - vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf); - /* Back in object space... */ - mul_m4_v3(ob_eval->imat, vec); - - /* Get location of grid point in pose space. */ - BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec); - - /* adjust location on the original pchan*/ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name); - if ((pchan->protectflag & OB_LOCK_LOCX) == 0) { - pchan->loc[0] = vec[0]; - } - if ((pchan->protectflag & OB_LOCK_LOCY) == 0) { - pchan->loc[1] = vec[1]; - } - if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) { - pchan->loc[2] = vec[2]; - } - - /* auto-keyframing */ - ED_autokeyframe_pchan(C, scene, ob, pchan, ks); + bPoseChannel *pchan_eval; + bArmature *arm_eval = ob_eval->data; + + invert_m4_m4(ob_eval->imat, ob_eval->obmat); + + for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval; pchan_eval = pchan_eval->next) { + if (pchan_eval->bone->flag & BONE_SELECTED) { + if (pchan_eval->bone->layer & arm_eval->layer) { + if ((pchan_eval->bone->flag & BONE_CONNECTED) == 0) { + float nLoc[3]; + + /* get nearest grid point to snap to */ + copy_v3_v3(nLoc, pchan_eval->pose_mat[3]); + /* We must operate in world space! */ + mul_m4_v3(ob_eval->obmat, nLoc); + vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf); + vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf); + vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf); + /* Back in object space... */ + mul_m4_v3(ob_eval->imat, vec); + + /* Get location of grid point in pose space. */ + BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec); + + /* adjust location on the original pchan*/ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name); + if ((pchan->protectflag & OB_LOCK_LOCX) == 0) { + pchan->loc[0] = vec[0]; + } + if ((pchan->protectflag & OB_LOCK_LOCY) == 0) { + pchan->loc[1] = vec[1]; + } + if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) { + pchan->loc[2] = vec[2]; } - /* if the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. - */ + + /* auto-keyframing */ + ED_autokeyframe_pchan(C, scene, ob, pchan, ks); } + /* if the bone has a parent and is connected to the parent, + * don't do anything - will break chain unless we do auto-ik. + */ } } - ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK); - - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } - else { - vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf); - vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf); - vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf); + ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK); - if (ob->parent) { - float originmat[3][3]; - BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat); + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + } + MEM_freeN(objects_eval); + } + else { + /* Object mode. */ - invert_m3_m3(imat, originmat); - mul_m3_v3(imat, vec); - } - if ((ob->protectflag & OB_LOCK_LOCX) == 0) { - ob->loc[0] = ob_eval->loc[0] + vec[0]; - } - if ((ob->protectflag & OB_LOCK_LOCY) == 0) { - ob->loc[1] = ob_eval->loc[1] + vec[1]; - } - if ((ob->protectflag & OB_LOCK_LOCZ) == 0) { - ob->loc[2] = ob_eval->loc[2] + vec[2]; - } + struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); - /* auto-keyframing */ - ED_autokeyframe_object(C, scene, ob, ks); + FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN (view_layer_eval, v3d, ob_eval) { + Object *ob = DEG_get_original_object(ob_eval); + vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf); + vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf); + vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + if (ob->parent) { + float originmat[3][3]; + BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat); + + invert_m3_m3(imat, originmat); + mul_m3_v3(imat, vec); + } + if ((ob->protectflag & OB_LOCK_LOCX) == 0) { + ob->loc[0] = ob_eval->loc[0] + vec[0]; } + if ((ob->protectflag & OB_LOCK_LOCY) == 0) { + ob->loc[1] = ob_eval->loc[1] + vec[1]; + } + if ((ob->protectflag & OB_LOCK_LOCZ) == 0) { + ob->loc[2] = ob_eval->loc[2] + vec[2]; + } + + /* auto-keyframing */ + ED_autokeyframe_object(C, scene, ob, ks); + + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); } FOREACH_SELECTED_EDITABLE_OBJECT_END; } @@ -323,12 +330,12 @@ static int snap_selected_to_location(bContext *C, } MEM_freeN(objects); } - else if (obact && (obact->mode & OB_MODE_POSE)) { + else if (OBPOSE_FROM_OBACT(obact)) { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); ViewLayer *view_layer = CTX_data_view_layer(C); uint objects_len = 0; - Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data( - view_layer, CTX_wm_view3d(C), &objects_len, OB_MODE_POSE); + Object **objects = BKE_object_pose_array_get(view_layer, v3d, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; bPoseChannel *pchan; |