Fix T80677: Absolute grid snapping doesn't work with constraints
Regression introduced in rB546b900194f0
This commit is contained in:
@@ -163,41 +163,6 @@ void constraintNumInput(TransInfo *t, float vec[3])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void postConstraintChecks(TransInfo *t, float vec[3])
|
|
||||||
{
|
|
||||||
mul_m3_v3(t->spacemtx_inv, vec);
|
|
||||||
|
|
||||||
transform_snap_increment(t, vec);
|
|
||||||
|
|
||||||
if (t->flag & T_NULL_ONE) {
|
|
||||||
if (!(t->con.mode & CON_AXIS0)) {
|
|
||||||
vec[0] = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(t->con.mode & CON_AXIS1)) {
|
|
||||||
vec[1] = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(t->con.mode & CON_AXIS2)) {
|
|
||||||
vec[2] = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applyNumInput(&t->num, vec)) {
|
|
||||||
constraintNumInput(t, vec);
|
|
||||||
removeAspectRatio(t, vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If `t->values` is operator param, use that directly but not if snapping is forced */
|
|
||||||
if (t->flag & T_INPUT_IS_VALUES_FINAL && (t->tsnap.status & SNAP_FORCED) == 0) {
|
|
||||||
copy_v3_v3(vec, t->values);
|
|
||||||
constraintValuesFinal(t, vec);
|
|
||||||
/* inverse transformation at the end */
|
|
||||||
}
|
|
||||||
|
|
||||||
mul_m3_v3(t->spacemtx, vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
|
static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
|
||||||
{
|
{
|
||||||
if (t->spacetype == SPACE_VIEW3D) {
|
if (t->spacetype == SPACE_VIEW3D) {
|
||||||
@@ -432,15 +397,22 @@ static void applyAxisConstraintVec(
|
|||||||
{
|
{
|
||||||
copy_v3_v3(out, in);
|
copy_v3_v3(out, in);
|
||||||
if (!td && t->con.mode & CON_APPLY) {
|
if (!td && t->con.mode & CON_APPLY) {
|
||||||
|
bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false;
|
||||||
mul_m3_v3(t->con.pmtx, out);
|
mul_m3_v3(t->con.pmtx, out);
|
||||||
bool is_snap_to_edge = false, is_snap_to_face = false;
|
|
||||||
if (activeSnap(t)) {
|
if (activeSnap(t)) {
|
||||||
is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
|
if (validSnap(t)) {
|
||||||
is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
|
is_snap_to_point = (t->tsnap.snapElem & SCE_SNAP_MODE_VERTEX) != 0;
|
||||||
|
is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
|
||||||
|
is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
|
||||||
|
}
|
||||||
|
else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) {
|
||||||
|
is_snap_to_point = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* With snap points, a projection is alright, no adjustments needed. */
|
/* With snap points, a projection is alright, no adjustments needed. */
|
||||||
if (!validSnap(t) || is_snap_to_edge || is_snap_to_face) {
|
if (!is_snap_to_point || is_snap_to_edge || is_snap_to_face) {
|
||||||
const int dims = getConstraintSpaceDimension(t);
|
const int dims = getConstraintSpaceDimension(t);
|
||||||
if (dims == 2) {
|
if (dims == 2) {
|
||||||
if (!is_zero_v3(out)) {
|
if (!is_zero_v3(out)) {
|
||||||
@@ -486,7 +458,6 @@ static void applyAxisConstraintVec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postConstraintChecks(t, out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,22 +93,29 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
|
|||||||
static void applySeqSlide(TransInfo *t, const int mval[2])
|
static void applySeqSlide(TransInfo *t, const int mval[2])
|
||||||
{
|
{
|
||||||
char str[UI_MAX_DRAW_STR];
|
char str[UI_MAX_DRAW_STR];
|
||||||
|
float values_final[3];
|
||||||
|
|
||||||
snapSequenceBounds(t, mval);
|
snapSequenceBounds(t, mval);
|
||||||
|
if (applyNumInput(&t->num, values_final)) {
|
||||||
if (t->con.mode & CON_APPLY) {
|
if (t->con.mode & CON_APPLY) {
|
||||||
float tvec[3];
|
if (t->con.mode & CON_AXIS0) {
|
||||||
t->con.applyVec(t, NULL, NULL, t->values, tvec);
|
/* Do nothing. */
|
||||||
copy_v3_v3(t->values_final, tvec);
|
}
|
||||||
|
else {
|
||||||
|
mul_v2_v2fl(values_final, t->spacemtx[1], values_final[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (t->con.mode & CON_APPLY) {
|
||||||
|
t->con.applyVec(t, NULL, NULL, t->values, values_final);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// transform_snap_increment(t, t->values);
|
copy_v2_v2(values_final, t->values);
|
||||||
applyNumInput(&t->num, t->values);
|
|
||||||
copy_v3_v3(t->values_final, t->values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t->values_final[0] = floorf(t->values_final[0] + 0.5f);
|
values_final[0] = floorf(values_final[0] + 0.5f);
|
||||||
t->values_final[1] = floorf(t->values_final[1] + 0.5f);
|
values_final[1] = floorf(values_final[1] + 0.5f);
|
||||||
|
copy_v2_v2(t->values_final, values_final);
|
||||||
|
|
||||||
headerSeqSlide(t, t->values_final, str);
|
headerSeqSlide(t, t->values_final, str);
|
||||||
applySeqSlideValue(t, t->values_final);
|
applySeqSlideValue(t, t->values_final);
|
||||||
|
|||||||
@@ -360,42 +360,49 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
|
|||||||
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
|
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
|
||||||
mul_v3_m3v3(global_dir, t->spacemtx, t->values);
|
mul_v3_m3v3(global_dir, t->spacemtx, t->values);
|
||||||
}
|
}
|
||||||
|
else if (applyNumInput(&t->num, global_dir)) {
|
||||||
|
if (t->con.mode & CON_APPLY) {
|
||||||
|
if (t->con.mode & CON_AXIS0) {
|
||||||
|
/* Do nothing. */
|
||||||
|
}
|
||||||
|
else if (t->con.mode & CON_AXIS1) {
|
||||||
|
mul_v3_v3fl(global_dir, t->spacemtx[1], global_dir[0]);
|
||||||
|
}
|
||||||
|
else if (t->con.mode & CON_AXIS2) {
|
||||||
|
mul_v3_v3fl(global_dir, t->spacemtx[2], global_dir[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(global_dir, t->values);
|
copy_v3_v3(global_dir, t->values);
|
||||||
if (applyNumInput(&t->num, global_dir)) {
|
|
||||||
removeAspectRatio(t, global_dir);
|
t->tsnap.snapElem = 0;
|
||||||
|
applySnapping(t, global_dir);
|
||||||
|
transform_snap_grid(t, global_dir);
|
||||||
|
|
||||||
|
if (t->con.mode & CON_APPLY) {
|
||||||
|
float in[3];
|
||||||
|
copy_v3_v3(in, global_dir);
|
||||||
|
t->con.applyVec(t, NULL, NULL, in, global_dir);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
applySnapping(t, global_dir);
|
|
||||||
|
|
||||||
if (!validSnap(t) && !(t->con.mode & CON_APPLY)) {
|
float incr_dir[3];
|
||||||
float dist_sq = FLT_MAX;
|
mul_v3_m3v3(incr_dir, t->spacemtx_inv, global_dir);
|
||||||
if (transform_snap_grid(t, global_dir)) {
|
if (transform_snap_increment(t, incr_dir)) {
|
||||||
dist_sq = len_squared_v3v3(t->values, global_dir);
|
mul_v3_m3v3(incr_dir, t->spacemtx, incr_dir);
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the snap distance to the initial value to work with mixed snap. */
|
/* Test for mixed snap with grid. */
|
||||||
float increment_loc[3];
|
float snap_dist_sq = FLT_MAX;
|
||||||
copy_v3_v3(increment_loc, t->values);
|
if (t->tsnap.snapElem != 0) {
|
||||||
if (transform_snap_increment(t, increment_loc)) {
|
snap_dist_sq = len_squared_v3v3(t->values, global_dir);
|
||||||
if ((dist_sq == FLT_MAX) || (len_squared_v3v3(t->values, increment_loc) < dist_sq)) {
|
}
|
||||||
copy_v3_v3(global_dir, increment_loc);
|
if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {
|
||||||
}
|
copy_v3_v3(global_dir, incr_dir);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->con.mode & CON_APPLY) {
|
headerTranslation(t, global_dir, str);
|
||||||
float in[3];
|
|
||||||
copy_v3_v3(in, global_dir);
|
|
||||||
t->con.applyVec(t, NULL, NULL, in, global_dir);
|
|
||||||
headerTranslation(t, global_dir, str);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
headerTranslation(t, global_dir, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyTranslationValue(t, global_dir);
|
applyTranslationValue(t, global_dir);
|
||||||
|
|
||||||
/* evil hack - redo translation if clipping needed */
|
/* evil hack - redo translation if clipping needed */
|
||||||
|
|||||||
@@ -464,6 +464,7 @@ void applySnapping(TransInfo *t, float *vec)
|
|||||||
void resetSnapping(TransInfo *t)
|
void resetSnapping(TransInfo *t)
|
||||||
{
|
{
|
||||||
t->tsnap.status = 0;
|
t->tsnap.status = 0;
|
||||||
|
t->tsnap.snapElem = 0;
|
||||||
t->tsnap.align = false;
|
t->tsnap.align = false;
|
||||||
t->tsnap.project = 0;
|
t->tsnap.project = 0;
|
||||||
t->tsnap.mode = 0;
|
t->tsnap.mode = 0;
|
||||||
@@ -1412,12 +1413,12 @@ void snapSequenceBounds(TransInfo *t, const int mval[2])
|
|||||||
t->values[0] = frame_near - frame_snap;
|
t->values[0] = frame_near - frame_snap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snap_grid_apply_ex(
|
static void snap_grid_apply(
|
||||||
TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
|
TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
|
||||||
{
|
{
|
||||||
|
BLI_assert(max_index <= 2);
|
||||||
const float *center_global = t->center_global;
|
const float *center_global = t->center_global;
|
||||||
const float *asp = t->aspect;
|
const float *asp = t->aspect;
|
||||||
bool use_local_axis = false;
|
|
||||||
|
|
||||||
/* use a fallback for cursor selection,
|
/* use a fallback for cursor selection,
|
||||||
* this isn't useful as a global center for absolute grid snapping
|
* this isn't useful as a global center for absolute grid snapping
|
||||||
@@ -1427,74 +1428,27 @@ static void snap_grid_apply_ex(
|
|||||||
center_global = cd->global;
|
center_global = cd->global;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
|
float in[3];
|
||||||
use_local_axis = true;
|
if (t->con.mode & CON_APPLY) {
|
||||||
|
BLI_assert(t->tsnap.snapElem == 0);
|
||||||
|
t->con.applyVec(t, NULL, NULL, loc, in);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copy_v3_v3(in, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= max_index; i++) {
|
for (int i = 0; i <= max_index; i++) {
|
||||||
/* do not let unconstrained axis jump to absolute grid increments */
|
const float iter_fac = grid_dist * asp[i];
|
||||||
if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) {
|
r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snap_grid_apply(TransInfo *t, int max_index, const float grid_dist, float *r_val)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool transform_snap_grid(TransInfo *t, float *val)
|
bool transform_snap_grid(TransInfo *t, float *val)
|
||||||
{
|
{
|
||||||
|
if (!activeSnap(t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) {
|
if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) {
|
||||||
/* Don't do grid snapping if there is a valid snap point. */
|
/* Don't do grid snapping if there is a valid snap point. */
|
||||||
return false;
|
return false;
|
||||||
@@ -1508,10 +1462,15 @@ bool transform_snap_grid(TransInfo *t, float *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float grid_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] :
|
float grid_dist = (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1];
|
||||||
t->snap[0];
|
|
||||||
|
|
||||||
snap_grid_apply(t, t->idx_max, grid_dist, val);
|
/* Early bailing out if no need to snap */
|
||||||
|
if (grid_dist == 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap_grid_apply(t, t->idx_max, grid_dist, val, val);
|
||||||
|
t->tsnap.snapElem = SCE_SNAP_MODE_GRID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user