From 8ce53a2a984238aa371b28b44bb2598473a64875 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jul 2012 20:10:41 +0000 Subject: new mask rasterizer written to take advantage of the compositors threading, mostly functional but disabled by default (still a little wip). --- source/blender/blenkernel/BKE_mask.h | 21 +- source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/intern/mask.c | 6 +- source/blender/blenkernel/intern/mask_rasterize.c | 586 +++++++++++++++++++++ source/blender/blenkernel/intern/particle_system.c | 2 +- .../compositor/operations/COM_MaskOperation.cpp | 73 ++- .../compositor/operations/COM_MaskOperation.h | 11 + source/creator/CMakeLists.txt | 1 + 8 files changed, 695 insertions(+), 6 deletions(-) create mode 100644 source/blender/blenkernel/intern/mask_rasterize.c diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 384bc327a81..50d8576dd91 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -64,6 +64,8 @@ void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase * /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); +int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, const int resol); + float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; @@ -203,4 +205,21 @@ void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int w #define MASKPOINT_SEL_HANDLE(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 -#endif +/* disable to test alternate rasterizer */ +#define USE_RASKTER + +/* mask_rasterize.c */ +#ifndef USE_RASKTER +struct MaskRasterHandle; +typedef struct MaskRasterHandle MaskRasterHandle; + +MaskRasterHandle *BLI_maskrasterize_handle_new(void); +void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle); +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, + const short do_feather); +float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]); +#endif /* USE_RASKTER */ + +#endif /* __BKE_MASK_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 02f7467f06e..8ae705fa3eb 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -101,6 +101,7 @@ set(SRC intern/lamp.c intern/lattice.c intern/library.c + intern/mask_rasterize.c intern/mask.c intern/material.c intern/mball.c diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 2326a8fa59c..4e683d1618f 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -314,7 +314,7 @@ static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int return resol; } -static int mask_spline_points_calc_tot(const MaskSpline *spline, const int resol) +int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const int resol) { int len; @@ -338,7 +338,7 @@ float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, con MaskSplinePoint *point, *prev; float (*diff_points)[2], (*fp)[2]; - const int tot = mask_spline_points_calc_tot(spline, resol); + const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol); int a; if (spline->tot_point <= 1) { @@ -412,7 +412,7 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl MaskSplinePoint *point, *prev; float (*feather)[2], (*fp)[2]; - const int tot = mask_spline_points_calc_tot(spline, resol); + const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol); int a; /* tot+1 because of 'forward_diff_bezier' function */ diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c new file mode 100644 index 00000000000..922d0ed65ac --- /dev/null +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -0,0 +1,586 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/mask_rasterize.c + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_vec_types.h" +#include "DNA_mask_types.h" + +#include "BLI_utildefines.h" +#include "BLI_kdopbvh.h" +#include "BLI_scanfill.h" + +#include "BLI_math.h" +#include "BLI_rect.h" +#include "BLI_listbase.h" +#include "BLI_mempool.h" + +#include "BKE_mask.h" + +#ifndef USE_RASKTER + +/** + * A single #MaskRasterHandle contains multile #MaskRasterLayer's, + * each #MaskRasterLayer does its own lookup which contributes to + * the final pixel with its own blending mode and the final pixel is blended between these. + */ + +/* internal use only */ +typedef struct MaskRasterLayer { + /* xy raytree */ + BVHTree *bvhtree; + + /* 2d bounds (to quickly skip raytree lookup) */ + rctf bounds; + + /* geometry */ + unsigned int (*tri_array)[3]; /* access coords */ + float (*tri_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ + + + /* copied direct from #MaskLayer.--- */ + /* blending options */ + float alpha; + char blend; + char blend_flag; + +} MaskRasterLayer; + + +/** + * opaque local struct for mask pixel lookup, each MaskLayer needs one of these + */ +struct MaskRasterHandle { + MaskRasterLayer *layers; + unsigned int layers_tot; + + /* 2d bounds (to quickly skip raytree lookup) */ + rctf bounds; +}; + +MaskRasterHandle *BLI_maskrasterize_handle_new(void) +{ + MaskRasterHandle *mr_handle; + + mr_handle = MEM_callocN(sizeof(MaskRasterHandle), STRINGIFY(MaskRasterHandle)); + + return mr_handle; +} + +void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) +{ + const unsigned int layers_tot = mr_handle->layers_tot; + unsigned int i; + MaskRasterLayer *raslayers = mr_handle->layers; + + /* raycast vars */ + for (i = 0; i < layers_tot; i++, raslayers++) { + BLI_bvhtree_free(raslayers->bvhtree); + + if (raslayers->tri_array) { + MEM_freeN(raslayers->tri_array); + } + + if (raslayers->tri_coords) { + MEM_freeN(raslayers->tri_coords); + } + } + + MEM_freeN(mr_handle->layers); + MEM_freeN(mr_handle); +} + +#define PRINT_MASK_DEBUG printf + +#define SF_EDGE_IS_BOUNDARY 0xff + +#define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) + + +void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points)[2], float (*diff_points)[2], + const int tot_diff_point, const float ofs, const int do_test) +{ + int k_prev = tot_diff_point - 2; + int k_curr = tot_diff_point - 1; + int k_next = 0; + + int k; + + float d_prev[2]; + float d_next[2]; + float d[2]; + + const float *co_prev; + const float *co_curr; + const float *co_next; + + const float ofs_squared = ofs * ofs; + + co_prev = diff_points[k_prev]; + co_curr = diff_points[k_curr]; + co_next = diff_points[k_next]; + + /* precalc */ + sub_v2_v2v2(d_prev, co_prev, co_curr); + normalize_v2(d_prev); + + /* TODO, speedup by only doing one normalize per iter */ + + + for (k = 0; k < tot_diff_point; k++) { + + co_prev = diff_points[k_prev]; + co_curr = diff_points[k_curr]; + co_next = diff_points[k_next]; + + /* sub_v2_v2v2(d_prev, co_prev, co_curr); */ /* precalc */ + sub_v2_v2v2(d_next, co_curr, co_next); + + /* normalize_v2(d_prev); */ /* precalc */ + normalize_v2(d_next); + + if ((do_test == FALSE) || + (len_squared_v2v2(diff_feather_points[k], diff_points[k]) < ofs_squared)) + { + + add_v2_v2v2(d, d_prev, d_next); + + normalize_v2(d); + + diff_feather_points[k][0] = diff_points[k][0] + ( d[1] * ofs); + diff_feather_points[k][1] = diff_points[k][1] + (-d[0] * ofs); + } + + /* use next iter */ + copy_v2_v2(d_prev, d_next); + + k_prev = k_curr; + k_curr = k_next; + k_next++; + } +} + +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, + const short do_feather) +{ + /* TODO: real size */ + const int resol = 16; + const float aa_filter_size = 1.0f / MIN2(width, height); + + const float zvec[3] = {0.0f, 0.0f, 1.0f}; + MaskLayer *masklay; + int masklay_index; + + mr_handle->layers_tot = BLI_countlist(&mask->masklayers); + mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, STRINGIFY(MaskRasterLayer)); + BLI_rctf_init_minmax(&mr_handle->bounds); + + for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) { + + MaskSpline *spline; + + /* scanfill */ + ScanFillContext sf_ctx; + ScanFillVert *sf_vert = NULL; + ScanFillVert *sf_vert_next = NULL; + ScanFillFace *sf_tri; + + unsigned int sf_vert_tot = 0; + unsigned int tot_feather_quads = 0; + + if (masklay->restrictflag & MASK_RESTRICT_RENDER) { + continue; + } + + BLI_scanfill_begin(&sf_ctx); + + for (spline = masklay->splines.first; spline; spline = spline->next) { + + float (*diff_points)[2]; + int tot_diff_point; + + float (*diff_feather_points)[2]; + int tot_diff_feather_points; + + diff_points = BKE_mask_spline_differentiate_with_resolution_ex(spline, resol, &tot_diff_point); + + /* dont ch*/ + if (do_feather) { + diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, resol, &tot_diff_feather_points); + } + else { + tot_diff_feather_points = 0; + diff_feather_points = NULL; + } + + if (do_aspect_correct) { + if (width != height) { + float *fp; + float *ffp; + int i; + float asp; + + if (width < height) { + fp = &diff_points[0][0]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; + asp = (float)width / (float)height; + } + else { + fp = &diff_points[0][1]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; + asp = (float)height / (float)width; + } + + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } + + if (tot_diff_feather_points) { + for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { + (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; + } + } + } + } + + /* fake aa, using small feather */ + if (do_mask_aa == TRUE) { + if (do_feather == FALSE) { + tot_diff_feather_points = tot_diff_point; + diff_feather_points = MEM_mallocN(sizeof(*diff_feather_points) * tot_diff_feather_points, __func__); + /* add single pixel feather */ + maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, + tot_diff_point, aa_filter_size, FALSE); + } + else { + /* ensure single pixel feather, on any zero feather areas */ + maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, + tot_diff_point, aa_filter_size, TRUE); + } + } + + if (tot_diff_point > 3) { + ScanFillVert *sf_vert_prev; + int j; + + float co[3]; + co[2] = 0.0f; + + copy_v2_v2(co, diff_points[0]); + sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co); + sf_vert_prev->tmp.u = sf_vert_tot; + sf_vert_prev->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ + sf_vert_tot++; + + /* TODO, an alternate functions so we can avoid double vector copy! */ + for (j = 1; j < tot_diff_point; j++) { + copy_v2_v2(co, diff_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co); + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ + sf_vert_tot++; + } + + sf_vert = sf_vert_prev; + sf_vert_prev = sf_ctx.fillvertbase.last; + + for (j = 0; j < tot_diff_point; j++) { + ScanFillEdge *sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert); + sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY; + + sf_vert_prev = sf_vert; + sf_vert = sf_vert->next; + } + + if (diff_feather_points) { + float co_feather[3]; + co_feather[2] = 1.0f; + + BLI_assert(tot_diff_feather_points == tot_diff_point); + + /* note: only added for convenience, we dont infact use these to scanfill, + * only to create feather faces after scanfill */ + for (j = 0; j < tot_diff_feather_points; j++) { + copy_v2_v2(co_feather, diff_feather_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); + + /* no need for these attrs */ +#if 0 + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ +#endif + sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; + sf_vert_tot++; + } + + if (diff_feather_points) { + MEM_freeN(diff_feather_points); + } + + tot_feather_quads += tot_diff_point; + } + } + + if (diff_points) { + MEM_freeN(diff_points); + } + } + + if (sf_ctx.fillvertbase.first) { + unsigned int (*tri_array)[3], *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]; + + /* now we have all the splines */ + tri_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_tri_coords"); + + /* init bounds */ + BLI_rctf_init_minmax(&bounds); + + /* coords */ + cos = (float *)tri_coords; + for (sf_vert = sf_ctx.fillvertbase.first; sf_vert; sf_vert = sf_vert_next) { + sf_vert_next = sf_vert->next; + copy_v3_v3(cos, sf_vert->co); + + /* remove so as not to interfear with fill (called after) */ + if (sf_vert->keyindex == SF_KEYINDEX_TEMP_ID) { + BLI_remlink(&sf_ctx.fillvertbase, sf_vert); + } + + /* bounds */ + BLI_rctf_do_minmax_v(&bounds, cos); + + cos += 3; + } + + /* 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"); + + /* */ + bvhtree = BLI_bvhtree_new(sf_tri_tot + (tot_feather_quads * 2), 0.000001f, 4, 6); + + /* tri's */ + tri = (unsigned int *)tri_array; + for (sf_tri = sf_ctx.fillfacebase.first, tri_index = 0; sf_tri; sf_tri = sf_tri->next, tri_index++) { + *(tri++) = sf_tri->v1->tmp.u; + *(tri++) = sf_tri->v2->tmp.u; + *(tri++) = sf_tri->v3->tmp.u; + + 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)]); + + BLI_bvhtree_insert(bvhtree, tri_index, (float *)bvhcos, 3); + } + + /* start of feather faces... if we have this set, + * 'j' is kept from loop above */ + + BLI_assert(tri_index == sf_tri_tot); + + if (tot_feather_quads) { + ScanFillEdge *sf_edge; + + 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]]); + + BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 3); + + /* 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); + } + } + } + + fprintf(stderr, "%d %d\n", tri_index, sf_tri_tot + (tot_feather_quads * 2)); + + BLI_assert(tri_index == sf_tri_tot + (tot_feather_quads * 2)); + + BLI_bvhtree_balance(bvhtree); + + { + MaskRasterLayer *raslayer = &mr_handle->layers[masklay_index]; + + raslayer->tri_coords = tri_coords; + raslayer->tri_array = tri_array; + raslayer->bounds = bounds; + raslayer->bvhtree = bvhtree; + + /* copy as-is */ + raslayer->alpha = masklay->alpha; + raslayer->blend = masklay->blend; + raslayer->blend_flag = masklay->blend_flag; + + + BLI_union_rctf(&mr_handle->bounds, &bounds); + } + + PRINT_MASK_DEBUG("tris %d, feather tris %d\n", sf_tri_tot, (tot_feather_quads * 2)); + } + + /* add trianges */ + BLI_scanfill_end(&sf_ctx); + } +} + +/* 2D ray test */ +static float maskrasterize_layer_z_depth(const float pt[2], float v1[3], float v2[3], 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 void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +{ + MaskRasterLayer *layer = (struct MaskRasterLayer *)userdata; + unsigned int *tri = layer->tri_array[index]; + float (*cos)[3] = layer->tri_coords; + const float dist_orig = hit->dist; + + /* we always cast from same place only need xy */ + + /* 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(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]]); + if (dist < dist_orig) { + hit->index = index; + hit->dist = dist; + } + } + } +} + +float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) +{ + /* TODO - AA jitter */ + + if (BLI_in_rctf_v(&mr_handle->bounds, xy)) { + const unsigned int layers_tot = mr_handle->layers_tot; + unsigned int i; + MaskRasterLayer *layer = mr_handle->layers; + + /* raycast vars*/ + const float co[3] = {xy[0], xy[1], 0.0f}; + const float dir[3] = {0.0f, 0.0f, 1.0f}; + const float radius = 1.0f; + BVHTreeRayHit hit = {0}; + + /* return */ + float value = 0.0f; + + for (i = 0; i < layers_tot; i++, layer++) { + + if (BLI_in_rctf_v(&layer->bounds, xy)) { + + hit.dist = FLT_MAX; + hit.index = -1; + + /* TODO, and axis aligned version of this function, avoids 2 casts */ + BLI_bvhtree_ray_cast(layer->bvhtree, co, dir, radius, &hit, maskrasterize_layer_bvh_cb, layer); + + /* --- hit (start) --- */ + if (hit.index != -1) { + const float dist = 1.0f - hit.dist; + const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + + float v; + /* apply alpha */ + v = dist_ease * layer->alpha; + + if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { + v = 1.0f - v; + } + + switch (layer->blend) { + case MASK_BLEND_SUBTRACT: + { + value -= v; + break; + } + case MASK_BLEND_ADD: + default: + { + value += v; + break; + } + } + } + /* --- hit (end) --- */ + + } + } + + return CLAMPIS(value, 0.0f, 1.0f); + } + else { + return 0.0f; + } +} + +#endif /* USE_RASKTER */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 65f22ebc88f..aa798f59482 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1576,7 +1576,7 @@ static void initialize_all_particles(ParticleSimulationData *sim) } } -static void get_angular_velocity_vector(short avemode, ParticleKey *state, float *vec) +static void get_angular_velocity_vector(short avemode, ParticleKey *state, float vec[3]) { switch (avemode) { case PART_AVE_VELOCITY: diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 2b45cd53fd5..682ccf712ad 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -30,8 +30,10 @@ #include "DNA_scene_types.h" + +#ifdef USE_RASKTER + extern "C" { - #include "BKE_mask.h" #include "../../../../intern/raskter/raskter.h" } @@ -127,3 +129,72 @@ void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *input color[0] = buffer[index]; } } + +#else /* mask rasterizer by campbell wip */ + +MaskOperation::MaskOperation() : NodeOperation() +{ + this->addOutputSocket(COM_DT_VALUE); + this->m_mask = NULL; + this->m_maskWidth = 0; + this->m_maskHeight = 0; + this->m_framenumber = 0; + this->m_rasterMaskHandle = NULL; + setComplex(true); +} + +void MaskOperation::initExecution() +{ + initMutex(); + + if (this->m_rasterMaskHandle == NULL) { + const int width = this->getWidth(); + const int height = this->getHeight(); + + this->m_rasterMaskHandle = BLI_maskrasterize_handle_new(); + + BLI_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather); + } +} + +void MaskOperation::deinitExecution() +{ + if (this->m_rasterMaskHandle) { + BLI_maskrasterize_handle_free(this->m_rasterMaskHandle); + this->m_rasterMaskHandle = NULL; + } + + deinitMutex(); +} + +void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + /* pass */ + return NULL; +} + +void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + if (this->m_maskWidth == 0 || this->m_maskHeight == 0) { + NodeOperation::determineResolution(resolution, preferredResolution); + } + else { + unsigned int nr[2]; + + nr[0] = this->m_maskWidth; + nr[1] = this->m_maskHeight; + + NodeOperation::determineResolution(resolution, nr); + + resolution[0] = this->m_maskWidth; + resolution[1] = this->m_maskHeight; + } +} + +void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + const float xy[2] = {x / (float)this->m_maskWidth, y / (float)this->m_maskHeight}; + color[0] = BLI_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy); +} + +#endif /* USE_RASKTER */ diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 74fd12277e8..8fb98481ec7 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -25,6 +25,11 @@ #ifndef _COM_MaskOperation_h #define _COM_MaskOperation_h +/* XXX, remove when the USE_RASKTER option is also removed */ +extern "C" { + #include "BKE_mask.h" +} + #include "COM_NodeOperation.h" #include "DNA_scene_types.h" #include "DNA_mask_types.h" @@ -46,10 +51,16 @@ protected: int m_framenumber; bool m_do_smooth; bool m_do_feather; + +#ifdef USE_RASKTER float *m_rasterizedMask; ListBase m_maskLayers; +#else /* USE_RASKTER */ + struct MaskRasterHandle *m_rasterMaskHandle; +#endif /* USE_RASKTER */ + /** * Determine the output resolution. The resolution is retrieved from the Renderer */ diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 940c92b349c..abfbe366b88 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -912,6 +912,7 @@ endif() #added for opencl compositor list(APPEND BLENDER_SORTED_LIBS bf_compositor) list(APPEND BLENDER_SORTED_LIBS bf_opencl) + list(APPEND BLENDER_SORTED_LIBS bf_blenkernel) # hrmf, needed for BKE_mask only endif() if(WITH_LIBMV) -- cgit v1.2.3