diff options
author | Antonioya <blendergit@gmail.com> | 2018-08-30 12:11:10 +0300 |
---|---|---|
committer | Antonioya <blendergit@gmail.com> | 2018-08-30 12:11:47 +0300 |
commit | f2d8241b23bdf118336b94d54146bac41b791580 (patch) | |
tree | bfd23494a303117c9b3d29f37932f0829e88b7c3 /source/blender | |
parent | 0845b1c8c8da818607fcff0a1bdb2114a0cb9729 (diff) |
GP: Add weights while drawing strokes
Now it's possible to add the weight of the current selected vertex group to any new stroke created.
This is very handy when add drawings after the weight paint was done and it will be required with Armatures.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_fill.c | 77 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_paint.c | 209 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_primitive.c | 53 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 7 |
5 files changed, 229 insertions, 121 deletions
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 09a21cbca1e..2ff7e45d7a2 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -23,9 +23,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/gpencil/gpencil_fill.c - * \ingroup edgpencil - */ + /** \file blender/editors/gpencil/gpencil_fill.c + * \ingroup edgpencil + */ #include <stdio.h> @@ -47,6 +47,7 @@ #include "BKE_main.h" #include "BKE_brush.h" +#include "BKE_deform.h" #include "BKE_image.h" #include "BKE_gpencil.h" #include "BKE_material.h" @@ -84,7 +85,7 @@ #define LEAK_VERT 1 -/* Temporary fill operation data (op->customdata) */ + /* Temporary fill operation data (op->customdata) */ typedef struct tGPDfill { struct Main *bmain; struct Depsgraph *depsgraph; @@ -124,10 +125,10 @@ typedef struct tGPDfill { } tGPDfill; - /* draw a given stroke using same thickness and color for all points */ +/* draw a given stroke using same thickness and color for all points */ static void gp_draw_basic_stroke( - tGPDfill *tgpf, bGPDstroke *gps, const float diff_mat[4][4], - bool cyclic, float ink[4], int flag, float thershold) + tGPDfill *tgpf, bGPDstroke *gps, const float diff_mat[4][4], + bool cyclic, float ink[4], int flag, float thershold) { bGPDspoint *points = gps->points; @@ -247,7 +248,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) /* normal strokes */ if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { ED_gp_draw_fill(&tgpw); @@ -255,7 +256,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) /* 3D Lines with basic shapes and invisible lines */ if ((tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { gp_draw_basic_stroke(tgpf, gps, tgpw.diff_mat, gps->flag & GP_STROKE_CYCLIC, ink, tgpf->flag, tgpf->fill_threshold); @@ -266,7 +267,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) glDisable(GL_BLEND); } - /* draw strokes in offscreen buffer */ +/* draw strokes in offscreen buffer */ static void gp_render_offscreen(tGPDfill *tgpf) { bool is_ortho = false; @@ -298,8 +299,8 @@ static void gp_render_offscreen(tGPDfill *tgpf) int bwiny = tgpf->ar->winy; rcti brect = tgpf->ar->winrct; - tgpf->ar->winx = (short) tgpf->sizex; - tgpf->ar->winy = (short) tgpf->sizey; + tgpf->ar->winx = (short)tgpf->sizex; + tgpf->ar->winy = (short)tgpf->sizey; tgpf->ar->winrct.xmin = 0; tgpf->ar->winrct.ymin = 0; tgpf->ar->winrct.xmax = tgpf->sizex; @@ -314,8 +315,8 @@ static void gp_render_offscreen(tGPDfill *tgpf) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ED_view3d_update_viewmat( - tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, - NULL, winmat, NULL); + tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, + NULL, winmat, NULL); /* set for opengl */ GPU_matrix_projection_set(tgpf->rv3d->winmat); GPU_matrix_set(tgpf->rv3d->viewmat); @@ -419,7 +420,7 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index if (pt <= maxpixel) { get_pixel(ibuf, pt, rgba); if (rgba[0] == 1.0f) { - t_a = true; + t_a = true; break; } } @@ -675,7 +676,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf) int cur_back_offset = -1; for (int i = 0; i < NEIGHBOR_COUNT; i++) { if (backtracked_offset[0][0] == offset[i][0] && - backtracked_offset[0][1] == offset[i][1]) + backtracked_offset[0][1] == offset[i][1]) { /* Finding the bracktracked pixel offset index */ cur_back_offset = i; @@ -709,7 +710,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf) } /* current pixel is equal to starting pixel */ if (boundary_co[0] == start_co[0] && - boundary_co[1] == start_co[1]) + boundary_co[1] == start_co[1]) { BLI_stack_pop(tgpf->stack, &v); // boundary_found = true; @@ -757,9 +758,9 @@ static void gpencil_get_depth_array(tGPDfill *tgpf) copy_v2_v2_int(mval, &ptc->x); if ((ED_view3d_autodist_depth( - tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) && - (i && (ED_view3d_autodist_depth_seg( - tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) + tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) && + (i && (ED_view3d_autodist_depth_seg( + tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) { interp_depth = true; } @@ -822,7 +823,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) } bGPDspoint *pt; - MDeformVert *dvert; + MDeformVert *dvert = NULL; tGPspoint *point2D; if (tgpf->sbuffer_size == 0) { @@ -867,25 +868,43 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) /* add points */ pt = gps->points; - dvert = gps->dvert; point2D = (tGPspoint *)tgpf->sbuffer; + + const int def_nr = tgpf->ob->actdef - 1; + const bool have_weight = (bool)BLI_findlink(&tgpf->ob->defbase, def_nr); + + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + dvert = gps->dvert; + } + for (int i = 0; i < tgpf->sbuffer_size && point2D; i++, point2D++, pt++) { /* convert screen-coordinates to 3D coordinates */ gp_stroke_convertcoords_tpoint( - tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob, - tgpf->gpl, point2D, - tgpf->depth_arr ? tgpf->depth_arr + i : NULL, - &pt->x); + tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob, + tgpf->gpl, point2D, + tgpf->depth_arr ? tgpf->depth_arr + i : NULL, + &pt->x); pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = 0.0f; - if (gps->dvert != NULL) { - dvert->totweight = 0; - dvert->dw = NULL; + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + MDeformWeight *dw = defvert_verify_index(dvert, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + dvert++; } + else { + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + dvert++; + } + } } /* smooth stroke */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index ef70608d99c..9822f4a1029 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -23,9 +23,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/gpencil/gpencil_paint.c - * \ingroup edgpencil - */ + /** \file blender/editors/gpencil/gpencil_paint.c + * \ingroup edgpencil + */ #include <stdio.h> @@ -59,6 +59,7 @@ #include "BKE_brush.h" #include "BKE_paint.h" #include "BKE_context.h" +#include "BKE_deform.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_report.h" @@ -92,10 +93,10 @@ #include "gpencil_intern.h" -/* ******************************************* */ -/* 'Globals' and Defines */ + /* ******************************************* */ + /* 'Globals' and Defines */ -/* values for tGPsdata->status */ + /* values for tGPsdata->status */ typedef enum eGPencil_PaintStatus { GP_STATUS_IDLING = 0, /* stroke isn't in progress yet */ GP_STATUS_PAINTING, /* a stroke is in progress */ @@ -170,7 +171,7 @@ typedef struct tGPsdata { double ocurtime; /* Used when converting to path */ float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space - * to region space */ + * to region space */ float mat[4][4]; float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */ @@ -552,7 +553,7 @@ static void gp_smooth_buffer(tGPsdata *p, float inf, int idx) /* add current stroke-point to buffer (returns whether point was successfully added) */ static short gp_stroke_addpoint( - tGPsdata *p, const int mval[2], float pressure, double curtime) + tGPsdata *p, const int mval[2], float pressure, double curtime) { bGPdata *gpd = p->gpd; Brush *brush = p->brush; @@ -560,9 +561,11 @@ static short gp_stroke_addpoint( ToolSettings *ts = p->scene->toolsettings; Object *obact = (Object *)p->ownerPtr.data; Depsgraph *depsgraph = p->depsgraph; \ - RegionView3D *rv3d = p->ar->regiondata; + RegionView3D *rv3d = p->ar->regiondata; View3D *v3d = p->sa->spacedata.first; MaterialGPencilStyle *gp_style = p->material->gp_style; + const int def_nr = obact->actdef - 1; + const bool have_weight = (bool)BLI_findlink(&obact->defbase, def_nr); /* check painting mode */ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { @@ -631,7 +634,7 @@ static short gp_stroke_addpoint( } /* apply randomness to pressure */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_random_press > 0.0f)) + (brush->gpencil_settings->draw_random_press > 0.0f)) { float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure); float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity; @@ -660,7 +663,7 @@ static short gp_stroke_addpoint( /* apply angle of stroke to brush size */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_angle_factor > 0.0f)) + (brush->gpencil_settings->draw_angle_factor > 0.0f)) { gp_brush_angle(gpd, brush, pt, mval); } @@ -679,7 +682,7 @@ static short gp_stroke_addpoint( /* apply randomness to color strength */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_random_strength > 0.0f)) + (brush->gpencil_settings->draw_random_strength > 0.0f)) { if (BLI_rng_get_float(p->rng) > 0.5f) { pt->strength -= pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng); @@ -785,7 +788,7 @@ static short gp_stroke_addpoint( if (gpencil_project_check(p)) { view3d_region_operator_needs_opengl(p->win, p->ar); ED_view3d_autodist_init( - p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); } /* convert screen-coordinates to appropriate coordinates (and store them) */ @@ -801,9 +804,18 @@ static short gp_stroke_addpoint( pts->uv_fac = pt->uv_fac; pts->uv_rot = pt->uv_rot; - if (dvert != NULL) { - dvert->totweight = 0; - dvert->dw = NULL; + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + MDeformWeight *dw = defvert_verify_index(dvert, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + } + else { + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + } } /* force fill recalc */ @@ -854,9 +866,9 @@ static void gp_stroke_simplify(tGPsdata *p) gp_session_validatebuffer(p); gpd->runtime.sbuffer_sflag = flag; -/* macro used in loop to get position of new point - * - used due to the mixture of datatypes in use here - */ + /* macro used in loop to get position of new point + * - used due to the mixture of datatypes in use here + */ #define GP_SIMPLIFY_AVPOINT(offs, sfac) \ { \ co[0] += (float)(old_points[offs].x * sfac); \ @@ -865,7 +877,7 @@ static void gp_stroke_simplify(tGPsdata *p) time += old_points[offs].time * sfac; \ } (void)0 - /* XXX Here too, do not lose start and end points! */ + /* XXX Here too, do not lose start and end points! */ gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); for (i = 0, j = 0; i < num_points; i++) { if (i - j == 3) { @@ -895,7 +907,7 @@ static void gp_stroke_simplify(tGPsdata *p) } } gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure, - p->inittime + (double)old_points[num_points - 1].time); + p->inittime + (double)old_points[num_points - 1].time); /* free old buffer */ MEM_freeN(old_points); @@ -914,6 +926,8 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) ToolSettings *ts = p->scene->toolsettings; Depsgraph *depsgraph = p->depsgraph; Object *obact = (Object *)p->ownerPtr.data; + const int def_nr = obact->actdef - 1; + const bool have_weight = (bool)BLI_findlink(&obact->defbase, def_nr); int i, totelem; /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */ @@ -992,12 +1006,21 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) pt->time = ptc->time; pt++; - if (dvert != NULL) { - dvert->totweight = 0; - dvert->dw = NULL; - + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + MDeformWeight *dw = defvert_verify_index(dvert, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } dvert++; } + else { + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + dvert++; + } + } } if (totelem == 2) { @@ -1012,9 +1035,18 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; - if (dvert != NULL) { - dvert->totweight = 0; - dvert->dw = NULL; + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + MDeformWeight *dw = defvert_verify_index(dvert, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + } + else { + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + } } } @@ -1042,10 +1074,20 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; - if (dvert != NULL) { - dvert->totweight = 0; - dvert->dw = NULL; + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + MDeformWeight *dw = defvert_verify_index(dvert, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + } + else { + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + } } + } else { float *depth_arr = NULL; @@ -1062,7 +1104,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) copy_v2_v2_int(mval, &ptc->x); if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) && - (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0))) + (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0))) { interp_depth = true; } @@ -1110,6 +1152,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } pt = gps->points; + dvert = gps->dvert; /* convert all points (normal behavior) */ for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && ptc; i++, ptc++, pt++) { @@ -1123,6 +1166,12 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) pt->time = ptc->time; pt->uv_fac = ptc->uv_fac; pt->uv_rot = ptc->uv_rot; + + if (dvert != NULL) { + dvert->totweight = 0; + dvert->dw = NULL; + dvert++; + } } /* subdivide and smooth the stroke */ @@ -1131,7 +1180,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } /* apply randomness to stroke */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_random_sub > 0.0f)) + (brush->gpencil_settings->draw_random_sub > 0.0f)) { gp_randomize_stroke(gps, brush, p->rng); } @@ -1141,7 +1190,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) * the original stroke */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && - (brush->gpencil_settings->draw_smoothfac > 0.0f)) + (brush->gpencil_settings->draw_smoothfac > 0.0f)) { float reduce = 0.0f; for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) { @@ -1154,7 +1203,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } /* smooth thickness */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && - (brush->gpencil_settings->thick_smoothfac > 0.0f)) + (brush->gpencil_settings->thick_smoothfac > 0.0f)) { for (int r = 0; r < brush->gpencil_settings->thick_smoothlvl * 2; r++) { for (i = 0; i < gps->totpoints; i++) { @@ -1188,6 +1237,18 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) else { BLI_addtail(&p->gpf->strokes, gps); } + /* add weights */ + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + for (i = 0; i < gps->totpoints; i++) { + MDeformVert *ve = &gps->dvert[i]; + MDeformWeight *dw = defvert_verify_index(ve, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + } + } + gp_stroke_added_enable(p); } @@ -1210,7 +1271,7 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons Object *obact = (Object *)p->ownerPtr.data; if ((p->sa->spacetype == SPACE_VIEW3D) && - (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) + (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) { RegionView3D *rv3d = p->ar->regiondata; bGPDlayer *gpl = p->gpl; @@ -1227,7 +1288,7 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons const float depth_mval = view3d_point_depth(rv3d, mval_3d); mul_v3_m4v3(fpt, diff_mat, &pt->x); - const float depth_pt = view3d_point_depth(rv3d, fpt); + const float depth_pt = view3d_point_depth(rv3d, fpt); if (depth_pt > depth_mval) { return true; @@ -1275,9 +1336,9 @@ static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps) /* eraser tool - evaluation per stroke */ /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ static void gp_stroke_eraser_dostroke(tGPsdata *p, - bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, - const int mval[2], const int mvalo[2], - const int radius, const rcti *rect) + bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, + const int mval[2], const int mvalo[2], + const int radius, const rcti *rect) { Depsgraph *depsgraph = p->depsgraph; Object *obact = (Object *)p->ownerPtr.data; @@ -1339,7 +1400,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* Pressure threshold at which stroke should be culled: Calculated as pressure value * below which we would have invisible strokes */ - const float cull_thresh = (gps->thickness) ? 1.0f / ((float)gps->thickness) : 1.0f; + const float cull_thresh = (gps->thickness) ? 1.0f / ((float)gps->thickness) : 1.0f; /* Amount to decrease the pressure of each point with each stroke */ // TODO: Fetch from toolsettings, or compute based on thickness instead? @@ -1382,7 +1443,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* Check that point segment of the boundbox of the eraser stroke */ if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) || - ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) + ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) { /* Check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) @@ -1390,7 +1451,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, */ if (gp_stroke_inside_circle(mval, mvalo, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) || - (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) + (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) { /* Point is affected: */ /* 1) Adjust thickness @@ -1402,13 +1463,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* 2) Tag any point with overly low influence for removal in the next pass */ if ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || - (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) { pt1->flag |= GP_SPOINT_TAG; do_cull = true; } if ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || - (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) { pt2->flag |= GP_SPOINT_TAG; do_cull = true; @@ -1521,7 +1582,7 @@ static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts) Brush *brush_old = paint->brush; for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) { if ((brush->ob_mode == OB_MODE_GPENCIL_PAINT) && - (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { /* save first eraser to use later if no default */ if (brush_dft == NULL) { @@ -1893,7 +1954,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps if (has_layer_to_erase == false) { p->status = GP_STATUS_ERROR; //if (G.debug & G_DEBUG) - printf("Error: Eraser will not be affecting anything (gpencil_paint_init)\n"); + printf("Error: Eraser will not be affecting anything (gpencil_paint_init)\n"); return; } } @@ -2072,9 +2133,9 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) immUniform1f("dash_factor", 0.5f); imm_draw_circle_wire_2d(shdr_pos, x, y, p->radius, - /* XXX Dashed shader gives bad results with sets of small segments currently, - * temp hack around the issue. :( */ - max_ii(8, p->radius / 2)); /* was fixed 40 */ + /* XXX Dashed shader gives bad results with sets of small segments currently, + * temp hack around the issue. :( */ + max_ii(8, p->radius / 2)); /* was fixed 40 */ immUnbindProgram(); @@ -2095,9 +2156,9 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en ED_gpencil_toggle_brush_cursor(p->C, false, NULL); /* enable cursor */ p->erasercursor = WM_paint_cursor_activate( - CTX_wm_manager(C), - NULL, /* XXX */ - gpencil_draw_eraser, p); + CTX_wm_manager(C), + NULL, /* XXX */ + gpencil_draw_eraser, p); } } @@ -2227,7 +2288,7 @@ static void gpencil_draw_cursor_set(tGPsdata *p) { Brush *brush = p->brush; if ((p->paintmode == GP_PAINTMODE_ERASER) || - (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */ } @@ -2247,10 +2308,10 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) case GP_PAINTMODE_DRAW_POLY: /* Provide usage tips, since this is modal, and unintuitive without hints */ ED_workspace_status_text( - C, IFACE_( - "Annotation Create Poly: LMB click to place next stroke vertex | " - "ESC/Enter to end (or click outside this area)" - )); + C, IFACE_( + "Annotation Create Poly: LMB click to place next stroke vertex | " + "ESC/Enter to end (or click outside this area)" + )); break; default: /* Do nothing - the others are self explanatory, exit quickly once the mouse is released @@ -2265,18 +2326,18 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) switch (p->paintmode) { case GP_PAINTMODE_ERASER: ED_workspace_status_text(C, IFACE_("Grease Pencil Erase Session: Hold and drag LMB or RMB to erase | " - "ESC/Enter to end (or click outside this area)")); + "ESC/Enter to end (or click outside this area)")); break; case GP_PAINTMODE_DRAW_STRAIGHT: ED_workspace_status_text(C, IFACE_("Grease Pencil Line Session: Hold and drag LMB to draw | " - "ESC/Enter to end (or click outside this area)")); + "ESC/Enter to end (or click outside this area)")); break; case GP_PAINTMODE_DRAW: ED_workspace_status_text(C, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw")); break; case GP_PAINTMODE_DRAW_POLY: ED_workspace_status_text(C, IFACE_("Grease Pencil Poly Session: LMB click to place next stroke vertex | " - "Release Shift/ESC/Enter to end (or click outside this area)")); + "Release Shift/ESC/Enter to end (or click outside this area)")); break; default: /* unhandled future cases */ @@ -2370,7 +2431,7 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra } } else if ((p->brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) && - (gpd->runtime.sbuffer_size > 0)) + (gpd->runtime.sbuffer_size > 0)) { pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1; if (p->paintmode != GP_PAINTMODE_ERASER) { @@ -2533,7 +2594,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) /* loop over the stroke RNA elements recorded (i.e. progress of mouse movement), * setting the relevant values in context at each step, then applying */ - RNA_BEGIN (op->ptr, itemptr, "stroke") + RNA_BEGIN(op->ptr, itemptr, "stroke") { float mousef[2]; @@ -2613,9 +2674,9 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event /* TODO: set any additional settings that we can take from the events? * TODO? if tablet is erasing, force eraser to be on? */ - /* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway... */ + /* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway... */ - /* if eraser is on, draw radial aid */ + /* if eraser is on, draw radial aid */ if (p->paintmode == GP_PAINTMODE_ERASER) { gpencil_draw_toggle_eraser_cursor(C, p, true); } @@ -2801,7 +2862,7 @@ static void gpencil_add_missing_events(bContext *C, wmOperator *op, const wmEven sub_v2_v2v2(pt, b, pt); /* create fake event */ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), - (int)pt[0], (int)pt[1]); + (int)pt[0], (int)pt[1]); } else if (dist >= factor) { int slices = 2 + (int)((dist - 1.0) / factor); @@ -2811,7 +2872,7 @@ static void gpencil_add_missing_events(bContext *C, wmOperator *op, const wmEven sub_v2_v2v2(pt, b, pt); /* create fake event */ gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), - (int)pt[0], (int)pt[1]); + (int)pt[0], (int)pt[1]); } } } @@ -2859,7 +2920,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) else if ((event->type == BKEY) && (event->val == KM_RELEASE)) { /* Add Blank Frame * - Since this operator is non-modal, we can just call it here, and keep going... - * - This operator is especially useful when animating + * - This operator is especially useful when animating */ WM_operator_name_call(C, "GPENCIL_OT_blank_frame_add", WM_OP_EXEC_DEFAULT, NULL); estate = OPERATOR_RUNNING_MODAL; @@ -2874,9 +2935,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) /* exit painting mode (and/or end current stroke) * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647] */ - /* if polyline and release shift must cancel */ + /* if polyline and release shift must cancel */ if ((ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) || - ((p->paintmode == GP_PAINTMODE_DRAW_POLY) && (event->shift == 0))) + ((p->paintmode == GP_PAINTMODE_DRAW_POLY) && (event->shift == 0))) { /* exit() ends the current stroke before cleaning up */ /* printf("\t\tGP - end of paint op + end of stroke\n"); */ @@ -3033,7 +3094,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) * NOTE: Don't enter this case if an error occurred while finding the * region (as above) */ - /* if drawing polygon and enable on back, must move stroke */ + /* if drawing polygon and enable on back, must move stroke */ if (ts) { if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) && (p->paintmode == GP_PAINTMODE_DRAW_POLY)) { if (p->flags & GP_PAINTFLAG_STROKEADDED) { @@ -3074,12 +3135,12 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* eraser size */ else if ((p->paintmode == GP_PAINTMODE_ERASER) && - ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, PADPLUSKEY, PADMINUS)) + ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, PADPLUSKEY, PADMINUS)) { /* just resize the brush (local version) * TODO: fix the hardcoded size jumps (set to make a visible difference) and hardcoded keys */ - /* printf("\t\tGP - resize eraser\n"); */ + /* printf("\t\tGP - resize eraser\n"); */ switch (event->type) { case WHEELDOWNMOUSE: /* larger */ case PADPLUSKEY: @@ -3135,7 +3196,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) /* event doesn't need to be handled */ #if 0 printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", - event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); + event->type, event->type == MIDDLEMOUSE, event->type == MOUSEMOVE); #endif break; } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 6fa7d0b7a81..570825d0106 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -25,9 +25,9 @@ * Operators for creating new Grease Pencil primitives (boxes, circles, ...) */ -/** \file blender/editors/gpencil/gpencil_primitive.c - * \ingroup edgpencil - */ + /** \file blender/editors/gpencil/gpencil_primitive.c + * \ingroup edgpencil + */ #include <stdio.h> @@ -56,6 +56,7 @@ #include "BKE_main.h" #include "BKE_brush.h" #include "BKE_context.h" +#include "BKE_deform.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_library.h" @@ -89,10 +90,10 @@ #define IDLE 0 #define IN_PROGRESS 1 -/* ************************************************ */ -/* Core/Shared Utilities */ + /* ************************************************ */ + /* Core/Shared Utilities */ -/* Poll callback for primitive operators */ + /* Poll callback for primitive operators */ static bool gpencil_primitive_add_poll(bContext *C) { /* only 3D view */ @@ -230,26 +231,26 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi else { if (tgpi->flag == IN_PROGRESS) { BLI_snprintf( - status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges, - tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); } else { BLI_snprintf( - status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges, - tgpi->bottom[0], tgpi->bottom[1]); + status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->bottom[0], tgpi->bottom[1]); } } } else { if (tgpi->flag == IN_PROGRESS) { BLI_snprintf( - status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str, - tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); } else { BLI_snprintf( - status_str, sizeof(status_str), "%s: (%d, %d)", msg_str, - tgpi->bottom[0], tgpi->bottom[1]); + status_str, sizeof(status_str), "%s: (%d, %d)", msg_str, + tgpi->bottom[0], tgpi->bottom[1]); } } ED_workspace_status_text(C, status_str); @@ -367,12 +368,12 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) bGPDspoint *tpt = gps->points; float origin[3]; ED_gp_get_drawing_reference(tgpi->v3d, tgpi->scene, tgpi->ob, tgpi->gpl, - ts->gpencil_v3d_align, origin); + ts->gpencil_v3d_align, origin); for (int i = 0; i < gps->totpoints; i++, tpt++) { ED_gp_project_point_to_plane(tgpi->ob, tgpi->rv3d, origin, - ts->gp_sculpt.lock_axis - 1, - tpt); + ts->gp_sculpt.lock_axis - 1, + tpt); } } @@ -531,6 +532,11 @@ static void gpencil_primitive_done(bContext *C, wmOperator *op, wmWindow *win, t bGPDframe *gpf; bGPDstroke *gps; + ToolSettings *ts = tgpi->scene->toolsettings; + + const int def_nr = tgpi->ob->actdef - 1; + const bool have_weight = (bool)BLI_findlink(&tgpi->ob->defbase, def_nr); + /* return to normal cursor and header status */ ED_workspace_status_text(C, NULL); WM_cursor_modal_restore(win); @@ -549,6 +555,19 @@ static void gpencil_primitive_done(bContext *C, wmOperator *op, wmWindow *win, t BLI_movelisttolist(&gpf->strokes, &tgpi->gpf->strokes); BLI_assert(BLI_listbase_is_empty(&tgpi->gpf->strokes)); + /* add weights if required */ + if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) { + BKE_gpencil_dvert_ensure(gps); + for (int i = 0; i < gps->totpoints; i++) { + MDeformVert *ve = &gps->dvert[i]; + MDeformWeight *dw = defvert_verify_index(ve, def_nr); + if (dw) { + dw->weight = ts->vgroup_weight; + } + + } + } + /* clean up temp data */ gpencil_primitive_exit(C, op); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index ed8e71e86f2..1429e7ce238 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2068,7 +2068,9 @@ typedef enum eGPencil_Flags { /* Add the strokes below all strokes in the layer */ GP_TOOL_FLAG_PAINT_ONBACK = (1 << 2), /* Show compact list of colors */ - GP_TOOL_FLAG_THUMBNAIL_LIST = (1 << 3), + GP_TOOL_FLAG_THUMBNAIL_LIST = (1 << 3), + /* Generate wheight data for new strokes */ + GP_TOOL_FLAG_CREATE_WEIGHTS = (1 << 4), } eGPencil_Flags; /* scene->r.simplify_gpencil */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 356ffe6a17b..84910b6b1b3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2451,6 +2451,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) "Show compact list of color instead of thumbnails"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "add_gpencil_weight_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_CREATE_WEIGHTS); + RNA_def_property_ui_text(prop, "Add weight data for new strokes", + "When creating new strokes, the weight data is added according to the current vertex group and weight, " + "if no vertex group selected, weight is not added"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "gpencil_sculpt", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gp_sculpt"); RNA_def_property_struct_type(prop, "GPencilSculptSettings"); |