diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-05-12 20:20:23 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-05-12 20:20:23 +0400 |
commit | 705764fe050fd15703fe2ab410516ff3ccc3f421 (patch) | |
tree | ab54cb5705829dd0bc22bfdf9c881d78abcc5f7a | |
parent | b6fa9afccb941aa413ac788a5bc73d9170fd6228 (diff) |
Fix face occlusion for projection paint, (was broken for all RC's but nobody noticed)
Its still not working right in perspective mode.
For bleed use a faster method then Barycentric weights function since the point is always on the edge.
last commit with memset in readfile.c missed one var.
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 11 | ||||
-rw-r--r-- | source/blender/src/imagepaint.c | 46 |
2 files changed, 35 insertions, 22 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0873c572382..cbf2516da77 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -617,15 +617,16 @@ static BHeadN *get_bhead(FileData *fd) BHead bhead; BHeadN *new_bhead = 0; int readsize; - - /* not strictly needed but shuts valgrind up - * since uninitialized memory gets compared */ - memset(&bhead8, 0, sizeof(BHead8)); - memset(&bhead4, 0, sizeof(BHead4)); if (fd) { if ( ! fd->eof) { + /* not strictly needed but shuts valgrind up + * since uninitialized memory gets compared */ + memset(&bhead8, 0, sizeof(BHead8)); + memset(&bhead4, 0, sizeof(BHead4)); + memset(&bhead, 0, sizeof(BHead)); + // First read the bhead structure. // Depending on the platform the file was written on this can // be a big or little endian BHead4 or BHead8 structure. diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 86534438ba0..37670d09749 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -230,8 +230,8 @@ typedef struct ProjPaintState { char *faceSeamFlags; /* store info about faces, if they are initialized etc*/ float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */ LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */ - char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ #endif + char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */ int buckets_y; @@ -867,7 +867,7 @@ static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *buc else isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho); } - if (isect_ret==1) { + if (isect_ret>=1) { /* TODO - we may want to cache the first hit, * it is not possible to swap the face order in the list anymore */ return 1; @@ -952,6 +952,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve * Its possible this gives incorrect results, when the UVs for 1 face go into the next * tile, but do not do this for the adjacent face, it could return a false positive. * This is so unlikely that Id not worry about it. */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int cmp_uv(const float vec2a[2], const float vec2b[2]) { /* if the UV's are not between 0.0 and 1.0 */ @@ -969,10 +970,11 @@ static int cmp_uv(const float vec2a[2], const float vec2b[2]) return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; } - +#endif /* set min_px and max_px to the image space bounds of the UV coords * return zero if there is no area in the returned rectangle */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int pixel_bounds_uv( const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2], rcti *bounds_px, @@ -1000,6 +1002,7 @@ static int pixel_bounds_uv( /* face uses no UV area when quantized to pixels? */ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1; } +#endif static int pixel_bounds_array(float (* uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot) { @@ -2498,7 +2501,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float *uv_seam_quad[4]; float fac; float *vCoSS[4]; /* vertex screenspace coords */ @@ -2554,16 +2556,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i fac1 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[0]) / ftot; fac2 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[1]) / ftot; - uv_seam_quad[0] = tf_uv_pxoffset[fidx1]; - uv_seam_quad[1] = tf_uv_pxoffset[fidx2]; - uv_seam_quad[2] = outset_uv[fidx2]; - uv_seam_quad[3] = outset_uv[fidx1]; - - Vec2Lerpf(seam_subsection[0], uv_seam_quad[0], uv_seam_quad[1], fac1); - Vec2Lerpf(seam_subsection[1], uv_seam_quad[0], uv_seam_quad[1], fac2); - - Vec2Lerpf(seam_subsection[2], uv_seam_quad[3], uv_seam_quad[2], fac2); - Vec2Lerpf(seam_subsection[3], uv_seam_quad[3], uv_seam_quad[2], fac1); + Vec2Lerpf(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1); + Vec2Lerpf(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2); + + Vec2Lerpf(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2); + Vec2Lerpf(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1); /* if the bucket_clip_edges values Z values was kept we could avoid this * Inset needs to be added so occlusion tests wont hit adjacent faces */ @@ -2616,14 +2613,28 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* Only bother calculating the weights if we intersect */ if (ps->do_mask_normal || ps->dm_mtface_clone) { - /* TODO, this is not QUITE correct since UV is not inside the UV's but good enough for seams */ +#if 0 + /* This is not QUITE correct since UV is not inside the UV's but good enough for seams */ if (side) { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], w); } else { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], w); } - +#endif +#if 1 + /* Cheat, we know where we are along the edge so work out the weights from that */ + fac = fac1 + (fac * (fac2-fac1)); + w[0]=w[1]=w[2]= 0.0; + if (side) { + w[fidx1?fidx1-1:0] = fac; + w[fidx2?fidx2-1:0] = 1.0-fac; + } + else { + w[fidx1] = fac; + w[fidx2] = 1.0-fac; + } +#endif } /* a pitty we need to get the worldspace pixel location here */ @@ -3356,15 +3367,16 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->bucketFaces); MEM_freeN(ps->bucketFlags); +#ifndef PROJ_DEBUG_NOSEAMBLEED if (ps->seam_bleed_px > 0.0f) { MEM_freeN(ps->vertFaces); MEM_freeN(ps->faceSeamFlags); MEM_freeN(ps->faceSeamUVs); } +#endif if (ps->vertFlags) MEM_freeN(ps->vertFlags); - for (a=0; a<ps->thread_tot; a++) { BLI_memarena_free(ps->arena_mt[a]); } |