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