[Bf-blender-cvs] [3c060b2216b] master: Fix T100633: Node Editor: Edge scrolling breaks node snapping

Germano Cavalcante noreply at git.blender.org
Fri Aug 26 18:18:22 CEST 2022


Commit: 3c060b2216b868eec99bb0acb3534c3780344774
Author: Germano Cavalcante
Date:   Fri Aug 26 13:17:30 2022 -0300
Branches: master
https://developer.blender.org/rB3c060b2216b868eec99bb0acb3534c3780344774

Fix T100633: Node Editor: Edge scrolling breaks node snapping

The view offset, calculated by the Edge Pan system, only affects the
position of the nodes, but forget to update:
- snapping data
- final value of transform
- values used for custom drawing

Therefore, to avoid having to update a lot of scattered data, the
`transformViewUpdate` utility has been implemented to recalculate input
values when the view changes.

This utility does more than is necessary to fix the bug, but with that,
it can work in any situation.

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

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_mode.h
M	source/blender/editors/transform/transform_mode_edge_slide.c
M	source/blender/editors/transform/transform_mode_vert_slide.c

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

diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index b84ce83500f..0429e37a077 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -355,10 +355,12 @@ typedef struct MouseInput {
 
   /** Initial mouse position. */
   int imval[2];
-  bool precision;
-  float precision_factor;
+  float imval_unproj[3];
   float center[2];
   float factor;
+  float precision_factor;
+  bool precision;
+
   /** Additional data, if needed by the particular function. */
   void *data;
 
@@ -758,6 +760,7 @@ void applyMouseInput(struct TransInfo *t,
                      struct MouseInput *mi,
                      const int mval[2],
                      float output[3]);
+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]);
@@ -806,6 +809,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 e18f75b71ae..0712fd8f719 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.c
@@ -153,6 +153,7 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
 static 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;
 
@@ -166,14 +167,16 @@ static 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);
+        tranformViewUpdate(t);
+      }
     }
   }
 
-  /* 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);
 
@@ -184,10 +187,7 @@ static 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 56a7d045dfd..5bdd64dacb9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1132,6 +1132,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->region->regiontype == RGN_TYPE_WINDOW)) {
+    t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global);
+  }
+  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) {
@@ -1166,22 +1193,46 @@ void calculateCenter(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(). */
+  calculateZfac(t);
+}
+
+/* Called every time the view changes due to navigation.
+ * Adjusts the mouse position relative to the object. */
+void tranformViewUpdate(TransInfo *t)
+{
+  float zoom_prev = t->zfac;
+  float zoom_new;
+  if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
+    if (!t->persp) {
+      zoom_prev *= len_v3(t->persinv[0]);
+    }
+
+    setTransformViewMatrices(t);
+    calculateZfac(t);
 
-    /* NOTE: `t->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);
+    zoom_new = t->zfac;
+    if (!t->persp) {
+      zoom_new *= len_v3(t->persinv[0]);
     }
-    else {
-      t->zfac = 0.0f;
+
+    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);
+        }
+      }
     }
   }
+  else {
+    calculateZfac(t);
+    zoom_new = t->zfac;
+  }
+
+  calculateCenter2D(t);
+  transform_input_update(t, zoom_prev / zoom_new);
 }
 
 void calculatePropRatio(TransInfo *t)
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 3b320ff51d5..b541b199328 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 
 #include "DNA_screen_types.h"
+#include "DNA_space_types.h"
 
 #include "BKE_context.h"
 
@@ -18,6 +19,7 @@
 #include "WM_types.h"
 
 #include "transform.h"
+#include "transform_mode.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -251,11 +253,8 @@ void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[
 /** \name Setup & Handle Mouse Input
  * \{ */
 
-void initMouseInput(TransInfo *UNUSED(t),
-                    MouseInput *mi,
-                    const float center[2],
-                    const int mval[2],
-                    const bool precision)
+void initMouseInput(
+    TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], const bool precision)
 {
   mi->factor = 0;
   mi->precision = precision;
@@ -266,6 +265,12 @@ void initMouseInput(TransInfo *UNUSED(t),
   mi->imval[0] = mval[0];
   mi->imval[1] = mval[1];
 
+  if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
+    float delta[3] = {mval[0] - center[0], mval[1] - center[1]};
+    ED_view3d_win_to_delta(t->region, delta, t->zfac, delta);
+    add_v3_v3v3(mi->imval_unproj, t->center_global, delta);
+  }
+
   mi->post = NULL;
 }
 
@@ -441,4 +446,52 @@ 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;
+  t->mouse.factor *= fac;
+  if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
+    projectIntView(t, mi->imval_unproj, mi->imval);
+  }
+  else {
+    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;
+
+    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 (mi->use_virtual_mval) {
+    /* Update accumulator. */
+    double mval_delta[2];
+    sub_v2_v2v2_db(mval_delta, mi->virtual_mval.accum, mi->virtual_mval.prev);
+    mval_delta[0] *= fac;
+    mval_delta[1] *= fac;
+    copy_v2_v2_db(mi->virtual_mval.accum, mi->virtual_mval.prev);
+    add_v2_v2_db(mi->virtual_mval.accum, mval_delta);
+  }
+
+  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];
+  }
+
+  if (t->mode == TFM_EDGE_SLIDE) {
+    transform_mode_edge_slide_reproject_input(t);
+  }
+  else if (t->mode == TFM_VERT_SLIDE) {
+    transform_mode_vert_slide_reproject_input(t);
+  }
+}
+
 /** \} */
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index eac6734ed88..063de87ebb2 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -117,6 +117,7 @@ void drawEdgeSlide(TransInfo *t);
 void initEdgeSlide_ex(
     TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
 void initEdgeSlide(TransInfo *t);
+void transform_mode_edge_slide_reproject_input(TransInfo *t);
 
 /* transform_mode_gpopacity.c */
 
@@ -191,3 +192,4 @@ void initT

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list