Fix T48554: Absolute grid snap fails w/ cursor pivot
Use center of selection when using absolute grid snapping and cursor pivot.
This commit is contained in:
@@ -2863,7 +2863,7 @@ static void initBend(TransInfo *t)
|
||||
|
||||
//copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view));
|
||||
calculateCenterCursor(t, t->center);
|
||||
calculateCenterGlobal(t);
|
||||
calculateCenterGlobal(t, t->center, t->center_global);
|
||||
|
||||
t->val = 0.0f;
|
||||
|
||||
|
||||
@@ -369,6 +369,11 @@ typedef struct TransCustomData {
|
||||
unsigned int use_free : 1;
|
||||
} TransCustomData;
|
||||
|
||||
typedef struct TransCenterData {
|
||||
float local[3], global[3];
|
||||
unsigned int is_set : 1;
|
||||
} TransCenterData;
|
||||
|
||||
typedef struct TransInfo {
|
||||
int mode; /* current mode */
|
||||
int flag; /* generic flags for special behaviors */
|
||||
@@ -396,6 +401,9 @@ typedef struct TransInfo {
|
||||
float center[3]; /* center of transformation (in local-space) */
|
||||
float center_global[3]; /* center of transformation (in global-space) */
|
||||
float center2d[2]; /* center in screen coordinates */
|
||||
/* Lazy initialize center data for when we need other center values.
|
||||
* V3D_AROUND_ACTIVE + 1 (static assert checks this) */
|
||||
TransCenterData center_cache[5];
|
||||
short idx_max; /* maximum index on the input vector */
|
||||
float snap[3]; /* Snapping Gears */
|
||||
float snap_spatial[3]; /* Spatial snapping gears(even when rotating, scaling... etc) */
|
||||
@@ -742,8 +750,11 @@ void restoreTransObjects(TransInfo *t);
|
||||
void recalcData(TransInfo *t);
|
||||
|
||||
void calculateCenter2D(TransInfo *t);
|
||||
void calculateCenterGlobal(TransInfo *t);
|
||||
void calculateCenterGlobal(
|
||||
TransInfo *t, const float center_local[3],
|
||||
float r_center_global[3]);
|
||||
|
||||
const TransCenterData *transformCenter_from_type(TransInfo *t, int around);
|
||||
void calculateCenter(TransInfo *t);
|
||||
|
||||
/* API functions for getting center points */
|
||||
|
||||
@@ -1610,16 +1610,18 @@ void calculateCenter2D(TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
void calculateCenterGlobal(TransInfo *t)
|
||||
void calculateCenterGlobal(
|
||||
TransInfo *t, const float center_local[3],
|
||||
float r_center_global[3])
|
||||
{
|
||||
/* setting constraint center */
|
||||
/* note, init functions may over-ride t->center */
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = t->obedit ? t->obedit : t->poseobj;
|
||||
mul_v3_m4v3(t->center_global, ob->obmat, t->center);
|
||||
mul_v3_m4v3(r_center_global, ob->obmat, center_local);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(t->center_global, t->center);
|
||||
copy_v3_v3(r_center_global, center_local);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1794,43 +1796,55 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void calculateCenter(TransInfo *t)
|
||||
static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[3])
|
||||
{
|
||||
switch (t->around) {
|
||||
switch (around) {
|
||||
case V3D_AROUND_CENTER_BOUNDS:
|
||||
calculateCenterBound(t, t->center);
|
||||
calculateCenterBound(t, r_center);
|
||||
break;
|
||||
case V3D_AROUND_CENTER_MEAN:
|
||||
calculateCenterMedian(t, t->center);
|
||||
calculateCenterMedian(t, r_center);
|
||||
break;
|
||||
case V3D_AROUND_CURSOR:
|
||||
if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP))
|
||||
calculateCenterCursor2D(t, t->center);
|
||||
calculateCenterCursor2D(t, r_center);
|
||||
else if (t->spacetype == SPACE_IPO)
|
||||
calculateCenterCursorGraph2D(t, t->center);
|
||||
calculateCenterCursorGraph2D(t, r_center);
|
||||
else
|
||||
calculateCenterCursor(t, t->center);
|
||||
calculateCenterCursor(t, r_center);
|
||||
break;
|
||||
case V3D_AROUND_LOCAL_ORIGINS:
|
||||
/* Individual element center uses median center for helpline and such */
|
||||
calculateCenterMedian(t, t->center);
|
||||
calculateCenterMedian(t, r_center);
|
||||
break;
|
||||
case V3D_AROUND_ACTIVE:
|
||||
{
|
||||
if (calculateCenterActive(t, false, t->center)) {
|
||||
if (calculateCenterActive(t, false, r_center)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
/* fallback */
|
||||
calculateCenterMedian(t, t->center);
|
||||
calculateCenterMedian(t, r_center);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calculateCenter(TransInfo *t)
|
||||
{
|
||||
calculateCenter_FromAround(t, t->around, t->center);
|
||||
calculateCenterGlobal(t, t->center, t->center_global);
|
||||
|
||||
/* avoid calculating again */
|
||||
{
|
||||
TransCenterData *cd = &t->center_cache[t->around];
|
||||
copy_v3_v3(cd->local, t->center);
|
||||
copy_v3_v3(cd->global, t->center_global);
|
||||
cd->is_set = true;
|
||||
}
|
||||
|
||||
calculateCenter2D(t);
|
||||
calculateCenterGlobal(t);
|
||||
|
||||
/* for panning from cameraview */
|
||||
if (t->flag & T_OBJECT) {
|
||||
@@ -1884,6 +1898,23 @@ void calculateCenter(TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1), "test size");
|
||||
|
||||
/**
|
||||
* Lazy initialize transform center data, when we need to access center values from other types.
|
||||
*/
|
||||
const TransCenterData *transformCenter_from_type(TransInfo *t, int around)
|
||||
{
|
||||
BLI_assert(around <= V3D_AROUND_ACTIVE);
|
||||
TransCenterData *cd = &t->center_cache[around];
|
||||
if (cd->is_set == false) {
|
||||
calculateCenter_FromAround(t, around, cd->local);
|
||||
calculateCenterGlobal(t, cd->local, cd->global);
|
||||
cd->is_set = true;
|
||||
}
|
||||
return cd;
|
||||
}
|
||||
|
||||
void calculatePropRatio(TransInfo *t)
|
||||
{
|
||||
TransData *td = t->data;
|
||||
|
||||
@@ -1520,11 +1520,21 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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_MEAN);
|
||||
center_global = cd->global;
|
||||
}
|
||||
|
||||
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];
|
||||
val[i] = iter_fac * roundf((val[i] + center_global[i]) / iter_fac) - center_global[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user