From ce08bff6f020ffc4748a9582384ae6056a246d7e Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Sat, 21 Jan 2023 14:14:44 +0100 Subject: [PATCH 01/16] Sculpt: Added vector displacement for sculpting draw brush (area plane method only for now) Vector displacement maps (VDM) provide a way to create complex displacements that can have overhangs in one brush dab. This is unlike standard displacement with height maps that only displace in normal direction. Forms like ears, curled horns, etc can be created in one click if VMDs are used. This patch reads the RGB channels of a texture in a brush stroke and interprets them as individual vectors, that are used for the vertex offset. As of now, this is only working for the draw brush using the area plane method. Symmetry and radial symmetry is working. --- .../startup/bl_ui/properties_paint_common.py | 7 + .../editors/sculpt_paint/paint_cursor.cc | 6 +- .../editors/sculpt_paint/paint_intern.h | 8 +- .../editors/sculpt_paint/paint_utils.c | 31 ++- source/blender/editors/sculpt_paint/sculpt.cc | 94 +++++---- .../editors/sculpt_paint/sculpt_brush_types.c | 179 ++++++++++++------ .../editors/sculpt_paint/sculpt_cloth.c | 6 +- .../editors/sculpt_paint/sculpt_face_set.cc | 20 +- .../editors/sculpt_paint/sculpt_intern.h | 29 +-- .../sculpt_paint/sculpt_multiplane_scrape.c | 12 +- .../editors/sculpt_paint/sculpt_paint_color.c | 18 +- .../sculpt_paint/sculpt_paint_image.cc | 6 +- .../editors/sculpt_paint/sculpt_smooth.c | 24 ++- source/blender/makesdna/DNA_brush_enums.h | 1 + source/blender/makesrna/intern/rna_brush.c | 6 + 15 files changed, 297 insertions(+), 150 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index c912de8f3e4..e4bc21a5c62 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1141,6 +1141,13 @@ def brush_texture_settings(layout, brush, sculpt): # texture_sample_bias layout.prop(brush, "texture_sample_bias", slider=True, text="Sample Bias") + # use_rgb_as_vector_displacement (Only working for draw brush for now) + if brush.sculpt_tool == 'DRAW': + col = layout.column() + col.active = tex_slot.map_mode == 'AREA_PLANE' + col.prop(brush, "use_rgb_as_vector_displacement", text="RGB as Vector Displacement") + + def brush_mask_texture_settings(layout, brush): mask_tex_slot = brush.mask_texture_slot diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 63535a2bbe9..087e34b88fe 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -203,7 +203,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata, if (col) { float rgba[4]; - paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace); + paint_get_tex_pixel_srgb_with_clamp(mtex, x, y, rgba, thread_id, pool, convert_to_linear, colorspace); buffer[index * 4] = rgba[0] * 255; buffer[index * 4 + 1] = rgba[1] * 255; @@ -211,7 +211,9 @@ static void load_tex_task_cb_ex(void *__restrict userdata, buffer[index * 4 + 3] = rgba[3] * 255; } else { - float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_id); + float avg; + float rgba_dummy[4]; + paint_get_tex_pixel(mtex, x, y, thread_id, pool, &avg, rgba_dummy); avg += br->texture_sample_bias; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index fbb69b1fc5b..6f14e7ff1c2 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -352,14 +352,14 @@ void paint_calc_redraw_planes(float planes[4][4], float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); -float paint_get_tex_pixel( - const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread); -void paint_get_tex_pixel_col(const struct MTex *mtex, +bool paint_get_tex_pixel( +const struct MTex *mtex, float u, float v, int thread, struct ImagePool *pool, float *r_intensity, float r_rgba[4]); +void paint_get_tex_pixel_srgb_with_clamp(const struct MTex *mtex, float u, float v, float rgba[4], - struct ImagePool *pool, int thread, + struct ImagePool *pool, bool convert, struct ColorSpace *colorspace); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index ccfdd0c0e49..f80bb1104aa 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -146,32 +146,45 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], flo return len_v3(delta) / scale; } -float paint_get_tex_pixel(const MTex *mtex, float u, float v, struct ImagePool *pool, int thread) +bool paint_get_tex_pixel(const MTex *mtex, + float u, + float v, + int thread, + struct ImagePool *pool, + /* Return arguments. */ + float *r_intensity, + float r_rgba[4]) { - float intensity; - float rgba_dummy[4]; const float co[3] = {u, v, 0.0f}; + float intensity; + const bool hasRGB = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, r_rgba); + *r_intensity = intensity; - RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba_dummy); + if (!hasRGB) { + r_rgba[0] = intensity; + r_rgba[1] = intensity; + r_rgba[2] = intensity; + r_rgba[3] = 1.0f; + } - return intensity; + return hasRGB; } -void paint_get_tex_pixel_col(const MTex *mtex, +void paint_get_tex_pixel_srgb_with_clamp(const MTex *mtex, float u, float v, float rgba[4], - struct ImagePool *pool, int thread, + struct ImagePool *pool, bool convert_to_linear, struct ColorSpace *colorspace) { const float co[3] = {u, v, 0.0f}; float intensity; - const bool hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba); + const bool hasRGB = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba); - if (!hasrgb) { + if (!hasRGB) { rgba[0] = intensity; rgba[1] = intensity; rgba[2] = intensity; diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 676f2de49ef..dadde967b37 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -74,6 +74,8 @@ #include "RNA_define.h" #include "bmesh.h" +#include "IMB_imbuf_types.h" +#include "RE_texture.h" using blender::float3; using blender::MutableSpan; @@ -2555,20 +2557,21 @@ static float brush_strength(const Sculpt *sd, } } -float SCULPT_brush_strength_factor(SculptSession *ss, - const Brush *br, - const float brush_point[3], - float len, - const float vno[3], - const float fno[3], - float mask, - const PBVHVertRef vertex, - const int thread_id, - AutomaskingNodeData *automask_data) +float SCULPT_brush_factor_with_color(SculptSession *ss, + const Brush *brush, + const float brush_point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + AutomaskingNodeData *automask_data, + float r_rgb[3]) { StrokeCache *cache = ss->cache; const Scene *scene = cache->vc->scene; - const MTex *mtex = BKE_brush_mask_texture_get(br, OB_MODE_SCULPT); + const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); float avg = 1.0f; float rgba[4]; float point[3]; @@ -2576,16 +2579,16 @@ float SCULPT_brush_strength_factor(SculptSession *ss, sub_v3_v3v3(point, brush_point, cache->plane_offset); if (!mtex->tex) { - avg = 1.0f; + rgba[0] = 1.0f; + rgba[1] = 1.0f; + rgba[2] = 1.0f; } else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) { /* Get strength by feeding the vertex location directly into a texture. */ - avg = BKE_brush_sample_tex_3d(scene, br, mtex, point, rgba, 0, ss->tex_pool); + avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point, rgba, thread_id, ss->tex_pool); } else { - float symm_point[3], point_2d[2]; - /* Quite warnings. */ - float x = 0.0f, y = 0.0f; + float symm_point[3]; /* If the active area is being applied for symmetry, flip it * across the symmetry axis and rotate it back to the original @@ -2596,8 +2599,6 @@ float SCULPT_brush_strength_factor(SculptSession *ss, } flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass); - ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat); - /* Still no symmetry supported for other paint modes. * Sculpt does it DIY. */ if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) { @@ -2606,22 +2607,25 @@ float SCULPT_brush_strength_factor(SculptSession *ss, mul_m4_v3(cache->brush_local_mat, symm_point); - x = symm_point[0]; - y = symm_point[1]; + float x = symm_point[0]; + float y = symm_point[1]; - x *= mtex->size[0]; - y *= mtex->size[1]; + x *= brush->mtex.size[0]; + y *= brush->mtex.size[1]; - x += mtex->ofs[0]; - y += mtex->ofs[1]; + x += brush->mtex.ofs[0]; + y += brush->mtex.ofs[1]; - avg = paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id); + paint_get_tex_pixel(&brush->mtex, x, y, thread_id, ss->tex_pool, &avg, rgba); - avg += br->texture_sample_bias; + add_v3_fl(rgba, brush->texture_sample_bias); // v3 -> Ignore alpha + avg -= brush->texture_sample_bias; } else { + float point_2d[2]; + ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat); const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f}; - avg = BKE_brush_sample_tex_3d(scene, br, mtex, point_3d, rgba, 0, ss->tex_pool); + avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, rgba, thread_id, ss->tex_pool); } } @@ -2641,18 +2645,39 @@ float SCULPT_brush_strength_factor(SculptSession *ss, } /* Falloff curve. */ - avg *= BKE_brush_curve_strength(br, final_len, cache->radius); - avg *= frontface(br, cache->view_normal, vno, fno); + const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) + * frontface(brush, cache->view_normal, vno, fno); /* Paint mask. */ - avg *= 1.0f - mask; + const float paint_mask = 1.0f - mask; /* Auto-masking. */ - avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); + const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); + + /* Apply masks */ + const float masks_combined = falloff * paint_mask * automasking_factor; + mul_v3_fl(rgba, masks_combined); + avg *= masks_combined; + + /* Copy rgba for vector displacement */ + copy_v3_v3(r_rgb, rgba); return avg; } +void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgb[3], float out_offset[3]) +{ + rgb[2] *= ss->cache->bstrength; + float mat[4][4]; + invert_m4_m4(mat, ss->cache->brush_local_mat); + mul_mat3_m4_v3(mat, rgb); + + if (ss->cache->radial_symmetry_pass) { + mul_m4_v3(ss->cache->symm_rot_mat, rgb); // TODO: Not working yet + } + flip_v3_v3(out_offset, rgb, ss->cache->mirror_symmetry_pass); +} + bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v) { SculptSearchSphereData *data = static_cast(data_v); @@ -3236,7 +3261,9 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } - const float fade = SCULPT_brush_strength_factor(ss, + + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -3245,7 +3272,8 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - nullptr); + nullptr, + rgb); mul_v3_v3fl(proxy[vd.i], offset, fade); diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c index c24bdba662a..a327faaf7a7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c @@ -266,18 +266,26 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* Offset vertex. */ - const float fade = SCULPT_brush_strength_factor(ss, - brush, - vd.co, - sqrtf(test.dist), - vd.no, - vd.fno, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - &automask_data); + float rgb[3]; + float fade = SCULPT_brush_factor_with_color(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + &automask_data, + rgb); - mul_v3_v3fl(proxy[vd.i], offset, fade); + if(ss->cache->brush->flag2 & BRUSH_RGB_AS_VECTOR_DISPLACEMENT + && (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) { + SCULPT_calc_vertex_displacement(ss, rgb, proxy[vd.i]); + } + else { + mul_v3_v3fl(proxy[vd.i], offset, fade); + } if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); @@ -304,6 +312,7 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) * initialize before threads so they can do curve mapping. */ BKE_curvemapping_init(brush->curve); + /* Threaded loop over nodes. */ SculptThreadedTaskData data = { .sd = sd, @@ -371,7 +380,8 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -380,7 +390,8 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -476,7 +487,8 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -485,7 +497,8 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -601,7 +614,8 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -610,7 +624,8 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -763,7 +778,8 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, if (SCULPT_plane_trim(ss->cache, brush, val)) { SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -772,7 +788,8 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -927,7 +944,8 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -936,7 +954,8 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -1061,7 +1080,8 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */ - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, ss->cache->radius * test.dist, @@ -1070,7 +1090,8 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -1221,7 +1242,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, else { SCULPT_automasking_node_update(ss, &automask_data, &vd); - fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1230,7 +1252,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); } mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1363,7 +1386,8 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, orig_data.co, sqrtf(test.dist), @@ -1372,7 +1396,8 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1445,7 +1470,8 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); float vec[3], rot[3][3]; - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, orig_data.co, sqrtf(test.dist), @@ -1454,7 +1480,8 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); sub_v3_v3v3(vec, orig_data.co, ss->cache->location); axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); @@ -1524,7 +1551,8 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1533,7 +1561,8 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); const int vi = vd.index; float *disp_factor; @@ -1644,7 +1673,8 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1653,7 +1683,8 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float val[3]; if (vd.fno) { @@ -1719,7 +1750,8 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1728,7 +1760,8 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1805,7 +1838,8 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, /* Offset vertex. */ SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1814,7 +1848,8 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float val1[3]; float val2[3]; @@ -1928,7 +1963,8 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -1937,7 +1973,8 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float disp_center[3]; float x_disp[3]; float z_disp[3]; @@ -2051,16 +2088,18 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float fade = bstrength * SCULPT_brush_strength_factor(ss, - brush, - orig_data.co, - sqrtf(test.dist), - orig_data.no, - NULL, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - &automask_data); + float rgb[3]; + float fade = bstrength * SCULPT_brush_factor_with_color(ss, + brush, + orig_data.co, + sqrtf(test.dist), + orig_data.no, + NULL, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + &automask_data, + rgb); if (grab_silhouette) { float silhouette_test_dir[3]; @@ -2262,7 +2301,8 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, /* Offset vertex. */ SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2271,7 +2311,8 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -2352,7 +2393,8 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2361,7 +2403,8 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float current_disp[3]; float current_disp_norm[3]; float final_disp[3] = {0.0f, 0.0f, 0.0f}; @@ -2516,7 +2559,8 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2525,7 +2569,8 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co); if (vd.is_mesh) { @@ -2599,7 +2644,8 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -2608,7 +2654,8 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float limit_co[3]; float disp[3]; @@ -2672,7 +2719,8 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -2681,7 +2729,8 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float current_disp[3]; float current_disp_norm[3]; @@ -2840,8 +2889,9 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); + float rgb[3]; const float fade = bstrength * - SCULPT_brush_strength_factor(ss, + SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -2850,7 +2900,8 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, *vd.mask, vd.vertex, thread_id, - &automask_data) * + &automask_data, + rgb) * ss->cache->pressure; float avg[3], val[3]; @@ -2931,7 +2982,8 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -2940,7 +2992,8 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); if (bstrength > 0.0f) { (*vd.mask) += fade * bstrength * (1.0f - *vd.mask); diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index a5c469ca3a0..bc4868a43db 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -507,8 +507,9 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, dist = dist_to_plane_v3(current_vertex_location, deform_plane); } + float rgb[3]; const float fade = sim_factor * bstrength * - SCULPT_brush_strength_factor(ss, + SCULPT_brush_factor_with_color(ss, brush, current_vertex_location, dist, @@ -517,7 +518,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float brush_disp[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 9c2d6a78fab..dd3c3012f07 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -144,7 +144,9 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, if (face_hidden) { continue; } - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -153,7 +155,8 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); if (fade > 0.05f) { ss->face_sets[vert_map->indices[j]] = ss->cache->paint_face_set; @@ -165,7 +168,9 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -174,7 +179,8 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); if (fade > 0.05f) { SCULPT_vertex_face_set_set(ss, vd.vertex, ss->cache->paint_face_set); @@ -225,7 +231,8 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, continue; } - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -234,7 +241,8 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co); if (vd.is_mesh) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index ffd1554be89..d9d7f260967 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1237,18 +1237,25 @@ const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss, char falloff_shape); /** - * Return a multiplier for brush strength on a particular vertex. + * Return a color and grayscale of a brush texture at a particular vertex multiplied by active masks. + * The grayscale value is usually multiplied by the offset vector and the color is used for non-linear vertex displacement. */ -float SCULPT_brush_strength_factor(struct SculptSession *ss, - const struct Brush *br, - const float point[3], - float len, - const float vno[3], - const float fno[3], - float mask, - const PBVHVertRef vertex, - int thread_id, - struct AutomaskingNodeData *automask_data); +float SCULPT_brush_factor_with_color(struct SculptSession *ss, + const struct Brush *brush, + const float point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + struct AutomaskingNodeData *automask_data, + float rgb[3]); + +/** + * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement. + */ + void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgb[3], float out_offset[3]); /** * Tilts a normal by the x and y tilt values using the view axis. diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index ccee7814f83..7602b62501c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -72,7 +72,8 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* Use the brush falloff to weight the sampled normals. */ - const float fade = SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -81,7 +82,8 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); /* Sample the normal and area of the +X and -X axis individually. */ if (local_co[0] > 0.0f) { @@ -187,8 +189,9 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */ /* This produces a not round brush tip. */ + float rgb[3]; local_co[1] *= 2.0f; - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, len_v3(local_co), @@ -197,7 +200,8 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); mul_v3_v3fl(proxy[vd.i], val, fade); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index ee716d1107a..aac46f0c875 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -59,7 +59,8 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -68,7 +69,8 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float smooth_color[4]; SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex); @@ -153,7 +155,8 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, distance_to_stroke_location, @@ -162,7 +165,8 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); /* Density. */ float noise = 1.0f; @@ -409,7 +413,8 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -418,7 +423,8 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float current_disp[3]; float current_disp_norm[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 75c84c48f77..d86422d6f1a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -174,7 +174,8 @@ template class PaintingKernel { const float3 face_normal(0.0f, 0.0f, 0.0f); const float mask = 0.0f; - const float falloff_strength = SCULPT_brush_strength_factor( + float rgb[3]; + const float falloff_strength = SCULPT_brush_factor_with_color( ss, brush, pixel_pos, @@ -184,7 +185,8 @@ template class PaintingKernel { mask, BKE_pbvh_make_vref(PBVH_REF_NONE), thread_id, - automask_data); + automask_data, + rgb); float4 paint_color = brush_color * falloff_strength * brush_strength; float4 buffer_color; blend_color_mix_float(buffer_color, color, paint_color); diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index 5af8381f6da..4673a1745ff 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -206,7 +206,8 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -215,7 +216,8 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float disp[3]; madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); @@ -296,7 +298,8 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor( + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color( ss, brush, vd.co, @@ -306,7 +309,8 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); if (smooth_mask) { float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask; val *= fade * bstrength; @@ -474,7 +478,8 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -483,7 +488,8 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); float disp[3]; SCULPT_surface_smooth_laplacian_step( @@ -522,7 +528,8 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( SCULPT_automasking_node_update(ss, &automask_data, &vd); - const float fade = bstrength * SCULPT_brush_strength_factor(ss, + float rgb[3]; + const float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush, vd.co, sqrtf(test.dist), @@ -531,7 +538,8 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data); + &automask_data, + rgb); SCULPT_surface_smooth_displace_step( ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade); } diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 72357ea6734..98e90ca3d4a 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -412,6 +412,7 @@ typedef enum eBrushFlags2 { BRUSH_CLOTH_USE_COLLISION = (1 << 6), BRUSH_AREA_RADIUS_PRESSURE = (1 << 7), BRUSH_GRAB_SILHOUETTE = (1 << 8), + BRUSH_RGB_AS_VECTOR_DISPLACEMENT = (1 << 9), } eBrushFlags2; typedef enum { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index db38c3d4af7..bec281403d3 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2893,6 +2893,12 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Sample Bias", "Value added to texture samples"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_rgb_as_vector_displacement", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_RGB_AS_VECTOR_DISPLACEMENT); + RNA_def_property_ui_text(prop, "RGB as vector displacement", +"Handles each pixel as individual vector for displacement instead of an offset in normal direction"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "normal_weight"); RNA_def_property_float_default(prop, 0); -- 2.30.2 From 02b958e9afe6d048a7fe85315b9708d1adf8ac88 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Sun, 22 Jan 2023 10:49:46 +0100 Subject: [PATCH 02/16] Sculpt: Store inverse of brush_local_mat beforehand so it won't be calculated for every displaced vertex Brush_local_mat_inv is needed to transform vectors of a vertex displacement map back to object space. --- source/blender/editors/sculpt_paint/sculpt.cc | 12 ++++++------ source/blender/editors/sculpt_paint/sculpt_intern.h | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index dadde967b37..34e8094cfc7 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2668,12 +2668,10 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgb[3], float out_offset[3]) { rgb[2] *= ss->cache->bstrength; - float mat[4][4]; - invert_m4_m4(mat, ss->cache->brush_local_mat); - mul_mat3_m4_v3(mat, rgb); + mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgb); if (ss->cache->radial_symmetry_pass) { - mul_m4_v3(ss->cache->symm_rot_mat, rgb); // TODO: Not working yet + mul_m4_v3(ss->cache->symm_rot_mat, rgb); } flip_v3_v3(out_offset, rgb, ss->cache->mirror_symmetry_pass); } @@ -2915,7 +2913,7 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) mul_m4_v3(ob->world_to_object, y); } -static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4]) +static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4], float local_mat_inv[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; @@ -2961,6 +2959,8 @@ static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4 scale_m4_fl(scale, radius); mul_m4_m4m4(tmat, mat, scale); + /* Return tmat as is (for converting from local area coords to model-space coords). */ + copy_m4_m4(local_mat_inv, tmat); /* Return inverse (for converting from model-space coords to local area coords). */ invert_m4_m4(local_mat, tmat); } @@ -2995,7 +2995,7 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) { const Brush *brush = BKE_paint_brush(&sd->paint); const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); - calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat); + calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat, cache->brush_local_mat_inv); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index d9d7f260967..51d60982488 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -583,8 +583,13 @@ typedef struct StrokeCache { float sculpt_normal_symm[3]; /* Used for area texture mode, local_mat gets calculated by - * calc_brush_local_mat() and used in tex_strength(). */ + * calc_brush_local_mat() and used in brush_factor_with_color(). + * Transforms from model-space coords to local area coords. + */ float brush_local_mat[4][4]; + /* The matrix from local area coords to model-space coords is used to calculate the vector + * displacement in area plane mode. */ + float brush_local_mat_inv[4][4]; float plane_offset[3]; /* used to shift the plane around when doing tiled strokes */ int tile_pass; -- 2.30.2 From 01c579db5487c1c431c8a2b3b18d78d89a0813ff Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Sun, 22 Jan 2023 11:15:35 +0100 Subject: [PATCH 03/16] Sculpt: Added vector displacement for sculpting draw brush (area plane method only for now) Vector displacement maps (VDM) provide a way to create complex displacements that can have overhangs in one brush dab. This is unlike standard displacement with height maps that only displace in normal direction. Forms like ears, curled horns, etc can be created in one click if VMDs are used. This patch reads the RGB channels of a texture in a brush stroke and interprets them as individual vectors, that are used for the vertex offset. As of now, this is only working for the draw brush using the area plane method. Symmetry and radial symmetry is working. Sculpt: Store inverse of brush_local_mat beforehand so it won't be calculated for every displaced vertex Brush_local_mat_inv is needed to transform vectors of a vertex displacement map back to object space. Sculpt: Added hint in tooltip that vector displacement works only with area plane mapping Differential Revision: https://developer.blender.org/D17080 --- source/blender/makesrna/intern/rna_brush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index bec281403d3..bedb04ff3df 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2896,7 +2896,7 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_rgb_as_vector_displacement", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_RGB_AS_VECTOR_DISPLACEMENT); RNA_def_property_ui_text(prop, "RGB as vector displacement", -"Handles each pixel as individual vector for displacement instead of an offset in normal direction"); +"Handles each pixel as individual vector for displacement. Works only with area plane mapping"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR); -- 2.30.2 From 696c8fe263ecbd070dd3508991c4f1710e5accc6 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Sun, 22 Jan 2023 12:14:10 +0100 Subject: [PATCH 04/16] Sculpt: Undo changes to mtex and threadid in brush_factor method --- source/blender/editors/sculpt_paint/sculpt.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 34e8094cfc7..cbef1bc40f8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2585,7 +2585,7 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, } else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) { /* Get strength by feeding the vertex location directly into a texture. */ - avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point, rgba, thread_id, ss->tex_pool); + avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point, rgba, 0, ss->tex_pool); } else { float symm_point[3]; @@ -2610,13 +2610,13 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, float x = symm_point[0]; float y = symm_point[1]; - x *= brush->mtex.size[0]; - y *= brush->mtex.size[1]; + x *= mtex->size[0]; + y *= mtex->size[1]; - x += brush->mtex.ofs[0]; - y += brush->mtex.ofs[1]; + x += mtex->ofs[0]; + y += mtex->ofs[1]; - paint_get_tex_pixel(&brush->mtex, x, y, thread_id, ss->tex_pool, &avg, rgba); + paint_get_tex_pixel(mtex, x, y, thread_id, ss->tex_pool, &avg, rgba); add_v3_fl(rgba, brush->texture_sample_bias); // v3 -> Ignore alpha avg -= brush->texture_sample_bias; @@ -2625,7 +2625,7 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, float point_2d[2]; ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat); const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f}; - avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, rgba, thread_id, ss->tex_pool); + avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, rgba, 0, ss->tex_pool); } } -- 2.30.2 From 5ca7ce0752569882fb85100155887361b69e1bd4 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Mon, 23 Jan 2023 22:36:24 +0100 Subject: [PATCH 05/16] Sculpt: Reduced modified files for patch and included feedback --- .../startup/bl_ui/properties_paint_common.py | 3 +- .../editors/sculpt_paint/paint_cursor.cc | 4 +- .../editors/sculpt_paint/paint_intern.h | 6 +- .../editors/sculpt_paint/paint_utils.c | 6 +- source/blender/editors/sculpt_paint/sculpt.cc | 172 ++++++++++------ .../editors/sculpt_paint/sculpt_brush_types.c | 188 +++++++----------- .../editors/sculpt_paint/sculpt_cloth.c | 6 +- .../editors/sculpt_paint/sculpt_face_set.cc | 20 +- .../editors/sculpt_paint/sculpt_intern.h | 41 ++-- .../sculpt_paint/sculpt_multiplane_scrape.c | 12 +- .../editors/sculpt_paint/sculpt_paint_color.c | 18 +- .../sculpt_paint/sculpt_paint_image.cc | 6 +- .../editors/sculpt_paint/sculpt_smooth.c | 24 +-- source/blender/makesdna/DNA_brush_enums.h | 2 +- source/blender/makesrna/intern/rna_brush.c | 8 +- 15 files changed, 257 insertions(+), 259 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index e4bc21a5c62..6e8f032ee7c 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1141,11 +1141,10 @@ def brush_texture_settings(layout, brush, sculpt): # texture_sample_bias layout.prop(brush, "texture_sample_bias", slider=True, text="Sample Bias") - # use_rgb_as_vector_displacement (Only working for draw brush for now) if brush.sculpt_tool == 'DRAW': col = layout.column() col.active = tex_slot.map_mode == 'AREA_PLANE' - col.prop(brush, "use_rgb_as_vector_displacement", text="RGB as Vector Displacement") + col.prop(brush, "use_color_as_displacement", text="Vector Displacement") diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 087e34b88fe..690aa86b7bd 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -203,7 +203,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata, if (col) { float rgba[4]; - paint_get_tex_pixel_srgb_with_clamp(mtex, x, y, rgba, thread_id, pool, convert_to_linear, colorspace); + paint_get_tex_pixel_color_with_clamp(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace); buffer[index * 4] = rgba[0] * 255; buffer[index * 4 + 1] = rgba[1] * 255; @@ -213,7 +213,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata, else { float avg; float rgba_dummy[4]; - paint_get_tex_pixel(mtex, x, y, thread_id, pool, &avg, rgba_dummy); + paint_get_tex_pixel(mtex, x, y, pool, thread_id, &avg, rgba_dummy); avg += br->texture_sample_bias; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 6f14e7ff1c2..65abb73b1c9 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -353,13 +353,13 @@ float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); bool paint_get_tex_pixel( -const struct MTex *mtex, float u, float v, int thread, struct ImagePool *pool, float *r_intensity, float r_rgba[4]); -void paint_get_tex_pixel_srgb_with_clamp(const struct MTex *mtex, +const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread, float *r_intensity, float r_rgba[4]); +void paint_get_tex_pixel_color_with_clamp(const struct MTex *mtex, float u, float v, float rgba[4], - int thread, struct ImagePool *pool, + int thread, bool convert, struct ColorSpace *colorspace); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index f80bb1104aa..0b9563dfe31 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -149,8 +149,8 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], flo bool paint_get_tex_pixel(const MTex *mtex, float u, float v, - int thread, struct ImagePool *pool, + int thread, /* Return arguments. */ float *r_intensity, float r_rgba[4]) @@ -170,12 +170,12 @@ bool paint_get_tex_pixel(const MTex *mtex, return hasRGB; } -void paint_get_tex_pixel_srgb_with_clamp(const MTex *mtex, +void paint_get_tex_pixel_color_with_clamp(const MTex *mtex, float u, float v, float rgba[4], - int thread, struct ImagePool *pool, + int thread, bool convert_to_linear, struct ColorSpace *colorspace) { diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index cbef1bc40f8..1600f087586 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2557,35 +2557,52 @@ static float brush_strength(const Sculpt *sd, } } -float SCULPT_brush_factor_with_color(SculptSession *ss, - const Brush *brush, - const float brush_point[3], - float len, - const float vno[3], - const float fno[3], - float mask, - const PBVHVertRef vertex, - int thread_id, - AutomaskingNodeData *automask_data, - float r_rgb[3]) +static float sculpt_apply_hardness(const SculptSession *ss, const float input_len) +{ + const StrokeCache *cache = ss->cache; + float final_len = input_len; + const float hardness = cache->paint_brush.hardness; + float p = input_len / cache->radius; + if (p < hardness) { + final_len = 0.0f; + } + else if (hardness == 1.0f) { + final_len = cache->radius; + } + else { + p = (p - hardness) / (1.0f - hardness); + final_len = p * cache->radius; + } + + return final_len; +} + +static void sculpt_apply_texture(const SculptSession *ss, + const Brush *brush, + const float brush_point[3], + const int thread_id, + float *r_value, + float r_rgba[4]) { StrokeCache *cache = ss->cache; const Scene *scene = cache->vc->scene; const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); - float avg = 1.0f; - float rgba[4]; - float point[3]; - - sub_v3_v3v3(point, brush_point, cache->plane_offset); if (!mtex->tex) { - rgba[0] = 1.0f; - rgba[1] = 1.0f; - rgba[2] = 1.0f; + *r_value = 1.0f; + r_rgba[0] = 1.0f; + r_rgba[1] = 1.0f; + r_rgba[2] = 1.0f; + r_rgba[3] = 1.0f; + return; } - else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) { + + float point[3]; + sub_v3_v3v3(point, brush_point, cache->plane_offset); + + if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) { /* Get strength by feeding the vertex location directly into a texture. */ - avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point, rgba, 0, ss->tex_pool); + *r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point, r_rgba, 0, ss->tex_pool); } else { float symm_point[3]; @@ -2616,33 +2633,39 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, x += mtex->ofs[0]; y += mtex->ofs[1]; - paint_get_tex_pixel(mtex, x, y, thread_id, ss->tex_pool, &avg, rgba); + paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba); - add_v3_fl(rgba, brush->texture_sample_bias); // v3 -> Ignore alpha - avg -= brush->texture_sample_bias; + add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha + *r_value -= brush->texture_sample_bias; } else { float point_2d[2]; ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat); const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f}; - avg = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, rgba, 0, ss->tex_pool); + *r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool); } } +} + +float SCULPT_brush_strength_factor(SculptSession *ss, + const Brush *brush, + const float brush_point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + AutomaskingNodeData *automask_data) +{ + StrokeCache *cache = ss->cache; + + float avg = 1.0f; + float rgba[4]; + sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, rgba); /* Hardness. */ - float final_len = len; - const float hardness = cache->paint_brush.hardness; - float p = len / cache->radius; - if (p < hardness) { - final_len = 0.0f; - } - else if (hardness == 1.0f) { - final_len = cache->radius; - } - else { - p = (p - hardness) / (1.0f - hardness); - final_len = p * cache->radius; - } + const float final_len = sculpt_apply_hardness(ss, len); /* Falloff curve. */ const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) @@ -2654,26 +2677,57 @@ float SCULPT_brush_factor_with_color(SculptSession *ss, /* Auto-masking. */ const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); - /* Apply masks */ const float masks_combined = falloff * paint_mask * automasking_factor; - mul_v3_fl(rgba, masks_combined); - avg *= masks_combined; - /* Copy rgba for vector displacement */ - copy_v3_v3(r_rgb, rgba); + avg *= masks_combined; return avg; } -void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgb[3], float out_offset[3]) +void SCULPT_brush_strength_color(struct SculptSession *ss, + const struct Brush *brush, + const float brush_point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + struct AutomaskingNodeData *automask_data, + float r_rgba[4]) { - rgb[2] *= ss->cache->bstrength; - mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgb); + StrokeCache *cache = ss->cache; + + float avg = 1.0f; + sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, r_rgba); + + /* Hardness. */ + const float final_len = sculpt_apply_hardness(ss, len); + + /* Falloff curve. */ + const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) + * frontface(brush, cache->view_normal, vno, fno); + + /* Paint mask. */ + const float paint_mask = 1.0f - mask; + + /* Auto-masking. */ + const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); + + const float masks_combined = falloff * paint_mask * automasking_factor; + + mul_v4_fl(r_rgba, masks_combined); +} + +void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgba[4], float out_offset[3]) +{ + rgba[2] *= ss->cache->bstrength; + mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba); if (ss->cache->radial_symmetry_pass) { - mul_m4_v3(ss->cache->symm_rot_mat, rgb); + mul_m4_v3(ss->cache->symm_rot_mat, rgba); } - flip_v3_v3(out_offset, rgb, ss->cache->mirror_symmetry_pass); + flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass); } bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v) @@ -3262,18 +3316,16 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, continue; } - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, - brush, - vd.co, - sqrtf(test.dist), - vd.no, - vd.fno, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - nullptr, - rgb); + const float fade = SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + nullptr); mul_v3_v3fl(proxy[vd.i], offset, fade); diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c index a327faaf7a7..de11d1825bc 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c @@ -266,24 +266,33 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* Offset vertex. */ - float rgb[3]; - float fade = SCULPT_brush_factor_with_color(ss, - brush, - vd.co, - sqrtf(test.dist), - vd.no, - vd.fno, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - &automask_data, - rgb); - - if(ss->cache->brush->flag2 & BRUSH_RGB_AS_VECTOR_DISPLACEMENT + if(ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT && (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) { - SCULPT_calc_vertex_displacement(ss, rgb, proxy[vd.i]); + float r_rgba[4]; + SCULPT_brush_strength_color(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + &automask_data, + r_rgba); + SCULPT_calc_vertex_displacement(ss, r_rgba, proxy[vd.i]); } else { + float fade = SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + &automask_data); mul_v3_v3fl(proxy[vd.i], offset, fade); } @@ -312,7 +321,6 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) * initialize before threads so they can do curve mapping. */ BKE_curvemapping_init(brush->curve); - /* Threaded loop over nodes. */ SculptThreadedTaskData data = { .sd = sd, @@ -380,8 +388,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -390,8 +397,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -487,8 +493,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -497,8 +502,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -614,8 +618,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -624,8 +627,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -778,8 +780,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, if (SCULPT_plane_trim(ss->cache, brush, val)) { SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -788,8 +789,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -944,8 +944,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -954,8 +953,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -1080,8 +1078,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */ - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, ss->cache->radius * test.dist, @@ -1090,8 +1087,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -1242,8 +1238,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, else { SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - fade = bstrength * SCULPT_brush_factor_with_color(ss, + fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1252,8 +1247,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); } mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1386,8 +1380,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, orig_data.co, sqrtf(test.dist), @@ -1396,8 +1389,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1470,8 +1462,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); float vec[3], rot[3][3]; - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, orig_data.co, sqrtf(test.dist), @@ -1480,8 +1471,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); sub_v3_v3v3(vec, orig_data.co, ss->cache->location); axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); @@ -1551,8 +1541,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1561,8 +1550,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); const int vi = vd.index; float *disp_factor; @@ -1673,8 +1661,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1683,8 +1670,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float val[3]; if (vd.fno) { @@ -1750,8 +1736,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1760,8 +1745,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1838,8 +1822,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, /* Offset vertex. */ SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1848,8 +1831,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float val1[3]; float val2[3]; @@ -1963,8 +1945,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -1973,8 +1954,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float disp_center[3]; float x_disp[3]; float z_disp[3]; @@ -2088,18 +2068,16 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - float fade = bstrength * SCULPT_brush_factor_with_color(ss, - brush, - orig_data.co, - sqrtf(test.dist), - orig_data.no, - NULL, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - &automask_data, - rgb); + float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + orig_data.co, + sqrtf(test.dist), + orig_data.no, + NULL, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + &automask_data); if (grab_silhouette) { float silhouette_test_dir[3]; @@ -2301,8 +2279,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, /* Offset vertex. */ SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2311,8 +2288,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -2393,8 +2369,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2403,8 +2378,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float current_disp[3]; float current_disp_norm[3]; float final_disp[3] = {0.0f, 0.0f, 0.0f}; @@ -2559,8 +2533,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, orig_data.co, sqrtf(test.dist), @@ -2569,8 +2542,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co); if (vd.is_mesh) { @@ -2644,8 +2616,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -2654,8 +2625,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float limit_co[3]; float disp[3]; @@ -2719,8 +2689,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -2729,8 +2698,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float current_disp[3]; float current_disp_norm[3]; @@ -2889,9 +2857,8 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; const float fade = bstrength * - SCULPT_brush_factor_with_color(ss, + SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -2900,8 +2867,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, *vd.mask, vd.vertex, thread_id, - &automask_data, - rgb) * + &automask_data) * ss->cache->pressure; float avg[3], val[3]; @@ -2982,8 +2948,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, } SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -2992,8 +2957,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); if (bstrength > 0.0f) { (*vd.mask) += fade * bstrength * (1.0f - *vd.mask); diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index bc4868a43db..a5c469ca3a0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -507,9 +507,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, dist = dist_to_plane_v3(current_vertex_location, deform_plane); } - float rgb[3]; const float fade = sim_factor * bstrength * - SCULPT_brush_factor_with_color(ss, + SCULPT_brush_strength_factor(ss, brush, current_vertex_location, dist, @@ -518,8 +517,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float brush_disp[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index dd3c3012f07..9c2d6a78fab 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -144,9 +144,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, if (face_hidden) { continue; } - - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -155,8 +153,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); if (fade > 0.05f) { ss->face_sets[vert_map->indices[j]] = ss->cache->paint_face_set; @@ -168,9 +165,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } - - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -179,8 +174,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); if (fade > 0.05f) { SCULPT_vertex_face_set_set(ss, vd.vertex, ss->cache->paint_face_set); @@ -231,8 +225,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, continue; } - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -241,8 +234,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co); if (vd.is_mesh) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 51d60982488..4d734093eac 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1242,25 +1242,38 @@ const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss, char falloff_shape); /** - * Return a color and grayscale of a brush texture at a particular vertex multiplied by active masks. - * The grayscale value is usually multiplied by the offset vector and the color is used for non-linear vertex displacement. + * Return a multiplier for brush strength on a particular vertex. */ -float SCULPT_brush_factor_with_color(struct SculptSession *ss, - const struct Brush *brush, - const float point[3], - float len, - const float vno[3], - const float fno[3], - float mask, - const PBVHVertRef vertex, - int thread_id, - struct AutomaskingNodeData *automask_data, - float rgb[3]); +float SCULPT_brush_strength_factor(struct SculptSession *ss, + const struct Brush *brush, + const float point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + struct AutomaskingNodeData *automask_data); + +/** + * Return a color of a brush texture on a particular vertex multiplied by active masks. + */ +void SCULPT_brush_strength_color(struct SculptSession *ss, + const struct Brush *brush, + const float brush_point[3], + float len, + const float vno[3], + const float fno[3], + float mask, + const PBVHVertRef vertex, + int thread_id, + struct AutomaskingNodeData *automask_data, + float r_rgba[4]); /** * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement. */ - void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgb[3], float out_offset[3]); + void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgba[3], float out_offset[3]); /** * Tilts a normal by the x and y tilt values using the view axis. diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index 7602b62501c..ccee7814f83 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -72,8 +72,7 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* Use the brush falloff to weight the sampled normals. */ - float rgb[3]; - const float fade = SCULPT_brush_factor_with_color(ss, + const float fade = SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -82,8 +81,7 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); /* Sample the normal and area of the +X and -X axis individually. */ if (local_co[0] > 0.0f) { @@ -189,9 +187,8 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */ /* This produces a not round brush tip. */ - float rgb[3]; local_co[1] *= 2.0f; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, len_v3(local_co), @@ -200,8 +197,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); mul_v3_v3fl(proxy[vd.i], val, fade); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index aac46f0c875..ee716d1107a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -59,8 +59,7 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -69,8 +68,7 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float smooth_color[4]; SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex); @@ -155,8 +153,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - float fade = bstrength * SCULPT_brush_factor_with_color(ss, + float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, distance_to_stroke_location, @@ -165,8 +162,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); /* Density. */ float noise = 1.0f; @@ -413,8 +409,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -423,8 +418,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float current_disp[3]; float current_disp_norm[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index d86422d6f1a..75c84c48f77 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -174,8 +174,7 @@ template class PaintingKernel { const float3 face_normal(0.0f, 0.0f, 0.0f); const float mask = 0.0f; - float rgb[3]; - const float falloff_strength = SCULPT_brush_factor_with_color( + const float falloff_strength = SCULPT_brush_strength_factor( ss, brush, pixel_pos, @@ -185,8 +184,7 @@ template class PaintingKernel { mask, BKE_pbvh_make_vref(PBVH_REF_NONE), thread_id, - automask_data, - rgb); + automask_data); float4 paint_color = brush_color * falloff_strength * brush_strength; float4 buffer_color; blend_color_mix_float(buffer_color, color, paint_color); diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index 4673a1745ff..5af8381f6da 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -206,8 +206,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -216,8 +215,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float disp[3]; madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); @@ -298,8 +296,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color( + const float fade = bstrength * SCULPT_brush_strength_factor( ss, brush, vd.co, @@ -309,8 +306,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); if (smooth_mask) { float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask; val *= fade * bstrength; @@ -478,8 +474,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -488,8 +483,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); float disp[3]; SCULPT_surface_smooth_laplacian_step( @@ -528,8 +522,7 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( SCULPT_automasking_node_update(ss, &automask_data, &vd); - float rgb[3]; - const float fade = bstrength * SCULPT_brush_factor_with_color(ss, + const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, sqrtf(test.dist), @@ -538,8 +531,7 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - &automask_data, - rgb); + &automask_data); SCULPT_surface_smooth_displace_step( ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade); } diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 98e90ca3d4a..3ea2c3d70b7 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -412,7 +412,7 @@ typedef enum eBrushFlags2 { BRUSH_CLOTH_USE_COLLISION = (1 << 6), BRUSH_AREA_RADIUS_PRESSURE = (1 << 7), BRUSH_GRAB_SILHOUETTE = (1 << 8), - BRUSH_RGB_AS_VECTOR_DISPLACEMENT = (1 << 9), + BRUSH_USE_COLOR_AS_DISPLACEMENT = (1 << 9), } eBrushFlags2; typedef enum { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index bedb04ff3df..3d150846a5a 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2893,10 +2893,10 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Sample Bias", "Value added to texture samples"); RNA_def_property_update(prop, 0, "rna_Brush_update"); - prop = RNA_def_property(srna, "use_rgb_as_vector_displacement", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_RGB_AS_VECTOR_DISPLACEMENT); - RNA_def_property_ui_text(prop, "RGB as vector displacement", -"Handles each pixel as individual vector for displacement. Works only with area plane mapping"); + prop = RNA_def_property(srna, "use_color_as_displacement", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_COLOR_AS_DISPLACEMENT); + RNA_def_property_ui_text(prop, "Vector Displacement", +"Handles each pixel color as individual vector for displacement. Works only with area plane mapping"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR); -- 2.30.2 From 3cea9dd4a19e41cdede1402e159cbefee3e5cda8 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Mon, 23 Jan 2023 23:14:58 +0100 Subject: [PATCH 06/16] Sculpt: Apply texture size to displacement vector and use strength on all vector components --- source/blender/editors/sculpt_paint/sculpt.cc | 9 +++++++-- source/blender/editors/sculpt_paint/sculpt_brush_types.c | 2 +- source/blender/editors/sculpt_paint/sculpt_intern.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 1600f087586..b18f776124d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2719,9 +2719,14 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, mul_v4_fl(r_rgba, masks_combined); } -void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgba[4], float out_offset[3]) +void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[4], float out_offset[3]) { - rgba[2] *= ss->cache->bstrength; + mul_v3_fl(rgba, ss->cache->bstrength); + + rgba[0] *= 1.0f / (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]); + rgba[1] *= 1.0f / (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]); + rgba[2] *= 1.0f / (brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]); + mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba); if (ss->cache->radial_symmetry_pass) { diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c index de11d1825bc..dea646e4a6e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c @@ -280,7 +280,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, thread_id, &automask_data, r_rgba); - SCULPT_calc_vertex_displacement(ss, r_rgba, proxy[vd.i]); + SCULPT_calc_vertex_displacement(ss, brush, r_rgba, proxy[vd.i]); } else { float fade = SCULPT_brush_strength_factor(ss, diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 4d734093eac..e4cc20ccf4b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1273,7 +1273,7 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, /** * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement. */ - void SCULPT_calc_vertex_displacement(SculptSession *ss, float rgba[3], float out_offset[3]); + void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[3], float out_offset[3]); /** * Tilts a normal by the x and y tilt values using the view axis. -- 2.30.2 From e18f7440cb60e89245c8ae7be4870898bb081793 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Mon, 23 Jan 2023 23:26:10 +0100 Subject: [PATCH 07/16] Reverted unnecessary formatting changes and includes --- source/blender/editors/sculpt_paint/sculpt.cc | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index b18f776124d..a63abfaaec6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -74,8 +74,6 @@ #include "RNA_define.h" #include "bmesh.h" -#include "IMB_imbuf_types.h" -#include "RE_texture.h" using blender::float3; using blender::MutableSpan; @@ -3320,17 +3318,16 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } - const float fade = SCULPT_brush_strength_factor(ss, - brush, - vd.co, - sqrtf(test.dist), - vd.no, - vd.fno, - vd.mask ? *vd.mask : 0.0f, - vd.vertex, - thread_id, - nullptr); + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.vertex, + thread_id, + nullptr); mul_v3_v3fl(proxy[vd.i], offset, fade); -- 2.30.2 From ed74933f2bfa9b34bf865649060ef29bd0e1f5f3 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Tue, 24 Jan 2023 11:08:35 +0100 Subject: [PATCH 08/16] Fixed comment for brush_local_mat --- source/blender/editors/sculpt_paint/sculpt_intern.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index e4cc20ccf4b..6af2d86b8fa 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -583,7 +583,7 @@ typedef struct StrokeCache { float sculpt_normal_symm[3]; /* Used for area texture mode, local_mat gets calculated by - * calc_brush_local_mat() and used in brush_factor_with_color(). + * calc_brush_local_mat() and used in sculpt_apply_texture(). * Transforms from model-space coords to local area coords. */ float brush_local_mat[4][4]; -- 2.30.2 From 3528f8a95518ab3da9d4f74d861a6cdc452be670 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Tue, 24 Jan 2023 11:10:16 +0100 Subject: [PATCH 09/16] Reverted changes for masking in SCULPT_brush_strength_factor --- source/blender/editors/sculpt_paint/sculpt.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index a63abfaaec6..72dcce136e6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2666,18 +2666,14 @@ float SCULPT_brush_strength_factor(SculptSession *ss, const float final_len = sculpt_apply_hardness(ss, len); /* Falloff curve. */ - const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) - * frontface(brush, cache->view_normal, vno, fno); + avg *= BKE_brush_curve_strength(brush, final_len, cache->radius); + avg *= frontface(brush, cache->view_normal, vno, fno); /* Paint mask. */ - const float paint_mask = 1.0f - mask; + avg *= 1.0f - mask; /* Auto-masking. */ - const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); - - const float masks_combined = falloff * paint_mask * automasking_factor; - - avg *= masks_combined; + avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); return avg; } -- 2.30.2 From 30b0063f363fa741d8cb131e982e39dfd90b85ec Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Tue, 24 Jan 2023 21:04:02 +0100 Subject: [PATCH 10/16] Improved code style and removed function paint_get_tex_pixel_color_with_clamp --- .../editors/sculpt_paint/paint_cursor.cc | 19 ++++++---- .../editors/sculpt_paint/paint_intern.h | 12 +++---- .../editors/sculpt_paint/paint_utils.c | 36 ++----------------- source/blender/editors/sculpt_paint/sculpt.cc | 5 +-- .../editors/sculpt_paint/sculpt_intern.h | 2 +- 5 files changed, 21 insertions(+), 53 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 690aa86b7bd..bc21de513ae 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -55,6 +55,7 @@ #include "paint_intern.h" /* still needed for sculpt_stroke_get_location, should be * removed eventually (TODO) */ +#include "IMB_colormanagement.h" #include "sculpt_intern.h" /* TODOs: @@ -200,10 +201,18 @@ static void load_tex_task_cb_ex(void *__restrict userdata, y = len * sinf(angle); } - if (col) { - float rgba[4]; + float avg; + float rgba[4]; + paint_get_tex_pixel(mtex, x, y, pool, thread_id, &avg, rgba); - paint_get_tex_pixel_color_with_clamp(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace); + if (col) { + if (convert_to_linear) { + IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace); + } + + linearrgb_to_srgb_v3_v3(rgba, rgba); + + clamp_v4(rgba, 0.0f, 1.0f); buffer[index * 4] = rgba[0] * 255; buffer[index * 4 + 1] = rgba[1] * 255; @@ -211,10 +220,6 @@ static void load_tex_task_cb_ex(void *__restrict userdata, buffer[index * 4 + 3] = rgba[3] * 255; } else { - float avg; - float rgba_dummy[4]; - paint_get_tex_pixel(mtex, x, y, pool, thread_id, &avg, rgba_dummy); - avg += br->texture_sample_bias; /* Clamp to avoid precision overflow. */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 65abb73b1c9..ae44d7e4204 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -352,16 +352,12 @@ void paint_calc_redraw_planes(float planes[4][4], float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); + +/** + * Returns true when a color was sampled and false when a value was sampled. + */ bool paint_get_tex_pixel( const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread, float *r_intensity, float r_rgba[4]); -void paint_get_tex_pixel_color_with_clamp(const struct MTex *mtex, - float u, - float v, - float rgba[4], - struct ImagePool *pool, - int thread, - bool convert, - struct ColorSpace *colorspace); /** * Used for both 3D view and image window. diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 0b9563dfe31..ba25343d577 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -157,47 +157,17 @@ bool paint_get_tex_pixel(const MTex *mtex, { const float co[3] = {u, v, 0.0f}; float intensity; - const bool hasRGB = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, r_rgba); + const bool has_rgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, r_rgba); *r_intensity = intensity; - if (!hasRGB) { + if (!has_rgb) { r_rgba[0] = intensity; r_rgba[1] = intensity; r_rgba[2] = intensity; r_rgba[3] = 1.0f; } - return hasRGB; -} - -void paint_get_tex_pixel_color_with_clamp(const MTex *mtex, - float u, - float v, - float rgba[4], - struct ImagePool *pool, - int thread, - bool convert_to_linear, - struct ColorSpace *colorspace) -{ - const float co[3] = {u, v, 0.0f}; - float intensity; - - const bool hasRGB = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba); - - if (!hasRGB) { - rgba[0] = intensity; - rgba[1] = intensity; - rgba[2] = intensity; - rgba[3] = 1.0f; - } - - if (convert_to_linear) { - IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace); - } - - linearrgb_to_srgb_v3_v3(rgba, rgba); - - clamp_v4(rgba, 0.0f, 1.0f); + return has_rgb; } void paint_stroke_operator_properties(wmOperatorType *ot) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 72dcce136e6..b13de770315 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2588,10 +2588,7 @@ static void sculpt_apply_texture(const SculptSession *ss, if (!mtex->tex) { *r_value = 1.0f; - r_rgba[0] = 1.0f; - r_rgba[1] = 1.0f; - r_rgba[2] = 1.0f; - r_rgba[3] = 1.0f; + copy_v4_fl(r_rgba, 1.0f); return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 6af2d86b8fa..d74395a0339 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1273,7 +1273,7 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, /** * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement. */ - void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[3], float out_offset[3]); +void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[3], float out_offset[3]); /** * Tilts a normal by the x and y tilt values using the view axis. -- 2.30.2 From 577a437c664851dba696add1ffbda3df2df4489a Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Tue, 24 Jan 2023 21:12:09 +0100 Subject: [PATCH 11/16] Changed order of includes because of comment --- source/blender/editors/sculpt_paint/paint_cursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index bc21de513ae..08f5efba812 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -55,8 +55,8 @@ #include "paint_intern.h" /* still needed for sculpt_stroke_get_location, should be * removed eventually (TODO) */ -#include "IMB_colormanagement.h" #include "sculpt_intern.h" +#include "IMB_colormanagement.h" /* TODOs: * -- 2.30.2 From 964afd48e1e724fe1f469fd9915dc909245a1475 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Thu, 9 Feb 2023 21:58:36 +0100 Subject: [PATCH 12/16] Fixed brush inversion --- release/scripts/startup/bl_ui/properties_paint_common.py | 1 - source/blender/editors/sculpt_paint/sculpt.cc | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 6e8f032ee7c..63dd18cb703 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1147,7 +1147,6 @@ def brush_texture_settings(layout, brush, sculpt): col.prop(brush, "use_color_as_displacement", text="Vector Displacement") - def brush_mask_texture_settings(layout, brush): mask_tex_slot = brush.mask_texture_slot diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index e88afff4868..44cac313c49 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2713,6 +2713,10 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[4], float out_offset[3]) { mul_v3_fl(rgba, ss->cache->bstrength); + if(ss->cache->bstrength < 0) { + rgba[0] *= -1; + rgba[1] *= -1; + } rgba[0] *= 1.0f / (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]); rgba[1] *= 1.0f / (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]); -- 2.30.2 From cf6502f04ccb3f07c4bf7fc39049315398cacf9a Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Fri, 10 Feb 2023 19:53:35 +0100 Subject: [PATCH 13/16] Applied clang format --- .../editors/sculpt_paint/paint_cursor.cc | 2 +- .../editors/sculpt_paint/paint_intern.h | 9 +++- .../editors/sculpt_paint/paint_utils.c | 3 +- source/blender/editors/sculpt_paint/sculpt.cc | 51 +++++++++++-------- .../sculpt_paint/sculpt_brush_types.cc | 4 +- .../editors/sculpt_paint/sculpt_intern.h | 8 ++- source/blender/makesrna/intern/rna_brush.c | 6 ++- 7 files changed, 53 insertions(+), 30 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 08f5efba812..783c7c668c9 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -37,6 +37,7 @@ #include "WM_api.h" #include "wm_cursors.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "ED_image.h" @@ -56,7 +57,6 @@ /* still needed for sculpt_stroke_get_location, should be * removed eventually (TODO) */ #include "sculpt_intern.h" -#include "IMB_colormanagement.h" /* TODOs: * diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index c70bafe7cba..900d25aaf3f 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -356,8 +356,13 @@ float paint_calc_object_space_radius(struct ViewContext *vc, /** * Returns true when a color was sampled and false when a value was sampled. */ -bool paint_get_tex_pixel( -const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread, float *r_intensity, float r_rgba[4]); +bool paint_get_tex_pixel(const struct MTex *mtex, + float u, + float v, + struct ImagePool *pool, + int thread, + float *r_intensity, + float r_rgba[4]); /** * Used for both 3D view and image window. diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 44d01cce90c..ef794ea6a39 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -157,7 +157,8 @@ bool paint_get_tex_pixel(const MTex *mtex, { const float co[3] = {u, v, 0.0f}; float intensity; - const bool has_rgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, r_rgba); + const bool has_rgb = RE_texture_evaluate( + mtex, co, thread, pool, false, false, &intensity, r_rgba); *r_intensity = intensity; if (!has_rgb) { diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 44cac313c49..26cfab5058b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2630,12 +2630,13 @@ static void sculpt_apply_texture(const SculptSession *ss, paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba); - add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha + add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha *r_value -= brush->texture_sample_bias; } else { float point_2d[2]; - ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat); + ED_view3d_project_float_v2_m4( + cache->vc->region, symm_point, point_2d, cache->projection_mat); const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f}; *r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool); } @@ -2696,38 +2697,45 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, const float final_len = sculpt_apply_hardness(ss, len); /* Falloff curve. */ - const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) - * frontface(brush, cache->view_normal, vno, fno); + const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) * + frontface(brush, cache->view_normal, vno, fno); /* Paint mask. */ const float paint_mask = 1.0f - mask; /* Auto-masking. */ - const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data); + const float automasking_factor = SCULPT_automasking_factor_get( + cache->automasking, ss, vertex, automask_data); const float masks_combined = falloff * paint_mask * automasking_factor; mul_v4_fl(r_rgba, masks_combined); } -void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[4], float out_offset[3]) +void SCULPT_calc_vertex_displacement(SculptSession *ss, + const struct Brush *brush, + float rgba[4], + float out_offset[3]) { - mul_v3_fl(rgba, ss->cache->bstrength); - if(ss->cache->bstrength < 0) { - rgba[0] *= -1; - rgba[1] *= -1; - } + mul_v3_fl(rgba, ss->cache->bstrength); + if (ss->cache->bstrength < 0) { + rgba[0] *= -1; + rgba[1] *= -1; + } - rgba[0] *= 1.0f / (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]); - rgba[1] *= 1.0f / (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]); - rgba[2] *= 1.0f / (brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]); + rgba[0] *= 1.0f / + (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]); + rgba[1] *= 1.0f / + (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]); + rgba[2] *= 1.0f / + (brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]); - mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba); + mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba); - if (ss->cache->radial_symmetry_pass) { - mul_m4_v3(ss->cache->symm_rot_mat, rgba); - } - flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass); + if (ss->cache->radial_symmetry_pass) { + mul_m4_v3(ss->cache->symm_rot_mat, rgba); + } + flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass); } bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v) @@ -2997,7 +3005,10 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) mul_m4_v3(ob->world_to_object, y); } -static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4], float local_mat_inv[4][4]) +static void calc_brush_local_mat(const MTex *mtex, + Object *ob, + float local_mat[4][4], + float local_mat_inv[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc index 808fa3b8bb9..247d1838b1f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc @@ -265,8 +265,8 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); /* Offset vertex. */ - if(ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT - && (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) { + if (ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT && + (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) { float r_rgba[4]; SCULPT_brush_strength_color(ss, brush, diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 40b25c73050..e6012649e29 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1274,9 +1274,13 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, float r_rgba[4]); /** - * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement. + * Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector + * displacement. */ -void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[3], float out_offset[3]); +void SCULPT_calc_vertex_displacement(SculptSession *ss, + const struct Brush *brush, + float rgba[3], + float out_offset[3]); /** * Tilts a normal by the x and y tilt values using the view axis. diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 20f6bc5b661..13832457c23 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2901,8 +2901,10 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_color_as_displacement", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_COLOR_AS_DISPLACEMENT); - RNA_def_property_ui_text(prop, "Vector Displacement", -"Handles each pixel color as individual vector for displacement. Works only with area plane mapping"); + RNA_def_property_ui_text(prop, + "Vector Displacement", + "Handles each pixel color as individual vector for displacement. Works " + "only with area plane mapping"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR); -- 2.30.2 From 36fa56bd1168f007a34c863e034263c11e2d1d22 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Fri, 10 Feb 2023 20:45:59 +0100 Subject: [PATCH 14/16] Removed unnecessary struct keyword --- source/blender/editors/sculpt_paint/sculpt.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 6c3c7a0f0e4..5523dd0134b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2676,8 +2676,8 @@ float SCULPT_brush_strength_factor(SculptSession *ss, return avg; } -void SCULPT_brush_strength_color(struct SculptSession *ss, - const struct Brush *brush, +void SCULPT_brush_strength_color(SculptSession *ss, + const Brush *brush, const float brush_point[3], float len, const float vno[3], @@ -2685,7 +2685,7 @@ void SCULPT_brush_strength_color(struct SculptSession *ss, float mask, const PBVHVertRef vertex, int thread_id, - struct AutomaskingNodeData *automask_data, + AutomaskingNodeData *automask_data, float r_rgba[4]) { StrokeCache *cache = ss->cache; -- 2.30.2 From 3564b4504f2a7abd6d24c9cde702ad3c18bf0b44 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Fri, 10 Feb 2023 20:57:35 +0100 Subject: [PATCH 15/16] One more struct keyword removed --- source/blender/editors/sculpt_paint/sculpt.cc | 2 +- source/blender/editors/sculpt_paint/sculpt_intern.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 5523dd0134b..a79593d6f63 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2713,7 +2713,7 @@ void SCULPT_brush_strength_color(SculptSession *ss, } void SCULPT_calc_vertex_displacement(SculptSession *ss, - const struct Brush *brush, + const Brush *brush, float rgba[4], float out_offset[3]) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index 41c66fda2d0..5117b49407f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -1266,7 +1266,7 @@ void SCULPT_brush_strength_color(SculptSession *ss, * displacement. */ void SCULPT_calc_vertex_displacement(SculptSession *ss, - const struct Brush *brush, + const Brush *brush, float rgba[3], float out_offset[3]); -- 2.30.2 From 2753cc0ee200be7b477c07a98a0909f8097e9399 Mon Sep 17 00:00:00 2001 From: Robin Hohnsbeen Date: Mon, 13 Feb 2023 09:36:07 +0100 Subject: [PATCH 16/16] Cleaned up texture size computation and added comments --- source/blender/editors/sculpt_paint/sculpt.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index a79593d6f63..d6065481a85 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -54,6 +54,7 @@ #include "BKE_scene.h" #include "BKE_subdiv_ccg.h" #include "BKE_subsurf.h" +#include "BLI_math_vector.hh" #include "NOD_texture.h" @@ -2718,20 +2719,21 @@ void SCULPT_calc_vertex_displacement(SculptSession *ss, float out_offset[3]) { mul_v3_fl(rgba, ss->cache->bstrength); + /* Handle brush inversion */ if (ss->cache->bstrength < 0) { rgba[0] *= -1; rgba[1] *= -1; } - rgba[0] *= 1.0f / - (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]); - rgba[1] *= 1.0f / - (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]); - rgba[2] *= 1.0f / - (brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]); + /* Apply texture size */ + for (int i = 0; i < 3; ++i) { + rgba[i] *= blender::math::safe_divide(1.0f, pow2f(brush->mtex.size[i])); + } + /* Transform vector to object space */ mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba); + /* Handle symmetry */ if (ss->cache->radial_symmetry_pass) { mul_m4_v3(ss->cache->symm_rot_mat, rgba); } -- 2.30.2