Transform: option to use incremental snapping
authorCampbell Barton <ideasman42@gmail.com>
Mon, 17 Dec 2018 23:03:50 +0000 (10:03 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 17 Dec 2018 23:08:23 +0000 (10:08 +1100)
This resolves this issue where users would enable a snapping mode
besides incremental (vertex for eg), then notice strange behavior w/
rotate and scale.
While this ability can be useful, it's quite an obscure use case.

Now changing snap-modes keeps rotate and scale using incremental snap,
with the option for these modes to be affected by other snapping modes.

D4022 by @kioku w/ own minor edits.

release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/versioning_280.c
source/blender/editors/transform/transform_snap.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index 536a3204ad96a122401dffe75f88e013b335eedb..bfba36f255bb8ec7f935a84a78847abd33b0ca3d 100644 (file)
@@ -5225,6 +5225,12 @@ class VIEW3D_PT_snapping(Panel):
             col.prop(tool_settings, "use_snap_grid_absolute")
 
         if snap_elements != {'INCREMENT'}:
+            col.label(text="Affect")
+            row = col.row(align=True)
+            row.prop(tool_settings, "use_snap_force_increment_translate", text="Move")
+            row.prop(tool_settings, "use_snap_force_increment_rotate", text="Rotate")
+            row.prop(tool_settings, "use_snap_force_increment_scale", text="Scale")
+
             col.label(text="Target")
             row = col.row(align=True)
             row.prop(tool_settings, "snap_target", expand=True)
index 3894d83c169c6c0cbca9cb4d366d748662256669..cd0e437ec7ee0be3fa3b6f9023a331e7600fa875 100644 (file)
@@ -670,6 +670,7 @@ void BKE_scene_init(Scene *sce)
        sce->toolsettings->snap_mode = SCE_SNAP_MODE_INCREMENT;
        sce->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID;
        sce->toolsettings->snap_uv_mode = SCE_SNAP_MODE_INCREMENT;
+       sce->toolsettings->snap_force_increment_flag = SCE_SNAP_FORCE_INCREMENT_ROTATE | SCE_SNAP_FORCE_INCREMENT_SCALE;
 
        sce->toolsettings->curve_paint_settings.curve_type = CU_BEZIER;
        sce->toolsettings->curve_paint_settings.flag |= CURVE_PAINT_FLAG_CORNERS_DETECT;
index f3c9d57a67ff6c009e108438c10ee08242a2d38a..4eda9bc7a123fa0050c4a48d23956953dbc9d7e0 100644 (file)
@@ -2737,5 +2737,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
        {
                /* Versioning code until next subversion bump goes here. */
 
+               if (!DNA_struct_elem_find(fd->filesdna, "ToolSettings", "char", "snap_force_increment_flag")) {
+                       for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+                               scene->toolsettings->snap_force_increment_flag =
+                                       SCE_SNAP_FORCE_INCREMENT_ROTATE | SCE_SNAP_FORCE_INCREMENT_SCALE;
+                       }
+               }
        }
 }
index 6af920c120d75e1ba90c2163755eac44a8f9add1..c2c864b51adee95cbed10f38a9f3b3ec4de02322 100644 (file)
@@ -137,6 +137,21 @@ bool activeSnap(const TransInfo *t)
               ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT);
 }
 
+static bool doForceIncrementSnap(const TransInfo *t)
+{
+       const ToolSettings *ts = t->settings;
+       if (t->mode == TFM_TRANSLATION) {
+               return ts->snap_force_increment_flag & SCE_SNAP_FORCE_INCREMENT_TRANSLATE;
+       }
+       if (t->mode == TFM_ROTATION) {
+               return ts->snap_force_increment_flag & SCE_SNAP_FORCE_INCREMENT_ROTATE;
+       }
+       if (t->mode == TFM_RESIZE) {
+               return ts->snap_force_increment_flag & SCE_SNAP_FORCE_INCREMENT_SCALE;
+       }
+       return false;
+}
+
 void drawSnapping(const struct bContext *C, TransInfo *t)
 {
        unsigned char col[4], selectedCol[4], activeCol[4];
@@ -405,8 +420,10 @@ void applyGridAbsolute(TransInfo *t)
 
 void applySnapping(TransInfo *t, float *vec)
 {
-       if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) {
-               /* Each Trans Data already makes the snap to face */
+       /* Each Trans Data already makes the snap to face */
+       if (doForceIncrementSnap(t) ||
+           (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE))
+       {
                return;
        }
 
@@ -1450,8 +1467,8 @@ void snapGridIncrement(TransInfo *t, float *val)
 
        /* only do something if using absolute or incremental grid snapping
         * and there is no valid snap point */
-       if (!(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) ||
-           validSnap(t))
+       if ((!(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) ||
+           validSnap(t)) && !doForceIncrementSnap(t))
        {
                return;
        }
@@ -1494,7 +1511,7 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl
        const float *asp = use_aspect ? t->aspect : asp_local;
        int i;
 
-       BLI_assert(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID));
+       BLI_assert((t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) || doForceIncrementSnap(t));
        BLI_assert(max_index <= 2);
 
        /* Early bailing out if no need to snap */
index 43f236cde1efcdca4f6f140b9044a0ace0ea3318..8be63add398fb6fce3090bb9a109a0a4860dd2e0 100644 (file)
@@ -1330,7 +1330,8 @@ typedef struct ToolSettings {
        float select_thresh;
 
        /* Auto-Keying Mode */
-       short autokey_mode, autokey_flag;       /* defines in DNA_userdef_types.h */
+       short autokey_flag;     /* defines in DNA_userdef_types.h */
+       char  autokey_mode;
        char keyframe_type;                 /* keyframe type (see DNA_curve_types.h) */
 
        /* Multires */
@@ -1350,13 +1351,15 @@ typedef struct ToolSettings {
        char snap_uv_mode;
        char snap_flag;
        char snap_target;
-       short proportional, prop_mode;
+       char snap_force_increment_flag;
+
+
+       char proportional, prop_mode;
        char proportional_objects; /* proportional edit, object mode */
        char proportional_mask; /* proportional edit, mask editing */
        char proportional_action; /* proportional edit, action editor */
        char proportional_fcurve; /* proportional edit, graph editor */
        char lock_markers; /* lock marker editing */
-       char pad4[5];
 
        char auto_normalize; /*auto normalizing mode in wpaint*/
        char multipaint; /* paint multiple bones in wpaint */
@@ -1364,7 +1367,7 @@ typedef struct ToolSettings {
        char vgroupsubset; /* subset selection filter in wpaint */
 
        /* UV painting */
-       char _pad2[2];
+       char _pad2[1];
        char use_uv_sculpt;
        char uv_sculpt_settings;
        char uv_sculpt_tool;
@@ -1907,6 +1910,13 @@ enum {
 #define SCE_SNAP_MODE_NODE_X    (1 << 6)
 #define SCE_SNAP_MODE_NODE_Y    (1 << 7)
 
+/** #ToolSettings.snap_force_increment_flag */
+enum {
+       SCE_SNAP_FORCE_INCREMENT_TRANSLATE  = (1 << 0),
+       SCE_SNAP_FORCE_INCREMENT_ROTATE     = (1 << 1),
+       SCE_SNAP_FORCE_INCREMENT_SCALE      = (1 << 2),
+};
+
 /* ToolSettings.selectmode */
 #define SCE_SELECT_VERTEX      (1 << 0) /* for mesh */
 #define SCE_SELECT_EDGE                (1 << 1)
index 4d499b93ab26c12ea21daec86350f0dc11780c4d..52e4c62ea00e812bd24e93c1cc85f346c53f306f 100644 (file)
@@ -2478,6 +2478,26 @@ static void rna_def_tool_settings(BlenderRNA  *brna)
        RNA_def_property_ui_text(prop, "Project onto Self", "Snap onto itself (Edit Mode Only)");
        RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
 
+       prop = RNA_def_property(srna, "use_snap_force_increment_translate", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_force_increment_flag", SCE_SNAP_FORCE_INCREMENT_TRANSLATE);
+       RNA_def_property_ui_text(prop, "Resctrict Translation",
+                                "Translate uses the snapping modes, otherwise use increment snapping");
+       RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
+
+       prop = RNA_def_property(srna, "use_snap_force_increment_rotate", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_force_increment_flag", SCE_SNAP_FORCE_INCREMENT_ROTATE);
+       RNA_def_property_boolean_default(prop, false);
+       RNA_def_property_ui_text(prop, "Resctrict Rotate",
+                                "Rotate uses the snapping modes, otherwise use increment snapping");
+       RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
+
+       prop = RNA_def_property(srna, "use_snap_force_increment_scale", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_force_increment_flag", SCE_SNAP_FORCE_INCREMENT_SCALE);
+       RNA_def_property_boolean_default(prop, false);
+       RNA_def_property_ui_text(prop, "Resctrict Scale",
+                                "Scale uses the snapping modes, otherwise use increment snapping");
+       RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
+
        prop = RNA_def_property(srna, "use_gizmo_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "gizmo_flag");
        RNA_def_property_enum_items(prop, rna_enum_gizmo_items);