Sculpt: Add plane mode for draw sharp brush

This commit is contained in:
Joseph Eagar 2021-10-06 18:26:19 -07:00
parent 313c6811c3
commit b970edb97e
7 changed files with 131 additions and 9 deletions

View File

@ -1907,10 +1907,16 @@ def brush_settings_advanced(layout, context, brush, popover=False):
# Draw shared settings.
if use_accumulate:
layout.prop(brush, "use_accumulate")
UnifiedPaintPanel.channel_unified(layout.column(),
context,
brush,
"accumulate")
if use_frontface:
layout.prop(brush, "use_frontface", text="Front Faces Only")
UnifiedPaintPanel.channel_unified(layout.column(),
context,
brush,
"use_frontface", text="Front Faces Only")
def draw_color_settings(context, layout, brush, color_type=False):

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 34
#define BLENDER_FILE_SUBVERSION 35
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -578,6 +578,12 @@ MAKE_ENUM(smear_deform_type, "Deformation", "Deformation type that is used in th
MAKE_FLOAT(smear_deform_blend, "Smear Blend", "Blend with existing paint", 1.0f, 0.0f, 1.0f)
MAKE_ENUM_EX(sharp_mode, "Sharp Mode", "", 0, 0, {
{0, "SIMPLE", "NONE", "Simple", ""},
{1, "PLANE", "NONE", "Plane", ""},
{-1}
})
//MAKE_FLOAT3_EX
/* clang-format on */
#if defined(BRUSH_CHANNEL_DEFINE_TYPES) || defined(BRUSH_CHANNEL_DEFINE_EXTERNAL)

View File

@ -267,6 +267,7 @@ static bool check_builtin_init()
// SETCAT(radius, "Basic");
// SETCAT(direction, "Basic");
SETCAT(accumulate, "Basic");
SETCAT(use_frontface, "Basic");
SETCAT(smear_deform_type, "Smear");
SETCAT(smear_deform_blend, "Smear");
@ -973,7 +974,9 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
ADDCH(strength);
ADDCH(radius_unit);
ADDCH(unprojected_radius);
ADDCH(use_frontface);
ADDCH(sharp_mode);
ADDCH(show_origco);
ADDCH(use_surface_falloff);
@ -1245,6 +1248,7 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
if (!ELEM(tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
SHOWWRK(autosmooth);
SHOWWRK(topology_rake);
SHOWWRK(topology_rake_mode);
SHOWCTX(autosmooth);
}
@ -1264,6 +1268,12 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
SHOWWRK(dyntopo_disabled);
switch (tool) {
case SCULPT_TOOL_DRAW_SHARP:
SHOWWRK(sharp_mode);
SHOWCTX(sharp_mode);
// SHOWWRK(plane_offset);
// SHOWCTX(plane_offset);
break;
case SCULPT_TOOL_INFLATE:
case SCULPT_TOOL_BLOB:
SHOWCTX(crease_pinch_factor);

View File

@ -1796,6 +1796,13 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 35)) {
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
BKE_brush_channelset_ui_init(brush, brush->sculpt_tool);
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 27)) {
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (brush->channels) {

View File

@ -5251,9 +5251,9 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
}
static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
static void do_draw_sharp_brush_task_cb_ex_plane(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@ -5273,6 +5273,13 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
float planeco[3], noffset[3];
copy_v3_v3(planeco, ss->cache->location);
add_v3_v3(planeco, offset);
copy_v3_v3(noffset, offset);
normalize_v3(noffset);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
// SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
SCULPT_vertex_check_origdata(ss, vd.vertex);
@ -5303,17 +5310,95 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_node_mark_update(data->nodes[n]);
}
static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const Brush *brush = data->brush;
const float *offset = data->offset;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
float(*proxy)[3];
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
SculptBrushTest test;
SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
float planeco[3], noffset[3];
copy_v3_v3(planeco, ss->cache->location);
add_v3_v3(planeco, offset);
copy_v3_v3(noffset, offset);
normalize_v3(noffset);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
// SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
SCULPT_vertex_check_origdata(ss, vd.vertex);
MSculptVert *mv = SCULPT_vertex_get_mdyntopo(ss, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, mv->origco)) {
continue;
}
/* Offset vertex. */
const float fade = SCULPT_brush_strength_factor(ss,
brush,
mv->origco,
sqrtf(test.dist),
NULL,
mv->origno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
thread_id);
float vec[3];
// copy_v3_v3(noffset, mv->origno);
copy_v3_v3(planeco, ss->cache->location);
madd_v3_v3fl(planeco, offset, fade);
sub_v3_v3v3(vec, mv->origco, planeco);
madd_v3_v3fl(vec, noffset, -dot_v3v3(noffset, vec));
add_v3_v3(vec, planeco);
sub_v3_v3(vec, vd.co);
mul_v3_v3fl(proxy[vd.i], vec, fade * fade);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
BKE_pbvh_node_mark_update(data->nodes[n]);
}
static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
Brush *brush = ss->cache->brush ? ss->cache->brush : BKE_paint_brush(&sd->paint);
float offset[3];
const float bstrength = ss->cache->bstrength;
bool mode = SCULPT_get_int(ss, sharp_mode, sd, brush);
float plane_offset = SCULPT_get_float(ss, plane_offset, sd, brush);
/* Offset with as much as possible factored in already. */
float effective_normal[3];
SCULPT_tilt_effective_normal_get(ss, brush, effective_normal);
mul_v3_v3fl(offset, effective_normal, ss->cache->radius);
if (mode == SCULPT_SHARP_PLANE) { // average with view normal
add_v3_v3(effective_normal, ss->cache->view_normal);
mul_v3_fl(effective_normal, 0.5f);
}
mul_v3_v3fl(offset, effective_normal, ss->cache->radius + ss->cache->radius * plane_offset);
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
@ -5332,7 +5417,13 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings);
if (mode == SCULPT_SHARP_SIMPLE) {
BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings);
}
else {
BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex_plane, &settings);
}
}
/* -------------------------------------------------------------------- */

View File

@ -1987,3 +1987,5 @@ struct BMesh *SCULPT_dyntopo_empty_bmesh();
SCULPT_TOOL_POSE)
void SCULPT_undo_ensure_bmlog(struct Object *ob);
enum { SCULPT_SHARP_SIMPLE, SCULPT_SHARP_PLANE };