[Bf-blender-cvs] [71c7083e1e0] greasepencil-object: GPencil: Avoid full filling when no borders
Antonio Vazquez
noreply at git.blender.org
Fri Dec 6 16:17:02 CET 2019
Commit: 71c7083e1e08ac1910f95dc1755a8fea4d2c17c3
Author: Antonio Vazquez
Date: Fri Dec 6 11:22:33 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rB71c7083e1e08ac1910f95dc1755a8fea4d2c17c3
GPencil: Avoid full filling when no borders
===================================================================
M source/blender/editors/gpencil/gpencil_fill.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index beeae085ae5..f57519e8bcb 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -134,6 +134,9 @@ typedef struct tGPDfill {
/* scaling factor */
short fill_factor;
+ /* Frame to use. */
+ int active_cfra;
+
/** number of elements currently in cache */
short sbuffer_used;
/** temporary points */
@@ -228,7 +231,6 @@ static void gp_draw_datablock(tGPDfill *tgpf, const float ink[4])
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
- int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph);
tGPDdraw tgpw;
tgpw.rv3d = tgpf->rv3d;
@@ -256,13 +258,13 @@ static void gp_draw_datablock(tGPDfill *tgpf, const float ink[4])
/* if active layer and no keyframe, create a new one */
if (gpl == tgpf->gpl) {
- if ((gpl->actframe == NULL) || (gpl->actframe->framenum != cfra_eval)) {
- BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+ if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) {
+ BKE_gpencil_layer_getframe(gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
}
}
/* get frame to draw */
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
if (gpf == NULL) {
continue;
}
@@ -666,6 +668,62 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf)
BLI_stack_free(stack);
}
+/* Check if there are some pixel not filled with green. If no points, means nothing to fill. */
+static bool gpencil_check_borders(tGPDfill *tgpf)
+{
+ ImBuf *ibuf;
+ void *lock;
+ ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+ int idx;
+ int pixel = 0;
+ float color[4];
+ bool found = false;
+
+ /* horizontal lines */
+ for (idx = 0; idx < ibuf->x; idx++) {
+ /* bottom line */
+ get_pixel(ibuf, idx, color);
+ if (color[1] != 1.0f) {
+ found = true;
+ break;
+ }
+ /* top line */
+ pixel = idx + (ibuf->x * (ibuf->y - 1));
+ get_pixel(ibuf, pixel, color);
+ if (color[1] != 1.0f) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ /* vertical lines */
+ for (idx = 0; idx < ibuf->y; idx++) {
+ /* left line */
+ get_pixel(ibuf, ibuf->x * idx, color);
+ if (color[1] != 1.0f) {
+ found = true;
+ break;
+ }
+ /* right line */
+ pixel = ibuf->x * idx + (ibuf->x - 1);
+ get_pixel(ibuf, pixel, color);
+ if (color[1] != 1.0f) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ /* release ibuf */
+ if (ibuf) {
+ BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+ }
+
+ tgpf->ima->id.tag |= LIB_TAG_DOIT;
+
+ return found;
+}
+
/* clean external border of image to avoid infinite loops */
static void gpencil_clean_borders(tGPDfill *tgpf)
{
@@ -1004,8 +1062,6 @@ static void gpencil_points_from_stack(tGPDfill *tgpf)
/* create a grease pencil stroke using points in buffer */
static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
{
- const int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph);
-
ToolSettings *ts = tgpf->scene->toolsettings;
const char *align_flag = &ts->gpencil_v3d_align;
const bool is_depth = (bool)(*align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE));
@@ -1024,8 +1080,11 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
return;
}
- /* get frame or create a new one */
- tgpf->gpf = BKE_gpencil_layer_getframe(tgpf->gpl, cfra_eval, GP_GETFRAME_ADD_NEW);
+ /* Get frame or create a new one. */
+ tgpf->gpf = BKE_gpencil_layer_getframe(tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
+
+ /* Set frame as selected. */
+ tgpf->gpf->flag |= GP_FRAME_SELECT;
/* create new stroke */
bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke");
@@ -1242,6 +1301,7 @@ static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op))
if (tgpf->gpl == NULL) {
tgpf->gpl = BKE_gpencil_layer_addnew(tgpf->gpd, DATA_("GP_Layer"), true);
}
+
tgpf->lock_axis = ts->gp_sculpt.lock_axis;
tgpf->oldkey = -1;
@@ -1423,6 +1483,7 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPDfill *tgpf = op->customdata;
+ Scene *scene = tgpf->scene;
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
@@ -1433,7 +1494,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
case LEFTMOUSE:
tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
- /* first time the event is not enabled to show help lines */
+ /* first time the event is not enabled to show help lines. */
if ((tgpf->oldkey != -1) || ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) == 0)) {
ARegion *ar = BKE_area_find_region_xy(CTX_wm_area(C), RGN_TYPE_ANY, event->x, event->y);
if (ar) {
@@ -1443,42 +1504,55 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
in_bounds = BLI_rcti_isect_pt(&ar->winrct, event->x, event->y);
if ((in_bounds) && (ar->regiontype == RGN_TYPE_WINDOW)) {
- /* TODO GPXX: Verify the mouse click is right for any window size */
tgpf->center[0] = event->mval[0];
tgpf->center[1] = event->mval[1];
+ /* Set active frame as current for filling. */
+ tgpf->active_cfra = CFRA;
+
/* render screen to temp image */
if (gp_render_offscreen(tgpf)) {
/* apply boundary fill */
gpencil_boundaryfill_area(tgpf);
- /* clean borders to avoid infinite loops */
- gpencil_clean_borders(tgpf);
+ /* Check if detected some border to fill. */
+ if (gpencil_check_borders(tgpf)) {
- /* analyze outline */
- gpencil_get_outline_points(tgpf);
+ /* clean borders to avoid infinite loops */
+ gpencil_clean_borders(tgpf);
- /* create array of points from stack */
- gpencil_points_from_stack(tgpf);
+ /* analyze outline */
+ gpencil_get_outline_points(tgpf);
- /* create z-depth array for reproject */
- gpencil_get_depth_array(tgpf);
+ /* create array of points from stack */
+ gpencil_points_from_stack(tgpf);
- /* create stroke and reproject */
- gpencil_stroke_from_buffer(tgpf);
- }
+ /* create z-depth array for reproject */
+ gpencil_get_depth_array(tgpf);
- /* restore size */
- tgpf->ar->winx = (short)tgpf->bwinx;
- tgpf->ar->winy = (short)tgpf->bwiny;
- tgpf->ar->winrct = tgpf->brect;
+ /* create stroke and reproject */
+ gpencil_stroke_from_buffer(tgpf);
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Fill canceled. No edges detected");
+ }
+ }
/* free temp stack data */
if (tgpf->stack) {
BLI_stack_free(tgpf->stack);
}
+ /* Free memory. */
+ MEM_SAFE_FREE(tgpf->sbuffer);
+ MEM_SAFE_FREE(tgpf->depth_arr);
+
+ /* restore size */
+ tgpf->ar->winx = (short)tgpf->bwinx;
+ tgpf->ar->winy = (short)tgpf->bwiny;
+ tgpf->ar->winrct = tgpf->brect;
+
/* push undo data */
gpencil_undo_push(tgpf->gpd);
More information about the Bf-blender-cvs
mailing list