From 3fe14a962a125992edd72edb5bf9e6d8d7fbb383 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jul 2012 09:22:58 +0000 Subject: masking - add feather faces as quads and interpolate as quads to avoid ugly diagonal lines. --- source/blender/blenkernel/intern/mask_rasterize.c | 113 ++++++++++++---------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 922d0ed65ac..6c5c7236115 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -61,7 +61,7 @@ typedef struct MaskRasterLayer { rctf bounds; /* geometry */ - unsigned int (*tri_array)[3]; /* access coords */ + unsigned int (*tri_array)[4]; /* access coords tri/quad */ float (*tri_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ @@ -187,6 +187,8 @@ void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points) } } +#define TRI_VERT ((unsigned int) -1) + void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, const int width, const int height, const short do_aspect_correct, const short do_mask_aa, @@ -356,14 +358,14 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } if (sf_ctx.fillvertbase.first) { - unsigned int (*tri_array)[3], *tri; /* access coords */ + unsigned int (*tri_array)[4], *tri; /* access coords */ float (*tri_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */ int sf_tri_tot; rctf bounds; int tri_index; BVHTree *bvhtree; - float bvhcos[3][3]; + float bvhcos[4][3]; /* now we have all the splines */ tri_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_tri_coords"); @@ -391,10 +393,10 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* main scanfill */ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec); - tri_array = MEM_mallocN((sizeof(unsigned int) * 3) * (sf_tri_tot + (tot_feather_quads * 8)), "maskrast_tri_index"); + tri_array = MEM_mallocN(sizeof(*tri_array) * (sf_tri_tot + tot_feather_quads), "maskrast_tri_index"); /* */ - bvhtree = BLI_bvhtree_new(sf_tri_tot + (tot_feather_quads * 2), 0.000001f, 4, 6); + bvhtree = BLI_bvhtree_new(sf_tri_tot + tot_feather_quads, 0.000001f, 4, 6); /* tri's */ tri = (unsigned int *)tri_array; @@ -402,16 +404,17 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas *(tri++) = sf_tri->v1->tmp.u; *(tri++) = sf_tri->v2->tmp.u; *(tri++) = sf_tri->v3->tmp.u; + *(tri++) = TRI_VERT; - copy_v3_v3(bvhcos[0], tri_coords[*(tri - 3)]); - copy_v3_v3(bvhcos[1], tri_coords[*(tri - 2)]); - copy_v3_v3(bvhcos[2], tri_coords[*(tri - 1)]); + copy_v3_v3(bvhcos[0], tri_coords[*(tri - 4)]); + copy_v3_v3(bvhcos[1], tri_coords[*(tri - 3)]); + copy_v3_v3(bvhcos[2], tri_coords[*(tri - 2)]); BLI_bvhtree_insert(bvhtree, tri_index, (float *)bvhcos, 3); } /* start of feather faces... if we have this set, - * 'j' is kept from loop above */ + * 'tri_index' is kept from loop above */ BLI_assert(tri_index == sf_tri_tot); @@ -420,44 +423,24 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas for (sf_edge = sf_ctx.filledgebase.first; sf_edge; sf_edge = sf_edge->next) { if (sf_edge->tmp.c == SF_EDGE_IS_BOUNDARY) { - unsigned int quad[4] = { - sf_edge->v1->tmp.u, - sf_edge->v2->tmp.u, - - sf_edge->v2->keyindex, - sf_edge->v1->keyindex, - }; - - /* tri 1 */ - *(tri++) = quad[0]; - *(tri++) = quad[1]; - *(tri++) = quad[2]; - - /* tri 2 */ - *(tri++) = quad[0]; - *(tri++) = quad[2]; - *(tri++) = quad[3]; - - /* tri 1 */ - copy_v3_v3(bvhcos[0], tri_coords[quad[0]]); - copy_v3_v3(bvhcos[1], tri_coords[quad[1]]); - copy_v3_v3(bvhcos[2], tri_coords[quad[2]]); + *(tri++) = sf_edge->v1->tmp.u; + *(tri++) = sf_edge->v2->tmp.u; + *(tri++) = sf_edge->v2->keyindex; + *(tri++) = sf_edge->v1->keyindex; - BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 3); + copy_v3_v3(bvhcos[0], tri_coords[*(tri - 4)]); + copy_v3_v3(bvhcos[1], tri_coords[*(tri - 3)]); + copy_v3_v3(bvhcos[2], tri_coords[*(tri - 2)]); + copy_v3_v3(bvhcos[3], tri_coords[*(tri - 1)]); - /* tri 2 */ - copy_v3_v3(bvhcos[0], tri_coords[quad[0]]); - copy_v3_v3(bvhcos[1], tri_coords[quad[2]]); - copy_v3_v3(bvhcos[2], tri_coords[quad[3]]); - - BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 3); + BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 4); } } } - fprintf(stderr, "%d %d\n", tri_index, sf_tri_tot + (tot_feather_quads * 2)); + fprintf(stderr, "%d %d\n", tri_index, sf_tri_tot + tot_feather_quads); - BLI_assert(tri_index == sf_tri_tot + (tot_feather_quads * 2)); + BLI_assert(tri_index == sf_tri_tot + tot_feather_quads); BLI_bvhtree_balance(bvhtree); @@ -478,7 +461,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_union_rctf(&mr_handle->bounds, &bounds); } - PRINT_MASK_DEBUG("tris %d, feather tris %d\n", sf_tri_tot, (tot_feather_quads * 2)); + PRINT_MASK_DEBUG("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); } /* add trianges */ @@ -487,13 +470,22 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } /* 2D ray test */ -static float maskrasterize_layer_z_depth(const float pt[2], float v1[3], float v2[3], float v3[3]) +static float maskrasterize_layer_z_depth_tri(const float pt[2], + const float v1[3], const float v2[3], const float v3[3]) { float w[3]; barycentric_weights_v2(v1, v2, v3, pt, w); return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]); } +static float maskrasterize_layer_z_depth_quad(const float pt[2], + const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + float w[4]; + barycentric_weights_v2_quad(v1, v2, v3, v4, pt, w); + return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]); +} + static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { MaskRasterLayer *layer = (struct MaskRasterLayer *)userdata; @@ -502,15 +494,38 @@ static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeR const float dist_orig = hit->dist; /* we always cast from same place only need xy */ + if (tri[3] == TRI_VERT) { + /* --- tri --- */ - /* not essential but avoids unneeded extra lookups */ - if (cos[0][2] < dist_orig || cos[1][2] < dist_orig || cos[2][2] < dist_orig) { + /* not essential but avoids unneeded extra lookups */ + if ((cos[0][2] < dist_orig) || + (cos[1][2] < dist_orig) || + (cos[2][2] < dist_orig)) + { + if (isect_point_tri_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + const float dist = maskrasterize_layer_z_depth_tri(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]]); + if (dist < dist_orig) { + hit->index = index; + hit->dist = dist; + } + } + } + } + else { + /* --- quad --- */ - if (isect_point_tri_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { - const float dist = maskrasterize_layer_z_depth(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]]); - if (dist < dist_orig) { - hit->index = index; - hit->dist = dist; + /* not essential but avoids unneeded extra lookups */ + if ((cos[0][2] < dist_orig) || + (cos[1][2] < dist_orig) || + (cos[2][2] < dist_orig) || + (cos[3][2] < dist_orig)) + { + if (isect_point_quad_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]])) { + const float dist = maskrasterize_layer_z_depth_quad(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]]); + if (dist < dist_orig) { + hit->index = index; + hit->dist = dist; + } } } } -- cgit v1.2.3