[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17318] branches/projection-paint/source/ blender/src/imagepaint.c: perspective mode now works with seam bleeding.
Campbell Barton
ideasman42 at gmail.com
Tue Nov 4 11:17:43 CET 2008
Revision: 17318
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17318
Author: campbellbarton
Date: 2008-11-04 11:17:43 +0100 (Tue, 04 Nov 2008)
Log Message:
-----------
perspective mode now works with seam bleeding.
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-04 09:21:27 UTC (rev 17317)
+++ branches/projection-paint/source/blender/src/imagepaint.c 2008-11-04 10:17:43 UTC (rev 17318)
@@ -421,7 +421,7 @@
/* check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison */
-static int project_bucket_point_occluded(ProjectPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[3])
+static int project_bucket_point_occluded(ProjectPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[4])
{
LinkNode *node = ps->projectFaces[bucket_index];
MFace *mf;
@@ -833,45 +833,62 @@
return(Inp2f(u,h)/Inp2f(u,u));
}
+static screen_px_from_ortho(
+ ProjectPaintState *ps, float *uv,
+ float *v1co, float *v2co, float *v3co, /* Screenspace coords */
+ float *uv1co, float *uv2co, float *uv3co,
+ float *pixelScreenCo )
+{
+ float w1, w2, w3, wtot; /* weights for converting the pixel into 3d screenspace coords */
+ w1 = AreaF2Dfl(uv2co, uv3co, uv);
+ w2 = AreaF2Dfl(uv3co, uv1co, uv);
+ w3 = AreaF2Dfl(uv1co, uv2co, uv);
+
+ wtot = w1 + w2 + w3;
+ w1 /= wtot; w2 /= wtot; w3 /= wtot;
+
+ pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
+ pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
+ pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;
+}
-#define pixel_size 4
-static void project_paint_uvpixel_init(
- ProjectPaintState *ps, ProjectScanline *sc, ImBuf *ibuf, float *uv,
- float *v1co, float *v2co, float *v3co,
+static screen_px_from_persp(
+ ProjectPaintState *ps, float *uv,
+ float *v1co, float *v2co, float *v3co, /* Worldspace coords */
float *uv1co, float *uv2co, float *uv3co,
- int x, int y, int face_index,
- float *pixelScreenCo /* can provide own own coords, use for seams when we want to bleed our from the original location */
-) {
- float pixelScreenCo_own[3]; /* for testing occlusion we need the depth too, but not for saving into ProjectPixel */
- int bucket_index;
+ float *pixelScreenCo )
+{
+ float w1, w2, w3, wtot; /* weights for converting the pixel into 3d screenspace coords */
+ w1 = AreaF2Dfl(uv2co, uv3co, uv);
+ w2 = AreaF2Dfl(uv3co, uv1co, uv);
+ w3 = AreaF2Dfl(uv1co, uv2co, uv);
- ProjectPixel *projPixel;
+ wtot = w1 + w2 + w3;
+ w1 /= wtot; w2 /= wtot; w3 /= wtot;
+ pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
+ pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
+ pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;
+ pixelScreenCo[3] = 1.0;
- /* pixelScreenCo not provided? - calculate our own */
- if (pixelScreenCo==NULL) {
- float w1, w2, w3, wtot; /* weights for converting the pixel into 3d worldspace coords */
+ Mat4MulVec4fl(ps->projectMat, pixelScreenCo);
+
+ // if( pixelScreenCo[3] > 0.001 ) { ??? TODO
+ /* screen space, not clamped */
+ pixelScreenCo[0] = (float)(curarea->winx/2.0)+(curarea->winx/2.0)*pixelScreenCo[0]/pixelScreenCo[3];
+ pixelScreenCo[1] = (float)(curarea->winy/2.0)+(curarea->winy/2.0)*pixelScreenCo[1]/pixelScreenCo[3];
+ pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
+}
- pixelScreenCo = pixelScreenCo_own;
- /* Get the world coord for the point in uv space */
- if (ps->projectIsOrtho) {
- w1 = AreaF2Dfl(uv2co, uv3co, uv);
- w2 = AreaF2Dfl(uv3co, uv1co, uv);
- w3 = AreaF2Dfl(uv1co, uv2co, uv);
- } else { /* prespective mode needs an interpolation */
- w1 = AreaF2Dfl(uv2co, uv3co, uv) / v1co[2];
- w2 = AreaF2Dfl(uv3co, uv1co, uv) / v2co[2];
- w3 = AreaF2Dfl(uv1co, uv2co, uv) / v3co[2];
- }
-
- wtot = w1 + w2 + w3;
- w1 /= wtot; w2 /= wtot; w3 /= wtot;
-
- pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
- pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
- pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;
- }
+/* can provide own own coords, use for seams when we want to bleed our from the original location */
+
+#define pixel_size 4
+static void project_paint_uvpixel_init(ProjectPaintState *ps, ProjectScanline *sc, ImBuf *ibuf, float *uv, int x, int y, int face_index, float *pixelScreenCo)
+{
+ int bucket_index;
+ ProjectPixel *projPixel;
+
bucket_index = project_paint_BucketOffset(ps, pixelScreenCo);
/* even though it should be clamped, in some cases it can still run over */
@@ -919,6 +936,7 @@
int min_px[2], max_px[2]; /* UV Bounds converted to int's for pixel */
float *v1co, *v2co, *v3co; /* for convenience only, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
+ float pixelScreenCo[4], pixelScreenCoXMin[4], pixelScreenCoXMax[4];
int i, j;
/* scanlines since quads can have 2 triangles intersecting the same vertical location */
@@ -946,25 +964,75 @@
CLAMP(min_px[0], 0, ibuf->x);
CLAMP(max_px[0], 0, ibuf->x);
- v1co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[0])) ];
- v2co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[1])) ];
- v3co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[2])) ];
-
uv1co = tf->uv[sc->v[0]];
uv2co = tf->uv[sc->v[1]];
uv3co = tf->uv[sc->v[2]];
- for (x = min_px[0]; x < max_px[0]; x++) {
+ if (ps->projectIsOrtho) {
+ v1co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[0])) ];
+ v2co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[1])) ];
+ v3co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[2])) ];
+
+ for (x = min_px[0]; x < max_px[0]; x++) {
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCo);
+ project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y,face_index, pixelScreenCo);
+ }
+
+ /* interpolation is faster - no workies :( */
+ /*
+ x = min_px[0];
uv[0] = (((float)x)+0.5) / (float)ibuf->x;
- project_paint_uvpixel_init(ps, sc, ibuf, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, x,y,face_index, NULL);
+ screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMin);
+
+ x = max_px[0]-1;
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMax);
+
+ for (x = min_px[0]; x < max_px[0]; x++) {
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ VecLerpf(pixelScreenCo, pixelScreenCoXMin, pixelScreenCoXMax, ((float)x) / ((float)(max_px[0]-min_px[0])) );
+ project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y, face_index, pixelScreenCo);
+ }
+ */
+
+ } else {
+ v1co = ps->dm_mvert[ (*(&mf->v1 + sc->v[0])) ].co;
+ v2co = ps->dm_mvert[ (*(&mf->v1 + sc->v[1])) ].co;
+ v3co = ps->dm_mvert[ (*(&mf->v1 + sc->v[2])) ].co;
+
+ for (x = min_px[0]; x < max_px[0]; x++) {
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCo);
+ project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y,face_index, pixelScreenCo);
+ }
+
+
+ /* interpolation is faster */
+ /*
+ x = min_px[0];
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMin);
+
+ x = max_px[0]-1;
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMax);
+
+ for (x = min_px[0]; x < max_px[0]; x++) {
+ uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+ VecLerpf(pixelScreenCo, pixelScreenCoXMin, pixelScreenCoXMax, ((float)x) / ((float)(max_px[0]-min_px[0])) );
+ project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y, face_index, pixelScreenCo);
+ }
+ */
}
+
}
}
/* Pretty much a copy of above, except fill in seams if we have any */
if (ps->projectFaceFlags[face_index] & (PROJ_FACE_SEAM1|PROJ_FACE_SEAM2|PROJ_FACE_SEAM3|PROJ_FACE_SEAM4)) {
float outset_uv[4][2]; /* expanded UV's */
- float inset_screen_cos[4][3]; /* expanded UV's */
+ float insetCos[4][3]; /* expanded UV's */
float cent[3];
float *uv_seam_quads[4][4];
float *edge_verts[4][2];
@@ -972,39 +1040,49 @@
float fac;
int totuvseamquads = 0;
- VECCOPY2D(inset_screen_cos[0], ps->projectVertScreenCos[ mf->v1 ]);
- VECCOPY2D(inset_screen_cos[1], ps->projectVertScreenCos[ mf->v2 ]);
- VECCOPY2D(inset_screen_cos[2], ps->projectVertScreenCos[ mf->v3 ]);
+ if (ps->projectIsOrtho) {
+ VECCOPY(insetCos[0], ps->projectVertScreenCos[ mf->v1 ]);
+ VECCOPY(insetCos[1], ps->projectVertScreenCos[ mf->v2 ]);
+ VECCOPY(insetCos[2], ps->projectVertScreenCos[ mf->v3 ]);
+ if (mf->v4)
+ VECCOPY(insetCos[3], ps->projectVertScreenCos[ mf->v4 ]);
+ } else {
+ VECCOPY(insetCos[0], ps->dm_mvert[ mf->v1 ].co);
+ VECCOPY(insetCos[1], ps->dm_mvert[ mf->v2 ].co);
+ VECCOPY(insetCos[2], ps->dm_mvert[ mf->v3 ].co);
+ if (mf->v4)
+ VECCOPY(insetCos[3], ps->dm_mvert[ mf->v4 ].co);
+ }
+
+
if (mf->v4) {
- VECCOPY2D(inset_screen_cos[3], ps->projectVertScreenCos[ mf->v4 ]);
+ cent[0] = (insetCos[0][0] + insetCos[1][0] + insetCos[2][0] + insetCos[3][0]) / 4.0;
+ cent[1] = (insetCos[0][1] + insetCos[1][1] + insetCos[2][1] + insetCos[3][1]) / 4.0;
+ cent[2] = (insetCos[0][2] + insetCos[1][2] + insetCos[2][2] + insetCos[3][2]) / 4.0;
- cent[0] = (inset_screen_cos[0][0] + inset_screen_cos[1][0] + inset_screen_cos[2][0] + inset_screen_cos[3][0]) / 4.0;
- cent[1] = (inset_screen_cos[0][1] + inset_screen_cos[1][1] + inset_screen_cos[2][1] + inset_screen_cos[3][1]) / 4.0;
- cent[2] = (inset_screen_cos[0][2] + inset_screen_cos[1][2] + inset_screen_cos[2][2] + inset_screen_cos[3][2]) / 4.0;
-
} else {
- cent[0] = (inset_screen_cos[0][0] + inset_screen_cos[1][0] + inset_screen_cos[2][0]) / 3.0;
- cent[1] = (inset_screen_cos[0][1] + inset_screen_cos[1][1] + inset_screen_cos[2][1]) / 3.0;
- cent[2] = (inset_screen_cos[0][2] + inset_screen_cos[1][2] + inset_screen_cos[2][2]) / 3.0;
+ cent[0] = (insetCos[0][0] + insetCos[1][0] + insetCos[2][0]) / 3.0;
+ cent[1] = (insetCos[0][1] + insetCos[1][1] + insetCos[2][1]) / 3.0;
+ cent[2] = (insetCos[0][2] + insetCos[1][2] + insetCos[2][2]) / 3.0;
}
- Vec2Subf(inset_screen_cos[0], inset_screen_cos[0], cent);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list