[Bf-blender-cvs] [1fadff53501] transform-navigation-snapsource: Transform: interactive mode for setting a 'Snap Source'

Germano Cavalcante noreply at git.blender.org
Fri Dec 3 00:27:48 CET 2021


Commit: 1fadff5350105ed1fd318a5d063171e1858d6f07
Author: Germano Cavalcante
Date:   Wed Nov 17 11:02:54 2021 -0300
Branches: transform-navigation-snapsource
https://developer.blender.org/rB1fadff5350105ed1fd318a5d063171e1858d6f07

Transform: interactive mode for setting a 'Snap Source'

This patch implements part of what was stated in {T66484}, with respect to `Base Point`.

## Introduction

The snapping feature of the transform tools has a variety of applications:
- Organization of nodes.
- Positioning of frames in precise time units.
- Retopology with snap to face
- Creation of armatures with bone positioning through the snap to volume
- Precise positioning of 3D or 2D objects in the surrounding geometry (CAD modeling)

The goal of this document is to make it more powerful for precision modeling and still supporting the old use cases without extra complexity.
The main topic addressed here is the introduction of a **interactive mode for setting a snap source** (See terminology).

## Terminology

* **Snap Source**: 3d coordinate * we want to snap from. (Currently defined by the `Snap With` options: `Closest`, `Center`, `Median` and `Active`).
* **Snap Target**: 3d coordinate*  we want to snap to. (Vertices, Edges, Faces, Grid...)

## Interactive Mode for Editing a Snap Source

Currently the fixed snap point can only be obtained through the `Snap With` options. So it's a little tricky for the user to define a snap source point having so much geometry on an object.
Because of this, the user needs to resort to impractical solutions to get a point in the geometry.
See example of an impractical use:
{F11714181, layout=left, width=960, alt="The user used the cursor (which can be snapped) to choose the snap origin point."}
The user used the cursor (which can be snapped) to choose the snap source point.

While it is possible to work around this current limitation, it is important to reduce the number of steps and allow the user to set a snap source point through an optional interactive mode during a transformation.

The proposed solution is to be able to move the current snap source point through a modal modifier activated with a key (eg. B).
The snap source point can thus "snap" to the elements in the scene (vertex, mid-edge, Lamp, …) during this mode.
{F9122814, layout=left, width=960, alt="Base Point Snap, example of transform operation via the shortcut (not the tool). After pressing g and the snap base change shortcut (e.g., shift + ctrl) the user set the base point. The base point is then visible until the end of the operation. The z axis constrains the final position."}

## Implementation Details

- The feature will only be available in 3D View.
- The feature will only be available for `Move`, `Rotate` and `Scale` transform modes.
- The snap source editing will be enabled with a single click on the modifier key (B).
- Having a snap point indicated, the new snap origin point will be confirmed with the same buttons that confirms the transformation (but the transformation will not be concluded).
- The snap source editing can be canceled with the same key that activated it (B).
- If the transformation is done with "release_confirm" (common for gizmos), the new feature cannot be enabled.
- During the transformation, when enabling the feature, if the snap option is turned off in the scene, the snap will be forced on throughout the rest of the transformation (unless interactive mode is canceled).
- During a transformation, if no snap target is set for an element in the scene (Vertex, Grid...), the snap targets to geometry Vertex, Edge, Face, Center of Edge and Perpendicular of Edge will be set automatically.
- Snap cannot be turned off during the snap source editing.
- Constraint or similar modification features will not be available during the snap source editing.
- Text input will not be available during the snap source editing.
- When adding multiple snap points (A) the new prone snap source point will be indicated with an "X" drawing.
{F11817267}

Maniphest Tasks: T66484

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

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform.h
M	source/blender/editors/transform/transform_input.c
M	source/blender/editors/transform/transform_snap.c
M	source/blender/editors/transform/transform_snap.h
M	source/blender/editors/transform/transform_snap_object.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 543742709ef..25fdadc04db 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5606,6 +5606,7 @@ def km_transform_modal_map(_params):
         ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
         ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
         ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
+        ("EDIT_SNAP_SOURCE", {"type": 'B', "value": 'PRESS'}, None),
     ])
 
     return keymap
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 3019322d340..a5a8cba5c74 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -3997,6 +3997,7 @@ def km_transform_modal_map(_params):
         ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
         ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
         ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
