Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-07-13 13:22:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-07-13 13:22:58 +0400
commit3fe14a962a125992edd72edb5bf9e6d8d7fbb383 (patch)
tree24c910cdd44345480cc80ac12e90d6749ca47ca5
parent73c2abe83d4e9636c4d00dc714dcba88374d9e34 (diff)
masking - add feather faces as quads and interpolate as quads to avoid ugly diagonal lines.
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c113
1 files 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;
+ }
}
}
}