From 3b8251664eb7b64a04391463ca9793fee9c1a1e9 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 13 Sep 2018 12:38:50 +0200 Subject: GP: Improve soft eraser rounded caps When draw segments the rounded cap must be only visible in some situations. --- source/blender/editors/gpencil/gpencil_paint.c | 52 ++++++++++++++++++++++++++ source/blender/makesdna/DNA_gpencil_types.h | 2 + 2 files changed, 54 insertions(+) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 4fda6456b10..683dbb3faf1 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1331,6 +1331,52 @@ static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps) gp_update_cache(gpd); } +/* analyze points to be removed when soft eraser is used + * to avoid that segments gets the end points rounded. This + * round cpas breaks the artistic effect. + */ +static void gp_stroke_soft_refine(bGPDstroke *gps, const float cull_thresh) +{ + bGPDspoint *pt = NULL; + bGPDspoint *pt_before = NULL; + bGPDspoint *pt_after = NULL; + int i; + + /* check if enough points*/ + if (gps->totpoints < 3) { + return; + } + + /* loop all points from second to last minus one + * to untag any point that is not surrounded by tagged points + */ + pt = gps->points; + for (i = 1; i < gps->totpoints - 1; i++, pt++) { + if (pt->flag & GP_SPOINT_TAG) { + pt_before = &gps->points[i - 1]; + pt_after = &gps->points[i + 1]; + + /* if any of the side points are not tagged, mark to keep */ + if (((pt_before->flag & GP_SPOINT_TAG) == 0) || + ((pt_after->flag & GP_SPOINT_TAG) == 0)) + { + if (pt->pressure > cull_thresh) { + pt->flag |= GP_SPOINT_TEMP_TAG; + } + } + } + } + + /* now untag temp tagged */ + pt = gps->points; + for (i = 1; i < gps->totpoints - 1; i++, pt++) { + if (pt->flag & GP_SPOINT_TEMP_TAG) { + pt->flag &= ~GP_SPOINT_TAG; + pt->flag &= ~GP_SPOINT_TEMP_TAG; + } + } +} + /* eraser tool - evaluation per stroke */ /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ static void gp_stroke_eraser_dostroke(tGPsdata *p, @@ -1501,6 +1547,12 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* Second Pass: Remove any points that are tagged */ if (do_cull) { + /* if soft eraser, must analyze points to be sure the stroke ends + * don't get rounded */ + if (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_SOFT) { + gp_stroke_soft_refine(gps, cull_thresh); + } + gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false); } gp_update_cache(p->gpd); diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index cdadb1764b8..8c3acf9d001 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -71,6 +71,8 @@ typedef enum eGPDspoint_Flag { /* stroke point is tagged (for some editing operation) */ GP_SPOINT_TAG = (1 << 1), + /* stroke point is temp tagged (for some editing operation) */ + GP_SPOINT_TEMP_TAG = (1 << 2), } eGPSPoint_Flag; /* ***************************************** */ -- cgit v1.2.3