Revision: 17372
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17372
Author:   campbellbarton
Date:     2008-11-09 04:34:22 +0100 (Sun, 09 Nov 2008)

Log Message:
-----------
mistake made initializing seam UV's fail

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c   2008-11-09 
02:47:30 UTC (rev 17371)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-09 
03:34:22 UTC (rev 17372)
@@ -134,6 +134,7 @@
 #define PROJ_BUCKET_DIV 128 /* TODO - test other values, this is a guess, 
seems ok */
 
 //#define PROJ_DEBUG_PAINT 1
+#define PROJ_DEBUG_NOSCANLINE 1
 //#define PROJ_DEBUG_NOSEAMBLEED 1
 
 /* projectFaceSeamFlags options */
@@ -213,6 +214,11 @@
        float viewHeight;
 } ProjectPaintState;
 
+typedef struct ProjectScanline {
+       int v[3]; /* verts for this scanline, 0,1,2 or 0,2,3 */
+       float x_limits[2]; /* UV min|max for this scanline */
+} ProjectScanline;
+
 typedef struct ProjectPixel {
        float projCo2D[2]; /* the floating point screen projection of this 
pixel */
        char *pixel;
@@ -700,6 +706,101 @@
        }
 }
 
+static int project_face_scanline(ProjectScanline *sc, float y_level, float 
v1[2], float v2[2], float v3[2], float v4[2])
+{      
+       /* Create a scanlines for the face at this Y level 
+        * triangles will only ever have 1 scanline, quads may have 2 */
+       int totscanlines = 0;
+       short i1=0,i2=0,i3=0;
+       
+       if (v4) { /* This is a quad?*/
+               int i4=0, i_mid=0;
+               float xi1, xi2, xi3, xi4, xi_mid;
+                               
+               i1 = line_isect_y(v1, v2, y_level, &xi1);
+               if (i1 != ISECT_TRUE_P2) /* rare cases we could be on the line, 
in these cases we dont want to intersect with the same point twice */
+                       i2 = line_isect_y(v2, v3, y_level, &xi2);
+               
+               if (i1 && i2) { /* both the first 2 edges intersect, this means 
the second half of the quad wont intersect */
+                       sc->v[0] = 0;
+                       sc->v[1] = 1;
+                       sc->v[2] = 2;
+                       sc->x_limits[0] = MIN2(xi1, xi2);
+                       sc->x_limits[1] = MAX2(xi1, xi2);
+                       totscanlines = 1;
+               } else {
+                       if (i2 != ISECT_TRUE_P2) 
+                               i3 = line_isect_y(v3, v4, y_level, &xi3);
+                       if (i1 != ISECT_TRUE_P1 && i3 != ISECT_TRUE_P2) 
+                               i4 = line_isect_y(v4, v1, y_level, &xi4);
+                       
+                       if (i3 && i4) { /* second 2 edges only intersect, same 
as above */
+                               sc->v[0] = 0;
+                               sc->v[1] = 2;
+                               sc->v[2] = 3;
+                               sc->x_limits[0] = MIN2(xi3, xi4);
+                               sc->x_limits[1] = MAX2(xi3, xi4);
+                               totscanlines = 1;
+                       } else {
+                               /* OK - we have a not-so-simple case, both 
sides of the quad intersect.
+                                * Will need to have 2 scanlines */
+                               if ((i1||i2) && (i3||i4)) {
+                                       i_mid = line_isect_y(v1, v3, y_level, 
&xi_mid);
+                                       /* it would be very rare this would be 
false, but possible */
+                                       sc->v[0] = 0;
+                                       sc->v[1] = 1;
+                                       sc->v[2] = 2;
+                                       sc->x_limits[0] = MIN2((i1?xi1:xi2), 
xi_mid);
+                                       sc->x_limits[1] = MAX2((i1?xi1:xi2), 
xi_mid);
+                                       
+                                       sc++;
+                                       sc->v[0] = 0;
+                                       sc->v[1] = 2;
+                                       sc->v[2] = 3;
+                                       sc->x_limits[0] = MIN2((i3?xi3:xi4), 
xi_mid);
+                                       sc->x_limits[1] = MAX2((i3?xi3:xi4), 
xi_mid);
+                                       
+                                       totscanlines = 2;
+                               }
+                       }
+               }
+       } else { /* triangle */
+               int i = 0;
+               
+               i1 = line_isect_y(v1, v2, y_level, &sc->x_limits[0]);
+               if (i1) i++;
+               
+               if (i1 != ISECT_TRUE_P2) {
+                       i2 = line_isect_y(v2, v3, y_level, &sc->x_limits[i]);
+                       if (i2) i++;
+               }
+               
+               /* if the triangle intersects then the first 2 lines must */
+               if (i!=0) {
+                       if (i!=2) {
+                               /* if we are here then this really should not 
fail since 2 edges MUST intersect  */
+                               if (i1 != ISECT_TRUE_P1 && i2 != ISECT_TRUE_P2) 
{
+                                       i3 = line_isect_y(v3, v1, y_level, 
&sc->x_limits[i]);
+                                       if (i3) i++;
+                                       
+                               }
+                       }
+                       
+                       if (i==2) {
+                               if (sc->x_limits[0] > sc->x_limits[1]) {
+                                       SWAP(float, sc->x_limits[0], 
sc->x_limits[1]);
+                               }
+                               sc->v[0] = 0;
+                               sc->v[1] = 1;
+                               sc->v[2] = 2;
+                               totscanlines = 1;
+                       }
+               }
+       }
+       /* done setting up scanlines */
+       return totscanlines;
+}
+
 static int cmp_uv(float vec2a[2], float vec2b[2])
 {
        return ((fabs(vec2a[0]-vec2b[0]) < 0.0001) && (fabs(vec2a[1]-vec2b[1]) 
< 0.0001)) ? 1:0;
@@ -1238,6 +1339,12 @@
        float w[3];
        int i1,i2,i3;
        
+       /* scanlines since quads can have 2 triangles intersecting the same 
vertical location */
+#ifndef PROJ_DEBUG_NOSCANLINE 
+       ProjectScanline scanlines[2];
+       ProjectScanline *sc;
+       int totscanlines; /* can only be 1 or 2, oh well */
+#endif
        i = mf->v4 ? 1:0;
        do {
                if (i==1) {
@@ -1340,26 +1447,22 @@
                        /* Now create new UV's for the seam face */
                        float (*outset_uv)[2];
                        float insetCos[4][3]; /* expanded UV's */
+                       float cent[3];
                        float *uv_seam_quads[4][4];
                        float *edge_verts_inset[4][2];
                        float *edge_verts[4][2];
+                       float fac;
                        float *vCoSS[4]; /* vertex screenspace coords */
                        
                        float bucket_clip_edges[4][2][2]; /* store the 
screenspace coords of the face, clipped by the bucket's screen aligned 
rectangle */
                        int totuvseamquads = 0;
                        int fidx1, fidx2; /* face edge pairs - loop throuh 
these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
                        
-                       /* seam subsection is a quad subsection of the seam 
that intersects the bucket */
-                       float seam_subsection[4][2];
-                       float fac1, fac2, ftot; /* factors for converting the 
distance along an edge from screenspace to uvspace */
-                       float edge_verts_inset_clip[2][3]; /* inset clipped 
line */
+                       outset_uv = ps->projectFaceSeamUVs[face_index];
                        
-                       outset_uv = ps->projectFaceSeamUVs[face_index];
-                       if (outset_uv[0][0]==MAXFLOAT) {
+                       if (outset_uv[0][0]==MAXFLOAT) /* first time initialize 
*/
                                uv_image_outset(tf->uv, outset_uv, 
ps->projectSeamBleed, ibuf->x, ibuf->y, mf->v4);
-                       }
                        
-                       
                        vCoSS[0] = ps->projectVertScreenCos[ mf->v1 ];
                        vCoSS[1] = ps->projectVertScreenCos[ mf->v2 ];
                        vCoSS[2] = ps->projectVertScreenCos[ mf->v3 ];
@@ -1391,7 +1494,13 @@
                        
                        
                        for (i=0; i< totuvseamquads; i++) { /* loop over our 
seams */
+                               
+                       
                                /* make a quad spanning the subsection of the 
face the bucket intersects with */
+                               float seam_subsection[4][2];
+                               float fac1, fac2, ftot;
+                               float edge_verts_inset_clip[2][3];
+
                                ftot = Vec2Lenf(edge_verts[i][0], 
edge_verts[i][1]);
                                fac1 = Vec2Lenf(edge_verts[i][0], 
bucket_clip_edges[i][0]) / ftot;
                                fac2 = Vec2Lenf(edge_verts[i][0], 
bucket_clip_edges[i][1]) / ftot;
@@ -1429,15 +1538,15 @@
                                                                else            
                        screen_px_from_persp(ps, uv, v1co,v2co,v3co, 
uv1co,uv2co,uv3co, pixelScreenCo);
                                                                */
                                                                
-                                                               /* Since this 
is a seam we need to work out the closest point on the UV edge this pixel is */
-                                                               fac1 = 
lambda_cp_line2(uv, seam_subsection[0], seam_subsection[1]); /* these 2 points 
in the seam_subsection happen to run along the inside */
-                                                               
-                                                               if (fac1 < 0.0) 
{
+                                                               /* Since this 
is a seam we need to work out where on the line this pixel is */
+                                                               //fac = 
lambda_cp_line2(uv, uv_seam_quads[i][0], uv_seam_quads[i][1]);
+                                                               fac = 
lambda_cp_line2(uv, seam_subsection[0], seam_subsection[1]);
+                                                               if (fac<0.0) {
                                                                        
VECCOPY(pixelScreenCo, edge_verts_inset_clip[0]);
-                                                               } else if (fac1 
> 1.0) {
+                                                               } else if 
(fac>1.0) {
                                                                        
VECCOPY(pixelScreenCo, edge_verts_inset_clip[1]);
                                                                } else {
-                                                                       
VecLerpf(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], 
fac1);
+                                                                       
VecLerpf(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], 
fac);
                                                                }
                                                                
                                                                if 
(!ps->projectIsOrtho) {
@@ -1644,9 +1753,11 @@
                }
        }
        
-       if (!mf->v4 && ps->projectSeamBleed > 0.0) {
-               ps->projectFaceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* 
so this wont show up as an untagged egde */
-               ps->projectFaceSeamUVs[face_index][0][0] = MAXFLOAT; /* set as 
uninitialized */
+       if (ps->projectSeamBleed > 0.0) {
+               if (!mf->v4) {
+                       ps->projectFaceSeamFlags[face_index] |= 
PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged egde */
+               }
+               **ps->projectFaceSeamUVs[face_index] = MAXFLOAT; /* set as 
uninitialized */
        }
 }
 
@@ -1744,7 +1855,7 @@
        if (ps->projectSeamBleed > 0.0) {
                ps->projectVertFaces= (LinkNode **)BLI_memarena_alloc( 
ps->projectArena, tot_bucketVertFacesMem);
                ps->projectFaceSeamFlags = (char *)BLI_memarena_alloc( 
ps->projectArena, tot_faceSeamFlagMem);
-               ps->projectFaceSeamUVs=  BLI_memarena_alloc( ps->projectArena, 
tot_faceSeamUVMem);
+               ps->projectFaceSeamUVs= BLI_memarena_alloc( ps->projectArena, 
tot_faceSeamUVMem);
        }
 #endif
        


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to