add Anti-Aliasing (very rough draft algorithm, NOT FINAL version) to raskter lib...
authorPeter Larabell <xgl.asyliax@gmail.com>
Wed, 13 Jun 2012 19:57:23 +0000 (19:57 +0000)
committerPeter Larabell <xgl.asyliax@gmail.com>
Wed, 13 Jun 2012 19:57:23 +0000 (19:57 +0000)
12 files changed:
intern/raskter/raskter.c
intern/raskter/raskter.h
source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/tracking.c
source/blender/compositor/nodes/COM_MaskNode.cpp
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/compositor/operations/COM_MaskOperation.h
source/blender/editors/space_node/drawnode.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/composite/nodes/node_composite_mask.c

index 081a7c6bdbd825bf57cd269d25cb466d2e6009ea..8bdd4dccbc0fee2c8444356e917753d0feea7d1f 100644 (file)
@@ -34,7 +34,7 @@
 /* from BLI_utildefines.h */
 #define MIN2(x, y)               ( (x) < (y) ? (x) : (y) )
 #define MAX2(x, y)               ( (x) > (y) ? (x) : (y) )
-
+#define ABS(a)          ( (a) < 0 ? (-(a)) : (a) )
 
 struct e_status {
        int x;
@@ -67,8 +67,7 @@ struct r_fill_context {
  * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate
  * for now.
  */
-static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge)
-{
+static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) {
        int i;
        int xbeg;
        int ybeg;
@@ -94,8 +93,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
                        /* we're not at the last vert, so end of the edge is the previous vertex */
                        xend = v[i - 1].x;
                        yend = v[i - 1].y;
-               }
-               else {
+               } else {
                        /* we're at the first vertex, so the "end" of this edge is the last vertex */
                        xend = v[num_verts - 1].x;
                        yend = v[num_verts - 1].y;
@@ -124,8 +122,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
                        if (dx > 0) {
                                e_new->xdir = 1;
                                xdist = dx;
-                       }
-                       else {
+                       } else {
                                e_new->xdir = -1;
                                xdist = -dx;
                        }
@@ -138,15 +135,13 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
                        /* calculate deltas for incremental drawing */
                        if (dx >= 0) {
                                e_new->drift = 0;
-                       }
-                       else {
+                       } else {
                                e_new->drift = -dy + 1;
                        }
                        if (dy >= xdist) {
                                e_new->drift_inc = xdist;
                                e_new->xshift = 0;
-                       }
-                       else {
+                       } else {
                                e_new->drift_inc = xdist % dy;
                                e_new->xshift = (xdist / dy) * e_new->xdir;
                        }
@@ -170,8 +165,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
  * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need
  * if it ends up being coupled with this function.
  */
-static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts)
-{
+static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float intensity) {
        int x_curr;                 /* current pixel position in X */
        int y_curr;                 /* current scan line being drawn */
        int yp;                     /* y-pixel's position in frame buffer */
@@ -260,8 +254,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
                                        edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
                                        ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
                                        break;                               /* Stop looping edges (since we ran out or hit empty X span. */
-                               }
-                               else {
+                               } else {
                                        edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
                                }
                        }
@@ -307,7 +300,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
 
                        if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
                                /* draw the pixels. */
-                               for (; cpxl <= mpxl; *cpxl++ = 1.0f);
+                               for(; cpxl <= mpxl; *cpxl++ += intensity);
                        }
                }
 
