[Bf-blender-cvs] [fa4a35d4c4e] master: Measure tool: Add support to restrict dimension to one axis

Eric Abrahamsson noreply at git.blender.org
Tue Aug 31 09:21:55 CEST 2021


Commit: fa4a35d4c4eea7cd0c4a9a8bf448afd27c273695
Author: Eric Abrahamsson
Date:   Tue Aug 31 17:14:32 2021 +1000
Branches: master
https://developer.blender.org/rBfa4a35d4c4eea7cd0c4a9a8bf448afd27c273695

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

===================================================================

M	source/blender/editors/space_view3d/view3d_gizmo_ruler.c

===================================================================

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) {



More information about the Bf-blender-cvs mailing list