Sculpt: Grab silhouette option

This adds a property to the grab that masks vertices based on its
original normal and grab delta. When used on thin meshes, it allows to
grab the silhouette from one side of the object without affecting the
shape of the other side.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D9205
This commit is contained in:
Pablo Dobarro 2020-10-22 19:06:00 +02:00 committed by Pablo Dobarro
parent b5169cd230
commit 383c20a6ab
4 changed files with 30 additions and 9 deletions

View File

@ -698,6 +698,7 @@ def brush_settings(layout, context, brush, popover=False):
elif sculpt_tool == 'GRAB':
layout.prop(brush, "use_grab_active_vertex")
layout.prop(brush, "use_grab_silhouette")
elif sculpt_tool == 'PAINT':
row = layout.row(align=True)

View File

@ -3805,20 +3805,33 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
const 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.index,
thread_id);
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.index,
thread_id);
if (grab_silhouette) {
float silhouette_test_dir[3];
normalize_v3_v3(silhouette_test_dir, grab_delta);
if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta) < 0.0f) {
mul_v3_fl(silhouette_test_dir, -1.0f);
}
float vno[3];
normal_short_to_float_v3(vno, orig_data.no);
fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
}
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);

View File

@ -775,6 +775,7 @@ typedef enum eBrushFlags2 {
BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5),
BRUSH_CLOTH_USE_COLLISION = (1 << 6),
BRUSH_AREA_RADIUS_PRESSURE = (1 << 7),
BRUSH_GRAB_SILHOUETTE = (1 << 8),
} eBrushFlags2;
typedef enum {

View File

@ -2968,6 +2968,12 @@ static void rna_def_brush(BlenderRNA *brna)
"Apply the maximum grab strength to the active vertex instead of the cursor location");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_grab_silhouette", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_GRAB_SILHOUETTE);
RNA_def_property_ui_text(
prop, "Grab Silhouette", "Grabs trying to automask the silhouette of the object");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_paint_antialiasing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sampling_flag", BRUSH_PAINT_ANTIALIASING);
RNA_def_property_ui_text(prop, "Anti-Aliasing", "Smooths the edges of the strokes");