diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-03-22 14:14:26 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-03-22 14:37:30 +0300 |
commit | 220a7a4fb1f2529655be545274f279b1588fad67 (patch) | |
tree | bdcbbd8870db26178e8928a5a9082b10c097cfa0 | |
parent | 29acdb48899a25c32726ee8411088d8086a5cdb4 (diff) |
Weight Paint: blur now smooths connected weights
Previously it would average all points under the brush, giving an off feedback loop that often depended on the
direction of the brush stroke, giving not-very-useful smearing effect.
Now blend brush smooths between connected edges.
-rw-r--r-- | source/blender/blenloader/intern/versioning_defaults.c | 6 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 90 |
2 files changed, 54 insertions, 42 deletions
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index be7bca4280b..ad7a3c5b9c4 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -250,6 +250,12 @@ void BLO_update_defaults_startup_blend(Main *bmain) if (br) { br->flag |= BRUSH_ORIGINAL_NORMAL; } + + /* increase strength, better for smoothing method */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Blur"); + if (br) { + br->alpha = 1.0f; + } } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index f245685abbd..362427cb1c5 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1844,6 +1844,12 @@ struct WPaintData { int defbase_tot_sel; /* number of selected groups */ bool do_multipaint; /* true if multipaint enabled and multiple groups selected */ + /* variables for blur */ + struct { + MeshElemMap *vmap; + int *vmap_mem; + } blur_data; + int defbase_tot; }; @@ -1935,6 +1941,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN struct WPaintVGroupIndex vgroup_index; int defbase_tot, defbase_tot_sel; bool *defbase_sel; + const Brush *brush = BKE_paint_brush(&wp->paint); float mat[4][4], imat[4][4]; @@ -2039,6 +2046,12 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN wpd->indexar = get_indexarray(me); copy_wpaint_prev(wp, me->dvert, me->totvert); + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { + BKE_mesh_vert_edge_vert_map_create( + &wpd->blur_data.vmap, &wpd->blur_data.vmap_mem, + me->medge, me->totvert, me->totedge); + } + /* imat for normals */ mul_m4_m4m4(mat, wpd->vc.rv3d->viewmat, ob->obmat); invert_m4_m4(imat, mat); @@ -2060,6 +2073,26 @@ static float wpaint_blur_weight_multi(MDeformVert *dv, WeightPaintInfo *wpi) return weight; } +static float wpaint_blur_weight_calc_from_connected( + VPaint *wp, WeightPaintInfo *wpi, struct WPaintData *wpd, const unsigned int vidx, + float (*blur_weight_func)(MDeformVert *, WeightPaintInfo *)) +{ + const MeshElemMap *map = &wpd->blur_data.vmap[vidx]; + float paintweight; + if (map->count != 0) { + paintweight = 0.0f; + for (int j = 0; j < map->count; j++) { + paintweight += blur_weight_func(&wp->wpaint_prev[map->indices[j]], wpi); + } + paintweight /= map->count; + } + else { + paintweight = blur_weight_func(&wp->wpaint_prev[vidx], wpi); + } + + return paintweight; +} + static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) { Scene *scene = CTX_data_scene(C); @@ -2073,10 +2106,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P float mat[4][4]; float paintweight; int *indexar; - float totw; unsigned int index, totindex; - float alpha; float mval[2]; + const bool use_blur = (brush->vertexpaint_tool == PAINT_BLEND_BLUR); bool use_vert_sel; bool use_face_sel; bool use_depth; @@ -2174,24 +2206,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* make sure each vertex gets treated only once */ /* and calculate filter weight */ - totw = 0.0f; - if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) - paintweight = 0.0f; - else - paintweight = BKE_brush_weight_get(scene, brush); - -#define WP_BLUR_ACCUM(v_idx_var) \ - { \ - const unsigned int vidx = v_idx_var; \ - const float fac = calc_vp_strength_col_dl( \ - wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure, NULL); \ - if (fac > 0.0f) { \ - float weight = blur_weight_func(&me->dvert[vidx], &wpi); \ - paintweight += weight * fac; \ - totw += fac; \ - } \ - } (void)0 - + paintweight = BKE_brush_weight_get(scene, brush); if (use_depth) { for (index = 0; index < totindex; index++) { @@ -2210,13 +2225,6 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P me->dvert[ml->v].flag = 1; } } - - if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { - ml = me->mloop + mpoly->loopstart; - for (i = 0; i < mpoly->totloop; i++, ml++) { - WP_BLUR_ACCUM(ml->v); - } - } } } } @@ -2235,28 +2243,19 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P me->dvert[i].flag = SELECT; } } - - if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { - for (i = 0; i < totvert; i++) { - WP_BLUR_ACCUM(i); - } - } - } - -#undef WP_BLUR_ACCUM - - - if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { - paintweight /= totw; } #define WP_PAINT(v_idx_var) \ { \ unsigned int vidx = v_idx_var; \ if (me->dvert[vidx].flag) { \ - alpha = calc_vp_alpha_col_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \ - mval, brush_size_pressure, brush_alpha_pressure, NULL); \ + const float alpha = calc_vp_alpha_col_dl( \ + wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \ + mval, brush_size_pressure, brush_alpha_pressure, NULL); \ if (alpha) { \ + if (use_blur) { \ + paintweight = wpaint_blur_weight_calc_from_connected(wp, &wpi, wpd, vidx, blur_weight_func); \ + } \ do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \ } \ me->dvert[vidx].flag = 0; \ @@ -2324,6 +2323,13 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) if (wpd->mirror.lock) MEM_freeN((void *)wpd->mirror.lock); + if (wpd->blur_data.vmap) { + MEM_freeN(wpd->blur_data.vmap); + } + if (wpd->blur_data.vmap_mem) { + MEM_freeN(wpd->blur_data.vmap_mem); + } + MEM_freeN(wpd); } |