[Bf-blender-cvs] [c6e49ad951e] transform-navigation-snapsource: Allow navigating while transforming

Germano Cavalcante noreply at git.blender.org
Fri Nov 19 20:15:56 CET 2021


Commit: c6e49ad951e3a49b2d184febd70b9dfaafc906ce
Author: Germano Cavalcante
Date:   Fri Nov 19 15:29:02 2021 -0300
Branches: transform-navigation-snapsource
https://developer.blender.org/rBc6e49ad951e3a49b2d184febd70b9dfaafc906ce

Allow navigating while transforming

Navigating while transforming is not a new idea:
- https://rightclickselect.com/p/ui/Tqbbbc/allow-navigating-while-transforming (See comments);
- {D1583}
- {T37427}

This feature allows us to be more precise where the transformed element will be placed.

This would avoid, for example, the need for the node editor to automatically update the viewport when a node is transformed.

And with {D9415} navigating while transform becomes a necessity because: how could we move from a point at the bottom of one object to the top of another without being able to rotate the view?

##Patch
The patch implements this feature as being experimental (See image):
{F11826349, layout=left, width=600}
Because transform's modal keymaps conflict, two (temporary) operators were created to update the keymap and avoid conflicts.
The main solution in the patch was to create the `bool WM_operator_do_navigation(...);` utility that can be used for any operator.

##Implementation Details
- This feature affects all editors where transforming is possible (UV, VSE, Graph...)
- The Node editor is the only one that, when canceling, the viewport position is reset
- Default modal keymaps need to be edited to avoid conflict (in the patch a temporary operator was implemented to automatically update keymaps)

Differential Revision: https://developer.blender.org/D2624

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

M	release/scripts/startup/bl_ui/space_userpref.py
M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform.h
M	source/blender/editors/transform/transform_convert_node.c
M	source/blender/editors/transform/transform_generics.c
M	source/blender/editors/transform/transform_input.c
M	source/blender/editors/transform/transform_ops.c
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_userdef.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_operator_utils.c
M	source/blender/windowmanager/wm_event_system.h
M	source/tools

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

diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 5032256e4d1..93f01cbe139 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -2292,8 +2292,16 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
                 ({"property": "use_sculpt_tools_tilt"}, "T82877"),
                 ({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")),
                 ({"property": "use_override_templates"}, ("T73318", "Milestone 4")),
+                ({"property": "use_navigate_while_transform"}, ("T73993", "Milestone 2")),
             ),
         )
+        experimental = context.preferences.experimental
+
+        if experimental.use_navigate_while_transform:
+            split = self.layout.split(factor=0.66)
+            row = split.split()
+            row.operator("transform.modalkeymap_update")
+            row.operator("transform.modalkeymap_restore")
 
 
 class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ae4c3f02c46..8e1be2a36b1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -108,9 +108,6 @@ void setTransformViewMatrices(TransInfo *t)
     unit_m4(t->persinv);
     t->persp = RV3D_ORTHO;
   }
-
-  calculateCenter2D(t);
-  calculateCenterLocal(t, t->center_global);
 }
 
 void setTransformViewAspect(TransInfo *t, float r_aspect[3])
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index d78cd13f8b8..f314d87b63e 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -155,6 +155,9 @@ typedef enum {
 
   /** No cursor wrapping on region bounds */
   T_NO_CURSOR_WRAP = 1 << 23,
+
+  /** To indicate that V3D matrices have changed due to navigation. */
+  T_VIEW_DIRTY = 1 << 24,
 } eTFlag;
 
 /** #TransInfo.modifiers */
@@ -761,6 +764,8 @@ void applyMouseInput(struct TransInfo *t,
                      struct MouseInput *mi,
                      const int mval[2],
                      float output[3]);
+void transform_input_reset(MouseInput *mi, const int mval[2]);
+void transform_input_update(TransInfo *t, const float fac);
 
 void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
 void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]);
@@ -793,6 +798,7 @@ void calculateCenter2D(TransInfo *t);
 void calculateCenterLocal(TransInfo *t, const float center_global[3]);
 
 void calculateCenter(TransInfo *t);
+void tranformViewUpdate(TransInfo *t);
 
 /* API functions for getting center points */
 void calculateCenterBound(TransInfo *t, float r_center[3]);
diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c
index da11666d445..10c0ee48749 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.c
@@ -164,6 +164,7 @@ void createTransNodeData(TransInfo *t)
 void flushTransNodes(TransInfo *t)
 {
   const float dpi_fac = UI_DPI_FAC;
+  float offset[2] = {0.0f, 0.0f};
 
   View2DEdgePanData *customdata = (View2DEdgePanData *)t->custom.type.data;
 
@@ -177,14 +178,16 @@ void flushTransNodes(TransInfo *t)
           t->region->winrct.xmin + t->mval[0],
           t->region->winrct.ymin + t->mval[1],
       };
+      const rctf rect = t->region->v2d.cur;
       UI_view2d_edge_pan_apply(t->context, customdata, xy);
+      if (!BLI_rctf_compare(&rect, &t->region->v2d.cur, FLT_EPSILON)) {
+        /* Additional offset due to change in view2D rect. */
+        BLI_rctf_transform_pt_v(&t->region->v2d.cur, &rect, offset, offset);
+        t->flag |= T_VIEW_DIRTY;
+      }
     }
   }
 
-  /* Initial and current view2D rects for additional transform due to view panning and zooming */
-  const rctf *rect_src = &customdata->initial_rect;
-  const rctf *rect_dst = &t->region->v2d.cur;
-
   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
     applyGridAbsolute(t);
 
@@ -195,10 +198,7 @@ void flushTransNodes(TransInfo *t)
       bNode *node = td->extra;
 
       float loc[2];
