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

Log Message:
-----------
changes to projection painting
* initializing a bucket only initializes pixels from that bucket (was 
initializing all pixels in intersecting faces before which made large faces 
slow to paint onto)
* removed scanline functions, they are not as useful when initializing small 
areas. 
* UV seam checking also sets the seam flag on the adjacent face to avoid double 
lookups.

TODO - uv seam bleed doesn't work in perspective mode.

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 
01:16:12 UTC (rev 17370)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-09 
02:47:30 UTC (rev 17371)
@@ -133,18 +133,22 @@
 /* testing options */
 #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_PAINT 1
 //#define PROJ_DEBUG_NOSEAMBLEED 1
 
-/* projectFaceFlags options */
-#define PROJ_FACE_IGNORE       1<<0    /* When the face is hidden, backfacing 
or occluded */
-#define PROJ_FACE_INIT 1<<1    /* When we have initialized the faces data */
-#define PROJ_FACE_SEAM1        1<<2    /* If this face has a seam on any of 
its edges */
-#define PROJ_FACE_SEAM2        1<<3
-#define PROJ_FACE_SEAM3        1<<4
-#define PROJ_FACE_SEAM4        1<<5
+/* projectFaceSeamFlags options */
+//#define PROJ_FACE_IGNORE     1<<0    /* When the face is hidden, backfacing 
or occluded */
+//#define PROJ_FACE_INIT       1<<1    /* When we have initialized the faces 
data */
+#define PROJ_FACE_SEAM1        1<<0    /* If this face has a seam on any of 
its edges */
+#define PROJ_FACE_SEAM2        1<<1
+#define PROJ_FACE_SEAM3        1<<2
+#define PROJ_FACE_SEAM4        1<<3
 
+#define PROJ_FACE_NOSEAM1      1<<4
+#define PROJ_FACE_NOSEAM2      1<<5
+#define PROJ_FACE_NOSEAM3      1<<6
+#define PROJ_FACE_NOSEAM4      1<<7
+
 #define PROJ_BUCKET_NULL               0
 #define PROJ_BUCKET_INIT               1<<0
 // #define PROJ_BUCKET_CLONE_INIT      1<<1
@@ -170,25 +174,26 @@
        MTFace             *dm_mtface;
        
        /* projection painting only */
-       MemArena *projectArena;         /* use for alocating many pixel structs 
and link-lists */
-       LinkNode **projectBuckets;      /* screen sized 2D array, each pixel 
has a linked list of ProjectPixel's */
-       LinkNode **projectFaces;        /* projectBuckets alligned array 
linkList of faces overlapping each bucket */
-       char *projectBucketFlags;       /* store if the bucks have been 
initialized  */
-       char *projectFaceFlags;         /* store info about faces, if they are 
initialized etc*/
-       LinkNode **projectVertFaces;/* Only needed for when projectIsSeamBleed 
is enabled, use to find UV seams */
+       MemArena *projectArena;                 /* use for alocating many pixel 
structs and link-lists */
+       LinkNode **projectBuckets;              /* screen sized 2D array, each 
pixel has a linked list of ProjectPixel's */
+       LinkNode **projectFaces;                /* projectBuckets alligned 
array linkList of faces overlapping each bucket */
+       char *projectBucketFlags;               /* store if the bucks have been 
initialized  */
+       char *projectFaceSeamFlags;             /* store info about faces, if 
they are initialized etc*/
+       float (*projectFaceSeamUVs)[4][2];      /* expanded UVs for faces to 
use as seams */
+       LinkNode **projectVertFaces;    /* Only needed for when 
projectSeamBleed is enabled, use to find UV seams */
        
-       int bucketsX;                           /* The size of the bucket grid, 
the grid span's viewMin2D/viewMax2D so you can paint outsize the screen or with 
2 brushes at once */
+       int bucketsX;                                   /* The size of the 
bucket grid, the grid span's viewMin2D/viewMax2D so you can paint outsize the 
screen or with 2 brushes at once */
        int bucketsY;
        
-       Image **projectImages;          /* array of images we are painting onto 
while, use so we can tag for updates */
+       Image **projectImages;                  /* array of images we are 
painting onto while, use so we can tag for updates */
        
-       int projectImageTotal;          /* size of projectImages array */
-       int imaContextIndex;            /* current image, use for context 
switching */
+       int projectImageTotal;                  /* size of projectImages array 
*/
+       int imaContextIndex;                    /* current image, use for 
context switching */
        
        float (*projectVertScreenCos)[3];       /* verts projected into 
floating point screen space */
        
        /* options for projection painting */
-       short projectIsOcclude;         /* Use raytraced occlusion? - 
ortherwise will paint right through to the back*/
+       short projectIsOcclude;                 /* Use raytraced occlusion? - 
ortherwise will paint right through to the back*/
        short projectIsBackfaceCull;    /* ignore faces with normals pointing 
away, skips a lot of raycasts if your normals are correctly flipped */
        short projectIsOrtho;
 #ifndef PROJ_DEBUG_NOSEAMBLEED
