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:
authorBrecht Van Lommel <brecht@blender.org>2020-08-12 13:12:12 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-08-12 13:12:12 +0300
commit1f8cb908285b18817cb09fd32e7473cca0a22d08 (patch)
tree7ddc2103437cfcfa8d3d2111395adcbde3b2c729 /source/blender/editors/uvedit
parenta1a81e3b88de80fe3a4fa4d77b63a3aff36070e8 (diff)
parent9280fb19e4ff5038734d9867d152c10d4daf03bb (diff)
Merge branch 'blender-v2.90-release'
Diffstat (limited to 'source/blender/editors/uvedit')
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c96
1 files changed, 76 insertions, 20 deletions
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index dd422f2443a..f6485fdef5d 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -190,6 +190,9 @@ typedef struct PChart {
LinearSolver *context;
float *abf_alpha;
PVert *pin1, *pin2;
+ PVert *single_pin;
+ float single_pin_area;
+ float single_pin_uv[2];
} lscm;
struct PChartPack {
float rescale, area;
@@ -467,6 +470,17 @@ static void p_chart_uv_bbox(PChart *chart, float minv[2], float maxv[2])
}
}
+static float p_chart_uv_area(PChart *chart)
+{
+ float area = 0.0f;
+
+ for (PFace *f = chart->faces; f; f = f->nextlink) {
+ area += fabsf(p_face_uv_area_signed(f));
+ }
+
+ return area;
+}
+
static void p_chart_uv_scale(PChart *chart, float scale)
{
PVert *v;
@@ -3176,7 +3190,7 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
}
}
- if ((live && (!select || !deselect)) || (npins == 1)) {
+ if ((live && (!select || !deselect))) {
chart->u.lscm.context = NULL;
}
else {
@@ -3185,6 +3199,16 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
p_chart_topological_sanity_check(chart);
#endif
+ if (npins == 1) {
+ chart->u.lscm.single_pin_area = p_chart_uv_area(chart);
+ for (v = chart->verts; v; v = v->nextlink) {
+ if (v->flag & PVERT_PIN) {
+ chart->u.lscm.single_pin = v;
+ break;
+ }
+ }
+ }
+
if (abf) {
if (!p_chart_abf_solve(chart)) {
param_warning("ABF solving failed: falling back to LSCM.\n");
@@ -3192,12 +3216,12 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
}
if (npins <= 1) {
- /* not enough pins, lets find some ourself */
+ /* No pins, let's find some ourself. */
PEdge *outer;
p_chart_boundaries(chart, NULL, &outer);
- /* outer can be NULL with non-finite coords. */
+ /* Outer can be NULL with non-finite coords. */
if (!(outer && p_chart_symmetry_pins(chart, outer, &pin1, &pin2))) {
p_chart_extrema_verts(chart, &pin1, &pin2);
}
@@ -3235,6 +3259,11 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
}
}
+ if (chart->u.lscm.single_pin) {
+ /* If only one pin, save area and pin for transform later. */
+ copy_v2_v2(chart->u.lscm.single_pin_uv, chart->u.lscm.single_pin->uv);
+ }
+
if (chart->u.lscm.pin1) {
EIG_linear_solver_variable_lock(context, 2 * pin1->u.id);
EIG_linear_solver_variable_lock(context, 2 * pin1->u.id + 1);
@@ -3358,6 +3387,25 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
return P_FALSE;
}
+static void p_chart_lscm_transform_single_pin(PChart *chart)
+{
+ PVert *pin = chart->u.lscm.single_pin;
+
+ /* If only one pin, keep UV area the same. */
+ const float new_area = p_chart_uv_area(chart);
+ if (new_area > 0.0f) {
+ const float scale = chart->u.lscm.single_pin_area / new_area;
+ if (scale > 0.0f) {
+ p_chart_uv_scale(chart, sqrtf(scale));
+ }
+ }
+
+ /* Translate to keep the pinned vertex in place. */
+ float offset[2];
+ sub_v2_v2v2(offset, chart->u.lscm.single_pin_uv, pin->uv);
+ p_chart_uv_translate(chart, offset);
+}
+
static void p_chart_lscm_end(PChart *chart)
{
if (chart->u.lscm.context) {
@@ -3372,6 +3420,8 @@ static void p_chart_lscm_end(PChart *chart)
chart->u.lscm.context = NULL;
chart->u.lscm.pin1 = NULL;
chart->u.lscm.pin2 = NULL;
+ chart->u.lscm.single_pin = NULL;
+ chart->u.lscm.single_pin_area = 0.0f;
}
/* Stretch */
@@ -3781,6 +3831,23 @@ static void p_chart_rotate_minimum_area(PChart *chart)
}
}
+static void p_chart_rotate_fit_aabb(PChart *chart)
+{
+ float(*points)[2] = MEM_mallocN(sizeof(*points) * chart->nverts, __func__);
+
+ p_chart_uv_to_array(chart, points);
+
+ float angle = BLI_convexhull_aabb_fit_points_2d(points, chart->nverts);
+
+ MEM_freeN(points);
+
+ if (angle != 0.0f) {
+ float mat[2][2];
+ angle_to_mat2(mat, angle);
+ p_chart_uv_transform(chart, mat);
+ }
+}
+
/* Area Smoothing */
/* 2d bsp tree for inverse mapping - that's a bit silly */
@@ -4576,8 +4643,12 @@ void param_lscm_solve(ParamHandle *handle)
if (result && !(chart->flag & PCHART_HAS_PINS)) {
p_chart_rotate_minimum_area(chart);
}
+ else if (result && chart->u.lscm.single_pin) {
+ p_chart_rotate_fit_aabb(chart);
+ p_chart_lscm_transform_single_pin(chart);
+ }
- if (!result || (chart->u.lscm.pin1)) {
+ if (!result || !(chart->flag & PCHART_HAS_PINS)) {
p_chart_lscm_end(chart);
}
}
@@ -4692,28 +4763,13 @@ static void param_pack_rotate(ParamHandle *handle, bool ignore_pinned)
PHandle *phandle = (PHandle *)handle;
for (i = 0; i < phandle->ncharts; i++) {
- float(*points)[2];
- float angle;
-
chart = phandle->charts[i];
if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) {
continue;
}
- points = MEM_mallocN(sizeof(*points) * chart->nverts, __func__);
-
- p_chart_uv_to_array(chart, points);
-
- angle = BLI_convexhull_aabb_fit_points_2d(points, chart->nverts);
-
- MEM_freeN(points);
-
- if (angle != 0.0f) {
- float mat[2][2];
- angle_to_mat2(mat, angle);
- p_chart_uv_transform(chart, mat);
- }
+ p_chart_rotate_fit_aabb(chart);
}
}