Commit: d3c67bc81e29ce3fc323be2c22432b583d8e3084
Author: Antony Riakiotakis
Date:   Thu May 21 16:06:24 2015 +0200
Branches: master
https://developer.blender.org/rBd3c67bc81e29ce3fc323be2c22432b583d8e3084

Fix T44791 triangles when painting on a texpaint plane

Problem was float precision issues across tile boundaries. Since we are
comparing pixels, give a small tolerance when comparing clipped vertices
against triangle lines.

===================================================================

M       source/blender/editors/sculpt_paint/paint_image_proj.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c 
b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 330b93b..ac34184 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -1680,13 +1680,14 @@ static ProjPixel *project_paint_uvpixel_init(
 }
 
 static bool line_clip_rect2f(
+        const rctf *cliprect,
         const rctf *rect,
         const float l1[2], const float l2[2],
         float l1_clip[2], float l2_clip[2])
 {
        /* first account for horizontal, then vertical lines */
        /* horiz */
-       if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) {
+       if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) {
                /* is the line out of range on its Y axis? */
                if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
                        return 0;
@@ -1697,7 +1698,7 @@ static bool line_clip_rect2f(
                }
 
 
-               if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a 
single point  (or close to)*/
+               if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) { /* this is a 
single point  (or close to)*/
                        if (BLI_rctf_isect_pt_v(rect, l1)) {
                                copy_v2_v2(l1_clip, l1);
                                copy_v2_v2(l2_clip, l2);
@@ -1714,7 +1715,7 @@ static bool line_clip_rect2f(
                CLAMP(l2_clip[0], rect->xmin, rect->xmax);
                return 1;
        }
-       else if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) {
+       else if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) {
                /* is the line out of range on its X axis? */
                if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
                        return 0;
@@ -1725,7 +1726,7 @@ static bool line_clip_rect2f(
                        return 0;
                }
 
-               if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a 
single point  (or close to)*/
+               if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) { /* this is a 
single point  (or close to)*/
                        if (BLI_rctf_isect_pt_v(rect, l1)) {
                                copy_v2_v2(l1_clip, l1);
                                copy_v2_v2(l2_clip, l2);
@@ -1764,7 +1765,7 @@ static bool line_clip_rect2f(
                if (ok1 && ok2) return 1;
 
                /* top/bottom */
-               if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= 
rect->xmin) && (isect <= rect->xmax)) {
+               if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= 
cliprect->xmin) && (isect <= cliprect->xmax)) {
                        if (l1[1] < l2[1]) { /* line 1 is outside */
                                l1_clip[0] = isect;
                                l1_clip[1] = rect->ymin;
@@ -1779,7 +1780,7 @@ static bool line_clip_rect2f(
 
                if (ok1 && ok2) return 1;
 
-               if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= 
rect->xmin) && (isect <= rect->xmax)) {
+               if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= 
cliprect->xmin) && (isect <= cliprect->xmax)) {
                        if (l1[1] > l2[1]) { /* line 1 is outside */
                                l1_clip[0] = isect;
                                l1_clip[1] = rect->ymax;
@@ -1795,7 +1796,7 @@ static bool line_clip_rect2f(
                if (ok1 && ok2) return 1;
 
                /* left/right */
-               if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= 
rect->ymin) && (isect <= rect->ymax)) {
+               if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= 
cliprect->ymin) && (isect <= cliprect->ymax)) {
                        if (l1[0] < l2[0]) { /* line 1 is outside */
                                l1_clip[0] = rect->xmin;
                                l1_clip[1] = isect;
@@ -1810,7 +1811,7 @@ static bool line_clip_rect2f(
 
                if (ok1 && ok2) return 1;
 
-               if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= 
rect->ymin) && (isect <= rect->ymax)) {
+               if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= 
cliprect->ymin) && (isect <= cliprect->ymax)) {
                        if (l1[0] > l2[0]) { /* line 1 is outside */
                                l1_clip[0] = rect->xmax;
                                l1_clip[1] = isect;
@@ -2108,6 +2109,7 @@ static bool line_rect_clip(
 
 static void project_bucket_clip_face(
         const bool is_ortho, const bool is_flip_object,
+        const rctf *cliprect,
         const rctf *bucket_bounds,
         const float *v1coSS, const float *v2coSS, const float *v3coSS,
         const float *uv1co, const float *uv2co, const float *uv3co,
@@ -2272,21 +2274,21 @@ static void project_bucket_clip_face(
                if (inside_bucket_flag & ISECT_3) { 
copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
 
                if ((inside_bucket_flag & (ISECT_1 | ISECT_2)) != (ISECT_1 | 
ISECT_2)) {
-                       if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, 
v1_clipSS, v2_clipSS)) {
+                       if (line_clip_rect2f(cliprect, bucket_bounds, v1coSS, 
v2coSS, v1_clipSS, v2_clipSS)) {
                                if ((inside_bucket_flag & ISECT_1) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
                                if ((inside_bucket_flag & ISECT_2) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
                        }
                }
 
                if ((inside_bucket_flag & (ISECT_2 | ISECT_3)) != (ISECT_2 | 
ISECT_3)) {
-                       if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, 
v1_clipSS, v2_clipSS)) {
+                       if (line_clip_rect2f(cliprect, bucket_bounds, v2coSS, 
v3coSS, v1_clipSS, v2_clipSS)) {
                                if ((inside_bucket_flag & ISECT_2) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
                                if ((inside_bucket_flag & ISECT_3) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
                        }
                }
 
                if ((inside_bucket_flag & (ISECT_3 | ISECT_1)) != (ISECT_3 | 
ISECT_1)) {
-                       if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, 
v1_clipSS, v2_clipSS)) {
+                       if (line_clip_rect2f(cliprect, bucket_bounds, v3coSS, 
v1coSS, v1_clipSS, v2_clipSS)) {
                                if ((inside_bucket_flag & ISECT_3) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
                                if ((inside_bucket_flag & ISECT_1) == 0) { 
copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
                        }
@@ -2488,7 +2490,7 @@ static bool IsectPoly2Df_twoside(const float pt[2], float 
uv[][2], const int tot
 static void project_paint_face_init(
         const ProjPaintState *ps,
         const int thread_index, const int bucket_index, const int face_index, 
const int image_index,
-        const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf,
+        const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf 
**tmpibuf,
         const bool clamp_u, const bool clamp_v)
 {
        /* Projection vars, to get the 3D locations into screen space  */
@@ -2602,7 +2604,7 @@ static void project_paint_face_init(
                /* This funtion gives is a concave polyline in UV space from 
the clipped quad and tri*/
                project_bucket_clip_face(
                        is_ortho, is_flip_object,
-                       bucket_bounds,
+                       clip_rect, bucket_bounds,
                        v1coSS, v2coSS, v3coSS,
                        uv1co, uv2co, uv3co,
                        uv_clip, &uv_clip_tot,
@@ -2774,7 +2776,7 @@ static void project_paint_face_init(
                                else        fidx2 = (fidx1 == 2) ? 0 : fidx1 + 
1;  /* next fidx in the face (0,1,2) -> (1,2,0) */
 
                                if ((face_seam_flag & (1 << fidx1)) && /* 
1<<fidx1 -> PROJ_FACE_SEAM# */
-                                   line_clip_rect2f(bucket_bounds, 
vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
+                                   line_clip_rect2f(clip_rect, bucket_bounds, 
vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
                                {
                                        if (len_squared_v2v2(vCoSS[fidx1], 
vCoSS[fidx2]) > FLT_EPSILON) { /* avoid div by zero */
                                                if (mf->v4) {
@@ -2947,7 +2949,7 @@ static void project_bucket_bounds(const ProjPaintState 
*ps, const int bucket_x,
 /* Fill this bucket with pixels from the faces that intersect it.
  *
  * have bucket_bounds as an argument so we don't need to give bucket_x/y the 
rect function needs */
-static void project_bucket_init(const ProjPaintState *ps, const int 
thread_index, const int bucket_index, const rctf *bucket_bounds)
+static void project_bucket_init(const ProjPaintState *ps, const int 
thread_index, const int bucket_index, const rctf *clip_rect, const rctf 
*bucket_bounds)
 {
        LinkNode *node;
        int face_index, image_index = 0;
@@ -2964,7 +2966,7 @@ static void project_bucket_init(const ProjPaintState *ps, 
const int thread_index
                for (node = ps->bucketFaces[bucket_index]; node; node = 
node->next) {
                        project_paint_face_init(
                                ps, thread_index, bucket_index, 
GET_INT_FROM_POINTER(node->link), 0,
-                               bucket_bounds, ibuf, &tmpibuf,
+                               clip_rect, bucket_bounds, ibuf, &tmpibuf,
                                (ima->tpageflag & IMA_CLAMP_U) != 0, 
(ima->tpageflag & IMA_CLAMP_V) != 0);
                }
        }
@@ -2991,7 +2993,7 @@ static void project_bucket_init(const ProjPaintState *ps, 
const int thread_index
 
                        project_paint_face_init(
                                ps, thread_index, bucket_index, face_index, 
image_index,
-                               bucket_bounds, ibuf, &tmpibuf,
+                               clip_rect, bucket_bounds, ibuf, &tmpibuf,
                                (ima->tpageflag & IMA_CLAMP_U) != 0, 
(ima->tpageflag & IMA_CLAMP_V) != 0);
                }
        }
@@ -4563,8 +4565,13 @@ static void *do_projectpaint_thread(void *ph_v)
 
                /* Check this bucket and its faces are initialized */
                if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
+                       rctf clip_rect = bucket_bounds;
+                       clip_rect.xmin -= PROJ_PIXEL_TOLERANCE;
+                       clip_rect.xmax += PROJ_PIXEL_TOLERANCE;
+                       clip_rect.ymin -= PROJ_PIXEL_TOLERANCE;
+                       clip_rect.ymax += PROJ_PIXEL_TOLERANCE;
                        /* No pixels initialized */
-                       project_bucket_init(ps, thread_index, bucket_index, 
&bucket_bounds);
+                       project_bucket_init(ps, thread_index, bucket_index, 
&clip_rect, &bucket_bounds);
                }
 
                if (ps->source != PROJ_SRC_VIEW) {

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to