Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / gpencil / gpencil_brush.c
index 1cb882e..c2e532b 100644 (file)
@@ -87,54 +87,54 @@ typedef struct tGP_BrushEditData {
        /* Current editor/region/etc. */
        /* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */
        Scene *scene;
-       
+
        ScrArea *sa;
        ARegion *ar;
-       
+
        /* Current GPencil datablock */
        bGPdata *gpd;
-       
+
        /* Brush Settings */
        GP_BrushEdit_Settings *settings;
        GP_EditBrush_Data *brush;
-       
+
        eGP_EditBrush_Types brush_type;
        eGP_EditBrush_Flag  flag;
-       
+
        /* Space Conversion Data */
        GP_SpaceConversion gsc;
-       
-       
+
+
        /* Is the brush currently painting? */
        bool is_painting;
-       
+
        /* Start of new sculpt stroke */
        bool first;
-       
+
        /* Current frame */
        int cfra;
-       
-       
+
+
        /* Brush Runtime Data: */
        /* - position and pressure
         * - the *_prev variants are the previous values
         */
        int   mval[2], mval_prev[2];
        float pressure, pressure_prev;
-       
+
        /* - effect vector (e.g. 2D/3D translation for grab brush) */
        float dvec[3];
-       
+
        /* brush geometry (bounding box) */
        rcti brush_rect;
-       
+
        /* Custom data for certain brushes */
        /* - map from bGPDstroke's to structs containing custom data about those strokes */
        GHash *stroke_customdata;
        /* - general customdata */
        void *customdata;
-       
-       
+
+
        /* Timer for in-place accumulation of brush effect */
        wmTimer *timer;
        bool timerTick; /* is this event from a timer */
@@ -170,12 +170,12 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
 {
        /* The basic setting is the brush's setting (from the panel) */
        bool invert = ((gso->brush->flag & GP_EDITBRUSH_FLAG_INVERT) != 0);
-       
+
        /* During runtime, the user can hold down the Ctrl key to invert the basic behaviour */
        if (gso->flag & GP_EDITBRUSH_FLAG_INVERT) {
                invert ^= true;
        }
-               
+
        return invert;
 }
 
@@ -183,26 +183,26 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
 static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, const int co[2])
 {
        GP_EditBrush_Data *brush = gso->brush;
-       
+
        /* basic strength factor from brush settings */
        float influence = brush->strength;
-       
+
        /* use pressure? */
        if (brush->flag & GP_EDITBRUSH_FLAG_USE_PRESSURE) {
                influence *= gso->pressure;
        }
-       
+
        /* distance fading */
        if (brush->flag & GP_EDITBRUSH_FLAG_USE_FALLOFF) {
                float distance = (float)len_v2v2_int(gso->mval, co);
                float fac;
-               
+
                CLAMP(distance, 0.0f, (float)radius);
                fac = 1.0f - (distance / (float)radius);
-               
+
                influence *= fac;
        }
-       
+
        /* return influence */
        return influence;
 }
@@ -241,7 +241,7 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i
        if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) {
                gp_smooth_stroke_thickness(gps, i, inf);
        }
-       
+
        return true;
 }
 
@@ -254,13 +254,13 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
 {
        bGPDspoint *pt = gps->points + i;
        float inf;
-       
+
        /* Compute strength of effect
         * - We divide the strength by 10, so that users can set "sane" values.
         *   Otherwise, good default values are in the range of 0.093
         */
        inf = gp_brush_influence_calc(gso, radius, co) / 10.0f;
-       
+
        /* apply */
        // XXX: this is much too strong, and it should probably do some smoothing with the surrounding stuff
        if (gp_brush_invert_check(gso)) {
@@ -271,7 +271,7 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
                /* make line thicker - increase stroke pressure */
                pt->pressure += inf;
        }
-       
+
        /* Pressure should stay within [0.0, 1.0]
         * However, it is nice for volumetric strokes to be able to exceed
         * the upper end of this range. Therefore, we don't actually clamp
@@ -279,7 +279,7 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
         */
        if (pt->pressure < 0.0f)
                pt->pressure = 0.0f;
-       
+
        return true;
 }
 
