Commit: b963434f4965ca348c00b34e3aea5d7ab7374c71
Author: Antony Riakiotakis
Date:   Wed May 21 18:35:08 2014 +0200
https://developer.blender.org/rBb963434f4965ca348c00b34e3aea5d7ab7374c71

Fix T40222 texture painting on mirrored meshes does not apply pixel
bleeding at the symmetry edges.

We need an extra way to detect if faces overlap here. An easy way is to
detect the winding of the faces in UV space. If the winding differs, the
faces will naturally overlap. I have tried a few approaches here such as
choosing an offset point from the middle of the edge for intersection in
both faces of the edge in uv space, but winding is the safest way and
should work with very small faces/dense meshes too.

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

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 b0e1cdf..92fe8a2 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -134,6 +134,10 @@ BLI_INLINE unsigned char f_to_char(const float val)
 #define PROJ_FACE_NOSEAM3   (1 << 6)
 #define PROJ_FACE_NOSEAM4   (1 << 7)
 
+/* face winding */
+#define PROJ_FACE_WINDING_INIT 1
+#define PROJ_FACE_WINDING_CW 2
+
 #define PROJ_SRC_VIEW       1
 #define PROJ_SRC_IMAGE_CAM  2
 #define PROJ_SRC_IMAGE_VIEW 3
@@ -201,6 +205,7 @@ typedef struct ProjPaintState {
        unsigned char *bucketFlags;         /* store if the bucks have been 
initialized  */
 #ifndef PROJ_DEBUG_NOSEAMBLEED
        char *faceSeamFlags;                /* store info about faces, if they 
are initialized etc*/
+       char *faceWindingFlags;             /* save the winding of the face in 
uv space, helps as an extra validation step for seam detection */
        float (*faceSeamUVs)[4][2];         /* expanded UVs for faces to use as 
seams */
        LinkNode **vertFaces;               /* Only needed for when 
seam_bleed_px is enabled, use to find UV seams */
 #endif
@@ -835,6 +840,20 @@ static bool pixel_bounds_array(float (*uv)[2], rcti 
*bounds_px, const int ibuf_x
 
 #ifndef PROJ_DEBUG_NOSEAMBLEED
 
+static void project_face_winding_init(const ProjPaintState *ps, const int 
face_index)
+{
+       /* detect the winding of faces in uv space */
+       float winding = cross_tri_v2(ps->dm_mtface[face_index].uv[0], 
ps->dm_mtface[face_index].uv[1], ps->dm_mtface[face_index].uv[2]);
+
+       if (ps->dm_mface[face_index].v4)
+               winding += cross_tri_v2(ps->dm_mtface[face_index].uv[2], 
ps->dm_mtface[face_index].uv[3], ps->dm_mtface[face_index].uv[0]);
+
+       if (winding > 0)
+               ps->faceWindingFlags[face_index] |= PROJ_FACE_WINDING_CW;
+
+       ps->faceWindingFlags[face_index] |= PROJ_FACE_WINDING_INIT;
+}
+
 /* This function returns 1 if this face has a seam along the 2 face-vert 
indices
  * 'orig_i1_fidx' and 'orig_i2_fidx' */
 static bool check_seam(const ProjPaintState *ps,
@@ -882,11 +901,23 @@ static bool check_seam(const ProjPaintState *ps,
                                *other_face = face_index;
                                *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : 
i2_fidx;
 
+                               /* initialize face winding if needed */
+                               if (!ps->faceWindingFlags[face_index] & 
PROJ_FACE_WINDING_INIT)
+                                       project_face_winding_init(ps, 
face_index);
+
                                /* first test if they have the same image */
                                if ((orig_tpage == tpage) &&
                                    cmp_uv(orig_tf->uv[orig_i1_fidx], 
tf->uv[i1_fidx]) &&
                                    cmp_uv(orig_tf->uv[orig_i2_fidx], 
tf->uv[i2_fidx]) )
                                {
+                                       /* if faces don't have the same winding 
in uv space,
+                                        * they are on the same side so edge is 
boundary */
+                                       if ((ps->faceWindingFlags[face_index] & 
PROJ_FACE_WINDING_CW) !=
+                                           (ps->faceWindingFlags[orig_face] & 
PROJ_FACE_WINDING_CW))
+                                       {
+                                               return 1;
+                                       }
+
                                        // printf("SEAM (NONE)\n");
                                        return 0;
 
@@ -1016,6 +1047,10 @@ static void project_face_seams_init(const ProjPaintState 
*ps, const int face_ind
        int fidx1 = is_quad ? 3 : 2;
        int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or 
(0,1,2) -> (1,2,0) for a tri */
 
+       /* initialize face winding if needed */
+       if (!ps->faceWindingFlags[face_index] & PROJ_FACE_WINDING_INIT)
+               project_face_winding_init(ps, face_index);
+
        do {
                if ((ps->faceSeamFlags[face_index] & (1 << fidx1 | 16 << 
fidx1)) == 0) {
                        if (check_seam(ps, face_index, fidx1, fidx2, 
&other_face, &other_fidx)) {
@@ -3038,6 +3073,7 @@ static void project_paint_begin(ProjPaintState *ps)
        if (ps->seam_bleed_px > 0.0f) {
                ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * 
ps->dm_totvert, "paint-vertFaces");
                ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * 
ps->dm_totface, "paint-faceSeamFlags");
+               ps->faceWindingFlags = (char *)MEM_callocN(sizeof(char) * 
ps->dm_totface, "paint-faceWindindFlags");
                ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 
8, "paint-faceSeamUVs");
        }
 #endif
@@ -3346,6 +3382,7 @@ static void project_paint_end(ProjPaintState *ps)
        if (ps->seam_bleed_px > 0.0f) {
                MEM_freeN(ps->vertFaces);
                MEM_freeN(ps->faceSeamFlags);
+               MEM_freeN(ps->faceWindingFlags);
                MEM_freeN(ps->faceSeamUVs);
        }
 #endif

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

Reply via email to