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. @@

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

Reply via email to