@@ -333,7 +333,7 @@ typedef struct tGPSB_Grab_StrokeData {
        int   *points;
        /* array of influence weights for each of the included points */
        float *weights;
-       
+
        /* capacity of the arrays */
        int capacity;
        /* actual number of items currently stored */
@@ -344,9 +344,9 @@ typedef struct tGPSB_Grab_StrokeData {
 static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
 {
        tGPSB_Grab_StrokeData *data = NULL;
-       
+
        BLI_assert(gps->totpoints > 0);
-       
+
        /* Check if there are buffers already (from a prior run) */
        if (BLI_ghash_haskey(gso->stroke_customdata, gps)) {
                /* Ensure that the caches are empty
@@ -355,25 +355,25 @@ static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
                 */
                data = BLI_ghash_lookup(gso->stroke_customdata, gps);
                BLI_assert(data != NULL);
-               
+
                data->size = 0; /* minimum requirement - so that we can repopulate again */
-               
+
                memset(data->points, 0, sizeof(int) * data->capacity);
                memset(data->weights, 0, sizeof(float) * data->capacity);
        }
        else {
                /* Create new instance */
                data = MEM_callocN(sizeof(tGPSB_Grab_StrokeData), "GP Stroke Grab Data");
-               
+
                data->capacity = gps->totpoints;
                data->size = 0;
-               
+
                data->points  = MEM_callocN(sizeof(int) * data->capacity, "GP Stroke Grab Indices");
                data->weights = MEM_callocN(sizeof(float) * data->capacity, "GP Stroke Grab Weights");
-               
+
                /* hook up to the cache */
                BLI_ghash_insert(gso->stroke_customdata, gps, data);
-       }       
+       }
 }
 
 /* store references to stroke points in the initial stage */
@@ -382,15 +382,15 @@ static bool gp_brush_grab_store_points(tGP_BrushEditData *gso, bGPDstroke *gps,
 {
        tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
        float inf = gp_brush_influence_calc(gso, radius, co);
-       
+
        BLI_assert(data != NULL);
        BLI_assert(data->size < data->capacity);
-       
+
        /* insert this point into the set of affected points */
        data->points[data->size]  = i;
        data->weights[data->size] = inf;
        data->size++;
-       
+
        /* done */
        return true;
 }
@@ -406,13 +406,13 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso)
                RegionView3D *rv3d = gso->ar->regiondata;
                float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location;
                float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
-               
+
                float mval_f[2];
-               
+
                /* convert from 2D screenspace to 3D... */
                mval_f[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
                mval_f[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
-               
+
                ED_view3d_win_to_delta(gso->ar, mval_f, gso->dvec, zfac);
        }
        else {
@@ -435,7 +435,7 @@ static void gp_brush_grab_apply_cached(
        for (i = 0; i < data->size; i++) {
                bGPDspoint *pt = &gps->points[data->points[i]];
                float delta[3] = {0.0f};
-               
+
                /* adjust the amount of displacement to apply */
                mul_v3_v3fl(delta, gso->dvec, data->weights[i]);
                if (!parented) {
@@ -454,7 +454,7 @@ static void gp_brush_grab_apply_cached(
                        invert_m4_m4(inverse_diff_mat, diff_mat);
                        mul_m4_v3(inverse_diff_mat, &pt->x);
                }
-               
+
        }
 }
 
@@ -462,11 +462,11 @@ static void gp_brush_grab_apply_cached(
 static void gp_brush_grab_stroke_free(void *ptr)
 {
        tGPSB_Grab_StrokeData *data = (tGPSB_Grab_StrokeData *)ptr;
-       
+
        /* free arrays */
        MEM_freeN(data->points);
        MEM_freeN(data->weights);
-       
+
        /* ... and this item itself, since it was also allocated */
        MEM_freeN(data);
 }
@@ -481,10 +481,10 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
        bGPDspoint *pt = gps->points + i;
        float inf = gp_brush_influence_calc(gso, radius, co);
        float delta[3] = {0.0f};
-               
+
        /* adjust the amount of displacement to apply */
        mul_v3_v3fl(delta, gso->dvec, inf);
-       
+
        /* apply */
        add_v3_v3(&pt->x, delta);
 
@@ -506,12 +506,12 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso)
                RegionView3D *rv3d = gso->ar->regiondata;
                float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location;
                float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
-               
+
                float mval_f[2] = {UNPACK2(gso->mval)};
                float mval_prj[2];
                float dvec[3];
-               
-               
+
+
                if (ED_view3d_project_float_global(gso->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
                        sub_v2_v2v2(mval_f, mval_prj, mval_f);
                        ED_view3d_win_to_delta(gso->ar, mval_f, dvec, zfac);
@@ -537,17 +537,17 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
        bGPDspoint *pt = gps->points + i;
        float fac, inf;
        float vec[3];
-       
+
        /* Scale down standard influence value to get it more manageable...
         *  - No damping = Unmanageable at > 0.5 strength
         *  - Div 10     = Not enough effect
         *  - Div 5      = Happy medium... (by trial and error)
         */
        inf = gp_brush_influence_calc(gso, radius, co) / 5.0f;
-       
+
        /* 1) Make this point relative to the cursor/midpoint (dvec) */
        sub_v3_v3v3(vec, &pt->x, gso->dvec);
-       
+
        /* 2) Shrink the distance by pulling the point towards the midpoint
         *    (0.0 = at midpoint, 1 = at edge of brush region)
         *                         OR
@@ -562,10 +562,10 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
                fac = 1.0f - (inf * inf); /* squared to temper the effect... */
        }
        mul_v3_fl(vec, fac);
-       
+
        /* 3) Translate back to original space, with the shrinkage applied */
        add_v3_v3v3(&pt->x, gso->dvec, vec);
-       
+
        /* done */
        return true;
 }
@@ -582,16 +582,16 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
 {
        bGPDspoint *pt = gps->points + i;
        float angle, inf;
-       
+
        /* Angle to rotate by */
        inf = gp_brush_influence_calc(gso, radius, co);
        angle = DEG2RADF(1.0f) * inf;
-       
+
        if (gp_brush_invert_check(gso)) {
                /* invert angle that we rotate by */
                angle *= -1;
        }
-       
+
        /* Rotate in 2D or 3D space? */
        if (gps->flag & GP_STROKE_3DSPACE) {
                /* Perform rotation in 3D space... */
@@ -599,13 +599,13 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
                float rmat[3][3];
                float axis[3];
                float vec[3];
-               
+
                /* Compute rotation matrix - rotate around view vector by angle */
                negate_v3_v3(axis, rv3d->persinv[2]);
                normalize_v3(axis);
-               
+
                axis_angle_normalized_to_mat3(rmat, axis, angle);
-               
+
                /* Rotate point (no matrix-space transforms needed, as GP points are in world space) */
                sub_v3_v3v3(vec, &pt->x, gso->dvec); /* make relative to center (center is stored in dvec) */
                mul_m3_v3(rmat, vec);
@@ -615,20 +615,20 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
                const float axis[3] = {0.0f, 0.0f, 1.0f};
                float vec[3] = {0.0f};
                float rmat[3][3];
-               
+
                /* Express position of point relative to cursor, ready to rotate */
                // XXX: There is still some offset here, but it's close to working as expected...
                vec[0] = (float)(co[0] - gso->mval[0]);
                vec[1] = (float)(co[1] - gso->mval[1]);
-               
+
                /* rotate point */
                axis_angle_normalized_to_mat3(rmat, axis, angle);
                mul_m3_v3(rmat, vec);
-               
+
                /* Convert back to screen-coordinates */
                vec[0] += (float)gso->mval[0];
                vec[1] += (float)gso->mval[1];
-               
+
                /* Map from screen-coordinates to final coordinate space */
                if (gps->flag & GP_STROKE_2DSPACE) {
                        View2D *v2d = gso->gsc.v2d;
@@ -639,7 +639,7 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
                        copy_v2_v2(&pt->x, vec);
                }
        }
-       
+
        /* done */
        return true;
 }
@@ -653,7 +653,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
                                      const int radius, const int co[2])
 {
        bGPDspoint *pt = gps->points + i;
-       
+
        /* Amount of jitter to apply depends on the distance of the point to the cursor,
         * as well as the strength of the brush
         */
@@ -766,13 +766,13 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
 typedef struct tGPSB_CloneBrushData {
        /* midpoint of the strokes on the clipboard */
        float buffer_midpoint[3];
-       
+
        /* number of strokes in the paste buffer (and/or to be created each time) */
        size_t totitems;
-       
+
        /* for "stamp" mode, the currently pasted brushes */
        bGPDstroke **new_strokes;
-       
+
        /* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */
        GHash *new_colors;
 } tGPSB_CloneBrushData;
@@ -782,43 +782,43 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
 {
        tGPSB_CloneBrushData *data;
        bGPDstroke *gps;
-       
+
        /* init custom data */
        gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData");
-       
+
        /* compute midpoint of strokes on clipboard */
        for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
                if (ED_gpencil_stroke_can_use(C, gps)) {
                        const float dfac = 1.0f / ((float)gps->totpoints);
                        float mid[3] = {0.0f};
-                       
+
                        bGPDspoint *pt;
                        int i;
-                       
+
                        /* compute midpoint of this stroke */
                        for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
                                float co[3];
-                               
+
                                mul_v3_v3fl(co, &pt->x, dfac);
                                add_v3_v3(mid, co);
                        }
-                       
+
                        /* combine this stroke's data with the main data */
                        add_v3_v3(data->buffer_midpoint, mid);
                        data->totitems++;
                }
        }
-       
+
        /* Divide the midpoint by the number of strokes, to finish averaging it */
        if (data->totitems > 1) {
                mul_v3_fl(data->buffer_midpoint, 1.0f / (float)data->totitems);
        }
-       
+
        /* Create a buffer for storing the current strokes */
        if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
                data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array");
        }
-       
+
        /* Init colormap for mapping between the pasted stroke's source colour(names)
         * and the final colours that will be used here instead...
         */
@@ -829,19 +829,19 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
 static void gp_brush_clone_free(tGP_BrushEditData *gso)
 {
        tGPSB_CloneBrushData *data = gso->customdata;
-       
+
        /* free strokes array */
        if (data->new_strokes) {
                MEM_freeN(data->new_strokes);
                data->new_strokes = NULL;
        }
-       
+
        /* free copybuf colormap */
        if (data->new_colors) {
                BLI_ghash_free(data->new_colors, NULL, NULL);
                data->new_colors = NULL;
        }
-       
+
        /* free the customdata itself */
        MEM_freeN(data);
        gso->customdata = NULL;
@@ -851,44 +851,44 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
 static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
 {
        tGPSB_CloneBrushData *data = gso->customdata;
-       
+
        Scene *scene = gso->scene;
        bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
        bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
        bGPDstroke *gps;
-       
+
        float delta[3];
        size_t strokes_added = 0;
-       
+
        /* Compute amount to offset the points by */
        /* NOTE: This assumes that screenspace strokes are NOT used in the 3D view... */
-       
+
        gp_brush_calc_midpoint(gso); /* this puts the cursor location into gso->dvec */
        sub_v3_v3v3(delta, gso->dvec, data->buffer_midpoint);
-       
+
        /* Copy each stroke into the layer */
        for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
                if (ED_gpencil_stroke_can_use(C, gps)) {
                        bGPDstroke *new_stroke;
                        bGPDspoint *pt;
                        int i;
-                       
+
                        /* Make a new stroke */
                        new_stroke = MEM_dupallocN(gps);
-                       
+
                        new_stroke->points = MEM_dupallocN(gps->points);
                        new_stroke->triangles = MEM_dupallocN(gps->triangles);
-                       
+
                        new_stroke->next = new_stroke->prev = NULL;
                        BLI_addtail(&gpf->strokes, new_stroke);
-                       
+
                        /* Fix color references */
                        BLI_assert(new_stroke->colorname[0] != '\0');
                        new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname);
-                       
+
                        BLI_assert(new_stroke->palcolor != NULL);
                        BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
-                       
+
                        /* Adjust all the stroke's points, so that the strokes
                         * get pasted relative to where the cursor is now
                         */
@@ -896,7 +896,7 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
                                /* assume that the delta can just be applied, and then everything works */
                                add_v3_v3(&pt->x, delta);
                        }
-                       
+
                        /* Store ref for later */
                        if ((data->new_strokes) && (strokes_added < data->totitems)) {
                                data->new_strokes[strokes_added] = new_stroke;
@@ -911,31 +911,31 @@ static void gp_brush_clone_adjust(tGP_BrushEditData *gso)
 {
        tGPSB_CloneBrushData *data = gso->customdata;
        size_t snum;
-       
+
        /* Compute the amount of movement to apply (overwrites dvec) */
        gp_brush_grab_calc_dvec(gso);
-       
+
        /* For each of the stored strokes, apply the offset to each point */
        /* NOTE: Again this assumes that in the 3D view, we only have 3d space and not screenspace strokes... */
        for (snum = 0; snum < data->totitems; snum++) {
                bGPDstroke *gps = data->new_strokes[snum];
                bGPDspoint *pt;
                int i;
-               
+
                for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
                        if (gso->brush->flag & GP_EDITBRUSH_FLAG_USE_FALLOFF) {
                                /* "Smudge" Effect when falloff is enabled */
                                float delta[3] = {0.0f};
                                int sco[2] = {0};
                                float influence;
-                               
+
                                /* compute influence on point */
                                gp_point_to_xy(&gso->gsc, gps, pt, &sco[0], &sco[1]);
                                influence = gp_brush_influence_calc(gso, gso->brush->size, sco);
-                               
+
                                /* adjust the amount of displacement to apply */
                                mul_v3_v3fl(delta, gso->dvec, influence);
-                               
+
                                /* apply */
                                add_v3_v3(&pt->x, delta);
                        }
@@ -967,7 +967,7 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
                        gp_brush_clone_add(C, gso);
                }
        }
-       
+
        return true;
 }
 
@@ -1007,7 +1007,7 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customda
 static void gpencil_toggle_brush_cursor(bContext *C, bool enable)
 {
        GP_BrushEdit_Settings *gset = gpsculpt_get_settings(CTX_data_scene(C));
-       
+
        if (gset->paintcursor && !enable) {
                /* clear cursor */
                WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor);
@@ -1015,8 +1015,8 @@ static void gpencil_toggle_brush_cursor(bContext *C, bool enable)
        }
        else if (enable) {
                /* enable cursor */
-               gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), 
-                                                            NULL, 
+               gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+                                                            NULL,
                                                             gp_brush_drawcursor, NULL);
        }
 }
@@ -1029,15 +1029,15 @@ static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
 {
        const char *brush_name = NULL;
        char str[UI_MAX_DRAW_STR] = "";
-       
+
        RNA_enum_name(rna_enum_gpencil_sculpt_brush_items, gso->brush_type, &brush_name);
-       
+
        BLI_snprintf(str, sizeof(str),
                     IFACE_("GPencil Sculpt: %s Stroke  | LMB to paint | RMB/Escape to Exit"
                            " | Ctrl to Invert Action | Wheel Up/Down for Size "
                            " | Shift-Wheel Up/Down for Strength"),
                     (brush_name) ? brush_name : "<?>");
-       
+
        ED_area_headerprint(CTX_wm_area(C), str);
 }
 
@@ -1050,36 +1050,36 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
 {
        Scene *scene = CTX_data_scene(C);
        tGP_BrushEditData *gso;
-       
+
        /* setup operator data */
        gso = MEM_callocN(sizeof(tGP_BrushEditData), "tGP_BrushEditData");
        op->customdata = gso;
-       
+
        /* store state */
        gso->settings = gpsculpt_get_settings(scene);
        gso->brush = gpsculpt_get_brush(scene);
-       
+
        gso->brush_type = gso->settings->brushtype;
-       
-       
+
+
        gso->is_painting = false;
        gso->first = true;
-       
+
        gso->gpd = ED_gpencil_data_get_active(C);
        gso->cfra = INT_MAX; /* NOTE: So that first stroke will get handled in init_stroke() */
-       
+
        gso->scene = scene;
-       
+
        gso->sa = CTX_wm_area(C);
        gso->ar = CTX_wm_region(C);
-       
+
        /* initialise custom data for brushes */
        switch (gso->brush_type) {
                case GP_EDITBRUSH_TYPE_CLONE:
                {
                        bGPDstroke *gps;
                        bool found = false;
-                       
+
                        /* check that there are some usable strokes in the buffer */
                        for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
                                if (ED_gpencil_stroke_can_use(C, gps)) {
@@ -1087,12 +1087,12 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
                                        break;
                                }
                        }
-                       
+
                        if (found == false) {
                                /* STOP HERE! Nothing to paste! */
-                               BKE_report(op->reports, RPT_ERROR, 
+                               BKE_report(op->reports, RPT_ERROR,
                                           "Copy some strokes to the clipboard before using the Clone brush to paste copies of them");
-                                          
+
                                MEM_freeN(gso);
                                op->customdata = NULL;
                                return false;
@@ -1103,30 +1103,30 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
                        }
                        break;
                }
-               
+
                case GP_EDITBRUSH_TYPE_GRAB:
                {
                        /* initialise the cache needed for this brush */
                        gso->stroke_customdata = BLI_ghash_ptr_new("GP Grab Brush - Strokes Hash");
                        break;
                }
-                       
+
                /* Others - No customdata needed */
                default:
                        break;
        }
-       
-       
+
+
        /* setup space conversions */
        gp_point_conversion_init(C, &gso->gsc);
-       
+
        /* update header */
        gpsculpt_brush_header_set(C, gso);
-       
+
        /* setup cursor drawing */
        WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR);
        gpencil_toggle_brush_cursor(C, true);