+        ("EDIT_SNAP_SOURCE", {"type": 'B', "value": 'PRESS'}, None),
     ])
 
     return keymap
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ae4c3f02c46..c376c718245 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -578,6 +578,21 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
 static bool transform_modal_item_poll(const wmOperator *op, int value)
 {
   const TransInfo *t = op->customdata;
+  if (t->modifiers & MOD_EDIT_SNAP_SOURCE) {
+    if (value == TFM_MODAL_EDIT_SNAP_SOURCE) {
+      return true;
+    }
+    else if (!ELEM(value,
+                   TFM_MODAL_CANCEL,
+                   TFM_MODAL_CONFIRM,
+                   TFM_MODAL_SNAP_INV_ON,
+                   TFM_MODAL_SNAP_INV_OFF,
+                   TFM_MODAL_ADD_SNAP,
+                   TFM_MODAL_REMOVE_SNAP)) {
+      return false;
+    }
+  }
+
   switch (value) {
     case TFM_MODAL_CANCEL: {
       /* TODO: Canceling with LMB is not possible when the operator is activated
@@ -593,6 +608,13 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
       }
       break;
     }
+    case TFM_MODAL_SNAP_INV_ON:
+    case TFM_MODAL_SNAP_INV_OFF: {
+      if (t->modifiers & MOD_SNAP_TEMP) {
+        return false;
+      }
+      break;
+    }
     case TFM_MODAL_ADD_SNAP:
     case TFM_MODAL_REMOVE_SNAP: {
       if (t->spacetype != SPACE_VIEW3D) {
@@ -664,6 +686,19 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
       }
       break;
     }
+    case TFM_MODAL_EDIT_SNAP_SOURCE: {
+      if (t->spacetype != SPACE_VIEW3D) {
+        return false;
+      }
+      if (t->flag & T_RELEASE_CONFIRM) {
+        return false;
+      }
+      if (!ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
+        /* More modes can be added over time if this feature proves useful for them. */
+        return false;
+      }
+      break;
+    }
   }
   return true;
 }
@@ -714,6 +749,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
       {TFM_MODAL_AUTOCONSTRAINT, "AUTOCONSTRAIN", 0, "Automatic Constraint", ""},
       {TFM_MODAL_AUTOCONSTRAINTPLANE, "AUTOCONSTRAINPLANE", 0, "Automatic Constraint Plane", ""},
       {TFM_MODAL_PRECISION, "PRECISION", 0, "Precision Mode", ""},
+      {TFM_MODAL_EDIT_SNAP_SOURCE, "EDIT_SNAP_SOURCE", 0, "Snap Source Toggle", ""},
       {0, NULL, 0, NULL, NULL},
   };
 
@@ -891,7 +927,12 @@ int transformEvent(TransInfo *t, const wmEvent *event)
         handled = true;
         break;
       case TFM_MODAL_CONFIRM:
-        t->state = TRANS_CONFIRM;
+        if (t->modifiers & MOD_EDIT_SNAP_SOURCE) {
+          tranform_snap_source_mod_confirm(t);
+        }
+        else {
+          t->state = TRANS_CONFIRM;
+        }
         handled = true;
         break;
       case TFM_MODAL_TRANSLATE:
@@ -1156,6 +1197,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
           t->redraw |= TREDRAW_HARD;
         }
         break;
+      case TFM_MODAL_EDIT_SNAP_SOURCE:
+        tranform_snap_source_mod_toggle(t);
+        break;
       /* Those two are only handled in transform's own handler, see T44634! */
       case TFM_MODAL_EDGESLIDE_UP:
       case TFM_MODAL_EDGESLIDE_DOWN:
@@ -1532,7 +1576,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 
   if (t->flag & T_MODAL) {
     /* do we check for parameter? */
-    if (transformModeUseSnap(t)) {
+    if (transformModeUseSnap(t) && !(t->modifiers & MOD_SNAP_TEMP)) {
       if (!(t->modifiers & MOD_SNAP) != !(ts->snap_flag & SCE_SNAP)) {
         if (t->modifiers & MOD_SNAP) {
           ts->snap_flag |= SCE_SNAP;
@@ -1920,14 +1964,17 @@ void transformApply(bContext *C, TransInfo *t)
 
   if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) {
     selectConstraint(t);
-    if (t->transform) {
+    if (t->modifiers & MOD_EDIT_SNAP_SOURCE) {
+      tranform_snap_source_mod_update(t);
+    }
+    else if (t->transform) {
       t->transform(t, t->mval); /* calls recalcData() */
-      viewRedrawForce(C, t);
     }
-    t->redraw = TREDRAW_NOTHING;
   }
-  else if (t->redraw & TREDRAW_SOFT) {
+
+  if (t->redraw & (TREDRAW_HARD | TREDRAW_SOFT)) {
     viewRedrawForce(C, t);
+    t->redraw = TREDRAW_NOTHING;
   }
 
   /* If auto confirm is on, break after one pass */
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 380df739876..00ae4a82d95 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -163,7 +163,9 @@ typedef enum {
   MOD_PRECISION = 1 << 1,
   MOD_SNAP = 1 << 2,
   MOD_SNAP_INVERT = 1 << 3,
-  MOD_CONSTRAINT_SELECT_PLANE = 1 << 4,
+  MOD_SNAP_TEMP = 1 << 4,
+  MOD_CONSTRAINT_SELECT_PLANE = 1 << 5,
+  MOD_EDIT_SNAP_SOURCE = 1 << 6,
 } eTModifier;
 
 /** #TransSnap.status */
@@ -294,6 +296,8 @@ enum {
   TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
 
   TFM_MODAL_PRECISION = 30,
+
+  TFM_MODAL_EDIT_SNAP_SOURCE = 31,
 };
 
 /** \} */
@@ -761,6 +765,7 @@ 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 setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
 void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]);
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 0b46d0b9a13..d9a29b8d6b7 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -418,6 +418,10 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
 
 void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
 {
+  if (t->modifiers & MOD_EDIT_SNAP_SOURCE) {
+    return;
+  }
+
   double mval_db[2];
 
   if (mi->use_virtual_mval) {
@@ -455,4 +459,15 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
   }
 }
 
+void transform_input_reset(MouseInput *mi, const int mval[2])
+{
+  copy_v2_v2_int(mi->imval, mval);
+  if (ELEM(mi->apply, InputAngle, InputAngleSpring)) {
+    struct InputAngle_Data *data = mi->data;
+    data->mval_prev[0] = mi->imval[0];
+    data->mval_prev[1] = mi->imval[1];
+    data->angle = 0.0f;
+  }
+}
+
 /** \} */
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 71f26ef0594..8ed0a1f2ea8 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -136,6 +136,10 @@ bool validSnap(const TransInfo *t)
 
 bool activeSnap(const TransInfo *t)
 {
+  if (t->modifiers & MOD_SNAP_TEMP) {
+    return true;
+  }
+
   return ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP) ||
          ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT);
 }
@@ -178,7 +182,7 @@ bool transformModeUseSnap(const TransInfo *t)
 
 static bool doForceIncrementSnap(const TransInfo *t)
 {
-  return !transformModeUseSnap(t);
+  return !(t->modifiers & MOD_SNAP_TEMP) && !transformModeUseSnap(t);
 }
 
 void drawSnapping(const struct bContext *C, TransInfo *t)
@@ -232,6 +236,47 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
           imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size, view_inv, pos);
         }
 
+        if (t->modifiers & MOD_EDIT_SNAP_SOURCE) {
+          /* Indicate the new snap source position. */
+
+          float snap_point[3];
+          getSnapPoint(t, snap_point);
+
+          float vx[3], vy[3], v[3];
+          float size_tmp = ED_view3d_pixel_size(rv3d, snap_point) * size;
+          float size_fac = 0.5f;
+
+          mul_v3_v3fl(vx, view_inv[0], size_tmp);
+          mul_v3_v3fl(vy, view_inv[1], size_tmp);
+
+          immUniformColor4ubv(col);
+
+          imm_drawcircball(snap_point, size_tmp, view_inv, pos);
+
+          immBegin(GPU_PRIM_LINES, 8);
+          add_v3_v3v3(v, snap_point, vx);
+          immVertex3fv(pos, v);
+          madd_v3_v3fl(v, vx, size_fac);
+          immVertex3fv(pos, v);
+
+          sub_v3_v3v3(v, snap_point, vx);
+          immVertex3fv(pos, v);
+          madd_v3_v3fl(v, vx, -size_fac);
+          immVertex3fv(pos, v);
+
+          add_v3_v3v3(v, snap_point, vy);
+          immVertex3fv(pos, v);
+          madd_v3_v3fl(v, vy, size_fac);
+          immVertex3fv(pos, v);
+
+          sub_v3_v3v3(v, snap_point, vy);
+          immVertex3fv(pos, v);
+          madd_v3_v3fl(v, vy, -size_fac);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list