Vector displacement for the sculpting draw brush #104481

Merged
Jeroen Bakker merged 18 commits from robin.hohni/blender:sculpt-vector-displacement into main 2023-02-14 15:29:40 +01:00
15 changed files with 257 additions and 259 deletions
Showing only changes of commit 5ca7ce0752 - Show all commits

View File

@ -1141,11 +1141,10 @@ def brush_texture_settings(layout, brush, sculpt):
# texture_sample_bias # texture_sample_bias
layout.prop(brush, "texture_sample_bias", slider=True, text="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': if brush.sculpt_tool == 'DRAW':
col = layout.column() col = layout.column()
col.active = tex_slot.map_mode == 'AREA_PLANE' 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")
Jeroen-Bakker marked this conversation as resolved
Review

Python has some rules about the number of lines between statements. Here it is max 1.

Python has some rules about the number of lines between statements. Here it is max 1.

View File

@ -203,7 +203,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
if (col) { if (col) {
float rgba[4]; 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] = rgba[0] * 255;
buffer[index * 4 + 1] = rgba[1] * 255; buffer[index * 4 + 1] = rgba[1] * 255;
@ -213,7 +213,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
else { else {
float avg; float avg;
float rgba_dummy[4]; 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; avg += br->texture_sample_bias;

View File

@ -353,13 +353,13 @@ float paint_calc_object_space_radius(struct ViewContext *vc,
const float center[3], const float center[3],
float pixel_radius); float pixel_radius);
bool paint_get_tex_pixel( 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]); 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_srgb_with_clamp(const struct MTex *mtex, void paint_get_tex_pixel_color_with_clamp(const struct MTex *mtex,
float u, float u,
float v, float v,
float rgba[4], float rgba[4],
int thread,
struct ImagePool *pool, struct ImagePool *pool,
int thread,
bool convert, bool convert,
struct ColorSpace *colorspace); struct ColorSpace *colorspace);

View File

@ -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, bool paint_get_tex_pixel(const MTex *mtex,
float u, float u,
float v, float v,
int thread,
struct ImagePool *pool, struct ImagePool *pool,
int thread,
/* Return arguments. */ /* Return arguments. */
float *r_intensity, float *r_intensity,
float r_rgba[4]) float r_rgba[4])
@ -170,12 +170,12 @@ bool paint_get_tex_pixel(const MTex *mtex,
return hasRGB; 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 u,
float v, float v,
float rgba[4], float rgba[4],
int thread,
struct ImagePool *pool, struct ImagePool *pool,
int thread,
bool convert_to_linear, bool convert_to_linear,
struct ColorSpace *colorspace) struct ColorSpace *colorspace)
{ {

View File

@ -2557,35 +2557,52 @@ static float brush_strength(const Sculpt *sd,
} }
} }
float SCULPT_brush_factor_with_color(SculptSession *ss, static float sculpt_apply_hardness(const SculptSession *ss, const float input_len)
const Brush *brush, {
const float brush_point[3], const StrokeCache *cache = ss->cache;
float len, float final_len = input_len;
const float vno[3], const float hardness = cache->paint_brush.hardness;
const float fno[3], float p = input_len / cache->radius;
float mask, if (p < hardness) {
const PBVHVertRef vertex, final_len = 0.0f;
int thread_id, }
AutomaskingNodeData *automask_data, else if (hardness == 1.0f) {
float r_rgb[3]) 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; StrokeCache *cache = ss->cache;
const Scene *scene = cache->vc->scene; const Scene *scene = cache->vc->scene;
const MTex *mtex = BKE_brush_mask_texture_get(brush, 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];
sub_v3_v3v3(point, brush_point, cache->plane_offset);
if (!mtex->tex) { if (!mtex->tex) {
rgba[0] = 1.0f; *r_value = 1.0f;
rgba[1] = 1.0f; r_rgba[0] = 1.0f;
rgba[2] = 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. */ /* 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 { else {
float symm_point[3]; float symm_point[3];
@ -2616,33 +2633,39 @@ float SCULPT_brush_factor_with_color(SculptSession *ss,
x += mtex->ofs[0]; x += mtex->ofs[0];
y += mtex->ofs[1]; 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 add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha
avg -= brush->texture_sample_bias; *r_value -= brush->texture_sample_bias;
} }
else { else {
float point_2d[2]; 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}; 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. */ /* Hardness. */
float final_len = len; const float final_len = sculpt_apply_hardness(ss, 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;
}
/* Falloff curve. */ /* Falloff curve. */
const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) 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. */ /* 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);
/* Apply masks */
const float masks_combined = falloff * paint_mask * automasking_factor; const float masks_combined = falloff * paint_mask * automasking_factor;
mul_v3_fl(rgba, masks_combined);
avg *= masks_combined;
/* Copy rgba for vector displacement */ avg *= masks_combined;
copy_v3_v3(r_rgb, rgba);
return avg; 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; StrokeCache *cache = ss->cache;
mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgb);
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);
robin.hohni marked this conversation as resolved
Review

For readability would suggest to first square the size, and then do the inf check using math::safe_divide. Seems we currently don't have a safe divide in math for 2 vector types.

rgba[i] *= math::safe_divide(1.0f, POW2(brush->mtex.size[i])); perhaps?

For readability would suggest to first square the size, and then do the inf check using `math::safe_divide`. Seems we currently don't have a safe divide in math for 2 vector types. `rgba[i] *= math::safe_divide(1.0f, POW2(brush->mtex.size[i]));` perhaps?
Review

Thanks for the hint! Made a commit :)