-      copy_v2_v2(loc, td2d->loc);
-
-      /* additional offset due to change in view2D rect */
-      BLI_rctf_transform_pt_v(rect_dst, rect_src, loc, loc);
+      add_v2_v2v2(loc, td2d->loc, offset);
 
 #ifdef USE_NODE_CENTER
       loc[0] -= 0.5f * BLI_rctf_size_x(&node->totr);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 4194fb2a0ad..7846fa93f03 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -679,6 +679,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
   }
 
   setTransformViewMatrices(t);
+  calculateCenter2D(t);
+  calculateCenterLocal(t, t->center_global);
   initNumInput(&t->num);
 }
 
@@ -1140,6 +1142,33 @@ static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[
   }
 }
 
+static void calculateZfac(TransInfo *t)
+{
+  /* ED_view3d_calc_zfac() defines a factor for perspective depth correction,
+   * used in ED_view3d_win_to_delta() */
+
+  /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
+   * and never used in other cases.
+   *
+   * We need special case here as well, since ED_view3d_calc_zfac will crash when called
+   * for a region different from RGN_TYPE_WINDOW.
+   */
+  if (t->spacetype == SPACE_VIEW3D) {
+    t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global, NULL);
+  }
+  else if (t->spacetype == SPACE_IMAGE) {
+    SpaceImage *sima = t->area->spacedata.first;
+    t->zfac = 1.0f / sima->zoom;
+  }
+  else {
+    View2D *v2d = &t->region->v2d;
+    /* Get zoom fac the same way as in
+     * `ui_view2d_curRect_validate_resize` - better keep in sync! */
+    const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
+    t->zfac = 1.0f / zoomx;
+  }
+}
+
 void calculateCenter(TransInfo *t)
 {
   if ((t->flag & T_OVERRIDE_CENTER) == 0) {
@@ -1174,23 +1203,38 @@ void calculateCenter(TransInfo *t)
     }
   }
 
+  calculateZfac(t);
+}
+
+/* Called every time the view changes due to navigation.
+ * Adjusts the mouse position relative to the object. */
+void tranformViewUpdate(TransInfo *t)
+{
   if (t->spacetype == SPACE_VIEW3D) {
-    /* ED_view3d_calc_zfac() defines a factor for perspective depth correction,
-     * used in ED_view3d_win_to_delta() */
-
-    /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
-     * and never used in other cases.
-     *
-     * We need special case here as well, since ED_view3d_calc_zfac will crash when called
-     * for a region different from RGN_TYPE_WINDOW.
-     */
-    if (t->region->regiontype == RGN_TYPE_WINDOW) {
-      t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global, NULL);
-    }
-    else {
-      t->zfac = 0.0f;
+    setTransformViewMatrices(t);
+
+    for (int i = 0; i < ARRAY_SIZE(t->orient); i++) {
+      if (t->orient[i].type == V3D_ORIENT_VIEW) {
+        copy_m3_m4(t->orient[i].matrix, t->viewinv);
+        normalize_m3(t->orient[i].matrix);
+        if (t->orient_curr == i) {
+          copy_m3_m3(t->spacemtx, t->orient[i].matrix);
+          invert_m3_m3_safe_ortho(t->spacemtx_inv, t->spacemtx);
+        }
+      }
     }
   }
+
+  float fac = 1.0f;
+  if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE)) {
+    float zfac_prev = t->zfac;
+    calculateZfac(t);
+    fac = zfac_prev / t->zfac;
+  }
+
+  calculateCenter2D(t);
+  transform_input_update(t, fac);
+  t->flag &= ~T_VIEW_DIRTY;
 }
 
 void calculatePropRatio(TransInfo *t)
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 0b46d0b9a13..5d27f13bca9 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -455,4 +455,30 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
   }
 }
 
+void transform_input_update(TransInfo *t, const float fac)
+{
+  MouseInput *mi = &t->mouse;
+  int offset[2], center_2d_int[2] = {mi->center[0], mi->center[1]};
+  sub_v2_v2v2_int(offset, mi->imval, center_2d_int);
+  offset[0] *= fac;
+  offset[1] *= fac;
+  t->mouse.factor *= fac;
+
+  center_2d_int[0] = t->center2d[0];
+  center_2d_int[1] = t->center2d[1];
+  add_v2_v2v2_int(mi->imval, center_2d_int, offset);
+
+  float center_old[2];
+  copy_v2_v2(center_old, mi->center);
+  copy_v2_v2(mi->center, t->center2d);
+
+  if (ELEM(mi->apply, InputAngle, InputAngleSpring)) {
+    float offset_center[2];
+    sub_v2_v2v2(offset_center, mi->center, center_old);
+    struct InputAngle_Data *data = mi->data;
+    data->mval_prev[0] += offset_center[0];
+    data->mval_prev[1] += offset_center[1];
+  }
+}
+
 /** \} */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 5ed340abf97..abcdf51c430 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -23,7 +23,10 @@
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "BLI_alloca.h"
+#include "BLI_listbase.h"
 #include "BLI_math.h"
+#include "BLI_string.h"
 #include "BLI_utildefines.h"
 
 #include "BLT_translation.h"
@@ -427,6 +430,14 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
   exit_code = transformEvent(t, event);
   t->context = NULL;
 
+  if ((exit_code == OPERATOR_PASS_THROUGH) && WM_operator_do_navigation(C, op, event)) {
+    t->flag |= T_VIEW_DIRTY;
+    return OPERATOR_RUNNING_MODAL;
+  }
+  else if (t->flag & T_VIEW_DIRTY) {
+    tranformViewUpdate(t);
+  }
+
   /* XXX, workaround: active needs to be calculated before transformin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list