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_mode_tosphere.c')
-rw-r--r--source/blender/editors/transform/transform_mode_tosphere.c91
1 files changed, 72 insertions, 19 deletions
diff --git a/source/blender/editors/transform/transform_mode_tosphere.c b/source/blender/editors/transform/transform_mode_tosphere.c
index e747f0e75d0..15906f2c90c 100644
--- a/source/blender/editors/transform/transform_mode_tosphere.c
+++ b/source/blender/editors/transform/transform_mode_tosphere.c
@@ -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,13 +42,64 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (ToSphere) */
+/** \name To Sphere Utilities
+ * \{ */
+
+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;
+
+ const bool is_local_center = transdata_check_local_center(t, t->around);
+
+ 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;
+ }
+ const float *center = is_local_center ? td->center : tc->center_local;
+ radius += td->factor * len_v3v3(center, 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++) {
+ const float *center = is_local_center ? td->center : tc->center_local;
+ radius += len_v3v3(center, td->iloc);
+ }
+ }
+ radius /= (float)t->data_len_all;
+ }
+
+ data->prop_size_prev = t->prop_size;
+ data->radius = radius;
+}
-/** \name Transform ToSphere
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (ToSphere)
* \{ */
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
{
+ const bool is_local_center = transdata_check_local_center(t, t->around);
+
float vec[3];
float ratio, radius;
int i;
@@ -75,6 +128,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++) {
@@ -83,15 +141,17 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
continue;
}
- sub_v3_v3v3(vec, td->iloc, tc->center_local);
+ const float *center = is_local_center ? td->center : tc->center_local;
+
+ sub_v3_v3v3(vec, td->iloc, center);
radius = normalize_v3(vec);
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);
+ add_v3_v3v3(td->loc, center, vec);
}
}
@@ -102,8 +162,6 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
void initToSphere(TransInfo *t)
{
- int i;
-
t->mode = TFM_TOSPHERE;
t->transform = applyToSphere;
@@ -111,25 +169,20 @@ void initToSphere(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
- t->snap[0] = 0.0f;
- t->snap[1] = 0.1f;
- t->snap[2] = t->snap[1] * 0.1f;
+ t->snap[0] = 0.1f;
+ t->snap[1] = t->snap[0] * 0.1f;
- copy_v3_fl(t->num.val_inc, t->snap[1]);
+ copy_v3_fl(t->num.val_inc, t->snap[0]);
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE;
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);
}
/** \} */