Project Paint: resolve ugly bleed artifacts

Use the bilinear reverse to find the pixel to bleed from.
Was using pixel space which didn't work well.
This commit is contained in:
Campbell Barton 2015-05-13 18:04:46 +10:00
parent 3e782756e3
commit a050d6063c
3 changed files with 40 additions and 5 deletions

@ -259,6 +259,7 @@ void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], con
void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
float resolve_quad_u_v2(const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
/* use to find the point of a UV on a face */
void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]);

@ -3101,6 +3101,43 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
}
}
/* a version of resolve_quad_uv_v2 that only calculates the 'u' */
float resolve_quad_u_v2(
const float st[2],
const float st0[2], const float st1[2], const float st2[2], const float st3[2])
{
const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) + (st1[0] * st2[1] - st1[1] * st2[0]) +
(st2[0] * st3[1] - st2[1] * st3[0]) + (st3[0] * st0[1] - st3[1] * st0[0]);
/* X is 2D cross product (determinant)
* A = (p0 - p) X (p0 - p3)*/
const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
/* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */
const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) +
((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0])));
/* C = (p1-p) X (p1-p2) */
const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
double denom = a - 2 * b + fC;
if (IS_ZERO(denom) != 0) {
const double fDen = a - fC;
if (IS_ZERO(fDen) == 0)
return (float)(a / fDen);
else
return 0.0f;
}
else {
const double desc_sq = b * b - a * fC;
const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
const double s = signed_area > 0 ? (-1.0) : 1.0;
return (float)(((a - b) + s * desc) / denom);
}
}
#undef IS_ZERO
/* reverse of the functions above */

@ -2825,11 +2825,8 @@ static void project_paint_face_init(
/* Since this is a seam we need to work out where on the line this pixel is */
//fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
fac = resolve_quad_u_v2(uv, UNPACK4(seam_subsection));
interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac);
if (!is_ortho) {
pixelScreenCo[3] = 1.0f;