Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Abrahamsson <ecke101@gmail.com>2021-08-31 10:14:32 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-08-31 10:21:11 +0300
commitfa4a35d4c4eea7cd0c4a9a8bf448afd27c273695 (patch)
treee80bb5f6c4742bc0566134154bd7853ff765facf /source/blender/editors/space_view3d/view3d_gizmo_ruler.c
parentfa4f9292e16ce6a9253164ea731870c6d0161848 (diff)
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
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_gizmo_ruler.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index edc34d0d883..f8278edbcae 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -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) {