Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / sculpt_paint / paint_vertex.c
index a496c4c..53b7356 100644 (file)
@@ -54,8 +54,9 @@
 
 #include "BKE_brush.h"
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
 #include "BKE_deform.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_object_deform.h"
 #include "BKE_report.h"
 #include "BKE_subsurf.h"
 
+#include "DEG_depsgraph.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
 
 #include "ED_object.h"
 #include "ED_mesh.h"
@@ -203,7 +208,7 @@ int vertex_paint_mode_poll(bContext *C)
        return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly;
 }
 
-int vertex_paint_poll(bContext *C)
+static int vertex_paint_poll_ex(bContext *C, bool check_tool)
 {
        if (vertex_paint_mode_poll(C) &&
            BKE_paint_brush(&CTX_data_tool_settings(C)->vpaint->paint))
@@ -211,13 +216,26 @@ int vertex_paint_poll(bContext *C)
                ScrArea *sa = CTX_wm_area(C);
                if (sa && sa->spacetype == SPACE_VIEW3D) {
                        ARegion *ar = CTX_wm_region(C);
-                       if (ar->regiontype == RGN_TYPE_WINDOW)
-                               return 1;
+                       if (ar->regiontype == RGN_TYPE_WINDOW) {
+                               if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
+                                       return 1;
+                               }
+                       }
                }
        }
        return 0;
 }
 
+int vertex_paint_poll(bContext *C)
+{
+       return vertex_paint_poll_ex(C, true);
+}
+
+int vertex_paint_poll_ignore_tool(bContext *C)
+{
+       return vertex_paint_poll_ex(C, true);
+}
+
 int weight_paint_mode_poll(bContext *C)
 {
        Object *ob = CTX_data_active_object(C);
@@ -225,7 +243,7 @@ int weight_paint_mode_poll(bContext *C)
        return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly;
 }
 
-int weight_paint_poll(bContext *C)
+static int weight_paint_poll_ex(bContext *C, bool check_tool)
 {
        Object *ob = CTX_data_active_object(C);
        ScrArea *sa;
@@ -238,12 +256,24 @@ int weight_paint_poll(bContext *C)
        {
                ARegion *ar = CTX_wm_region(C);
                if (ar->regiontype == RGN_TYPE_WINDOW) {
-                       return 1;
+                       if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
+                               return 1;
+                       }
                }
        }
        return 0;
 }
 
+int weight_paint_poll(bContext *C)
+{
+       return weight_paint_poll_ex(C, true);
+}
+
+int weight_paint_poll_ignore_tool(bContext *C)
+{
+       return weight_paint_poll_ex(C, false);
+}
+
 static VPaint *new_vpaint(void)
 {
        VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
@@ -937,14 +967,14 @@ static void do_weight_paint_vertex(
 
 
 /* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */
-static void vertex_paint_init_session(Scene *scene, Object *ob)
+static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
 {
        /* Create persistent sculpt mode data */
        BKE_sculpt_toolsettings_data_ensure(scene);
 
        if (ob->sculpt == NULL) {
                ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
-               BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
+               BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, 0, false);
        }
 }
 
@@ -1031,8 +1061,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
  * \{ */
 
 static void ed_vwpaintmode_enter_generic(
-        wmWindowManager *wm,
-        Scene *scene,
+        Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene,
         Object *ob, const eObjectMode mode_flag)
 {
        ob->mode |= mode_flag;
@@ -1078,37 +1107,39 @@ static void ed_vwpaintmode_enter_generic(
                BKE_sculptsession_free(ob);
        }
 
-       vertex_paint_init_session(scene, ob);
+       vertex_paint_init_session(depsgraph, scene, ob);
 }
 
 void ED_object_vpaintmode_enter_ex(
-        wmWindowManager *wm,
+        Depsgraph *depsgraph, wmWindowManager *wm,
         Scene *scene, Object *ob)
 {
        ed_vwpaintmode_enter_generic(
-               wm, scene, ob, OB_MODE_VERTEX_PAINT);
+               depsgraph, wm, scene, ob, OB_MODE_VERTEX_PAINT);
 }
 void ED_object_vpaintmode_enter(struct bContext *C)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        wmWindowManager *wm = CTX_wm_manager(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
-       ED_object_vpaintmode_enter_ex(wm, scene, ob);
+       ED_object_vpaintmode_enter_ex(depsgraph, wm, scene, ob);
 }
 
 void ED_object_wpaintmode_enter_ex(
-        wmWindowManager *wm,
+        Depsgraph *depsgraph, wmWindowManager *wm,
         Scene *scene, Object *ob)
 {
        ed_vwpaintmode_enter_generic(
-               wm, scene, ob, OB_MODE_WEIGHT_PAINT);
+               depsgraph, wm, scene, ob, OB_MODE_WEIGHT_PAINT);
 }
 void ED_object_wpaintmode_enter(struct bContext *C)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        wmWindowManager *wm = CTX_wm_manager(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
-       ED_object_wpaintmode_enter_ex(wm, scene, ob);
+       ED_object_wpaintmode_enter_ex(depsgraph, wm, scene, ob);
 }
 
 /** \} */
@@ -1157,6 +1188,8 @@ static void ed_vwpaintmode_exit_generic(
                ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
                ED_mesh_mirror_topo_table(NULL, NULL, 'e');
        }
+
+       DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
 }
 
 void ED_object_vpaintmode_exit_ex(Object *ob)
@@ -1188,6 +1221,7 @@ void ED_object_wpaintmode_exit(struct bContext *C)
  */
 static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
 {
+       struct wmMsgBus *mbus = CTX_wm_message_bus(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_WEIGHT_PAINT;
        const bool is_mode_set = (ob->mode & mode_flag) != 0;
@@ -1205,8 +1239,9 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
                ED_object_wpaintmode_exit_ex(ob);
        }
        else {
+               Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
                wmWindowManager *wm = CTX_wm_manager(C);
-               ED_object_wpaintmode_enter_ex(wm, scene, ob);
+               ED_object_wpaintmode_enter_ex(depsgraph, wm, scene, ob);
        }
 
        /* Weightpaint works by overriding colors in mesh,
@@ -1214,10 +1249,14 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
         * exit (exit needs doing regardless because we
         * should redeform).
         */
-       DAG_id_tag_update(&me->id, 0);
+       DEG_id_tag_update(&me->id, 0);
 
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
 
+       WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
+
+       WM_toolsystem_update_from_context_view3d(C);
+
        return OPERATOR_FINISHED;
 }
 
@@ -1397,6 +1436,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
        bool *defbase_sel;
        SculptSession *ss = ob->sculpt;
        VPaint *vp = CTX_data_tool_settings(C)->wpaint;
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
 
        if (ED_wpaint_ensure_data(C, op->reports, WPAINT_ENSURE_MIRROR, &vgroup_index) == false) {
                return false;
@@ -1500,7 +1540,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
        }
 
        /* If not previously created, create vertex/weight paint mode session data */
-       vertex_paint_init_session(scene, ob);
+       vertex_paint_init_session(depsgraph, scene, ob);
        vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
        vertex_paint_init_session_data(ts, ob);
 
@@ -1941,7 +1981,8 @@ static void wpaint_paint_leaves(
 
        /* threaded loop over nodes */
        SculptThreadedTaskData data = {
-               .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, .C = C,
+                .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
+                .vp = vp, .wpd = wpd, .wpi = wpi, .me = me,
        };
 
        /* Use this so average can modify its weight without touching the brush. */
@@ -2169,7 +2210,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
        /* also needed for "View Selected" on last stroke */
        paint_last_stroke_update(scene, vc->ar, mval);
 
-       DAG_id_tag_update(ob->data, 0);
+       BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+
+       DEG_id_tag_update(ob->data, 0);
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
        swap_m4m4(wpd->vc.rv3d->persmat, mat);
 
@@ -2233,7 +2276,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
                }
        }
 
-       DAG_id_tag_update(ob->data, 0);
+       DEG_id_tag_update(ob->data, 0);
 
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
 
@@ -2315,6 +2358,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
  */
 static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
 {
+       struct wmMsgBus *mbus = CTX_wm_message_bus(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_VERTEX_PAINT;
        const bool is_mode_set = (ob->mode & mode_flag) != 0;
@@ -2333,15 +2377,22 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
                ED_object_vpaintmode_exit_ex(ob);
        }
        else {
+               Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
                wmWindowManager *wm = CTX_wm_manager(C);
-               ED_object_vpaintmode_enter_ex(wm, scene, ob);
+               ED_object_vpaintmode_enter_ex(depsgraph, wm, scene, ob);
        }
 
+       BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+
        /* update modifier stack for mapping requirements */
-       DAG_id_tag_update(&me->id, 0);
+       DEG_id_tag_update(&me->id, 0);
 
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
 
+       WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
+
+       WM_toolsystem_update_from_context_view3d(C);
+
        return OPERATOR_FINISHED;
 }
 
@@ -2424,6 +2475,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
        Object *ob = CTX_data_active_object(C);
        Mesh *me;
        SculptSession *ss = ob->sculpt;
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
 
        /* context checks could be a poll() */
        me = BKE_mesh_from_object(ob);
@@ -2471,12 +2523,12 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
        /* Create projection handle */
        if (vpd->is_texbrush) {
                ob->sculpt->building_vp_handle = true;
-               vpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &vpd->vertexcosnos);
+               vpd->vp_handle = ED_vpaint_proj_handle_create(depsgraph, scene, ob, &vpd->vertexcosnos);
                ob->sculpt->building_vp_handle = false;
        }
 
        /* If not previously created, create vertex/weight paint mode session data */
-       vertex_paint_init_session(scene, ob);
+       vertex_paint_init_session(depsgraph, scene, ob);
        vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
        vertex_paint_init_session_data(ts, ob);
 
@@ -2932,8 +2984,8 @@ static void vpaint_paint_leaves(
        const Brush *brush = ob->sculpt->cache->brush;
 
        SculptThreadedTaskData data = {
-               .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd,
-               .lcol = (uint *)me->mloopcol, .me = me, .C = C,
+               .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd,
+               .lcol = (uint *)me->mloopcol, .me = me,
        };
        ParallelRangeSettings settings;
        BLI_parallel_range_settings_defaults(&settings);
@@ -3070,6 +3122,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
 
        swap_m4m4(vc->rv3d->persmat, mat);
 
+       BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+
        if (vp->paint.brush->vertexpaint_tool == PAINT_BLEND_SMEAR) {
                memcpy(vpd->smear.color_prev, vpd->smear.color_curr, sizeof(uint) * ((Mesh *)ob->data)->totloop);
        }
@@ -3083,11 +3137,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
        if (vpd->use_fast_update == false) {
                /* recalculate modifier stack to get new colors, slow,
                 * avoid this if we can! */
-               DAG_id_tag_update(ob->data, 0);
-       }
-       else {
-               /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */
-               ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW;
+               DEG_id_tag_update(ob->data, 0);
        }
 }