Weight Paint: accumulate support
authorCampbell Barton <ideasman42@gmail.com>
Fri, 29 Sep 2017 15:36:41 +0000 (01:36 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 29 Sep 2017 15:36:41 +0000 (01:36 +1000)
- Clamp accumulate so it doesn't exceed brush strength.
- Was multiplying by brush strength twice.

release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/intern/paint.c
source/blender/editors/sculpt_paint/paint_vertex.c

index 6a319b45b06b705a71a01cbfaf6aee83994333ee..d260bfe3460320322a1893acdc6331009c004d32 100644 (file)
@@ -1133,7 +1133,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
 
             col.prop(brush, "vertex_tool", text="Blend")
 
-            if brush.vertex_tool == 'BLUR':
+            if brush.vertex_tool != 'SMEAR':
                 col.prop(brush, "use_accumulate")
                 col.separator()
 
index 015fd7c8a1427f231d87d859523c460e7bab32c9..6cae8d2894775696076f707616ec20f0aa93ce36 100644 (file)
@@ -220,14 +220,14 @@ typedef struct SculptSession {
 
                        /* For non-airbrush painting to re-apply from the original (MLoop aligned). */
                        unsigned int *previous_color;
-                       unsigned int *previous_accum;
+                       float        *previous_accum;
                } vpaint;
 
                struct {
                        struct SculptVertexPaintGeomMap gmap;
 
                        /* Vertex aligned arrays of weights. */
-                       /* For non-airbrush painting to re-apply from the original. */
+                       float *previous_accum;
                        float *previous_weight;
                        /* Keep track of how much each vertex has been painted (non-airbrush only). */
                        float *alpha_weight;
index 05d53ae4771b4fa02348e34f138612d2374a5aa1..849fb5c6b5a3280ed7f46e0ffb21a9e1384ab700 100644 (file)
@@ -687,6 +687,7 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
 
                MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight);
                MEM_SAFE_FREE(ss->mode.wpaint.previous_weight);
+               MEM_SAFE_FREE(ss->mode.wpaint.previous_accum);
        }
        else {
                return;
index 33cfe7aef5e0620b2b02ecc2ddeb5326b16d5f22..7466dff408e797b60736de7741a604fc9d2bd730 100644 (file)
@@ -922,7 +922,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
                if ((ts->vpaint->flag & VP_SPRAY) == 0) {
                        if (ob->sculpt->mode.vpaint.previous_color == NULL) {
                                ob->sculpt->mode.vpaint.previous_color =
-                                       MEM_callocN(me->totloop * sizeof(uint), "previous_color");
+                                       MEM_callocN(me->totloop * sizeof(uint), __func__);
                        }
                }
                else {
@@ -932,7 +932,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
                if (brush && brush->flag & BRUSH_ACCUMULATE) {
                        if (ob->sculpt->mode.vpaint.previous_accum == NULL) {
                                ob->sculpt->mode.vpaint.previous_accum =
-                                       MEM_callocN(me->totloop * sizeof(uint), "previous_color");
+                                       MEM_callocN(me->totloop * sizeof(float), __func__);
                        }
                }
                else {
@@ -943,16 +943,24 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
                if ((ts->wpaint->flag & VP_SPRAY) == 0) {
                        if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
                                ob->sculpt->mode.wpaint.alpha_weight =
-                                       MEM_callocN(me->totvert * sizeof(float), "alpha_weight");
+                                       MEM_callocN(me->totvert * sizeof(float), __func__);
                        }
                        if (ob->sculpt->mode.wpaint.previous_weight == NULL) {
                                ob->sculpt->mode.wpaint.previous_weight =
-                                       MEM_mallocN(me->totvert * sizeof(float), "previous_weight");
+                                       MEM_mallocN(me->totvert * sizeof(float), __func__);
                        }
                }
                else {
                        MEM_SAFE_FREE(ob->sculpt->mode.wpaint.alpha_weight);
-                       MEM_SAFE_FREE(ob->sculpt->mode.wpaint.previous_weight);
+               }
+               if (brush && brush->flag & BRUSH_ACCUMULATE) {
+                       if (ob->sculpt->mode.wpaint.previous_accum == NULL) {
+                               ob->sculpt->mode.wpaint.previous_accum =
+                                       MEM_callocN(me->totvert * sizeof(float), __func__);
+                       }
+               }
+               else {
+                       MEM_SAFE_FREE(ob->sculpt->mode.wpaint.previous_accum);
                }
        }
 
@@ -1351,7 +1359,6 @@ static void get_brush_alpha_data(
        *r_brush_alpha_value =
                BKE_brush_alpha_get(scene, brush);
        *r_brush_alpha_pressure =
-               *r_brush_alpha_value *
                (BKE_brush_use_alpha_pressure(scene, brush) ? ss->cache->pressure : 1.0f);
 }
 
@@ -1410,11 +1417,17 @@ static void do_wpaint_brush_blur_task_cb_ex(
                                        const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
                                        if (view_dot > 0.0f) {
                                                const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
-                                               const float final_alpha =
+                                               float final_alpha =
                                                        view_dot * brush_fade * brush_strength *
                                                        grid_alpha * brush_alpha_pressure;
-                                               weight_final /= total_hit_loops;
 
+                                               if (brush->flag & BRUSH_ACCUMULATE) {
+                                                       float mask_accum = ss->mode.wpaint.previous_accum[v_index];
+                                                       final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
+                                                       ss->mode.wpaint.previous_accum[v_index] = final_alpha;
+                                               }
+
+                                               weight_final /= total_hit_loops;
                                                /* Only paint visable verts */
                                                do_weight_paint_vertex(
                                                        data->vp, data->ob, data->wpi,
@@ -1559,6 +1572,12 @@ static void do_wpaint_brush_draw_task_cb_ex(
                                        const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
                                        float final_alpha = view_dot * brush_fade * brush_strength * grid_alpha * brush_alpha_pressure;
 
+                                       if (brush->flag & BRUSH_ACCUMULATE) {
+                                               float mask_accum = ss->mode.wpaint.previous_accum[v_index];
+                                               final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
+                                               ss->mode.wpaint.previous_accum[v_index] = final_alpha;
+                                       }
+
                                        /* Non-spray logic. */
                                        if ((data->vp->flag & VP_SPRAY) == 0) {
                                                /* Only paint if we have greater alpha. */
@@ -2329,7 +2348,7 @@ static void do_vpaint_brush_draw_task_cb_ex(
 
                                                        if (brush->flag & BRUSH_ACCUMULATE) {
                                                                float mask_accum = ss->mode.vpaint.previous_accum[l_index];
-                                                               final_alpha = min_ff(final_alpha + mask_accum, 255.0f);
+                                                               final_alpha = min_ff(final_alpha + mask_accum, 255.0f * brush_strength);
                                                                ss->mode.vpaint.previous_accum[l_index] = final_alpha;
                                                        }