@@ -323,8 +316,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
                for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
                        if (!(--(e_curr->num))) {
                                *edgec = e_curr->e_next;
-                       }
-                       else {
+                       } else {
                                e_curr->x += e_curr->xshift;
                                if ((e_curr->drift += e_curr->drift_inc) > 0) {
                                        e_curr->x += e_curr->xdir;
@@ -383,12 +375,17 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i
 }
 
 int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
-                   float *buf, int buf_x, int buf_y)
-{
+                                  float *buf, int buf_x, int buf_y, int do_mask_AA) {
+       int subdiv_AA = (do_mask_AA != 0)? 8:0;
        int i;                                   /* i: Loop counter. */
+       int sAx;
+       int sAy;
        struct poly_vert *ply;                   /* ply: Pointer to a list of integer buffer-space vertex coordinates. */
        struct r_fill_context ctx = {0};
-
+       const float buf_x_f = (float)(buf_x);
+       const float buf_y_f = (float)(buf_y);
+       float div_offset=(1.0f / (float)(subdiv_AA));
+       float div_offset_static = 0.5f * (float)(subdiv_AA) * div_offset;
        /*
         * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
         * data structure multiplied by the number of base_verts.
@@ -400,6 +397,9 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
                return(0);
        }
 
+       ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
+       ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
+       ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
        /*
         * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
         * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
@@ -408,16 +408,25 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
         * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
         * drawn will be 1.0f in value, there is no anti-aliasing.
         */
+
+       if(!subdiv_AA) {
        for (i = 0; i < num_base_verts; i++) {                          /* Loop over all base_verts. */
-               ply[i].x = (base_verts[i][0] * buf_x) + 0.5f;       /* Range expand normalized X to integer buffer-space X. */
-               ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */
+                       ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f);       /* Range expand normalized X to integer buffer-space X. */
+                       ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */
        }
 
-       ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
-       ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
-       ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
-
-       i = rast_scan_fill(&ctx, ply, num_base_verts);  /* Call our rasterizer, passing in the integer coords for each vert. */
+               i = rast_scan_fill(&ctx, ply, num_base_verts,1.0f);  /* Call our rasterizer, passing in the integer coords for each vert. */
+       } else {
+               for(sAx=0; sAx < subdiv_AA; sAx++) {
+                       for(sAy=0; sAy < subdiv_AA; sAy++) {
+                               for(i=0; i < num_base_verts; i++) {
+                                       ply[i].x = (int)((base_verts[i][0]*buf_x_f)+0.5f - div_offset_static + (div_offset*(float)(sAx)));
+                                       ply[i].y = (int)((base_verts[i][1]*buf_y_f)+0.5f - div_offset_static + (div_offset*(float)(sAy)));
+                               }
+                               i = rast_scan_fill(&ctx, ply, num_base_verts,(1.0f / (float)(subdiv_AA*subdiv_AA)));
+                       }
+               }
+       }
        free(ply);                                      /* Free the memory allocated for the integer coordinate table. */
        return(i);                                      /* Return the value returned by the rasterizer. */
 }
@@ -429,8 +438,7 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
  */
 static int rast_scan_feather(struct r_fill_context *ctx,
                              float (*base_verts_f)[2], int num_base_verts,
-                             struct poly_vert *feather_verts, float (*feather_verts_f)[2], int num_feather_verts)
-{
+                                                        struct poly_vert *feather_verts, float(*feather_verts_f)[2], int num_feather_verts) {
        int x_curr;                 /* current pixel position in X */
        int y_curr;                 /* current scan line being drawn */
        int yp;                     /* y-pixel's position in frame buffer */
@@ -536,8 +544,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
                                        edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
                                        ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
                                        break;                               /* Stop looping edges (since we ran out or hit empty X span. */
-                               }
-                               else {
+                               } else {
                                        edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
                                }
                        }