Thanks for the hint! Made a commit :)
if (ss->cache->radial_symmetry_pass) { 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) 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; continue;
} }
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss, brush,
brush, vd.co,
vd.co, sqrtf(test.dist),
sqrtf(test.dist), vd.no,
vd.no, vd.fno,
vd.fno, vd.mask ? *vd.mask : 0.0f,
vd.mask ? *vd.mask : 0.0f, vd.vertex,
vd.vertex, thread_id,
thread_id, nullptr);
nullptr,
rgb);
mul_v3_v3fl(proxy[vd.i], offset, fade); mul_v3_v3fl(proxy[vd.i], offset, fade);

View File

@ -266,24 +266,33 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
/* Offset vertex. */ /* Offset vertex. */
float rgb[3]; if(ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT
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
&& (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) { && (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 { 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); 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. */ * initialize before threads so they can do curve mapping. */
BKE_curvemapping_init(brush->curve); BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */ /* Threaded loop over nodes. */
SculptThreadedTaskData data = { SculptThreadedTaskData data = {
.sd = sd, .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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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)) { if (SCULPT_plane_trim(ss->cache, brush, val)) {
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
/* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */ /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
ss->cache->radius * test.dist, 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); 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 { else {
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; fade = bstrength * SCULPT_brush_strength_factor(ss,
fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
} }
mul_v3_v3fl(proxy[vd.i], grab_delta, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
orig_data.co, orig_data.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], cono, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float vec[3], rot[3][3]; float vec[3], rot[3][3];
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
orig_data.co, orig_data.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
sub_v3_v3v3(vec, orig_data.co, ss->cache->location); sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
const int vi = vd.index; const int vi = vd.index;
float *disp_factor; 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float val[3]; float val[3];
if (vd.fno) { 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], cono, fade); 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. */ /* Offset vertex. */
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float val1[3]; float val1[3];
float val2[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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float disp_center[3]; float disp_center[3];
float x_disp[3]; float x_disp[3];
float z_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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; float fade = bstrength * SCULPT_brush_strength_factor(ss,
float fade = bstrength * SCULPT_brush_factor_with_color(ss, brush,
brush, orig_data.co,
orig_data.co, sqrtf(test.dist),
sqrtf(test.dist), orig_data.no,
orig_data.no, NULL,
NULL, vd.mask ? *vd.mask : 0.0f,
vd.mask ? *vd.mask : 0.0f, vd.vertex,
vd.vertex, thread_id,
thread_id, &automask_data);
&automask_data,
rgb);
if (grab_silhouette) { if (grab_silhouette) {
float silhouette_test_dir[3]; float silhouette_test_dir[3];
@ -2301,8 +2279,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
/* Offset vertex. */ /* Offset vertex. */
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
orig_data.co, orig_data.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], offset, fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
orig_data.co, orig_data.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float current_disp[3]; float current_disp[3];
float current_disp_norm[3]; float current_disp_norm[3];
float final_disp[3] = {0.0f, 0.0f, 0.0f}; 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
orig_data.co, orig_data.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co); SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
if (vd.is_mesh) { 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float limit_co[3]; float limit_co[3];
float disp[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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float current_disp[3]; float current_disp[3];
float current_disp_norm[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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3];
const float fade = bstrength * const float fade = bstrength *
SCULPT_brush_factor_with_color(ss, SCULPT_brush_strength_factor(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), sqrtf(test.dist),
@ -2900,8 +2867,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
*vd.mask, *vd.mask,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data) *
rgb) *
ss->cache->pressure; ss->cache->pressure;
float avg[3], val[3]; 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), sqrtf(test.dist),
@ -2992,8 +2957,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
0.0f, 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
if (bstrength > 0.0f) { if (bstrength > 0.0f) {
(*vd.mask) += fade * bstrength * (1.0f - *vd.mask); (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);

View File

@ -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); dist = dist_to_plane_v3(current_vertex_location, deform_plane);
} }
float rgb[3];
const float fade = sim_factor * bstrength * const float fade = sim_factor * bstrength *
SCULPT_brush_factor_with_color(ss, SCULPT_brush_strength_factor(ss,
brush, brush,
current_vertex_location, current_vertex_location,
dist, 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float brush_disp[3]; float brush_disp[3];

View File

@ -144,9 +144,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
if (face_hidden) { if (face_hidden) {
continue; continue;
} }
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
float rgb[3];
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
if (fade > 0.05f) { if (fade > 0.05f) {
ss->face_sets[vert_map->indices[j]] = ss->cache->paint_face_set; 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)) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue; continue;
} }
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
float rgb[3];
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
if (fade > 0.05f) { if (fade > 0.05f) {
SCULPT_vertex_face_set_set(ss, vd.vertex, ss->cache->paint_face_set); 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; continue;
} }
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co); SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
if (vd.is_mesh) { if (vd.is_mesh) {

View File

@ -1242,25 +1242,38 @@ const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss,
char falloff_shape); char falloff_shape);
/** /**
* Return a color and grayscale of a brush texture at a particular vertex multiplied by active masks. * Return a multiplier for brush strength on a particular vertex.
* The grayscale value is usually multiplied by the offset vector and the color is used for non-linear vertex displacement.
*/ */
float SCULPT_brush_factor_with_color(struct SculptSession *ss, float SCULPT_brush_strength_factor(struct SculptSession *ss,
const struct Brush *brush, const struct Brush *brush,
const float point[3], const float point[3],
float len, float len,
const float vno[3], const float vno[3],
const float fno[3], const float fno[3],
float mask, float mask,
const PBVHVertRef vertex, const PBVHVertRef vertex,
int thread_id, int thread_id,
struct AutomaskingNodeData *automask_data, struct AutomaskingNodeData *automask_data);
float rgb[3]);
/**
* 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. * 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. * Tilts a normal by the x and y tilt values using the view axis.

View File

@ -72,8 +72,7 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
/* Use the brush falloff to weight the sampled normals. */ /* Use the brush falloff to weight the sampled normals. */
float rgb[3]; const float fade = SCULPT_brush_strength_factor(ss,
const float fade = SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
/* Sample the normal and area of the +X and -X axis individually. */ /* Sample the normal and area of the +X and -X axis individually. */
if (local_co[0] > 0.0f) { 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. */ /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
/* This produces a not round brush tip. */ /* This produces a not round brush tip. */
float rgb[3];
local_co[1] *= 2.0f; 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, brush,
vd.co, vd.co,
len_v3(local_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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
mul_v3_v3fl(proxy[vd.i], val, fade); mul_v3_v3fl(proxy[vd.i], val, fade);

View File

@ -59,8 +59,7 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float smooth_color[4]; float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; float fade = bstrength * SCULPT_brush_strength_factor(ss,
float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
distance_to_stroke_location, 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
/* Density. */ /* Density. */
float noise = 1.0f; 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float current_disp[3]; float current_disp[3];
float current_disp_norm[3]; float current_disp_norm[3];

View File

@ -174,8 +174,7 @@ template<typename ImageBuffer> class PaintingKernel {
const float3 face_normal(0.0f, 0.0f, 0.0f); const float3 face_normal(0.0f, 0.0f, 0.0f);
const float mask = 0.0f; const float mask = 0.0f;
float rgb[3]; const float falloff_strength = SCULPT_brush_strength_factor(
const float falloff_strength = SCULPT_brush_factor_with_color(
ss, ss,
brush, brush,
pixel_pos, pixel_pos,
@ -185,8 +184,7 @@ template<typename ImageBuffer> class PaintingKernel {
mask, mask,
BKE_pbvh_make_vref(PBVH_REF_NONE), BKE_pbvh_make_vref(PBVH_REF_NONE),
thread_id, thread_id,
automask_data, automask_data);
rgb);
float4 paint_color = brush_color * falloff_strength * brush_strength; float4 paint_color = brush_color * falloff_strength * brush_strength;
float4 buffer_color; float4 buffer_color;
blend_color_mix_float(buffer_color, color, paint_color); blend_color_mix_float(buffer_color, color, paint_color);

View File

@ -206,8 +206,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
SCULPT_automasking_node_update(ss, &automask_data, &vd); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float disp[3]; float disp[3];
madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(
const float fade = bstrength * SCULPT_brush_factor_with_color(
ss, ss,
brush, brush,
vd.co, 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), smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
if (smooth_mask) { if (smooth_mask) {
float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask; float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask;
val *= fade * bstrength; 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
float disp[3]; float disp[3];
SCULPT_surface_smooth_laplacian_step( 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); SCULPT_automasking_node_update(ss, &automask_data, &vd);
float rgb[3]; const float fade = bstrength * SCULPT_brush_strength_factor(ss,
const float fade = bstrength * SCULPT_brush_factor_with_color(ss,
brush, brush,
vd.co, vd.co,
sqrtf(test.dist), 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.mask ? *vd.mask : 0.0f,
vd.vertex, vd.vertex,
thread_id, thread_id,
&automask_data, &automask_data);
rgb);
SCULPT_surface_smooth_displace_step( SCULPT_surface_smooth_displace_step(
ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade); ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade);
} }

View File

@ -412,7 +412,7 @@ typedef enum eBrushFlags2 {
BRUSH_CLOTH_USE_COLLISION = (1 << 6), BRUSH_CLOTH_USE_COLLISION = (1 << 6),
BRUSH_AREA_RADIUS_PRESSURE = (1 << 7), BRUSH_AREA_RADIUS_PRESSURE = (1 << 7),
BRUSH_GRAB_SILHOUETTE = (1 << 8), BRUSH_GRAB_SILHOUETTE = (1 << 8),
BRUSH_RGB_AS_VECTOR_DISPLACEMENT = (1 << 9), BRUSH_USE_COLOR_AS_DISPLACEMENT = (1 << 9),
} eBrushFlags2; } eBrushFlags2;
typedef enum { typedef enum {

View File

@ -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_ui_text(prop, "Texture Sample Bias", "Value added to texture samples");
RNA_def_property_update(prop, 0, "rna_Brush_update"); RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_rgb_as_vector_displacement", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_color_as_displacement", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_RGB_AS_VECTOR_DISPLACEMENT); RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_COLOR_AS_DISPLACEMENT);
RNA_def_property_ui_text(prop, "RGB as vector displacement", RNA_def_property_ui_text(prop, "Vector Displacement",
"Handles each pixel as individual vector for displacement. Works only with area plane mapping"); "Handles each pixel color as individual vector for displacement. Works only with area plane mapping");
RNA_def_property_update(prop, 0, "rna_Brush_update"); RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR); prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR);