diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 127 |
1 files changed, 107 insertions, 20 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 24c5a9fce52..bbbed32e316 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2188,7 +2188,8 @@ void SCULPT_calc_area_normal_and_center( static float brush_strength(const Sculpt *sd, const StrokeCache *cache, const float feather, - const UnifiedPaintSettings *ups) + const UnifiedPaintSettings *ups, + const PaintModeSettings *UNUSED(paint_mode_settings)) { const Scene *scene = cache->vc->scene; const Brush *brush = BKE_paint_brush((Paint *)&sd->paint); @@ -2750,6 +2751,41 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Texture painting + * \{ */ + +static bool sculpt_needs_pbvh_pixels(PaintModeSettings *paint_mode_settings, + const Brush *brush, + Object *ob) +{ + if (brush->sculpt_tool == SCULPT_TOOL_PAINT && U.experimental.use_sculpt_texture_paint) { + Image *image; + ImageUser *image_user; + return SCULPT_paint_image_canvas_get(paint_mode_settings, ob, &image, &image_user); + } + + return false; +} + +static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings, + SculptSession *ss, + Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + Mesh *mesh = (Mesh *)ob->data; + + Image *image; + ImageUser *image_user; + if (!SCULPT_paint_image_canvas_get(paint_mode_settings, ob, &image, &image_user)) { + return; + } + + BKE_pbvh_build_pixels(ss->pbvh, mesh->mloop, &mesh->ldata, image, image_user); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Generic Brush Plane & Symmetry Utilities * \{ */ @@ -3075,7 +3111,8 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, - UnifiedPaintSettings *UNUSED(ups)) + UnifiedPaintSettings *UNUSED(ups), + PaintModeSettings *UNUSED(paint_mode_settings)) { SculptSession *ss = ob->sculpt; @@ -3170,7 +3207,11 @@ static void do_brush_action_task_cb(void *__restrict userdata, } } -static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups) +static void do_brush_action(Sculpt *sd, + Object *ob, + Brush *brush, + UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings) { SculptSession *ss = ob->sculpt; int totnode; @@ -3209,6 +3250,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode); } + if (sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) { + sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob); + } + /* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the * vertices and uses regular coords undo. */ /* It also assigns the paint_face_set here as it needs to be done regardless of the stroke type @@ -3399,7 +3444,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe SCULPT_do_displacement_smear_brush(sd, ob, nodes, totnode); break; case SCULPT_TOOL_PAINT: - SCULPT_do_paint_brush(sd, ob, nodes, totnode); + SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, totnode); break; case SCULPT_TOOL_SMEAR: SCULPT_do_smear_brush(sd, ob, nodes, totnode); @@ -3704,10 +3749,18 @@ void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache, } } -typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups); +typedef void (*BrushActionFunc)(Sculpt *sd, + Object *ob, + Brush *brush, + UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings); -static void do_tiled( - Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups, BrushActionFunc action) +static void do_tiled(Sculpt *sd, + Object *ob, + Brush *brush, + UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings, + BrushActionFunc action) { SculptSession *ss = ob->sculpt; StrokeCache *cache = ss->cache; @@ -3741,7 +3794,7 @@ static void do_tiled( /* First do the "un-tiled" position to initialize the stroke for this location. */ cache->tile_pass = 0; - action(sd, ob, brush, ups); + action(sd, ob, brush, ups, paint_mode_settings); /* Now do it for all the tiles. */ copy_v3_v3_int(cur, start); @@ -3760,7 +3813,7 @@ static void do_tiled( cache->plane_offset[dim] = cur[dim] * step[dim]; cache->initial_location[dim] = cur[dim] * step[dim] + original_initial_location[dim]; } - action(sd, ob, brush, ups); + action(sd, ob, brush, ups, paint_mode_settings); } } } @@ -3770,6 +3823,7 @@ static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings, BrushActionFunc action, const char symm, const int axis, @@ -3781,7 +3835,7 @@ static void do_radial_symmetry(Sculpt *sd, const float angle = 2.0f * M_PI * i / sd->radial_symm[axis - 'X']; ss->cache->radial_symmetry_pass = i; SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle); - do_tiled(sd, ob, brush, ups, action); + do_tiled(sd, ob, brush, ups, paint_mode_settings, action); } } @@ -3803,7 +3857,8 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob) static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob, BrushActionFunc action, - UnifiedPaintSettings *ups) + UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings) { Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; @@ -3812,7 +3867,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, float feather = calc_symmetry_feather(sd, ss->cache); - cache->bstrength = brush_strength(sd, cache, feather, ups); + cache->bstrength = brush_strength(sd, cache, feather, ups, paint_mode_settings); cache->symmetry = symm; /* `symm` is a bit combination of XYZ - @@ -3825,11 +3880,11 @@ static void do_symmetrical_brush_actions(Sculpt *sd, cache->radial_symmetry_pass = 0; SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0); - do_tiled(sd, ob, brush, ups, action); + do_tiled(sd, ob, brush, ups, paint_mode_settings, action); - do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather); - do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather); - do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'X', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'Y', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'Z', feather); } } @@ -4609,7 +4664,8 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd, SCULPT_TOOL_NEEDS_COLOR(brush->sculpt_tool) || (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) || (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) || - (brush->sculpt_tool == SCULPT_TOOL_DISPLACEMENT_SMEAR)); + (brush->sculpt_tool == SCULPT_TOOL_DISPLACEMENT_SMEAR) || + (brush->sculpt_tool == SCULPT_TOOL_PAINT)); } void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush) @@ -5057,6 +5113,15 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags) multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } + if ((update_flags & SCULPT_UPDATE_IMAGE) != 0) { + ED_region_tag_redraw(region); + if (update_flags == SCULPT_UPDATE_IMAGE) { + /* Early exit when only need to update the images. We don't want to tag any geometry updates + * that would rebuilt the PBVH. */ + return; + } + } + DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); /* Only current viewport matters, slower update for all viewports will @@ -5136,6 +5201,16 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up } } } + + if (update_flags & SCULPT_UPDATE_IMAGE) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + SpaceLink *sl = area->spacedata.first; + if (sl->spacetype != SPACE_IMAGE) { + continue; + } + ED_area_tag_redraw_regiontype(area, RGN_TYPE_WINDOW); + } + } } if (update_flags & SCULPT_UPDATE_COORDS) { @@ -5227,6 +5302,7 @@ static void sculpt_stroke_update_step(bContext *C, Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; const Brush *brush = BKE_paint_brush(&sd->paint); + ToolSettings *tool_settings = CTX_data_tool_settings(C); SCULPT_stroke_modifiers_check(C, ob, brush); sculpt_update_cache_variants(C, sd, ob, itemptr); @@ -5246,10 +5322,10 @@ static void sculpt_stroke_update_step(bContext *C, } if (SCULPT_stroke_is_dynamic_topology(ss, brush)) { - do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups); + do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups, &tool_settings->paint_mode); } - do_symmetrical_brush_actions(sd, ob, do_brush_action, ups); + do_symmetrical_brush_actions(sd, ob, do_brush_action, ups, &tool_settings->paint_mode); sculpt_combine_proxies(sd, ob); /* Hack to fix noise texture tearing mesh. */ @@ -5280,7 +5356,12 @@ static void sculpt_stroke_update_step(bContext *C, SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK); } else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) { - SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR); + if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) { + SCULPT_flush_update_step(C, SCULPT_UPDATE_IMAGE); + } + else { + SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR); + } } else { SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS); @@ -5302,6 +5383,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + ToolSettings *tool_settings = CTX_data_tool_settings(C); /* Finished. */ if (!ss->cache) { @@ -5335,6 +5417,11 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str if (brush->sculpt_tool == SCULPT_TOOL_MASK) { SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK); } + else if (brush->sculpt_tool == SCULPT_TOOL_PAINT) { + if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) { + SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE); + } + } else { SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); } |