diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2012-06-27 21:08:12 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2012-06-27 21:08:12 +0400 |
commit | ae2f3a4e5e3741b8ffa14ed86eda9e7058bc5393 (patch) | |
tree | 9763252eeba9fb7841a1c802921cebc771819a77 /source | |
parent | df201548ead1ef341e18c003661d136fdce8eca9 (diff) |
Fix for #31581, UVs shrink on edge slide.
Issue is that all loops of a face adjacent to the sliding verts were
getting project-corrected. Introduced a test to only project the
affected loops.
The projection code introduces a small offset to the boundaries so that
any boundary tests can work as expected, but this leads to shrinking of
the barycentric coordinates of the projection, causing a shrink of the
uvs in turn. This even affects the uvs that -should- be affected though
the unfixed behavior works strangely in a correctish way (my guess is
because the projection uses the same face as the opposite sliding loop).
I fixed the behaviour by taking the mean value of the uvs. This won't
support seams but current code doesn't either. Also, all CustomData to
exhibit this unfixed behaviour. I only fixed the uv case, other data
(Vcolors, etc) will have discontinuities when edge sliding. I expect
that the CorrectUV code I am working on may address some of these
issues.
Also, added NULL checks for utility function (was intended for this bug
but wasn't needed after all)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 7 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 31 |
2 files changed, 35 insertions, 3 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index ce4ce87b31f..b6a56e64dcf 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -196,7 +196,12 @@ BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v) BMLoop *BM_vert_find_first_loop(BMVert *v) { - BMEdge *e = bmesh_disk_faceedge_find_first(v->e, v); + BMEdge *e; + + if(!v || !v->e) + return NULL; + + e = bmesh_disk_faceedge_find_first(v->e, v); return bmesh_radial_faceloop_find_first(e->l, v); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index cedb09e187c..9965214af6f 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -5004,8 +5004,11 @@ void projectSVData(TransInfo *t, int final) for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { BMIter fiter; BMFace *f; + BMIter liter_v; + BMLoop *l_v; + float uv_med[2] = {0.0, 0.0}; + int tot_loops = 0; - /* BMESH_TODO, this interpolates between vertex/loops which are not moved * (are only apart of a face attached to a slide vert), couldn't we iterate BM_LOOPS_OF_VERT * here and only interpolate those? */ @@ -5034,6 +5037,8 @@ void projectSVData(TransInfo *t, int final) /* project onto copied projection face */ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + /* only affected verts will get interpolated */ + char affected = FALSE; f_copy_flip = f_copy; if (BM_elem_flag_test(l->e, BM_ELEM_SELECT) || BM_elem_flag_test(l->prev->e, BM_ELEM_SELECT)) { @@ -5058,6 +5063,8 @@ void projectSVData(TransInfo *t, int final) if (!f_copy_flip) { continue; /* shouldn't happen, but protection */ } + + affected = TRUE; } else { /* the loop is attached to only one vertex and not a selected edge, @@ -5094,10 +5101,15 @@ void projectSVData(TransInfo *t, int final) f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f); } } + + affected = TRUE; } } + if(!affected) + continue; + /* only loop data, no vertex data since that contains shape keys, * and we do not want to mess up other shape keys */ BM_loop_interp_from_face(em->bm, l, f_copy_flip, FALSE, FALSE); @@ -5121,8 +5133,23 @@ void projectSVData(TransInfo *t, int final) BM_elem_hide_set(em->bm, f, is_hide); } } + + /* make sure every loop of the vertex has identical uv data. Use this temporarily to + * fix #31581 until proper data correction/ support for islands is done */ + BM_ITER_ELEM (l_v, &liter_v, sv->v, BM_LOOPS_OF_VERT) { + MLoopUV *uv = CustomData_bmesh_get(&em->bm->ldata, l_v->head.data, CD_MLOOPUV); + add_v2_v2(uv_med, uv->uv); + tot_loops++; + } + + mul_v2_fl(uv_med, 1.0/tot_loops); + + BM_ITER_ELEM (l_v, &liter_v, sv->v, BM_LOOPS_OF_VERT) { + MLoopUV *uv = CustomData_bmesh_get(&em->bm->ldata, l_v->head.data, CD_MLOOPUV); + copy_v2_v2(uv->uv, uv_med); + } } - + BLI_smallhash_release(&visit); } |