-       
+
        return true;
 }
 
@@ -1134,7 +1134,7 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
 {
        tGP_BrushEditData *gso = op->customdata;
        wmWindow *win = CTX_wm_window(C);
-       
+
        /* free brush-specific data */
        switch (gso->brush_type) {
                case GP_EDITBRUSH_TYPE_GRAB:
@@ -1146,18 +1146,18 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
                        BLI_ghash_free(gso->stroke_customdata, NULL, gp_brush_grab_stroke_free);
                        break;
                }
-               
+
                case GP_EDITBRUSH_TYPE_CLONE:
                {
                        /* Free customdata */
                        gp_brush_clone_free(gso);
                        break;
                }
-               
+
                default:
                        break;
        }
-       
+
        /* unregister timer (only used for realtime) */
        if (gso->timer) {
                WM_event_remove_timer(CTX_wm_manager(C), win, gso->timer);
@@ -1167,7 +1167,7 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
        ED_area_headerprint(CTX_wm_area(C), NULL);
        WM_cursor_modal_restore(win);
        gpencil_toggle_brush_cursor(C, false);
-       
+
        /* free operator data */
        MEM_freeN(gso);
        op->customdata = NULL;
@@ -1188,18 +1188,18 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
        bGPdata *gpd = gso->gpd;
        bGPDlayer *gpl;
        int cfra = CFRA;
-       
+
        /* only try to add a new frame if this is the first stroke, or the frame has changed */
        if ((gpd == NULL) || (cfra == gso->cfra))
                return;
-       
+
        /* go through each layer, and ensure that we've got a valid frame to use */
        for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
                /* only editable and visible layers are considered */
                if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
                        bGPDframe *gpf = gpl->actframe;
-                       
-                       /* Make a new frame to work on if the layer's frame and the current scene frame don't match up 
+
+                       /* Make a new frame to work on if the layer's frame and the current scene frame don't match up
                         * - This is useful when animating as it saves that "uh-oh" moment when you realize you've
                         *   spent too much time editing the wrong frame...
                         */
@@ -1209,7 +1209,7 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
                        }
                }
        }