@@ -647,8 +654,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
                for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
                        if (!(--(e_curr->num))) {
                                *edgec = e_curr->e_next;
-                       }
-                       else {
+                       } else {
                                e_curr->x += e_curr->xshift;
                                if ((e_curr->drift += e_curr->drift_inc) > 0) {
                                        e_curr->x += e_curr->xdir;
@@ -708,8 +714,7 @@ static int rast_scan_feather(struct r_fill_context *ctx,
 }
 
 int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts,
-                           float *buf, int buf_x, int buf_y)
-{
+                                                  float *buf, int buf_x, int buf_y) {
        int i;                            /* i: Loop counter. */
        struct poly_vert *fe;             /* fe: Pointer to a list of integer buffer-space feather vertex coords. */
        struct r_fill_context ctx = {0};
@@ -751,3 +756,569 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f
        free(fe);
        return i;                                   /* Return the value returned by the rasterizer. */
 }
+
+int get_range_expanded_pixel_coord(float normalized_value, int max_value) {
+       return (int)((normalized_value * (float)(max_value)) + 0.5f);
+}
+
+float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) {
+       if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
+               return 0.0f;
+       }
+       return buf[(pos_y * buf_y) + buf_x];
+}
+
+float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) {
+       int a;
+       int b;
+       int a_plus_1;
+       int b_plus_1;
+       float prop_u;
+       float prop_v;
+       float inv_prop_u;
+       float inv_prop_v;
+       if(u<0.0f || u>1.0f || v<0.0f || v>1.0f) {
+               return 0.0f;
+       }
+       u = u * (float)(buf_x) - 0.5f;
+       v = v * (float)(buf_y) - 0.5f;
+       a = (int)(u);
+       b = (int)(v);
+       prop_u = u - (float)(a);
+       prop_v = v - (float)(b);
+       inv_prop_u = 1.0f - prop_u;
+       inv_prop_v = 1.0f - prop_v;
+       a_plus_1 = MIN2((buf_x-1),a+1);
+       b_plus_1 = MIN2((buf_y-1),b+1);
+       return (buf[(b * buf_y) + a] * inv_prop_u + buf[(b*buf_y)+(a_plus_1)] * prop_u)*inv_prop_v+(buf[((b_plus_1) * buf_y)+a] * inv_prop_u + buf[((b_plus_1)*buf_y)+(a_plus_1)] * prop_u) * prop_v;
+
+}
+
+void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) {
+       if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
+               return;
+       }
+       buf[(pos_y * buf_y) + buf_x] = intensity;
+}
+#define __PLX__FAKE_AA__
+int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) {
+#ifdef __PLX__FAKE_AA__
+#ifdef __PLX_GREY_AA__
+       int i=0;
+       int sz = buf_x * buf_y;
+       for(i=0; i<sz; i++) {
+               buf[i] *= 0.5f;
+       }
+#endif
+       return 1;
+#else
+       /*XXX - TODO: THIS IS NOT FINAL CODE - IT DOES NOT WORK - DO NOT ENABLE IT */
+       const float p0 = 1.0f;
+       const float p1 = 1.0f;
+       const float p2 = 1.0f;
+       const float p3 = 1.0f;
+       const float p4 = 1.0f;
+       const float p5 = 1.5f;
+       const float p6 = 2.0f;
+       const float p7 = 2.0f;
+       const float p8 = 2.0f;
+       const float p9 = 2.0f;
+       const float p10 = 4.0f;
+       const float p11 = 8.0f;
+
+       const float edge_threshold = 0.063f;
+       const float edge_threshold_min = 0.0312f;
+       const float quality_subpix = 1.0f;
+//     int px_x;
+//     int px_y;
+
+       float posM_x,posM_y;
+       float posB_x,posB_y;
+       float posN_x,posN_y;
+       float posP_x,posP_y;
+       float offNP_x,offNP_y;
+       float lumaM;
+       float lumaS;
+       float lumaE;
+       float lumaN;
+       float lumaW;
+       float lumaNW;
+       float lumaSE;
+       float lumaNE;
+       float lumaSW;
+       float lumaNS;
+       float lumaWE;
+       float lumaNESE;
+       float lumaNWNE;
+       float lumaNWSW;
+       float lumaSWSE;
+       float lumaNN;
+       float lumaSS;
+       float lumaEndN;
+       float lumaEndP;
+       float lumaMM;
+       float lumaMLTZero;
+       float subpixNWSWNESE;
+       float subpixRcpRange;
+       float subpixNSWE;
+       float maxSM;
+       float minSM;
+       float maxESM;
+       float minESM;
+       float maxWN;
+       float minWN;
+       float rangeMax;
+       float rangeMin;
+       float rangeMaxScaled;
+       float range;
+       float rangeMaxClamped;
+       float edgeHorz;
+       float edgeVert;
+       float edgeHorz1;
+       float edgeVert1;
+       float edgeHorz2;
+       float edgeVert2;
+       float edgeHorz3;
+       float edgeVert3;
+       float edgeHorz4;
+       float edgeVert4;
+       float lengthSign;
+       float subpixA;
+       float subpixB;
+       float subpixC;
+       float subpixD;
+       float subpixE;
+       float subpixF;
+       float subpixG;
+       float subpixH;
+       float gradientN;
+       float gradientS;
+       float gradient;
+       float gradientScaled;
+       float dstN;
+       float dstP;
+       float dst;
+       float spanLength;
+       float spanLengthRcp;
+       float pixelOffset;
+       float pixelOffsetGood;
+       float pixelOffsetSubpix;
+       int directionN;
+       int goodSpan;
+       int goodSpanN;
+       int goodSpanP;
+       int horzSpan;
+       int earlyExit;
+       int pairN;
+       int doneN;
+       int doneP;
+       int doneNP;
+       int curr_x=0;
+       int curr_y=0;
+       for(curr_y=0; curr_y < buf_y; curr_y++) {
+               for(curr_x=0; curr_x < buf_x; curr_x++) {
+                       posM_x = ((float)(curr_x) + 0.5f) * (1.0f/(float)(buf_x));
+                       posM_y = ((float)(curr_y) + 0.5f) * (1.0f/(float)(buf_y));
+
+                       lumaM = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y);
+                       lumaS = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y - 1);
+                       lumaE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y);
+                       lumaN = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y + 1);
+                       lumaW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y);
+
+                       maxSM = MAX2(lumaS, lumaM);
+                       minSM = MIN2(lumaS, lumaM);
+                       maxESM = MAX2(lumaE, maxSM);
+                       minESM = MIN2(lumaE, minSM);
+                       maxWN = MAX2(lumaN, lumaW);
+                       minWN = MIN2(lumaN, lumaW);
+                       rangeMax = MAX2(maxWN, maxESM);
+                       rangeMin = MIN2(minWN, minESM);
+                       rangeMaxScaled = rangeMax * edge_threshold;
+                       range = rangeMax - rangeMin;
+                       rangeMaxClamped = MAX2(edge_threshold_min, rangeMaxScaled);
+
+                       earlyExit = range < rangeMaxClamped ? 1:0;
+                       if(earlyExit) {
+                               set_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y, lumaM);
+                       }
+
+                       lumaNW = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y - 1);
+                       lumaSE = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y + 1);
+                       lumaNE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y + 1);
+                       lumaSW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y - 1);
+
+                       lumaNS = lumaN + lumaS;
+                       lumaWE = lumaW + lumaE;
+                       subpixRcpRange = 1.0f/range;
+                       subpixNSWE = lumaNS + lumaWE;
+                       edgeHorz1 = (-2.0f * lumaM) + lumaNS;
+                       edgeVert1 = (-2.0f * lumaM) + lumaWE;
+
+                       lumaNESE = lumaNE + lumaSE;
+                       lumaNWNE = lumaNW + lumaNE;
+                       edgeHorz2 = (-2.0f * lumaE) + lumaNESE;
+                       edgeVert2 = (-2.0f * lumaN) + lumaNWNE;
+
+                       lumaNWSW = lumaNW + lumaSW;
+                       lumaSWSE = lumaSW + lumaSE;
+                       edgeHorz4 = (ABS(edgeHorz1) * 2.0f) + ABS(edgeHorz2);
+                       edgeVert4 = (ABS(edgeVert1) * 2.0f) + ABS(edgeVert2);
+                       edgeHorz3 = (-2.0f * lumaW) + lumaNWSW;
+                       edgeVert3 = (-2.0f * lumaS) + lumaSWSE;
+                       edgeHorz = ABS(edgeHorz3) + edgeHorz4;
+                       edgeVert = ABS(edgeVert3) + edgeVert4;
+
+                       subpixNWSWNESE = lumaNWSW + lumaNESE;
+                       lengthSign = 1.0f / (float)(buf_x);
+                       horzSpan = edgeHorz >= edgeVert ? 1:0;
+                       subpixA = subpixNSWE * 2.0f + subpixNWSWNESE;
+
+                       if(!horzSpan) {
+                               lumaN = lumaW;
+                               lumaS = lumaE;
+                       } else {
+                               lengthSign = 1.0f / (float)(buf_y);
+                       }
+                       subpixB = (subpixA * (1.0f/12.0f)) - lumaM;
+
+                       gradientN = lumaN - lumaM;
+                       gradientS = lumaS - lumaM;
+                       lumaNN = lumaN + lumaM;
+                       lumaSS = lumaS + lumaM;
+                       pairN = (ABS(gradientN)) >= (ABS(gradientS)) ? 1:0;
+                       gradient = MAX2(ABS(gradientN), ABS(gradientS));
+                       if(pairN) {
+                               lengthSign = -lengthSign;
+                       }
+                       subpixC = MAX2(MIN2(ABS(subpixB) * subpixRcpRange,1.0f),0.0f);
+
+                       posB_x = posM_x;
+                       posB_y = posM_y;
+                       offNP_x = (!horzSpan) ? 0.0f:(1.0f / (float)(buf_x));
+                       offNP_y = (horzSpan) ? 0.0f:(1.0f / (float)(buf_y));
+                       if(!horzSpan) {
+                               posB_x += lengthSign * 0.5f;
+                       } else {
+                               posB_y += lengthSign * 0.5f;
+                       }
+
+                       posN_x = posB_x - offNP_x * p0;
+                       posN_y = posB_y - offNP_y * p0;
+                       posP_x = posB_x + offNP_x * p0;
+                       posP_y = posB_y + offNP_y * p0;
+                       subpixD = ((-2.0f)*subpixC) + 3.0f;
+                       //may need bilinear filtered get_pixel_intensity() here...done
+                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                       subpixE = subpixC * subpixC;
+                       //may need bilinear filtered get_pixel_intensity() here...done
+                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+
+                       if(!pairN) {
+                               lumaNN = lumaSS;
+                       }
+                       gradientScaled = gradient * 1.0f/4.0f;
+                       lumaMM =lumaM - lumaNN * 0.5f;
+                       subpixF = subpixD * subpixE;
+                       lumaMLTZero = lumaMM < 0.0f ? 1:0;
+
+                       lumaEndN -= lumaNN * 0.5f;
+                       lumaEndP -= lumaNN * 0.5f;
+                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                       if(!doneN) {
+                               posN_x -= offNP_x * p1;
+                               posN_y -= offNP_y * p1;
+                       }
+                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                       if(!doneP) {
+                               posP_x += offNP_x * p1;
+                               posP_y += offNP_y * p1;
+                       }
+
+                       if(doneNP) {
+                               if(!doneN) {
+                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posN_x,posN_y);
+                               }
+                               if(!doneP) {
+                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x, posP_y);
+                               }
+                               if(!doneN) {
+                                       lumaEndN = lumaEndN - lumaNN * 0.5;
+                               }
+                               if(!doneP) {
+                                       lumaEndP = lumaEndP - lumaNN * 0.5;
+                               }
+                               doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                               doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                               if(!doneN) {
+                                       posN_x -= offNP_x * p2;
+                                       posN_y -= offNP_y * p2;
+                               }
+                               doneNP = (!doneN) || (!doneP) ? 1:0;
+                               if(!doneP) {
+                                       posP_x += offNP_x * p2;
+                                       posP_y += offNP_y * p2;
+                               }
+                               if(doneNP) {
+                                       if(!doneN) {
+                                               lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                       }
+                                       if(!doneP) {
+                                               lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                       }
+                                       if(!doneN) {
+                                               lumaEndN = lumaEndN - lumaNN * 0.5;
+                                       }
+                                       if(!doneP) {
+                                               lumaEndP = lumaEndP - lumaNN * 0.5;
+                                       }
+                                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                       if(!doneN) {
+                                               posN_x -= offNP_x * p3;
+                                               posN_y -= offNP_y * p3;
+                                       }
+                                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                                       if(!doneP) {
+                                               posP_x += offNP_x * p3;
+                                               posP_y += offNP_y * p3;
+                                       }
+                                       if(doneNP) {
+                                               if(!doneN) {
+                                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                               }
+                                               if(!doneP) {
+                                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                               }
+                                               if(!doneN) {
+                                                       lumaEndN = lumaEndN - lumaNN * 0.5;
+                                               }
+                                               if(!doneP) {
+                                                       lumaEndP = lumaEndP - lumaNN * 0.5;
+                                               }
+                                               doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                               doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                               if(!doneN) {
+                                                       posN_x -= offNP_x * p4;
+                                                       posN_y -= offNP_y * p4;
+                                               }
+                                               doneNP = (!doneN) || (!doneP) ? 1:0;
+                                               if(!doneP) {
+                                                       posP_x += offNP_x * p4;
+                                                       posP_y += offNP_y * p4;
+                                               }
+                                               if(doneNP) {
+                                                       if(!doneN) {
+                                                               lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                       }
+                                                       if(!doneP) {
+                                                               lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                       }
+                                                       if(!doneN) {
+                                                               lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                       }
+                                                       if(!doneP) {
+                                                               lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                       }
+                                                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                       if(!doneN) {
+                                                               posN_x -= offNP_x * p5;
+                                                               posN_y -= offNP_y * p5;
+                                                       }
+                                                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                       if(!doneP) {
+                                                               posP_x += offNP_x * p5;
+                                                               posP_y += offNP_y * p5;
+                                                       }
+                                                       if(doneNP) {
+                                                               if(!doneN) {
+                                                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                               }
+                                                               if(!doneP) {
+                                                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                               }
+                                                               if(!doneN) {
+                                                                       lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                               }
+                                                               if(!doneP) {
+                                                                       lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                               }
+                                                               doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                               doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                               if(!doneN) {
+                                                                       posN_x -= offNP_x * p6;
+                                                                       posN_y -= offNP_y * p6;
+                                                               }
+                                                               doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                               if(!doneP) {
+                                                                       posP_x += offNP_x * p6;
+                                                                       posP_y += offNP_y * p6;
+                                                               }
+                                                               if(doneNP) {
+                                                                       if(!doneN) {
+                                                                               lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                                       }
+                                                                       if(!doneP) {
+                                                                               lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                                       }
+                                                                       if(!doneN) {
+                                                                               lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                                       }
+                                                                       if(!doneP) {
+                                                                               lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                                       }
+                                                                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                                       if(!doneN) {
+                                                                               posN_x -= offNP_x * p7;
+                                                                               posN_y -= offNP_y * p7;
+                                                                       }
+                                                                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                                       if(!doneP) {
+                                                                               posP_x += offNP_x * p7;
+                                                                               posP_y += offNP_y * p7;
+                                                                       }
+                                                                       if(doneNP) {
+                                                                               if(!doneN) {
+                                                                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                                               }
+                                                                               if(!doneP) {
+                                                                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                                               }
+                                                                               if(!doneN) {
+                                                                                       lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                                               }
+                                                                               if(!doneP) {
+                                                                                       lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                                               }
+                                                                               doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                                               doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                                               if(!doneN) {
+                                                                                       posN_x -= offNP_x * p8;
+                                                                                       posN_y -= offNP_y * p8;
+                                                                               }
+                                                                               doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                                               if(!doneP) {
+                                                                                       posP_x += offNP_x * p8;
+                                                                                       posP_y += offNP_y * p8;
+                                                                               }
+                                                                               if(doneNP) {
+                                                                                       if(!doneN) {
+                                                                                               lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                                                       }
+                                                                                       if(!doneP) {
+                                                                                               lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                                                       }
+                                                                                       if(!doneN) {
+                                                                                               lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                                                       }
+                                                                                       if(!doneP) {
+                                                                                               lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                                                       }
+                                                                                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                                                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                                                       if(!doneN) {
+                                                                                               posN_x -= offNP_x * p9;
+                                                                                               posN_y -= offNP_y * p9;
+                                                                                       }
+                                                                                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                                                       if(!doneP) {
+                                                                                               posP_x += offNP_x * p9;
+                                                                                               posP_y += offNP_y * p9;
+                                                                                       }
+                                                                                       if(doneNP) {
+                                                                                               if(!doneN) {
+                                                                                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                                                               }
+                                                                                               if(!doneP) {
+                                                                                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                                                               }
+                                                                                               if(!doneN) {
+                                                                                                       lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                                                               }
+                                                                                               if(!doneP) {
+                                                                                                       lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                                                               }
+                                                                                               doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                                                               doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                                                               if(!doneN) {
+                                                                                                       posN_x -= offNP_x * p10;
+                                                                                                       posN_y -= offNP_y * p10;
+                                                                                               }
+                                                                                               doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                                                               if(!doneP) {
+                                                                                                       posP_x += offNP_x * p10;
+                                                                                                       posP_y += offNP_y * p10;
+                                                                                               }
+                                                                                               if(doneNP) {
+                                                                                                       if(!doneN) {
+                                                                                                               lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
+                                                                                                       }
+                                                                                                       if(!doneP) {
+                                                                                                               lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
+                                                                                                       }
+                                                                                                       if(!doneN) {
+                                                                                                               lumaEndN = lumaEndN - lumaNN * 0.5;
+                                                                                                       }
+                                                                                                       if(!doneP) {
+                                                                                                               lumaEndP = lumaEndP - lumaNN * 0.5;
+                                                                                                       }
+                                                                                                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
+                                                                                                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
+                                                                                                       if(!doneN) {
+                                                                                                               posN_x -= offNP_x * p11;
+                                                                                                               posN_y -= offNP_y * p11;
+                                                                                                       }
+                                                                                                       doneNP = (!doneN) || (!doneP) ? 1:0;
+                                                                                                       if(!doneP) {
+                                                                                                               posP_x += offNP_x * p11;
+                                                                                                               posP_y += offNP_y * p11;
+                                                                                                       }
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       dstN = posM_x - posN_x;
+                       dstP = posP_x - posM_x;
+                       if(!horzSpan) {
+                               dstN = posM_y - posN_y;
+                               dstP = posP_y - posM_y;
+                       }
+
+                       goodSpanN = ((lumaEndN < 0.0f) ? 1:0) != lumaMLTZero ? 1:0;
+                       spanLength = (dstP + dstN);
+                       goodSpanP = ((lumaEndP < 0.0f) ? 1:0) != lumaMLTZero ? 1:0;
+                       spanLengthRcp = 1.0f/spanLength;
+
+                       directionN = dstN < dstP ? 1:0;
+                       dst = MIN2(dstN, dstP);
+                       goodSpan = (directionN==1) ? goodSpanN:goodSpanP;
+                       subpixG = subpixF * subpixF;
+                       pixelOffset = (dst * (-spanLengthRcp)) + 0.5f;
+                       subpixH = subpixG * quality_subpix;
+
+                       pixelOffsetGood = (goodSpan==1) ? pixelOffset : 0.0f;
+                       pixelOffsetSubpix = MAX2(pixelOffsetGood, subpixH);
+                       if(!horzSpan) {
+                               posM_x += pixelOffsetSubpix * lengthSign;
+                       } else {
+                               posM_y += pixelOffsetSubpix * lengthSign;
+                       }
+                       //may need bilinear filtered get_pixel_intensity() here...
+                       set_pixel_intensity(buf,buf_x,buf_y,curr_x,curr_y,get_pixel_intensity_bilinear(buf, buf_x, buf_y, posM_x,posM_y)* lumaM);
+
+               }
+       }
+       return 1;
+
+#endif
+}
+
index e80ca1d41c4c0233b8914e854a602b4a01a41e73..e078b0d26be2a9126749bfb0a3b286b48056f4bb 100644 (file)
@@ -49,11 +49,11 @@ extern "C" {
 #endif
 
 int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
-                   float *buf, int buf_x, int buf_y);
+                   float *buf, int buf_x, int buf_y, int do_mask_AA);
 int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts,
                            float (*feather_verts)[2], int num_feather_verts,
                            float *buf, int buf_x, int buf_y);
-
+int PLX_antialias_buffer(float *buf, int buf_x, int buf_y);
 #ifdef __cplusplus
 }
 #endif
index dd2c7cb3a18f89d02696e046cf1ce1be951660d2..0e93869a8b0d9e7d6bf6f63e742f0363ed7d222b 100644 (file)
@@ -170,7 +170,7 @@ void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, i
 /* rasterization */
 int BKE_mask_get_duration(struct Mask *mask);
 void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer,
-                        const short do_aspect_correct);
+                        const short do_aspect_correct, int do_mask_aa);
 
 #define MASKPOINT_ISSEL_ANY(p)          ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT)
 #define MASKPOINT_ISSEL_KNOT(p)         ( (p)->bezt.f2 & SELECT)
index 012ce97b4d75fa380e1d37e26d05486889108854..7e9f189ae0121d773c99ec2da75b6b73c7159eb4 100644 (file)
@@ -2089,7 +2089,7 @@ int BKE_mask_get_duration(Mask *mask)
 
 /* rasterization */
 void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
-                        const short do_aspect_correct)
+                        const short do_aspect_correct, int do_mask_aa)
 {
        MaskLayer *masklay;
 
@@ -2154,7 +2154,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
 
                                if (tot_diff_point) {
                                        PLX_raskterize(diff_points, tot_diff_point,
-                                                      buffer_tmp, width, height);
+                                                      buffer_tmp, width, height, do_mask_aa);
 
                                        if (tot_diff_feather_points) {
                                                PLX_raskterize_feather(diff_points, tot_diff_point,
index 889eee25d6bec1fe9c13f624a83102eed6c500db..ddf30ecfa81c38e861e6a3aa5ebd603cf3659cfe 100644 (file)
@@ -2081,7 +2081,8 @@ static ImBuf *seq_render_mask_strip(
                BKE_mask_rasterize(seq->mask,
                                   context.rectx, context.recty,
                                   maskbuf,
-                                  TRUE);
+                                  TRUE,
+                                  FALSE /*XXX- TODO: make on/off for anti-aliasing*/);
 
                fp_src = maskbuf;
                fp_dst = ibuf->rect_float;
@@ -2104,7 +2105,8 @@ static ImBuf *seq_render_mask_strip(
                BKE_mask_rasterize(seq->mask,
                                   context.rectx, context.recty,
                                   maskbuf,
-                                  TRUE);
+                                  TRUE,
+                                  FALSE /*XXX- TODO: mask on/off for anti-aliasing*/);
 
                fp_src = maskbuf;
                ub_dst = (unsigned char *)ibuf->rect;
index b61a39a2cd209bb4cf49d6e64159a2bf6dcae397..0aa0d36c537f07dd3be1d9713485fefb3428b6d8 100644 (file)
@@ -1428,7 +1428,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
                                        fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
                                }
 
-                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height);
+                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE /* XXX- TODO: make on/off for AA*/);
 
                                MEM_freeN(mask_points);
                        }
index e26756cfc5b6666a9d5673085dfc548412f8c8ad..4371a848a3dd5c894595cda4992c98b6d1a9958b 100644 (file)
@@ -54,6 +54,7 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c
 
        operation->setMask(mask);
        operation->setFramenumber(context->getFramenumber());
+    operation->setSmooth((bool)editorNode->custom1);
 
        graph->addOperation(operation);
 }
index bfbf2b42e825fe7252f045f9503b2e295264eae6..8f7115659a19ac82828cfa9169a0d4bc8cb2e7ac 100644 (file)
@@ -32,6 +32,7 @@
 
 extern "C" {
        #include "BKE_mask.h"
+    #include "../../../../intern/raskter/raskter.h"
 }
 
 MaskOperation::MaskOperation(): NodeOperation()
@@ -74,7 +75,10 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers
                float *buffer;
 
                buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask");
-               BKE_mask_rasterize(mask, width, height, buffer, TRUE);
+               BKE_mask_rasterize(mask, width, height, buffer, TRUE, this->smooth);
+        if(this->smooth) {
+            PLX_antialias_buffer(buffer, width, height);
+        }
 
                this->rasterizedMask = buffer;
        }
index 9f2c7f53f5674d46d8368f1456202459a7372b46..8534cb20416ff6a36ba796d1fdfa0b52cd14e476 100644 (file)
@@ -40,6 +40,7 @@ protected:
        int maskWidth;
        int maskHeight;
        int framenumber;
