From d896df3ccdef562cc8207f4186be6621594aa0bc Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 12 May 2020 10:33:59 +0200 Subject: Fix T73973: GPencil Fill fails when zoom the image The problem was related of how the initial pixel to create outline was detected. Now, a limit is set for any image to keep a fillable image in all situations, not only when some strokes contain the fill. --- source/blender/editors/gpencil/gpencil_fill.c | 105 ++++++++++++-------------- 1 file changed, 50 insertions(+), 55 deletions(-) (limited to 'source/blender/editors/gpencil') diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 0f57862efb2..82373850dc8 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -621,40 +621,38 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf) get_pixel(ibuf, v, rgba); - if (true) { /* Was: 'rgba' */ - /* check if no border(red) or already filled color(green) */ - if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) { - /* fill current pixel with green */ - set_pixel(ibuf, v, fill_col); - - /* add contact pixels */ - /* pixel left */ - if (v - 1 >= 0) { - index = v - 1; - if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { - BLI_stack_push(stack, &index); - } + /* check if no border(red) or already filled color(green) */ + if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) { + /* fill current pixel with green */ + set_pixel(ibuf, v, fill_col); + + /* add contact pixels */ + /* pixel left */ + if (v - 1 >= 0) { + index = v - 1; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { + BLI_stack_push(stack, &index); } - /* pixel right */ - if (v + 1 <= maxpixel) { - index = v + 1; - if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { - BLI_stack_push(stack, &index); - } + } + /* pixel right */ + if (v + 1 <= maxpixel) { + index = v + 1; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { + BLI_stack_push(stack, &index); } - /* pixel top */ - if (v + ibuf->x <= maxpixel) { - index = v + ibuf->x; - if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { - BLI_stack_push(stack, &index); - } + } + /* pixel top */ + if (v + ibuf->x <= maxpixel) { + index = v + ibuf->x; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { + BLI_stack_push(stack, &index); } - /* pixel bottom */ - if (v - ibuf->x >= 0) { - index = v - ibuf->x; - if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { - BLI_stack_push(stack, &index); - } + } + /* pixel bottom */ + if (v - ibuf->x >= 0) { + index = v - ibuf->x; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { + BLI_stack_push(stack, &index); } } } @@ -726,31 +724,32 @@ static bool gpencil_check_borders(tGPDfill *tgpf) return found; } -/* clean external border of image to avoid infinite loops */ -static void gpencil_clean_borders(tGPDfill *tgpf) +/* Set a border to create image limits. */ +static void gpencil_set_borders(tGPDfill *tgpf, const bool transparent) { ImBuf *ibuf; void *lock; - const float fill_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float fill_col[2][4] = {{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}; ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock); int idx; int pixel = 0; + const int coloridx = transparent ? 0 : 1; /* horizontal lines */ for (idx = 0; idx < ibuf->x; idx++) { /* bottom line */ - set_pixel(ibuf, idx, fill_col); + set_pixel(ibuf, idx, fill_col[coloridx]); /* top line */ pixel = idx + (ibuf->x * (ibuf->y - 1)); - set_pixel(ibuf, pixel, fill_col); + set_pixel(ibuf, pixel, fill_col[coloridx]); } /* vertical lines */ for (idx = 0; idx < ibuf->y; idx++) { /* left line */ - set_pixel(ibuf, ibuf->x * idx, fill_col); + set_pixel(ibuf, ibuf->x * idx, fill_col[coloridx]); /* right line */ pixel = ibuf->x * idx + (ibuf->x - 1); - set_pixel(ibuf, pixel, fill_col); + set_pixel(ibuf, pixel, fill_col[coloridx]); } /* release ibuf */ @@ -1503,30 +1502,26 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event) /* render screen to temp image */ if (gp_render_offscreen(tgpf)) { + /* Set red borders to create a external limit. */ + gpencil_set_borders(tgpf, true); + /* apply boundary fill */ gpencil_boundaryfill_area(tgpf); - /* Check if detected some border to fill. */ - if (gpencil_check_borders(tgpf)) { - - /* clean borders to avoid infinite loops */ - gpencil_clean_borders(tgpf); + /* Clean borders to avoid infinite loops. */ + gpencil_set_borders(tgpf, false); - /* analyze outline */ - gpencil_get_outline_points(tgpf); + /* analyze outline */ + gpencil_get_outline_points(tgpf); - /* create array of points from stack */ - gpencil_points_from_stack(tgpf); + /* create array of points from stack */ + gpencil_points_from_stack(tgpf); - /* create z-depth array for reproject */ - gpencil_get_depth_array(tgpf); + /* create z-depth array for reproject */ + gpencil_get_depth_array(tgpf); - /* create stroke and reproject */ - gpencil_stroke_from_buffer(tgpf); - } - else { - BKE_report(op->reports, RPT_ERROR, "Fill canceled. No edges detected"); - } + /* create stroke and reproject */ + gpencil_stroke_from_buffer(tgpf); } /* free temp stack data */ -- cgit v1.2.3