Measure tool: Add support to restrict dimension to one axis

Support axis constraints for the measure tool.

Press X, Y or Z to restrict the dimension to that axis,
it's also possible to toggle between orientations matching transform.

Reviewed By: campbellbarton

Ref D10872
This commit is contained in:
Eric Abrahamsson
2021-08-31 17:14:32 +10:00
committed by Campbell Barton
parent fa4f9292e1
commit fa4a35d4c4

View File

@@ -33,6 +33,7 @@
#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_unit.h"
#include "DNA_gpencil_types.h"
@@ -44,6 +45,7 @@
#include "ED_gizmo_utils.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
#include "ED_view3d.h"
@@ -69,6 +71,12 @@
#include "BLF_api.h"
/**
* Supporting transform features could be removed if the actual transform system is used.
* Keep the option open since each transform feature is duplicating logic.
*/
#define USE_AXIS_CONSTRAINTS
static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler";
#define MVAL_MAX_PX_DIST 12.0f
@@ -98,6 +106,24 @@ enum {
RULER_STATE_DRAG,
};
#ifdef USE_AXIS_CONSTRAINTS
/* Constrain axes */
enum {
CONSTRAIN_AXIS_NONE = -1,
CONSTRAIN_AXIS_X = 0,
CONSTRAIN_AXIS_Y = 1,
CONSTRAIN_AXIS_Z = 2,
};
/* Constraining modes.
Off / Scene orientation / Global (or Local if Scene orientation is Global) */
enum {
CONSTRAIN_MODE_OFF = 0,
CONSTRAIN_MODE_1 = 1,
CONSTRAIN_MODE_2 = 2,
};
#endif /* USE_AXIS_CONSTRAINTS */
struct RulerItem;
typedef struct RulerInfo {
@@ -106,6 +132,10 @@ typedef struct RulerInfo {
int snap_flag;
int state;
#ifdef USE_AXIS_CONSTRAINTS
short constrain_axis, constrain_mode;
#endif
/* wm state */
wmWindowManager *wm;
wmWindow *win;
@@ -394,6 +424,44 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph,
if (ED_gizmotypes_snap_3d_is_enabled(snap_gizmo)) {
ED_gizmotypes_snap_3d_data_get(snap_gizmo, co, NULL, NULL, NULL);
}
#ifdef USE_AXIS_CONSTRAINTS
if (!(ruler_item->flag & RULERITEM_USE_ANGLE) &&
ruler_info->constrain_mode != CONSTRAIN_MODE_OFF) {
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
RegionView3D *rv3d = ruler_info->region->regiondata;
Object *ob = OBACT(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
short orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
if (ruler_info->constrain_mode == CONSTRAIN_MODE_2) {
orient_index = (orient_index == V3D_ORIENT_GLOBAL) ? V3D_ORIENT_LOCAL :
V3D_ORIENT_GLOBAL;
}
const int pivot_point = scene->toolsettings->transform_pivot_point;
float mat[3][3];
ED_transform_calc_orientation_from_type_ex(
scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, mat);
invert_m3(mat);
mul_m3_m3_pre(ruler_item->co, mat);
/* Loop through the axes and constrain the dragged point to the current constrained axis.
*/
for (int i = 0; i <= 2; i++) {
if (ruler_info->constrain_axis != i) {
ruler_item->co[inter->co_index][i] = ruler_item->co[(inter->co_index == 0) ? 2 : 0][i];
}
}
invert_m3(mat);
mul_m3_m3_pre(ruler_item->co, mat);
}
#endif
}
return true;
}
@@ -940,6 +1008,35 @@ static int gizmo_ruler_modal(bContext *C,
ruler_info->region = region;
#ifdef USE_AXIS_CONSTRAINTS
if ((event->val == KM_PRESS) && ELEM(event->type, EVT_XKEY, EVT_YKEY, EVT_ZKEY)) {
/* Go to Mode 1 if a new axis is selected. */
if (event->type == EVT_XKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_X) {
ruler_info->constrain_axis = CONSTRAIN_AXIS_X;
ruler_info->constrain_mode = CONSTRAIN_MODE_1;
}
else if (event->type == EVT_YKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_Y) {
ruler_info->constrain_axis = CONSTRAIN_AXIS_Y;
ruler_info->constrain_mode = CONSTRAIN_MODE_1;
}
else if (event->type == EVT_ZKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_Z) {
ruler_info->constrain_axis = CONSTRAIN_AXIS_Z;
ruler_info->constrain_mode = CONSTRAIN_MODE_1;
}
else {
/* Cycle to the next mode if the same key is pressed again. */
if (ruler_info->constrain_mode != CONSTRAIN_MODE_2) {
ruler_info->constrain_mode++;
}
else {
ruler_info->constrain_mode = CONSTRAIN_MODE_OFF;
ruler_info->constrain_axis = CONSTRAIN_AXIS_NONE;
}
}
do_cursor_update = true;
}
#endif
#ifndef USE_SNAP_DETECT_FROM_KEYMAP_HACK
const bool do_snap = !(tweak_flag & WM_GIZMO_TWEAK_SNAP);
#endif
@@ -986,6 +1083,11 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
const float mval_fl[2] = {UNPACK2(event->mval)};
#ifdef USE_AXIS_CONSTRAINTS
ruler_info->constrain_axis = CONSTRAIN_AXIS_NONE;
ruler_info->constrain_mode = CONSTRAIN_MODE_OFF;
#endif
/* select and drag */
if (gz->highlight_part == PART_LINE) {
if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {