Transform: absolute grid snapping
authorCampbell Barton <ideasman42@gmail.com>
Sat, 27 Jun 2015 05:30:17 +0000 (15:30 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 27 Jun 2015 10:03:28 +0000 (20:03 +1000)
D910 by @donfabio with edits

New icon for menu is still TODO

release/scripts/startup/bl_ui/space_view3d.py
source/blender/editors/transform/transform_constraints.c
source/blender/editors/transform/transform_snap.c
source/blender/makesrna/intern/rna_scene.c

index b608ff902598a5429795cf60d61565ef587639d3..1047d12fa5bad0ade1369c0ed7c382d20af9a215 100644 (file)
@@ -86,7 +86,7 @@ class VIEW3D_HT_header(Header):
             row = layout.row(align=True)
             row.prop(toolsettings, "use_snap", text="")
             row.prop(toolsettings, "snap_element", icon_only=True)
-            if snap_element != 'INCREMENT':
+            if snap_element not in {'INCREMENT', 'GRID'}:
                 row.prop(toolsettings, "snap_target", text="")
                 if obj:
                     if mode in {'OBJECT', 'POSE'} and snap_element != 'VOLUME':
index ae5d2c8773982d40cc3142758f75454ca5a714d7..3063ee22c55a43de0842c1dc39195c133f7f2352 100644 (file)
@@ -310,7 +310,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, const float in[3
                mul_m3_v3(t->con.pmtx, out);
 
                // With snap, a projection is alright, no need to correct for view alignment
-               if (!(t->tsnap.mode != SCE_SNAP_MODE_INCREMENT && activeSnap(t))) {
+               if (ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) || activeSnap(t)) {
                        if (getConstraintSpaceDimension(t) == 2) {
                                if (out[0] != 0.0f || out[1] != 0.0f || out[2] != 0.0f) {
                                        planeProjection(t, in, out);
index 8e100b9c92565f0657a7278d8ca58404d42ac5e7..1b0256bdeede5268851b401eafb49076a54a6572 100644 (file)
@@ -454,7 +454,7 @@ void applySnapping(TransInfo *t, float *vec)
        
                t->tsnap.applySnap(t, vec);
        }
-       else if ((t->tsnap.mode != SCE_SNAP_MODE_INCREMENT) && activeSnap(t)) {
+       else if (!ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) && activeSnap(t)) {
                double current = PIL_check_seconds_timer();
                
                // Time base quirky code to go around findnearest slowness
@@ -2393,8 +2393,8 @@ void snapGridIncrement(TransInfo *t, float *val)
 {
        GearsType action;
 
-       // Only do something if using Snap to Grid
-       if (t->tsnap.mode != SCE_SNAP_MODE_INCREMENT)
+       /* only do something if using absolute or incremental grid snapping */
+       if (!ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID))
                return;
 
        action = activeSnap(t) ? BIG_GEARS : NO_GEARS;
@@ -2435,6 +2435,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(ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID));
        BLI_assert(max_index <= 2);
 
        /* Early bailing out if no need to snap */
@@ -2461,7 +2462,21 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl
                }
        }
 
-       for (i = 0; i <= max_index; i++) {
-               val[i] = fac[action] * asp[i] * floorf(val[i] / (fac[action] * asp[i]) + 0.5f);
+       /* absolute snapping on grid based on global center */
+       if ((t->tsnap.mode == SCE_SNAP_MODE_GRID) && (t->mode == TFM_TRANSLATION)) {
+               for (i = 0; i <= max_index; i++) {
+                       /* do not let unconstrained axis jump to absolute grid increments */
+                       if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) {
+                               const float iter_fac = fac[action] * asp[i];
+                               val[i] = iter_fac * roundf((val[i] + t->center_global[i]) / iter_fac) - t->center_global[i];
+                       }
+               }
+       }
+       else {
+               /* relative snapping in fixed increments */
+               for (i = 0; i <= max_index; i++) {
+                       const float iter_fac = fac[action] * asp[i];
+                       val[i] = iter_fac * roundf(val[i] / iter_fac);
+               }
        }
 }
index 0986c50e8e427cf40bdde46ee56bbdff60621f97..d288da9754b52ff1bf9cbe81334b70d6bf93a212 100644 (file)
@@ -158,7 +158,8 @@ EnumPropertyItem mesh_select_mode_items[] = {
 };
 
 EnumPropertyItem snap_element_items[] = {
-       {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"},
+       {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_ALIGN, "Grid (increment)", "Snap to increments of grid"},
+       {SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_INCREMENT, "Grid (absolute)", "Snap to grid"},
        {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
        {SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"},
        {SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap to faces"},