diff options
author | YimingWu <xp8110@outlook.com> | 2020-02-01 05:35:40 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2020-02-01 05:35:40 +0300 |
commit | f7770cb97bb9d19d0806f67da9377129fd4d09b0 (patch) | |
tree | 2cd22d612ffba3a509d5548332c9cc8a06a1a638 /source/blender/editors/space_view3d | |
parent | b47883a990ee68e659a8a8b44729be9b8e0d002f (diff) | |
parent | dc3f073d1c5255e79763dfff3ef17f6216f1b391 (diff) |
Merge remote-tracking branch 'origin/master' into temp-lanpr-review
Diffstat (limited to 'source/blender/editors/space_view3d')
7 files changed, 288 insertions, 126 deletions
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 76d9065905a..e2d32181bb3 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1032,19 +1032,9 @@ static void view3d_main_region_message_subscribe(const struct bContext *C, } } -/* concept is to retrieve cursor type context-less */ static void view3d_main_region_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) { - if (WM_cursor_set_from_tool(win, sa, ar)) { - return; - } - - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - if (obedit) { - WM_cursor_set(win, WM_CURSOR_EDIT); - } - else { + if (!WM_cursor_set_from_tool(win, sa, ar)) { WM_cursor_set(win, WM_CURSOR_DEFAULT); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index d40f79cea3f..83fb87264e3 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -158,6 +158,12 @@ typedef struct ViewOpsData { float trackvec[3]; /** Dolly only. */ float mousevec[3]; + + /** + * #RegionView3D.persp set after auto-perspective is applied. + * If we want the value before running the operator, add a separate member. + */ + char persp; } init; /** Previous state (previous modal event handled). */ @@ -413,6 +419,7 @@ static void viewops_data_create(bContext *C, * we may want to make this optional but for now its needed always */ ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d); + vod->init.persp = rv3d->persp; vod->init.dist = rv3d->dist; vod->init.camzoom = rv3d->camzoom; copy_qt_qt(vod->init.quat, rv3d->viewquat); @@ -613,6 +620,7 @@ static void viewrotate_apply_snap(ViewOpsData *vod) float zaxis_best[3]; int x, y, z; bool found = false; + bool is_axis_aligned = false; invert_qt_qt_normalized(viewquat_inv, vod->curr.viewquat); @@ -630,6 +638,10 @@ static void viewrotate_apply_snap(ViewOpsData *vod) if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) { copy_v3_v3(zaxis_best, zaxis_test); found = true; + + if (abs(x) + abs(y) + abs(z) == 1) { + is_axis_aligned = true; + } } } } @@ -700,6 +712,17 @@ static void viewrotate_apply_snap(ViewOpsData *vod) copy_qt_qt(rv3d->viewquat, quat_best); viewrotate_apply_dyn_ofs(vod, rv3d->viewquat); + + if (U.uiflag & USER_AUTOPERSP) { + if (is_axis_aligned) { + if (rv3d->persp == RV3D_PERSP) { + rv3d->persp = RV3D_ORTHO; + } + } + } + } + else if (U.uiflag & USER_AUTOPERSP) { + rv3d->persp = vod->init.persp; } } @@ -758,7 +781,32 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2]) quat_to_mat3(m, vod->curr.viewquat); invert_m3_m3(m_inv, m); - /* avoid gimble lock */ + /* Avoid Gimble Lock + * + * Even though turn-table mode is in use, this can occur when the user exits the camera view + * or when aligning the view to a rotated object. + * + * We have gimble lock when the user's view is rotated +/- 90 degrees along the view axis. + * In this case the vertical rotation is the same as the sideways turntable motion. + * Making it impossible to get out of the gimble locked state without resetting the view. + * + * The logic below lets the user exit out of this state without any abrupt 'fix' + * which would be disorienting. + * + * This works by blending two horizons: + * - Rotated-horizon: `cross_v3_v3v3(xaxis, zvec_global, m_inv[2])` + * When only this is used, this turntable rotation works - but it's side-ways + * (as if the entire turn-table has been placed on it's side) + * While there is no gimble lock, it's also awkward to use. + * - Un-rotated-horizon: `m_inv[0]` + * When only this is used, the turntable rotation can have gimbal lock. + * + * The solution used here is to blend between these two values, + * so the severity of the gimbal lock is used to blend the rotated horizon. + * Blending isn't essential, it just makes the transition smoother. + * + * This allows sideways turn-table rotation on a Z axis that isn't world-space Z, + * While up-down turntable rotation eventually corrects gimble lock. */ #if 1 if (len_squared_v3v3(zvec_global, m_inv[2]) > 0.001f) { float fac; @@ -834,6 +882,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) event_code = VIEW_APPLY; break; case VIEWROT_MODAL_AXIS_SNAP_DISABLE: + vod->rv3d->persp = vod->init.persp; vod->axis_snap = false; event_code = VIEW_APPLY; break; @@ -1448,10 +1497,20 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev const bool is_orbit_around_pivot = (U.ndof_flag & NDOF_MODE_ORBIT) || ED_view3d_offset_lock_check(v3d, rv3d); const bool has_rotation = ndof_has_rotate(ndof, rv3d); - const bool has_translate = !is_zero_v2(ndof->tvec) && ndof_has_translate(ndof, v3d, rv3d); - const bool has_zoom = (ndof->tvec[2] != 0.0f); + bool has_translate, has_zoom; - /* Rotation first because dynamic offset resets offset otherwise (and disasbles panning). */ + if (is_orbit_around_pivot) { + /* Orbit preference or forced lock (Z zooms). */ + has_translate = !is_zero_v2(ndof->tvec) && ndof_has_translate(ndof, v3d, rv3d); + has_zoom = (ndof->tvec[2] != 0.0f); + } + else { + /* Free preference (Z translates). */ + has_translate = ndof_has_translate(ndof, v3d, rv3d); + has_zoom = false; + } + + /* Rotation first because dynamic offset resets offset otherwise (and disables panning). */ if (has_rotation) { const float dist_backup = rv3d->dist; if (!is_orbit_around_pivot) { @@ -4944,6 +5003,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, .use_object_edit_cage = false, + .use_occlusion_test = true, }, mval_fl, NULL, @@ -4957,10 +5017,9 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, copy_v3_v3(cursor_co, ray_co); } - float tquat[4]; - /* Math normal (Z). */ { + float tquat[4]; float z_src[3] = {0, 0, 1}; mul_qt_v3(cursor_quat, z_src); rotation_between_vecs_to_quat(tquat, z_src, ray_no); @@ -4975,13 +5034,34 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, dot_v3v3(ray_no, obmat[2]), }; const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot); - float x_src[3] = {1, 0, 0}; - float x_dst[3]; - mul_qt_v3(cursor_quat, x_src); - project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no); - normalize_v3(x_dst); - rotation_between_vecs_to_quat(tquat, x_src, x_dst); - mul_qt_qtqt(cursor_quat, tquat, cursor_quat); + + float tquat_best[4]; + float angle_best = -1.0f; + + float tan_dst[3]; + project_plane_v3_v3v3(tan_dst, obmat[ortho_axis], ray_no); + normalize_v3(tan_dst); + + /* As the tangent is arbitrary from the users point of view, + * make the cursor 'roll' on the shortest angle. + * otherwise this can cause noticeable 'flipping', see T72419. */ + for (int axis = 0; axis < 2; axis++) { + float tan_src[3] = {0, 0, 0}; + tan_src[axis] = 1.0f; + mul_qt_v3(cursor_quat, tan_src); + + for (int axis_sign = 0; axis_sign < 2; axis_sign++) { + float tquat_test[4]; + rotation_between_vecs_to_quat(tquat_test, tan_src, tan_dst); + const float angle_test = angle_normalized_qt(tquat_test); + if (angle_test < angle_best || angle_best == -1.0f) { + angle_best = angle_test; + copy_qt_qt(tquat_best, tquat_test); + } + negate_v3(tan_src); + } + } + mul_qt_qtqt(cursor_quat, tquat_best, cursor_quat); } } ED_transform_snap_object_context_destroy(snap_context); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 504b10888e8..75ab6518a4f 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -515,12 +515,9 @@ static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mv return -1; } -static int gizmo_axis_cursor_get(wmGizmo *gz) +static int gizmo_axis_cursor_get(wmGizmo *UNUSED(gz)) { - if (gz->highlight_part > 0) { - return WM_CURSOR_EDIT; - } - return WM_CURSOR_NSEW_SCROLL; + return WM_CURSOR_DEFAULT; } void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c index 8cd5ed7a478..75d0384182b 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c @@ -22,6 +22,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_global.h" #include "ED_screen.h" #include "ED_transform.h" @@ -52,10 +53,6 @@ static const char *handle_free_id; static bool WIDGETGROUP_tool_generic_poll(const bContext *C, wmGizmoGroupType *gzgt) { - if (!USER_EXPERIMENTAL_TEST(&U, use_tool_fallback)) { - return false; - } - if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { return false; } @@ -65,6 +62,11 @@ static bool WIDGETGROUP_tool_generic_poll(const bContext *C, wmGizmoGroupType *g return false; } + /* Without this, refreshing the gizmo jitters in some cases with edit-mesh smooth. See T72948. */ + if (G.moving & G_TRANSFORM_EDIT) { + return false; + } + return true; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 092142a83cd..89baf60bd8c 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1785,7 +1785,13 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, return hits; } -/* returns basact */ +/** + * \param has_bones: When true, skip non-bone hits, also allow bases to be used + * that are visible but not select-able, + * since you may be in pose mode with an an unselect-able object. + * + * \return the active base or NULL. + */ static Base *mouse_select_eval_buffer(ViewContext *vc, const uint *buffer, int hits, @@ -1827,7 +1833,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, base = FIRSTBASE(view_layer); while (base) { - if (BASE_SELECTABLE(v3d, base)) { + if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) { if (base->object->runtime.select_id == selcol) { break; } @@ -1844,7 +1850,8 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, while (base) { /* skip objects with select restriction, to prevent prematurely ending this loop * with an un-selectable choice */ - if ((base->flag & BASE_SELECTABLE) == 0) { + if (has_bones ? (base->flag & BASE_VISIBLE_VIEWLAYER) == 0 : + (base->flag & BASE_SELECTABLE) == 0) { base = base->next; if (base == NULL) { base = FIRSTBASE(view_layer); @@ -1854,7 +1861,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, } } - if (BASE_SELECTABLE(v3d, base)) { + if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) { for (a = 0; a < hits; a++) { if (has_bones) { /* skip non-bone objects */ @@ -2077,7 +2084,8 @@ static bool ed_object_select_pick(bContext *C, if (has_bones && basact) { if (basact->object->type == OB_CAMERA) { - if (oldbasact == basact) { + MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false); + if (clip != NULL && oldbasact == basact) { int i, hitresult; bool changed = false; @@ -2094,7 +2102,6 @@ static bool ed_object_select_pick(bContext *C, * in height word, this buffer value belongs to camera. not to bundle */ if (buffer[4 * i + 3] & 0xFFFF0000) { - MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase; MovieTrackingTrack *track; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 35a116dc4b3..f13f41779c2 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -61,14 +61,16 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]); static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]); -/* *********************** operators ******************** */ +/* -------------------------------------------------------------------- */ +/** \name Snap Selection to Grid Operator + * \{ */ /** Snaps every individual object center to its nearest point on the grid. */ 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); @@ -79,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); @@ -122,91 +124,117 @@ 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 the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. - */ + 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); } + /* 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. */ + Main *bmain = CTX_data_main(C); - 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); + const bool use_transform_data_origin = (scene->toolsettings->transform_flag & + SCE_XFORM_DATA_ORIGIN); + struct XFormObjectData_Container *xds = NULL; - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + if (use_transform_data_origin) { + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); + xds = ED_object_data_xform_container_create(); + } + + 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); + + 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); + + if (use_transform_data_origin) { + ED_object_data_xform_container_item_ensure(xds, ob); + } + + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); } FOREACH_SELECTED_EDITABLE_OBJECT_END; + + if (use_transform_data_origin) { + ED_object_data_xform_container_update_all(xds, bmain, depsgraph); + ED_object_data_xform_container_destroy(xds); + } } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -229,7 +257,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* *************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Selection to Location (Utility) + * \{ */ /** * Snaps the selection as a whole (use_offset=true) or each selected object to the given location. @@ -317,12 +349,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; @@ -393,6 +425,7 @@ static int snap_selected_to_location(bContext *C, else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); ListBase ctx_data_list; CollectionPointerLink *ctx_ob; @@ -411,6 +444,22 @@ static int snap_selected_to_location(bContext *C, ob->flag |= OB_DONE; } + const bool use_transform_data_origin = (scene->toolsettings->transform_flag & + SCE_XFORM_DATA_ORIGIN); + struct XFormObjectData_Container *xds = NULL; + + if (use_transform_data_origin) { + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); + xds = ED_object_data_xform_container_create(); + + /* Initialize the transform data in a separate loop because the depsgraph + * may be evaluated while setting the locations. */ + for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { + ob = ctx_ob->ptr.data; + ED_object_data_xform_container_item_ensure(xds, ob); + } + } + for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { ob = ctx_ob->ptr.data; @@ -431,7 +480,7 @@ static int snap_selected_to_location(bContext *C, float originmat[3][3], parentmat[4][4]; /* Use the evaluated object here because sometimes * `ob->parent->runtime.curve_cache` is required. */ - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); BKE_object_get_parent_matrix(ob_eval, ob_eval->parent, parentmat); @@ -457,6 +506,11 @@ static int snap_selected_to_location(bContext *C, } BLI_freelistN(&ctx_data_list); + + if (use_transform_data_origin) { + ED_object_data_xform_container_update_all(xds, bmain, depsgraph); + ED_object_data_xform_container_destroy(xds); + } } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -464,6 +518,12 @@ static int snap_selected_to_location(bContext *C, return OPERATOR_FINISHED; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Selection to Cursor Operator + * \{ */ + static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op) { const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); @@ -497,7 +557,11 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) "If the selection should be snapped as a whole or by each object center"); } -/* *************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Selection to Active Operator + * \{ */ /** Snaps each selected object to the location of the active selected object. */ static int snap_selected_to_active_exec(bContext *C, wmOperator *op) @@ -527,7 +591,11 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* *************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Cursor to Grid Operator + * \{ */ /** Snaps the 3D cursor location to its nearest point on the grid. */ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) @@ -565,7 +633,11 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* **************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Cursor to Selection Operator + * \{ */ /** * Returns the center position of a tracking marker visible on the viewport @@ -761,7 +833,11 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ********************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Cursor to Active Operator + * \{ */ /** * Calculates the center position of the active object in global space. @@ -809,7 +885,11 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* **************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Cursor to Center Operator + * \{ */ /** Snaps the 3D cursor location to the origin and clears cursor rotation. */ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) @@ -842,7 +922,11 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* **************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Min/Max Object Vertices Utility + * \{ */ /** * Calculates the bounding box corners (min and max) for \a obedit. @@ -890,3 +974,5 @@ bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3]) return true; } + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 494e7529975..34470896fb9 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -676,7 +676,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event) return; } - if ((walk->is_cursor_absolute == false) && event->is_motion_absolute) { + if ((walk->is_cursor_absolute == false) && event->tablet.is_motion_absolute) { walk->is_cursor_absolute = true; copy_v2_v2_int(walk->prev_mval, event->mval); copy_v2_v2_int(walk->center_mval, event->mval); |