Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_snap.c')
-rw-r--r--source/blender/editors/transform/transform_snap.c294
1 files changed, 156 insertions, 138 deletions
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 5db41570e00..96b7c85713b 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -378,30 +378,14 @@ void applyProject(TransInfo *t)
void applyGridAbsolute(TransInfo *t)
{
- float grid_size = 0.0f;
- GearsType grid_action;
int i;
if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
return;
}
- grid_action = BIG_GEARS;
- if (t->modifiers & MOD_PRECISION) {
- grid_action = SMALL_GEARS;
- }
+ float grid_size = (t->modifiers & MOD_PRECISION) ? t->snap_spatial[2] : t->snap_spatial[1];
- switch (grid_action) {
- case NO_GEARS:
- grid_size = t->snap_spatial[0];
- break;
- case BIG_GEARS:
- grid_size = t->snap_spatial[1];
- break;
- case SMALL_GEARS:
- grid_size = t->snap_spatial[2];
- break;
- }
/* early exit on unusable grid size */
if (grid_size == 0.0f) {
return;
@@ -445,7 +429,12 @@ void applyGridAbsolute(TransInfo *t)
void applySnapping(TransInfo *t, float *vec)
{
/* Each Trans Data already makes the snap to face */
- if (doForceIncrementSnap(t) || (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE)) {
+ if (doForceIncrementSnap(t)) {
+ return;
+ }
+
+ if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) {
+ /* The snap has already been resolved for each transdata. */
return;
}
@@ -559,6 +548,12 @@ static void initSnappingMode(TransInfo *t)
}
t->tsnap.mode = ts->snap_mode;
+ if ((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
+ (t->mode == TFM_TRANSLATION)) {
+ /* Special case in which snap to increments is transformed to snap to grid. */
+ t->tsnap.mode &= ~SCE_SNAP_MODE_INCREMENT;
+ t->tsnap.mode |= SCE_SNAP_MODE_GRID;
+ }
}
if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) {
@@ -600,7 +595,7 @@ static void initSnappingMode(TransInfo *t)
}
}
else {
- /* Grid if snap is not possible */
+ /* Increment if snap is not possible */
t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
}
}
@@ -613,7 +608,7 @@ static void initSnappingMode(TransInfo *t)
t->tsnap.mode = SCE_SNAP_MODE_GRID; /* Dummy, should we rather add a NOP mode? */
}
else {
- /* Always grid outside of 3D view */
+ /* Always increment outside of 3D view */
t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
}
@@ -686,11 +681,6 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0);
t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
}
-
- /* for now only 3d view (others can be added if we want) */
- if (t->spacetype == SPACE_VIEW3D) {
- t->tsnap.snap_spatial_grid = ((t->settings->snap_flag & SCE_SNAP_ABS_GRID) != 0);
- }
}
t->tsnap.target = snap_target;
@@ -832,11 +822,6 @@ void getSnapPoint(const TransInfo *t, float vec[3])
/** \name Calc Snap (Generic)
* \{ */
-static void UNUSED_FUNCTION(CalcSnapGrid)(TransInfo *t, float *UNUSED(vec))
-{
- snapGridIncrementAction(t, t->tsnap.snapPoint, BIG_GEARS);
-}
-
static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
{
if (t->spacetype == SPACE_VIEW3D) {
@@ -1407,77 +1392,160 @@ void snapFrameTransform(TransInfo *t,
/*================================================================*/
-static void applyGridIncrement(
- TransInfo *t, float *val, int max_index, const float fac[3], GearsType action);
-
-void snapGridIncrementAction(TransInfo *t, float *val, GearsType action)
+void snapSequenceBounds(TransInfo *t, const int mval[2])
{
- float fac[3];
+ /* Reuse increment, strictly speaking could be another snap mode, but leave as is. */
+ if (!(t->modifiers & MOD_SNAP_INVERT)) {
+ return;
+ }
+
+ /* Convert to frame range. */
+ float xmouse, ymouse;
+ UI_view2d_region_to_view(&t->region->v2d, mval[0], mval[1], &xmouse, &ymouse);
+ const int frame_curr = round_fl_to_int(xmouse);
- fac[NO_GEARS] = t->snap[0];
- fac[BIG_GEARS] = t->snap[1];
- fac[SMALL_GEARS] = t->snap[2];
+ /* Now find the closest sequence. */
+ const int frame_near = BKE_sequencer_find_next_prev_edit(
+ t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true);
- applyGridIncrement(t, val, t->idx_max, fac, action);
+ const int frame_snap = transform_convert_sequencer_get_snap_bound(t);
+ t->values[0] = frame_near - frame_snap;
}
-void snapGridIncrement(TransInfo *t, float *val)
+static void snap_grid_apply_ex(
+ TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
{
- GearsType action;
+ const float *center_global = t->center_global;
+ const float *asp = t->aspect;
+ bool use_local_axis = false;
- /* 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)) &&
- !doForceIncrementSnap(t)) {
- return;
+ /* use a fallback for cursor selection,
+ * this isn't useful as a global center for absolute grid snapping
+ * since its not based on the position of the selection. */
+ if (t->around == V3D_AROUND_CURSOR) {
+ const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN);
+ center_global = cd->global;
}
- action = activeSnap(t) ? BIG_GEARS : NO_GEARS;
-
- if (action == BIG_GEARS && (t->modifiers & MOD_PRECISION)) {
- action = SMALL_GEARS;
+ if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
+ use_local_axis = true;
}
- snapGridIncrementAction(t, val, action);
+ for (int 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 = grid_dist * asp[i];
+
+ if (use_local_axis) {
+ float local_axis[3];
+ float pos_on_axis[3];
+
+ copy_v3_v3(local_axis, t->spacemtx[i]);
+ copy_v3_v3(pos_on_axis, t->spacemtx[i]);
+
+ /* amount of movement on axis from initial pos */
+ mul_v3_fl(pos_on_axis, loc[i]);
+
+ /* actual global position on axis */
+ add_v3_v3(pos_on_axis, center_global);
+
+ float min_dist = INFINITY;
+ for (int j = 0; j < 3; j++) {
+ if (fabs(local_axis[j]) < 0.01f) {
+ /* Ignore very small (normalized) axis changes */
+ continue;
+ }
+
+ /* closest point on grid */
+ float grid_p = iter_fac * roundf(pos_on_axis[j] / iter_fac);
+ float dist_p = fabs((grid_p - pos_on_axis[j]) / local_axis[j]);
+
+ /* The amount of distance needed to travel along the
+ * local axis to snap to the closest grid point */
+ /* in the global j axis direction */
+ float move_dist = (grid_p - center_global[j]) / local_axis[j];
+
+ if (dist_p < min_dist) {
+ min_dist = dist_p;
+ r_out[i] = move_dist;
+ }
+ }
+ }
+ else {
+ r_out[i] = iter_fac * roundf((loc[i] + center_global[i]) / iter_fac) - center_global[i];
+ }
+ }
+ }
}
-void snapSequenceBounds(TransInfo *t, const int mval[2])
+static void snap_grid_apply(TransInfo *t, int max_index, const float grid_dist, float *r_val)
{
- /* Reuse increment, strictly speaking could be another snap mode, but leave as is. */
- if (!(t->modifiers & MOD_SNAP_INVERT)) {
+ BLI_assert(t->tsnap.mode & SCE_SNAP_MODE_GRID);
+ BLI_assert(max_index <= 2);
+
+ /* Early bailing out if no need to snap */
+ if (grid_dist == 0.0f) {
return;
}
- /* Convert to frame range. */
- float xmouse, ymouse;
- UI_view2d_region_to_view(&t->region->v2d, mval[0], mval[1], &xmouse, &ymouse);
- const int frame_curr = round_fl_to_int(xmouse);
+ /* absolute snapping on grid based on global center.
+ * for now only 3d view (others can be added if we want) */
+ snap_grid_apply_ex(t, max_index, grid_dist, r_val, r_val);
+}
- /* Now find the closest sequence. */
- const int frame_near = BKE_sequencer_find_next_prev_edit(
- t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true);
+bool transform_snap_grid(TransInfo *t, float *val)
+{
+ if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) {
+ /* Don't do grid snapping if there is a valid snap point. */
+ return false;
+ }
- const int frame_snap = transform_convert_sequencer_get_snap_bound(t);
- t->values[0] = frame_near - frame_snap;
+ if (t->spacetype != SPACE_VIEW3D) {
+ return false;
+ }
+
+ if (t->mode != TFM_TRANSLATION) {
+ return false;
+ }
+
+ float grid_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] :
+ t->snap[0];
+
+ snap_grid_apply(t, t->idx_max, grid_dist, val);
+ return true;
}
-static void applyGridIncrement(
- TransInfo *t, float *val, int max_index, const float fac[3], GearsType action)
+static void snap_increment_apply_ex(TransInfo *t,
+ const int max_index,
+ const float increment_val,
+ const float aspect[3],
+ const float loc[3],
+ float r_out[3])
{
- float asp_local[3] = {1, 1, 1};
- const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION);
- const float *asp = use_aspect ? t->aspect : asp_local;
- int i;
+ /* relative snapping in fixed increments */
+ for (int i = 0; i <= max_index; i++) {
+ const float iter_fac = increment_val * aspect[i];
+ r_out[i] = iter_fac * roundf(loc[i] / iter_fac);
+ }
+}
- BLI_assert((t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) ||
- doForceIncrementSnap(t));
+static void snap_increment_apply(TransInfo *t,
+ int max_index,
+ const float increment_dist,
+ float *r_val)
+{
+ BLI_assert((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) || doForceIncrementSnap(t));
BLI_assert(max_index <= 2);
/* Early bailing out if no need to snap */
- if (fac[action] == 0.0f) {
+ if (increment_dist == 0.0f) {
return;
}
+ float asp_local[3] = {1, 1, 1};
+ const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION);
+ const float *asp = use_aspect ? t->aspect : asp_local;
+
if (use_aspect) {
/* custom aspect for fcurve */
if (t->spacetype == SPACE_GRAPH) {
@@ -1491,76 +1559,26 @@ static void applyGridIncrement(
}
}
- /* absolute snapping on grid based on global center */
- if ((t->tsnap.snap_spatial_grid) && (t->mode == TFM_TRANSLATION)) {
- const float *center_global = t->center_global;
- bool use_local_axis = false;
-
- /* use a fallback for cursor selection,
- * this isn't useful as a global center for absolute grid snapping
- * since its not based on the position of the selection. */
- if (t->around == V3D_AROUND_CURSOR) {
- const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN);
- center_global = cd->global;
- }
-
- if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
- use_local_axis = true;
- }
-
- 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];
-
- if (use_local_axis) {
- float local_axis[3];
- float pos_on_axis[3];
-
- copy_v3_v3(local_axis, t->spacemtx[i]);
- copy_v3_v3(pos_on_axis, t->spacemtx[i]);
-
- /* amount of movement on axis from initial pos */
- mul_v3_fl(pos_on_axis, val[i]);
-
- /* actual global position on axis */
- add_v3_v3(pos_on_axis, center_global);
+ snap_increment_apply_ex(t, max_index, increment_dist, asp, r_val, r_val);
+}
- float min_dist = INFINITY;
- for (int j = 0; j < 3; j++) {
- if (fabs(local_axis[j]) < 0.01f) {
- /* Ignore very small (normalized) axis changes */
- continue;
- }
+bool transform_snap_increment(TransInfo *t, float *val)
+{
+ if (!(t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && !doForceIncrementSnap(t)) {
+ return false;
+ }
- /* closest point on grid */
- float grid_p = iter_fac * roundf(pos_on_axis[j] / iter_fac);
- float dist_p = fabs((grid_p - pos_on_axis[j]) / local_axis[j]);
+ if (t->spacetype != SPACE_VIEW3D && validSnap(t)) {
+ /* Only do something if using absolute or incremental grid snapping
+ * and there is no valid snap point. */
+ return false;
+ }
- /* The amount of distance needed to travel along the
- * local axis to snap to the closest grid point */
- /* in the global j axis direction */
- float move_dist = (grid_p - center_global[j]) / local_axis[j];
+ float increment_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] :
+ t->snap[0];
- if (dist_p < min_dist) {
- min_dist = dist_p;
- val[i] = move_dist;
- }
- }
- }
- else {
- val[i] = iter_fac * roundf((val[i] + center_global[i]) / iter_fac) - 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);
- }
- }
+ snap_increment_apply(t, t->idx_max, increment_dist, val);
+ return true;
}
/** \} */