+    bool smooth;
        float *rasterizedMask;
 
        /**
@@ -59,6 +60,7 @@ public:
        void setMaskWidth(int width) {this->maskWidth = width;}
        void setMaskHeight(int height) {this->maskHeight = height;}
        void setFramenumber(int framenumber) {this->framenumber = framenumber;}
+    void setSmooth(bool smooth) {this->smooth = smooth;}
 
        void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data);
 };
index 12c369874fea299d95aac15d157de415e0be73ee..e6549034a855d5f688c9cc5d9d65a906ae7740ef 100644 (file)
@@ -2421,6 +2421,8 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C),
 static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
 {
        uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL);
+    uiItemR(layout, ptr, "smooth_mask", 0, NULL, ICON_NONE);
+
 }
 
 /* only once called */
index 92de882d48b737b0225ad5a056b04da08576a1a8..73e2b5da4f056f38ab0ea89bacdcbd850fd7c5fe 100644 (file)
@@ -3089,6 +3089,11 @@ static void def_cmp_mask(StructRNA *srna)
 {
        PropertyRNA *prop;
 
+    prop = RNA_def_property(srna, "smooth_mask", PROP_BOOLEAN, PROP_NONE);
+    RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0);
+    RNA_def_property_ui_text(prop, "Anti-Alias", "Apply an anti-aliasing filter to the mask");
+    RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
        prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "id");
        RNA_def_property_struct_type(prop, "Mask");
index dbe3c11ab55a22d9f2b9ed3f289ac5bc9b067693..d323839e690375ae5411c946d485178f673b2359 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "node_composite_util.h"
 
+#include "../../../../intern/raskter/raskter.h"
+
 /* **************** Translate  ******************** */
 
 static bNodeSocketTemplate cmp_node_mask_out[] = {
@@ -68,8 +70,11 @@ static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **
                stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE);
                res = stackbuf->rect;
 
-               BKE_mask_rasterize(mask, sx, sy, res, TRUE);
+               BKE_mask_rasterize(mask, sx, sy, res, TRUE, node->custom1);
 
+               if(node->custom1){
+                       PLX_antialias_buffer(res,sx,sy);
+               }
                /* pass on output and free */
                out[0]->data = stackbuf;
        }