diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-06-24 03:59:45 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-06-24 04:21:54 +0300 |
commit | 9ce738e0f6a8f725d5529d2478717506a77ffd5e (patch) | |
tree | a53c7fe14d33dcf0d6662cfba5861008b6f9a315 /source/blender | |
parent | a33b1ce5009a22c1f04ead3c3aa61cfa4284862e (diff) |
Fix edge/vert slide UV-correct & non-planar faces
non-flat ngons would give instability (bad UV's).
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/transform/transform.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index bf09fd3d00e..1e3622b8750 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -5407,6 +5407,13 @@ static void slide_origdata_interp_data_vert( int j, l_num; float *loop_weights; const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON); + const float *v_proj_axis = sv->v->no; + /* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */ + float v_proj[3][3]; + + if (do_loop_weight) { + project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis); + } // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) { BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v); @@ -5435,24 +5442,32 @@ static void slide_origdata_interp_data_vert( bool co_prev_ok; bool co_next_ok; + /* In the unlikely case that we're next to a zero length edge - walk around the to the next. * Since we only need to check if the vertex is in this corner, * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */ - while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(sv->co_orig_3d, co_prev) > eps)) == false) && + project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis); + while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) && ((l_prev = l_prev->prev) != l->next))) { co_prev = slide_origdata_orig_vert_co(sod, l_prev->v); + project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis); } - while (UNLIKELY(((co_next_ok = (len_squared_v3v3(sv->co_orig_3d, co_next) > eps)) == false) && + project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis); + while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) && ((l_next = l_next->next) != l->prev))) { co_next = slide_origdata_orig_vert_co(sod, l_next->v); + project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis); } - if (co_prev_ok && co_next_ok && (area_squared_tri_v3(co_prev, sv->co_orig_3d, co_next) > eps)) { - const float dist = dist_signed_squared_to_corner_v3v3v3( - sv->v->co, co_prev, sv->co_orig_3d, co_next, f_copy->no); + if (co_prev_ok && co_next_ok) { + const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, UNPACK3(v_proj), v_proj_axis); + loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps))); + if (UNLIKELY(!isfinite(loop_weights[j]))) { + loop_weights[j] = 0.0f; + } } else { loop_weights[j] = 0.0f; |