diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_image_proj.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_proj.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index a24ee13e3bf..553a5cbe9ac 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -1121,6 +1121,44 @@ static void screen_px_from_persp( interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w); } + +/* same as screen_px_from_persp except we return ortho weights back to the caller. + * These weights will be used to determine correct interpolation of uvs in cloned uv layer */ +static void screen_px_from_persp_ortho_weights( + float uv[2], + float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */ + float uv1co[2], float uv2co[2], float uv3co[2], + float pixelScreenCo[4], + float w[3]) +{ + float w_int[3]; + float wtot_inv, wtot; + barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w); + + /* re-weight from the 4th coord of each screen vert */ + w_int[0] = w[0] * v1co[3]; + w_int[1] = w[1] * v2co[3]; + w_int[2] = w[2] * v3co[3]; + + wtot = w_int[0] + w_int[1] + w_int[2]; + + if (wtot > 0.0f) { + wtot_inv = 1.0f / wtot; + w_int[0] *= wtot_inv; + w_int[1] *= wtot_inv; + w_int[2] *= wtot_inv; + } + else { + w[0] = w[1] = w[2] = + w_int[0] = w_int[1] = w_int[2] = 1.0f / 3.0f; /* dummy values for zero area face */ + } + /* done re-weighting */ + + /* do interpolation based on projected weight */ + interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w_int); +} + + static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4]) { @@ -2168,6 +2206,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float uv_clip[8][2]; int uv_clip_tot; const short is_ortho = ps->is_ortho; + const short is_clone_other = ((ps->brush->imagepaint_tool == PAINT_TOOL_CLONE) && ps->dm_mtface_clone); const short do_backfacecull = ps->do_backfacecull; const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0; @@ -2191,8 +2230,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i * but since the first thing most people try is painting onto a quad- better make it work. */ - - tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx; tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx; @@ -2277,7 +2314,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i has_x_isect = has_isect = 1; if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w); - else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w); + else if (is_clone_other) screen_px_from_persp_ortho_weights(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w); + else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w); /* a pity we need to get the worldspace pixel location here */ if (do_clip || do_3d_mapping) { |