diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_vertex.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 257 |
1 files changed, 160 insertions, 97 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index eb96425ee5b..d6aaaf31c21 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -54,24 +54,31 @@ #include "BKE_brush.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_deform.h" #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" +#include "BKE_object.h" #include "BKE_object_deform.h" #include "BKE_paint.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" #include "ED_screen.h" #include "ED_view3d.h" +/* For IMB_BlendMode only. */ +#include "IMB_imbuf.h" + #include "bmesh.h" #include "BKE_ccg.h" @@ -149,9 +156,17 @@ static bool vwpaint_use_normal(const VPaint *vp) ((vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); } -static bool brush_use_accumulate(const Brush *brush) +static bool brush_use_accumulate_ex(const Brush *brush, const int ob_mode) +{ + return ((brush->flag & BRUSH_ACCUMULATE) != 0 || + (ob_mode == OB_MODE_VERTEX_PAINT ? + (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) : + (brush->weightpaint_tool == WPAINT_TOOL_SMEAR))); +} + +static bool brush_use_accumulate(const VPaint *vp) { - return (brush->flag & BRUSH_ACCUMULATE) != 0 || brush->vertexpaint_tool == PAINT_BLEND_SMEAR; + return brush_use_accumulate_ex(vp->paint.brush, vp->paint.runtime.ob_mode); } static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index) @@ -169,12 +184,12 @@ static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev, MDeformVert *dv * (without rebuilding the 'derivedFinal') */ static bool vertex_paint_use_fast_update_check(Object *ob) { - DerivedMesh *dm = ob->derivedFinal; + Mesh *me_eval = ob->runtime.mesh_eval; - if (dm) { + if (me_eval != NULL) { Mesh *me = BKE_mesh_from_object(ob); if (me && me->mloopcol) { - return (me->mloopcol == CustomData_get_layer(&dm->loopData, CD_MLOOPCOL)); + return (me->mloopcol == CustomData_get_layer(&me_eval->ldata, CD_MLOOPCOL)); } } @@ -204,7 +219,7 @@ bool vertex_paint_mode_poll(bContext *C) return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly; } -bool vertex_paint_poll(bContext *C) +static bool 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)) @@ -212,13 +227,26 @@ bool 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; } +bool vertex_paint_poll(bContext *C) +{ + return vertex_paint_poll_ex(C, true); +} + +bool vertex_paint_poll_ignore_tool(bContext *C) +{ + return vertex_paint_poll_ex(C, true); +} + bool weight_paint_mode_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -226,7 +254,7 @@ bool weight_paint_mode_poll(bContext *C) return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly; } -bool weight_paint_poll(bContext *C) +static bool weight_paint_poll_ex(bContext *C, bool check_tool) { Object *ob = CTX_data_active_object(C); ScrArea *sa; @@ -239,26 +267,29 @@ bool 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; } -static VPaint *new_vpaint(void) +bool weight_paint_poll(bContext *C) { - VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint"); - - vp->paint.flags |= PAINT_SHOW_BRUSH; + return weight_paint_poll_ex(C, true); +} - return vp; +bool weight_paint_poll_ignore_tool(bContext *C) +{ + return weight_paint_poll_ex(C, false); } -uint vpaint_get_current_col(Scene *scene, VPaint *vp) +uint vpaint_get_current_col(Scene *scene, VPaint *vp, bool secondary) { Brush *brush = BKE_paint_brush(&vp->paint); uchar col[4]; - rgb_float_to_uchar(col, BKE_brush_color_get(scene, brush)); + rgb_float_to_uchar(col, secondary ? BKE_brush_secondary_color_get(scene, brush) : BKE_brush_color_get(scene, brush)); col[3] = 255; /* alpha isn't used, could even be removed to speedup paint a little */ return *(uint *)col; } @@ -271,16 +302,16 @@ static uint vpaint_blend( const int brush_alpha_value_i) { const Brush *brush = vp->paint.brush; - const int tool = brush->vertexpaint_tool; + const IMB_BlendMode blend = brush->blend; - uint color_blend = ED_vpaint_blend_tool(tool, color_curr, color_paint, alpha_i); + uint color_blend = ED_vpaint_blend_tool(blend, color_curr, color_paint, alpha_i); /* if no accumulate, clip color adding with colorig & orig alpha */ - if (!brush_use_accumulate(brush)) { + if (!brush_use_accumulate(vp)) { uint color_test, a; char *cp, *ct, *co; - color_test = ED_vpaint_blend_tool(tool, color_orig, color_paint, brush_alpha_value_i); + color_test = ED_vpaint_blend_tool(blend, color_orig, color_paint, brush_alpha_value_i); cp = (char *)&color_blend; ct = (char *)&color_test; @@ -299,7 +330,7 @@ static uint vpaint_blend( } if ((brush->flag & BRUSH_LOCK_ALPHA) && - !ELEM(tool, PAINT_BLEND_ALPHA_SUB, PAINT_BLEND_ALPHA_ADD)) + !ELEM(blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA)) { char *cp, *cc; cp = (char *)&color_blend; @@ -343,24 +374,25 @@ static float wpaint_blend( const short do_flip) { const Brush *brush = wp->paint.brush; - int tool = brush->vertexpaint_tool; + IMB_BlendMode blend = brush->blend; if (do_flip) { - switch (tool) { - case PAINT_BLEND_MIX: + switch (blend) { + case IMB_BLEND_MIX: paintval = 1.f - paintval; break; - case PAINT_BLEND_ADD: - tool = PAINT_BLEND_SUB; break; - case PAINT_BLEND_SUB: - tool = PAINT_BLEND_ADD; break; - case PAINT_BLEND_LIGHTEN: - tool = PAINT_BLEND_DARKEN; break; - case PAINT_BLEND_DARKEN: - tool = PAINT_BLEND_LIGHTEN; break; + case IMB_BLEND_ADD: + blend = IMB_BLEND_SUB; break; + case IMB_BLEND_SUB: + blend = IMB_BLEND_ADD; break; + case IMB_BLEND_LIGHTEN: + blend = IMB_BLEND_DARKEN; break; + case IMB_BLEND_DARKEN: + blend = IMB_BLEND_LIGHTEN; break; + default: break; } } - weight = ED_wpaint_blend_tool(tool, weight, paintval, alpha); + weight = ED_wpaint_blend_tool(blend, weight, paintval, alpha); CLAMP(weight, 0.0f, 1.0f); @@ -739,7 +771,7 @@ static void do_weight_paint_vertex_single( dw_mirr = NULL; } - if (!brush_use_accumulate(wp->paint.brush)) { + if (!brush_use_accumulate(wp)) { MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev; MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index); if (index_mirr != -1) { @@ -855,7 +887,7 @@ static void do_weight_paint_vertex_multi( return; } - if (!brush_use_accumulate(wp->paint.brush)) { + if (!brush_use_accumulate(wp)) { MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev; MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index); if (index_mirr != -1) { @@ -938,7 +970,7 @@ 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, eObjectMode object_mode) +static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob, eObjectMode object_mode) { /* Create persistent sculpt mode data */ BKE_sculpt_toolsettings_data_ensure(scene); @@ -946,27 +978,24 @@ static void vertex_paint_init_session(Scene *scene, Object *ob, eObjectMode obje BLI_assert(ob->sculpt == NULL); ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); ob->sculpt->mode_type = object_mode; - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); } -static void vertex_paint_init_stroke(Scene *scene, Object *ob) +static void vertex_paint_init_stroke(Depsgraph *depsgraph, Scene *scene, Object *ob) { - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); } static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) { /* Create maps */ struct SculptVertexPaintGeomMap *gmap = NULL; - const Brush *brush = NULL; if (ob->mode == OB_MODE_VERTEX_PAINT) { gmap = &ob->sculpt->mode.vpaint.gmap; - brush = BKE_paint_brush(&ts->vpaint->paint); BLI_assert(ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT); } else if (ob->mode == OB_MODE_WEIGHT_PAINT) { gmap = &ob->sculpt->mode.wpaint.gmap; - brush = BKE_paint_brush(&ts->wpaint->paint); BLI_assert(ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT); } else { @@ -994,7 +1023,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) /* Create average brush arrays */ if (ob->mode == OB_MODE_VERTEX_PAINT) { - if (!brush_use_accumulate(brush)) { + if (!brush_use_accumulate(ts->vpaint)) { if (ob->sculpt->mode.vpaint.previous_color == NULL) { ob->sculpt->mode.vpaint.previous_color = MEM_callocN(me->totloop * sizeof(uint), __func__); @@ -1005,7 +1034,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } } else if (ob->mode == OB_MODE_WEIGHT_PAINT) { - if (!brush_use_accumulate(brush)) { + if (!brush_use_accumulate(ts->wpaint)) { if (ob->sculpt->mode.wpaint.alpha_weight == NULL) { ob->sculpt->mode.wpaint.alpha_weight = MEM_callocN(me->totvert * sizeof(float), __func__); @@ -1037,22 +1066,23 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) * \{ */ static void ed_vwpaintmode_enter_generic( - Main *bmain, - wmWindowManager *wm, - Scene *scene, + Main *bmain, Depsgraph *depsgraph, + wmWindowManager *wm, Scene *scene, Object *ob, const eObjectMode mode_flag) { ob->mode |= mode_flag; Mesh *me = BKE_mesh_from_object(ob); + /* Same as sculpt mode, make sure we don't have cached derived mesh which + * points to freed arrays. + */ + BKE_object_free_derived_caches(ob); + if (mode_flag == OB_MODE_VERTEX_PAINT) { const ePaintMode paint_mode = PAINT_MODE_VERTEX; ED_mesh_color_ensure(me, NULL); - if (scene->toolsettings->vpaint == NULL) { - scene->toolsettings->vpaint = new_vpaint(); - } - + BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->vpaint); Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); paint_cursor_start_explicit(paint, wm, vertex_paint_poll); BKE_paint_init(bmain, scene, paint_mode, PAINT_CURSOR_VERTEX_PAINT); @@ -1060,10 +1090,7 @@ static void ed_vwpaintmode_enter_generic( else if (mode_flag == OB_MODE_WEIGHT_PAINT) { const ePaintMode paint_mode = PAINT_MODE_WEIGHT; - if (scene->toolsettings->wpaint == NULL) { - scene->toolsettings->wpaint = new_vpaint(); - } - + BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->wpaint); Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); paint_cursor_start_explicit(paint, wm, weight_paint_poll); BKE_paint_init(bmain, scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT); @@ -1085,39 +1112,44 @@ static void ed_vwpaintmode_enter_generic( BKE_sculptsession_free(ob); } - vertex_paint_init_session(scene, ob, mode_flag); + vertex_paint_init_session(depsgraph, scene, ob, mode_flag); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_vpaintmode_enter_ex( - Main *bmain, wmWindowManager *wm, + Main *bmain, Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene, Object *ob) { ed_vwpaintmode_enter_generic( - bmain, wm, scene, ob, OB_MODE_VERTEX_PAINT); + bmain, depsgraph, wm, scene, ob, OB_MODE_VERTEX_PAINT); } void ED_object_vpaintmode_enter(struct bContext *C) { Main *bmain = CTX_data_main(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(bmain, wm, scene, ob); + ED_object_vpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } void ED_object_wpaintmode_enter_ex( - Main *bmain, wmWindowManager *wm, + Main *bmain, Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene, Object *ob) { ed_vwpaintmode_enter_generic( - bmain, wm, scene, ob, OB_MODE_WEIGHT_PAINT); + bmain, depsgraph, wm, scene, ob, OB_MODE_WEIGHT_PAINT); } void ED_object_wpaintmode_enter(struct bContext *C) { Main *bmain = CTX_data_main(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(bmain, wm, scene, ob); + ED_object_wpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } /** \} */ @@ -1166,6 +1198,12 @@ static void ed_vwpaintmode_exit_generic( ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, NULL, 'e'); } + + /* Never leave derived meshes behind. */ + BKE_object_free_derived_caches(ob); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_vpaintmode_exit_ex(Object *ob) @@ -1198,10 +1236,12 @@ void ED_object_wpaintmode_exit(struct bContext *C) static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); + 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; Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; if (!is_mode_set) { if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { @@ -1215,8 +1255,10 @@ 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(bmain, wm, scene, ob); + ED_object_wpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); + BKE_paint_toolslots_brush_validate(bmain, &ts->wpaint->paint); } /* Weightpaint works by overriding colors in mesh, @@ -1224,10 +1266,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; } @@ -1407,6 +1453,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; @@ -1506,12 +1553,12 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo wpd->mirror.lock = tmpflags; } - if (ELEM(vp->paint.brush->vertexpaint_tool, PAINT_BLEND_SMEAR, PAINT_BLEND_BLUR)) { + if (ELEM(vp->paint.brush->weightpaint_tool, WPAINT_TOOL_SMEAR, WPAINT_TOOL_BLUR)) { wpd->precomputed_weight = MEM_mallocN(sizeof(float) * me->totvert, __func__); } /* If not previously created, create vertex/weight paint mode session data */ - vertex_paint_init_stroke(scene, ob); + vertex_paint_init_stroke(depsgraph, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); @@ -1574,7 +1621,7 @@ static void do_wpaint_precompute_weight_cb_ex( static void precompute_weight_values( bContext *C, Object *ob, Brush *brush, struct WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me) { - if (wpd->precomputed_weight_ready && !brush_use_accumulate(brush)) + if (wpd->precomputed_weight_ready && !brush_use_accumulate_ex(brush, ob->mode)) return; /* threaded loop over vertices */ @@ -1956,7 +2003,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. */ @@ -1967,8 +2015,8 @@ static void wpaint_paint_leaves( /* NOTE: current mirroring code cannot be run in parallel */ settings.use_threading = !(me->editflag & ME_EDIT_MIRROR_X); - switch (brush->vertexpaint_tool) { - case PAINT_BLEND_AVERAGE: + switch ((eBrushWeightPaintTool)brush->weightpaint_tool) { + case WPAINT_TOOL_AVERAGE: calculate_average_weight(&data, nodes, totnode); BLI_task_parallel_range( 0, totnode, @@ -1976,21 +2024,21 @@ static void wpaint_paint_leaves( do_wpaint_brush_draw_task_cb_ex, &settings); break; - case PAINT_BLEND_SMEAR: + case WPAINT_TOOL_SMEAR: BLI_task_parallel_range( 0, totnode, &data, do_wpaint_brush_smear_task_cb_ex, &settings); break; - case PAINT_BLEND_BLUR: + case WPAINT_TOOL_BLUR: BLI_task_parallel_range( 0, totnode, &data, do_wpaint_brush_blur_task_cb_ex, &settings); break; - default: + case WPAINT_TOOL_DRAW: BLI_task_parallel_range( 0, totnode, &data, @@ -2184,7 +2232,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_tag(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); @@ -2248,7 +2298,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); @@ -2331,10 +2381,12 @@ void PAINT_OT_weight_paint(wmOperatorType *ot) static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); + 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; Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; if (!is_mode_set) { if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { @@ -2349,15 +2401,23 @@ 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(bmain, wm, scene, ob); + ED_object_vpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); + BKE_paint_toolslots_brush_validate(bmain, &ts->vpaint->paint); } + BKE_mesh_batch_cache_dirty_tag(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; } @@ -2410,7 +2470,7 @@ struct VPaintData { uint paintcol; struct VertProjHandle *vp_handle; - struct DMCoNo *vertexcosnos; + struct CoNo *vertexcosnos; /* modify 'me->mcol' directly, since the derived mesh is drawing from this * array, otherwise we need to refresh the modifier stack */ @@ -2440,6 +2500,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); @@ -2458,9 +2519,9 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f &vpd->normal_angle_precalc, vp->paint.brush->falloff_angle, (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); - vpd->paintcol = vpaint_get_current_col(scene, vp); + vpd->paintcol = vpaint_get_current_col(scene, vp, (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT)); - vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) && brush->mtex.tex; + vpd->is_texbrush = !(brush->vertexpaint_tool == VPAINT_TOOL_BLUR) && brush->mtex.tex; /* are we painting onto a modified mesh?, * if not we can skip face map trickiness */ @@ -2474,11 +2535,11 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f } /* to keep tracked of modified loops for shared vertex color blending */ - if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { + if (brush->vertexpaint_tool == VPAINT_TOOL_BLUR) { vpd->mlooptag = MEM_mallocN(sizeof(bool) * me->totloop, "VPaintData mlooptag"); } - if (brush->vertexpaint_tool == PAINT_BLEND_SMEAR) { + if (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) { vpd->smear.color_prev = MEM_mallocN(sizeof(uint) * me->totloop, __func__); memcpy(vpd->smear.color_prev, me->mloopcol, sizeof(uint) * me->totloop); vpd->smear.color_curr = MEM_dupallocN(vpd->smear.color_prev); @@ -2487,12 +2548,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_stroke(scene, ob); + vertex_paint_init_stroke(depsgraph, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); @@ -2952,13 +3013,13 @@ 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); - switch (brush->vertexpaint_tool) { - case PAINT_BLEND_AVERAGE: + switch ((eBrushVertexPaintTool)brush->vertexpaint_tool) { + case VPAINT_TOOL_AVERAGE: calculate_average_color(&data, nodes, totnode); BLI_task_parallel_range( 0, totnode, @@ -2966,21 +3027,21 @@ static void vpaint_paint_leaves( do_vpaint_brush_draw_task_cb_ex, &settings); break; - case PAINT_BLEND_BLUR: + case VPAINT_TOOL_BLUR: BLI_task_parallel_range( 0, totnode, &data, do_vpaint_brush_blur_task_cb_ex, &settings); break; - case PAINT_BLEND_SMEAR: + case VPAINT_TOOL_SMEAR: BLI_task_parallel_range( 0, totnode, &data, do_vpaint_brush_smear_task_cb_ex, &settings); break; - default: + case VPAINT_TOOL_DRAW: BLI_task_parallel_range( 0, totnode, &data, @@ -3090,7 +3151,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P swap_m4m4(vc->rv3d->persmat, mat); - if (vp->paint.brush->vertexpaint_tool == PAINT_BLEND_SMEAR) { + BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + + if (vp->paint.brush->vertexpaint_tool == PAINT_TOOL_SMEAR) { memcpy(vpd->smear.color_prev, vpd->smear.color_curr, sizeof(uint) * ((Mesh *)ob->data)->totloop); } @@ -3103,11 +3166,11 @@ 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); + DEG_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; + /* Flush changes through DEG. */ + DEG_id_tag_update(ob->data, DEG_TAG_COPY_ON_WRITE); } } |