-       
+
        /* save off new current frame, so that next update works fine */
        gso->cfra = cfra;
 }
@@ -1224,7 +1224,7 @@ static bool gpsculpt_brush_do_stroke(
        GP_SpaceConversion *gsc = &gso->gsc;
        rcti *rect = &gso->brush_rect;
        const int radius = gso->brush->size;
-       
+
        bGPDspoint *pt1, *pt2;
        int pc1[2] = {0};
        int pc2[2] = {0};
@@ -1241,7 +1241,7 @@ static bool gpsculpt_brush_do_stroke(
                        gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
                        gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
                }
-               
+
                /* do boundbox check first */
                if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
                        /* only check if point is inside */
@@ -1252,14 +1252,14 @@ static bool gpsculpt_brush_do_stroke(
                }
        }
        else {
-               /* Loop over the points in the stroke, checking for intersections 
+               /* Loop over the points in the stroke, checking for intersections
                 *  - an intersection means that we touched the stroke
                 */
                for (i = 0; (i + 1) < gps->totpoints; i++) {
                        /* Get points to work with */
                        pt1 = gps->points + i;
                        pt2 = gps->points + i + 1;
-                       
+
                        /* Skip if neither one is selected (and we are only allowed to edit/consider selected points) */
                        if (gso->settings->flag & GP_BRUSHEDIT_FLAG_SELECT_MASK) {
                                if (!(pt1->flag & GP_SPOINT_SELECT) && !(pt2->flag & GP_SPOINT_SELECT)) {
@@ -1292,14 +1292,14 @@ static bool gpsculpt_brush_do_stroke(
                                if (gp_stroke_inside_circle(gso->mval, gso->mval_prev, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
                                        /* Apply operation to these points */
                                        bool ok = false;
-                                       
+
                                        /* To each point individually... */
                                        ok = apply(gso, gps, i, radius, pc1);
-                                       
+
                                        /* Only do the second point if this is the last segment,
                                         * and it is unlikely that the point will get handled
-                                        * otherwise. 
-                                        * 
+                                        * otherwise.
+                                        *
                                         * NOTE: There is a small risk here that the second point wasn't really
                                         *       actually in-range. In that case, it only got in because
                                         *       the line linking the points was!
@@ -1311,13 +1311,13 @@ static bool gpsculpt_brush_do_stroke(
                                        else {
                                                include_last = true;
                                        }
-                                       
+
                                        changed |= ok;
                                }
                                else if (include_last) {
                                        /* This case is for cases where for whatever reason the second vert (1st here) doesn't get included
                                         * because the whole edge isn't in bounds, but it would've qualified since it did with the
-                                        * previous step (but wasn't added then, to avoid double-ups) 
+                                        * previous step (but wasn't added then, to avoid double-ups)
                                         */
                                        changed |= apply(gso, gps, i, radius, pc1);
                                        include_last = false;
@@ -1325,7 +1325,7 @@ static bool gpsculpt_brush_do_stroke(
                        }
                }
        }
-       
+
        return changed;
 }
 
@@ -1333,7 +1333,7 @@ static bool gpsculpt_brush_do_stroke(
 static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
 {
        bool changed = false;
-       
+
        /* Calculate brush-specific data which applies equally to all points */
        switch (gso->brush_type) {
                case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
@@ -1343,7 +1343,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
                        gp_brush_grab_calc_dvec(gso);
                        break;
                }
-               
+
                case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
                case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
                {
@@ -1351,19 +1351,19 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
                        gp_brush_calc_midpoint(gso);
                        break;
                }
-               
+
                case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Random jitter */
                {
                        /* compute the displacement vector for the cursor (in data space) */
                        gp_brush_grab_calc_dvec(gso);
                        break;
                }
-               
+
                default:
                        break;
        }
-       
-       
+
+
        /* Find visible strokes, and perform operations on those if hit */
        float diff_mat[4][4];
        bool parented = false;
@@ -1373,7 +1373,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
                bGPDframe *gpf = gpl->actframe;
                if (gpf == NULL)
                        continue;
-               
+
                /* calculate difference matrix if parent object */
                if (gpl->parent != NULL) {
                        ED_gpencil_parent_location(gpl, diff_mat);
@@ -1382,7 +1382,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
                else {
                        parented = false;
                }
-               
+
                for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
                        /* skip strokes that are invalid for current view */
                        if (ED_gpencil_stroke_can_use(C, gps) == false)
@@ -1477,34 +1477,34 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
        float mousef[2];
        int mouse[2];
        bool changed = false;
-       
+
        /* Get latest mouse coordinates */
        RNA_float_get_array(itemptr, "mouse", mousef);
        gso->mval[0] = mouse[0] = (int)(mousef[0]);
        gso->mval[1] = mouse[1] = (int)(mousef[1]);
-       
+
        gso->pressure = RNA_float_get(itemptr, "pressure");
-       
+
        if (RNA_boolean_get(itemptr, "pen_flip"))
                gso->flag |= GP_EDITBRUSH_FLAG_INVERT;
        else
                gso->flag &= ~GP_EDITBRUSH_FLAG_INVERT;
-       
-       
+
+
        /* Store coordinates as reference, if operator just started running */
        if (gso->first) {
                gso->mval_prev[0]  = gso->mval[0];
                gso->mval_prev[1]  = gso->mval[1];
                gso->pressure_prev = gso->pressure;
        }
-       
+
        /* Update brush_rect, so that it represents the bounding rectangle of brush */
        gso->brush_rect.xmin = mouse[0] - radius;
        gso->brush_rect.ymin = mouse[1] - radius;
        gso->brush_rect.xmax = mouse[0] + radius;
        gso->brush_rect.ymax = mouse[1] + radius;
-       
-       
+
+
        /* Apply brush */
        if (gso->brush_type == GP_EDITBRUSH_TYPE_CLONE) {
                changed = gpsculpt_brush_apply_clone(C, gso);
@@ -1512,13 +1512,13 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
        else {
                changed = gpsculpt_brush_apply_standard(C, gso);
        }
-       
-       
+
+
        /* Updates */
        if (changed) {
                WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
        }
-       
+
        /* Store values for next step */
        gso->mval_prev[0]  = gso->mval[0];
        gso->mval_prev[1]  = gso->mval[1];
@@ -1535,24 +1535,24 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
        PointerRNA itemptr;
        float mouse[2];
        int tablet = 0;
-       
+
        mouse[0] = event->mval[0] + 1;
        mouse[1] = event->mval[1] + 1;
-       
+
        /* fill in stroke */
        RNA_collection_add(op->ptr, "stroke", &itemptr);
-       
+
        RNA_float_set_array(&itemptr, "mouse", mouse);
        RNA_boolean_set(&itemptr, "pen_flip", event->ctrl != false);
        RNA_boolean_set(&itemptr, "is_start", gso->first);
-       
+
        /* handle pressure sensitivity (which is supplied by tablets) */
        if (event->tablet_data) {
                const wmTabletData *wmtab = event->tablet_data;
                float pressure = wmtab->Pressure;
-               
+
                tablet = (wmtab->Active != EVT_TABLET_NONE);
-               
+
                /* special exception here for too high pressure values on first touch in
                 * windows for some tablets: clamp the values to be sane
                 */
@@ -1564,7 +1564,7 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
        else {
                RNA_float_set(&itemptr, "pressure", 1.0f);
        }
-       
+
        /* apply */
        gpsculpt_brush_apply(C, op, &itemptr);
 }
@@ -1574,15 +1574,15 @@ static int gpsculpt_brush_exec(bContext *C, wmOperator *op)
 {
        if (!gpsculpt_brush_init(C, op))
                return OPERATOR_CANCELLED;
-       
-       RNA_BEGIN(op->ptr, itemptr, "stroke") 
+
+       RNA_BEGIN(op->ptr, itemptr, "stroke")
        {
                gpsculpt_brush_apply(C, op, &itemptr);
        }
        RNA_END;
-       
+
        gpsculpt_brush_exit(C, op);
-       
+
        return OPERATOR_FINISHED;
 }
 
@@ -1594,13 +1594,13 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
        const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
        bool needs_timer = false;
        float brush_rate = 0.0f;
-       
+
        /* init painting data */
        if (!gpsculpt_brush_init(C, op))
                return OPERATOR_CANCELLED;
-       
+
        gso = op->customdata;
-       
+
        /* initialise type-specific data (used for the entire session) */
        switch (gso->brush_type) {
                /* Brushes requiring timer... */
@@ -1608,7 +1608,7 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
                        brush_rate = 0.01f; // XXX: hardcoded
                        needs_timer = true;
                        break;
-                       
+
                case GP_EDITBRUSH_TYPE_STRENGTH:
                        brush_rate = 0.01f; // XXX: hardcoded
                        needs_timer = true;
@@ -1618,39 +1618,39 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
                        brush_rate = 0.001f; // XXX: hardcoded
                        needs_timer = true;
                        break;
-               
+
                case GP_EDITBRUSH_TYPE_TWIST:
                        brush_rate = 0.01f; // XXX: hardcoded
                        needs_timer = true;
                        break;
-                       
+
                default:
                        break;
        }
-       
+
        /* register timer for increasing influence by hovering over an area */
        if (needs_timer) {
                gso->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, brush_rate);
        }
-       
+
        /* register modal handler */
        WM_event_add_modal_handler(C, op);
-       
+
        /* start drawing immediately? */
        if (is_modal == false) {
                ARegion *ar = CTX_wm_region(C);
-               
+
                /* ensure that we'll have a new frame to draw on */
                gpsculpt_brush_init_stroke(gso);
-               
+
                /* apply first dab... */
                gso->is_painting = true;
                gpsculpt_brush_apply_event(C, op, event);
-               
+
                /* redraw view with feedback */
                ED_region_tag_redraw(ar);
        }
-       
+
        return OPERATOR_RUNNING_MODAL;
 }
 
@@ -1661,7 +1661,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
        const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
        bool redraw_region = false;
        bool redraw_toolsettings = false;
-       
+
        /* The operator can be in 2 states: Painting and Idling */
        if (gso->is_painting) {
                /* Painting  */
@@ -1671,11 +1671,11 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                        case INBETWEEN_MOUSEMOVE:
                                /* apply brush effect at new position */
                                gpsculpt_brush_apply_event(C, op, event);
-                               
+
                                /* force redraw, so that the cursor will at least be valid */
                                redraw_region = true;
                                break;
-                       
+
                        /* Timer Tick - Only if this was our own timer */
                        case TIMER:
                                if (event->customdata == gso->timer) {
@@ -1684,7 +1684,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                        gso->timerTick = false;
                                }
                                break;
-                               
+
                        /* Adjust brush settings */
                        /* FIXME: Step increments and modifier keys are hardcoded here! */
                        case WHEELUPMOUSE:
@@ -1699,12 +1699,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                        gso->brush->size += 3;
                                        CLAMP_MAX(gso->brush->size, 300);
                                }
-                               
+
                                redraw_region = true;
                                redraw_toolsettings = true;
                                break;
-                       
-                       case WHEELDOWNMOUSE: 
+
+                       case WHEELDOWNMOUSE:
                        case PADMINUS:
                                if (event->shift) {
                                        /* decrease strength */
@@ -1716,11 +1716,11 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                        gso->brush->size -= 3;
                                        CLAMP_MIN(gso->brush->size, 1);
                                }
-                               
+
                                redraw_region = true;
                                redraw_toolsettings = true;
                                break;
-                       
+
                        /* Painting mbut release = Stop painting (back to idle) */
                        case LEFTMOUSE:
                                //BLI_assert(event->val == KM_RELEASE);
@@ -1731,12 +1731,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                else {
                                        /* end sculpt session, since we're not modal */
                                        gso->is_painting = false;
-                                       
+
                                        gpsculpt_brush_exit(C, op);
                                        return OPERATOR_FINISHED;
                                }
                                break;
-                               
+
                        /* Abort painting if any of the usual things are tried */
                        case MIDDLEMOUSE:
                        case RIGHTMOUSE:
@@ -1748,34 +1748,34 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
        else {
                /* Idling */
                BLI_assert(is_modal == true);
-               
+
                switch (event->type) {
                        /* Painting mbut press = Start painting (switch to painting state) */
                        case LEFTMOUSE:
                                /* do initial "click" apply */
                                gso->is_painting = true;
                                gso->first = true;
-                               
+
                                gpsculpt_brush_init_stroke(gso);
                                gpsculpt_brush_apply_event(C, op, event);
                                break;
-                               
+
                        /* Exit modal operator, based on the "standard" ops */
                        case RIGHTMOUSE:
                        case ESCKEY:
                                gpsculpt_brush_exit(C, op);
                                return OPERATOR_FINISHED;
-                               
+
                        /* MMB is often used for view manipulations */
                        case MIDDLEMOUSE:
                                return OPERATOR_PASS_THROUGH;
-                       
+
                        /* Mouse movements should update the brush cursor - Just redraw the active region */
                        case MOUSEMOVE:
                        case INBETWEEN_MOUSEMOVE:
                                redraw_region = true;
                                break;
-                       
+
                        /* Adjust brush settings */
                        /* FIXME: Step increments and modifier keys are hardcoded here! */
                        case WHEELUPMOUSE:
@@ -1790,12 +1790,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                        gso->brush->size += 3;
                                        CLAMP_MAX(gso->brush->size, 300);
                                }
-                               
+
                                redraw_region = true;
                                redraw_toolsettings = true;
                                break;
-                       
-                       case WHEELDOWNMOUSE: 
+
+                       case WHEELDOWNMOUSE:
                        case PADMINUS:
                                if (event->shift) {
                                        /* decrease strength */
@@ -1807,41 +1807,41 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
                                        gso->brush->size -= 3;
                                        CLAMP_MIN(gso->brush->size, 1);
                                }
-                               
+
                                redraw_region = true;
                                redraw_toolsettings = true;
                                break;
-                       
+
                        /* Change Frame - Allowed */
                        case LEFTARROWKEY:
                        case RIGHTARROWKEY:
                        case UPARROWKEY:
                        case DOWNARROWKEY:
                                return OPERATOR_PASS_THROUGH;
-                               
+
                        /* Camera/View Manipulations - Allowed */
                        /* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
                        case PAD0:  case PAD1:  case PAD2:  case PAD3:  case PAD4:
                        case PAD5:  case PAD6:  case PAD7:  case PAD8:  case PAD9:
                                return OPERATOR_PASS_THROUGH;
-                       
+
                        /* Unhandled event */
                        default:
                                break;
                }
        }
-       
+
        /* Redraw region? */
        if (redraw_region) {
                ARegion *ar = CTX_wm_region(C);
                ED_region_tag_redraw(ar);
        }
-       
+
        /* Redraw toolsettings (brush settings)? */
        if (redraw_toolsettings) {
                WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
        }
-       
+
        return OPERATOR_RUNNING_MODAL;
 }
 
@@ -1854,7 +1854,7 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot)
        ot->name = "Stroke Sculpt";
        ot->idname = "GPENCIL_OT_brush_paint";
        ot->description = "Apply tweaks to strokes by painting over the strokes"; // XXX
-       
+
        /* api callbacks */
        ot->exec = gpsculpt_brush_exec;
        ot->invoke = gpsculpt_brush_invoke;
@@ -1869,7 +1869,7 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot)
        PropertyRNA *prop;
        prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
        RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-       
+
        prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input",
                               "Enter a mini 'sculpt-mode' if enabled, otherwise, exit after drawing a single stroke");
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);