[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17372] branches/projection-paint/source/ blender/src/imagepaint.c: mistake made initializing seam UV's fail
Campbell Barton
ideasman42 at gmail.com
Sun Nov 9 04:34:23 CET 2008
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
More information about the Bf-blender-cvs
mailing list