[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17310] branches/projection-paint/source/ blender/src/imagepaint.c: fix for compile error in last commit + some WIP functions.
Campbell Barton
ideasman42 at gmail.com
Mon Nov 3 23:27:56 CET 2008
Revision: 17310
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17310
Author: campbellbarton
Date: 2008-11-03 23:27:55 +0100 (Mon, 03 Nov 2008)
Log Message:
-----------
fix for compile error in last commit + some WIP functions.
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-03 17:54:12 UTC (rev 17309)
+++ branches/projection-paint/source/blender/src/imagepaint.c 2008-11-03 22:27:55 UTC (rev 17310)
@@ -139,8 +139,12 @@
/* 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_OWNED 1<<2 /* When the face is in 1 bucket */
+#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
+
#define PROJ_BUCKET_NULL 0
#define PROJ_BUCKET_INIT 1
@@ -160,13 +164,13 @@
MFace *dm_mface;
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 */
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;
@@ -178,9 +182,10 @@
float (*projectVertScreenCos)[3]; /* verts projected into floating point screen space */
/* options for projection painting */
- short projectIsIsOcclude; /* 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;
+ short projectIsSeamBleed;
float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
float viewMat[4][4];
@@ -582,6 +587,82 @@
return totscanlines;
}
+static int cmp_uv(float *vec2a, float *vec2b)
+{
+ return ((fabs(vec2a[0]-vec2b[0]) < 0.0001) && (fabs(vec2a[1]-vec2b[1]) < 0.0001)) ? 1:0;
+}
+
+
+static int check_seam(ProjectPaintState *ps, int orig_face, int orig_i1_fidx, int orig_i2_fidx)
+{
+ LinkNode *node;
+ int face_index;
+ int i, i1, i2;
+ int i1_fidx = -1, i2_fidx = -1; /* indexi in face */
+ MFace *orig_mf, *mf;
+ MTFace *orig_tf, *tf;
+
+ orig_mf = ps->dm_mface + orig_face;
+ orig_tf = ps->dm_mtface + orig_face;
+
+ /* vert indicies from face vert order indicies */
+ i1 = (*(&orig_mf->v1 + orig_i1_fidx));
+ i2 = (*(&orig_mf->v1 + orig_i2_fidx));
+
+ for (node = ps->projectVertFaces[i1]; node; node = node->next) {
+ face_index = (int)node->link;
+ if (face_index != orig_face) {
+ mf = ps->dm_mface + face_index;
+
+ /* We need to know the order of the verts in the adjacent face
+ * set the i1_fidx and i2_fidx to (0,1,2,3) */
+ i = mf->v4 ? 3:2;
+ do {
+ if (i1 == (*(&mf->v1 + i))) {
+ i1_fidx = i;
+ } else if (i2 == (*(&mf->v1 + i))) {
+ i2_fidx = i;
+ }
+
+ } while (i--);
+
+ if (i2_fidx != -1) {
+ /* This IS an adjacent face!, now lets check if the UVs are ok */
+
+ tf = ps->dm_mtface + face_index;
+ if ( 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");
+ return 0;
+
+ } else {
+ // printf("SEAM (UV GAP)\n");
+ return 1;
+ }
+ }
+ }
+ }
+ // printf("SEAM (NO FACE)\n");
+ 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) |
+ (check_seam(ps, face_index, 2,3) ? PROJ_FACE_SEAM3 : 0) |
+ (check_seam(ps, face_index, 3,0) ? PROJ_FACE_SEAM4 : 0);
+ } else {
+ 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) |
+ (check_seam(ps, face_index, 2,0) ? PROJ_FACE_SEAM3 : 0);
+ }
+}
+
static void project_paint_face_init(ProjectPaintState *ps, int face_index, ImBuf *ibuf)
{
/* Projection vars, to get the 3D locations into screen space */
@@ -608,9 +689,7 @@
float pixelScreenCo[3]; /* for testing occlusion we need the depth too, but not for saving into ProjectPixel */
int bucket_index;
- //float pxWorldCo[3];
-
INIT_MINMAX2(min_uv, max_uv);
i = mf->v4 ? 3:2;
@@ -635,6 +714,10 @@
if (xmini == xmaxi || ymini == ymaxi)
return;
+ /* detect UV seams so we can bleed */
+ if (ps->projectIsSeamBleed)
+ project_face_seams_init(ps, face_index, mf->v4);
+
for (y = ymini; y < ymaxi; y++) {
uv[1] = (((float)y)+0.5) / (float)ibuf->y;
@@ -835,13 +918,24 @@
{
float min[2], max[2];
int bucket_min[2], bucket_max[2]; /* for ps->projectBuckets indexing */
- int i, bucket_x, bucket_y, bucket_index;
+ int i, a, bucket_x, bucket_y, bucket_index;
INIT_MINMAX2(min,max);
i = mf->v4 ? 3:2;
do {
- DO_MINMAX2(ps->projectVertScreenCos[ (*(&mf->v1 + i)) ], min, max);
+ a = (*(&mf->v1 + i)); /* vertex index */
+
+ DO_MINMAX2(ps->projectVertScreenCos[ a ], min, max);
+
+ /* add face user if we have bleed enabled, set the UV seam flags later */
+ if (ps->projectIsSeamBleed) {
+ BLI_linklist_prepend_arena(
+ &ps->projectVertFaces[ a ],
+ (void *)face_index, /* cast to a pointer to shut up the compiler */
+ ps->projectArena
+ );
+ }
} while (i--);
project_paint_rect(ps, min, max, bucket_min, bucket_max);
@@ -889,6 +983,7 @@
int tot_faceFlagMem=0;
int tot_faceListMem=0;
int tot_bucketFlagMem=0;
+ int tot_bucketVertFacesMem=0;
/* ---- end defines ---- */
@@ -914,24 +1009,33 @@
view3d_get_object_project_mat(curarea, s->ob, ps->projectMat, ps->viewMat);
- tot_bucketMem = sizeof(LinkNode *) * ps->bucketsX * ps->bucketsY;
- tot_faceListMem = sizeof(LinkNode *) * ps->bucketsX * ps->bucketsY;
- tot_faceFlagMem = sizeof(char) * ps->dm_totface;
- tot_bucketFlagMem = sizeof(char) * ps->bucketsX * ps->bucketsY;
+ tot_bucketMem = sizeof(LinkNode *) * ps->bucketsX * ps->bucketsY;
+ tot_faceListMem = sizeof(LinkNode *) * ps->bucketsX * ps->bucketsY;
+ tot_faceFlagMem = sizeof(char) * ps->dm_totface;
+ tot_bucketFlagMem = sizeof(char) * ps->bucketsX * ps->bucketsY;
+ if (ps->projectIsSeamBleed) /* UV Seams for bleeding */
+ tot_bucketVertFacesMem = sizeof(LinkNode *) * ps->dm_totvert;
+ ps->projectArena =
+ BLI_memarena_new( tot_bucketMem +
+ tot_faceListMem +
+ tot_faceFlagMem +
+ tot_bucketVertFacesMem + (1<<16));
- ps->projectArena = BLI_memarena_new(tot_bucketMem + tot_faceListMem + tot_faceFlagMem + (1<<16) );
-
ps->projectBuckets = (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_bucketMem);
ps->projectFaces= (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_faceListMem);
ps->projectFaceFlags = (char *)BLI_memarena_alloc( ps->projectArena, tot_faceFlagMem);
ps->projectBucketFlags= (char *)BLI_memarena_alloc( ps->projectArena, tot_bucketFlagMem);
-
+ if (ps->projectIsSeamBleed)
+ ps->projectVertFaces= (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_bucketVertFacesMem);
+
memset(ps->projectBuckets, 0, tot_bucketMem);
memset(ps->projectFaces, 0, tot_faceListMem);
memset(ps->projectFaceFlags, 0, tot_faceFlagMem);
memset(ps->projectBucketFlags, 0, tot_bucketFlagMem);
+ if (ps->projectIsSeamBleed)
+ memset(ps->projectVertFaces, 0, tot_bucketVertFacesMem);
Mat4Invert(s->ob->imat, s->ob->obmat);
@@ -1822,6 +1926,7 @@
ps.projectIsBackfaceCull = 1;
ps.projectIsOcclude = 1;
+ ps.projectIsSeamBleed = 0;
project_paint_begin(&s, &ps);
More information about the Bf-blender-cvs
mailing list