@@ -208,11 +213,6 @@
        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;
@@ -424,6 +424,7 @@
                w[1]/=wtot;
                w[2]/=wtot;
        } else {
+               printf("WATCH oUT ZAREA FACE\n");
                w[0] = w[1] = w[2] = 1.0/3.0; /* dummy values for zero area 
face */
        }
 }
@@ -624,6 +625,7 @@
                        }
                        
                        if (isect_ret==1) {
+#if 0
                                /* Cheap Optimization!
                                 * This function runs for every UV Screen pixel,
                                 * therefor swapping the swapping the faces for 
this buckets list helps because
@@ -639,7 +641,7 @@
                                } /*else {
                                        printf("first hit %d\n", face_index);
                                }*/
-                               
+#endif
                                return 1; 
                        }
                }
@@ -654,7 +656,7 @@
 #define ISECT_TRUE 1
 #define ISECT_TRUE_P1 2
 #define ISECT_TRUE_P2 3
-static int project_scanline_isect(float p1[2], float p2[2], float y_level, 
float *x_isect)
+static int line_isect_y(float p1[2], float p2[2], float y_level, float 
*x_isect)
 {
        if (y_level==p1[1]) {
                *x_isect = p1[0];
@@ -676,99 +678,26 @@
        }
 }
 
-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;
+static int line_isect_x(float p1[2], float p2[2], float x_level, float 
*y_isect)
+{
+       if (x_level==p1[0]) {
+               *y_isect = p1[1];
+               return ISECT_TRUE_P1;
+       }
+       if (x_level==p2[0]) {
+               *y_isect = p2[1];
+               return ISECT_TRUE_P2;
+       }
        
-       if (v4) { /* This is a quad?*/
-               int i4=0, i_mid=0;
-               float xi1, xi2, xi3, xi4, xi_mid;
-                               
-               i1 = project_scanline_isect(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 = project_scanline_isect(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 = project_scanline_isect(v3, v4, y_level, 
&xi3);
-                       if (i1 != ISECT_TRUE_P1 && i3 != ISECT_TRUE_P2) 
-                               i4 = project_scanline_isect(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 = project_scanline_isect(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 = project_scanline_isect(v1, v2, y_level, &sc->x_limits[0]);
-               if (i1) i++;
-               
-               if (i1 != ISECT_TRUE_P2) {
-                       i2 = project_scanline_isect(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 = project_scanline_isect(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;
-                       }
-               }
+       if (p1[0] > x_level && p2[0] < x_level) {
+               *y_isect = (p2[1]*(p1[0]-x_level) + p1[1]*(x_level-p2[0])) / 
(p1[0]-p2[0]);
+               return ISECT_TRUE;
+       } else if (p1[0] < x_level && p2[0] > x_level) {
+               *y_isect = (p2[1]*(x_level-p1[0]) + p1[1]*(p2[0]-x_level)) / 
(p2[0]-p1[0]);
+               return ISECT_TRUE;
+       } else {
+               return 0;
        }
-       /* done setting up scanlines */
-       return totscanlines;
 }
 
 static int cmp_uv(float vec2a[2], float vec2b[2])
@@ -778,7 +707,8 @@
        
 
 #ifndef PROJ_DEBUG_NOSEAMBLEED
-static int check_seam(ProjectPaintState *ps, int orig_face, int orig_i1_fidx, 
int orig_i2_fidx)
+/* TODO - set the seam flag on the other face to avoid double lookups */
+static int check_seam(ProjectPaintState *ps, int orig_face, int orig_i1_fidx, 
int orig_i2_fidx, int *other_face, int *orig_fidx)
 {
        LinkNode *node;
        int face_index;
@@ -814,15 +744,17 @@
                        if (i2_fidx != -1) {
                                /* This IS an adjacent face!, now lets check if 
the UVs are ok */
                                
+
+                               
                                tf = ps->dm_mtface + face_index;
                                
+                               /* set up the other face */
+                               *other_face = face_index;
+                               *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : 
i2_fidx;
+                               
                                /* first test if they have the same image */
-                               if (orig_tf->tpage != tf->tpage) {
-                                       // printf("SEAM (IMAGE DIFF)\n");
-                                       return 1;
-                               }
-                               
-                               if (    cmp_uv(orig_tf->uv[orig_i1_fidx], 
tf->uv[i1_fidx]) &&
+                               if (    (orig_tf->tpage == tf->tpage) &&
+                                               
cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
                                                
cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
                                {
                                        // printf("SEAM (NONE)\n");
@@ -836,25 +768,10 @@
                }
        }
        // printf("SEAM (NO FACE)\n");
+       *other_face = -1;
        return 1;
 }
 
-static void project_face_seams_init(ProjectPaintState *ps, int face_index, int 
is_quad)
-{
-       if (is_quad) {
-               ps->projectFaceFlags[face_index] |= 
-                       (check_seam(ps, face_index, 0,1) ? PROJ_FACE_SEAM1 : 0) 
|
-                       (check_seam(ps, face_index, 1,2) ? PROJ_FACE_SEAM2 : 0) 
|

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