Fix edge/vert slide UV-correct & non-planar faces

non-flat ngons would give instability (bad UV's).
This commit is contained in:
Campbell Barton 2015-06-24 10:59:45 +10:00
parent a33b1ce500
commit 9ce738e0f6
1 changed files with 20 additions and 5 deletions

View File

@ -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;