Fix T65205: "To Sphere" radius too large with proportional editing

The radius is now calculated based on the vertices being transformed
by proportional editing, updated when the falloff changes.
This commit is contained in:
2020-11-05 15:15:56 +11:00
parent 29780b8101
commit 8d88d9fd33
4 changed files with 59 additions and 20 deletions

View File

@@ -282,8 +282,6 @@ typedef struct TransInfo {
short state;
/** Current context/options for transform. */
int options;
/** Initial value for some transformations (and rotation angle). */
float val;
void (*transform)(struct TransInfo *, const int[2]);
/** Transform function pointer. */
eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *);

View File

@@ -270,9 +270,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->data_len_all = 0;
t->val = 0.0f;
zero_v3(t->vec);
zero_v3(t->center_global);
unit_m3(t->mat);

View File

@@ -278,8 +278,6 @@ void initBend(TransInfo *t)
}
calculateCenterLocal(t, t->center_global);
t->val = 0.0f;
data = MEM_callocN(sizeof(*data), __func__);
curs = t->scene->cursor.location;

View File

@@ -26,6 +26,8 @@
#include "BLI_math.h"
#include "BLI_string.h"
#include "MEM_guardedalloc.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -40,9 +42,54 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
/* Transform (ToSphere) */
/** \name To Sphere Utilities
* \{ */
/** \name Transform ToSphere
struct ToSphereInfo {
float prop_size_prev;
float radius;
};
/** Calculate average radius. */
static void to_sphere_radius_update(TransInfo *t)
{
struct ToSphereInfo *data = t->custom.mode.data;
float radius = 0.0f;
if (t->flag & T_PROP_EDIT_ALL) {
int factor_accum = 0.0f;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
if (td->factor == 0.0f) {
continue;
}
radius += td->factor * len_v3v3(tc->center_local, td->iloc);
factor_accum += td->factor;
}
}
if (factor_accum != 0.0f) {
radius /= factor_accum;
}
}
else {
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
radius += len_v3v3(tc->center_local, td->iloc);
}
}
radius /= (float)t->data_len_all;
}
data->prop_size_prev = t->prop_size;
data->radius = radius;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Transform (ToSphere)
* \{ */
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
@@ -75,6 +122,11 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
BLI_snprintf(str, sizeof(str), TIP_("To Sphere: %.4f %s"), ratio, t->proptext);
}
const struct ToSphereInfo *data = t->custom.mode.data;
if (data->prop_size_prev != t->prop_size) {
to_sphere_radius_update(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
@@ -89,7 +141,7 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
tratio = ratio * td->factor;
mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
mul_v3_fl(vec, radius * (1.0f - tratio) + data->radius * tratio);
add_v3_v3v3(td->loc, tc->center_local, vec);
}
@@ -102,8 +154,6 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
void initToSphere(TransInfo *t)
{
int i;
t->mode = TFM_TOSPHERE;
t->transform = applyToSphere;
@@ -121,14 +171,10 @@ void initToSphere(TransInfo *t)
t->num.val_flag[0] |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
/* Calculate average radius */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
t->val += len_v3v3(tc->center_local, td->iloc);
}
}
struct ToSphereInfo *data = MEM_callocN(sizeof(*data), __func__);
t->custom.mode.data = data;
t->custom.mode.use_free = true;
t->val /= (float)t->data_len_all;
to_sphere_radius_update(t);
}
/** \} */