diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_paint_common.py | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector_inline.c | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 6 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 90 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_intern.h | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_defaults.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 10 |
10 files changed, 105 insertions, 24 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 2031546f4d0..e82caccdfe1 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -629,10 +629,14 @@ def brush_settings(layout, context, brush, popover=False): if brush.sculpt_tool == 'SCRAPE': row = layout.row() + row.prop(brush, "area_radius_factor", slider=True) + row = layout.row() row.prop(brush, "invert_to_scrape_fill", text="Invert to Fill") if brush.sculpt_tool == 'FILL': row = layout.row() + row.prop(brush, "area_radius_factor", slider=True) + row = layout.row() row.prop(brush, "invert_to_scrape_fill", text="Invert to Scrape") if brush.sculpt_tool == 'GRAB': diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 69831f33ce5..6a40d126352 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -82,6 +82,7 @@ static void brush_defaults(Brush *brush) FROM_DEFAULT(topology_rake_factor); FROM_DEFAULT(crease_pinch_factor); FROM_DEFAULT(normal_radius_factor); + FROM_DEFAULT(area_radius_factor); FROM_DEFAULT(sculpt_plane); FROM_DEFAULT(plane_offset); FROM_DEFAULT(clone.alpha); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index b39e979ec47..19a378269fe 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -105,6 +105,7 @@ MINLINE void add_v4_fl(float r[4], float f); MINLINE void add_v2_v2(float r[2], const float a[2]); MINLINE void add_v2_v2_db(double r[2], const double a[2]); MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]); +MINLINE void add_v2_v2_int(int r[2], const int a[2]); MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]); MINLINE void add_v3_v3(float r[3], const float a[3]); MINLINE void add_v3_v3_db(double r[3], const double a[3]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index caa38c9cf08..a304042a605 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -373,6 +373,12 @@ MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]) r[1] = a[1] + b[1]; } +MINLINE void add_v2_v2_int(int r[2], const int a[2]) +{ + r[0] = r[0] + a[0]; + r[1] = r[1] + a[1]; +} + MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]) { r[0] = a[0] + b[0]; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 6062d971629..dd67a4d72cb 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -4254,6 +4254,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + for (Brush *br = bmain->brushes.first; br; br = br->id.next) { + if (br->ob_mode & OB_MODE_SCULPT && br->area_radius_factor == 0.0f) { + br->area_radius_factor = 0.5f; + } + } } if (!MAIN_VERSION_ATLEAST(bmain, 282, 2)) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 4fae136d133..92c74538fd1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1439,7 +1439,8 @@ typedef struct AreaNormalCenterTLSData { /* 0 = towards view, 1 = flipped */ float area_cos[2][3]; float area_nos[2][3]; - int area_count[2]; + int count_no[2]; + int count_co[2]; } AreaNormalCenterTLSData; static void calc_area_normal_and_center_task_cb(void *__restrict userdata, @@ -1456,24 +1457,45 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, SculptUndoNode *unode = NULL; bool use_original = false; + bool normal_test_r, area_test_r; if (ss->cache && ss->cache->original) { unode = sculpt_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS); use_original = (unode->co || unode->bm_entry); } - SculptBrushTest test; - SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape( - ss, &test, data->brush->falloff_shape); + SculptBrushTest normal_test; + SculptBrushTestFn sculpt_brush_normal_test_sq_fn = sculpt_brush_test_init_with_falloff_shape( + ss, &normal_test, data->brush->falloff_shape); /* Update the test radius to sample the normal using the normal radius of the brush. */ if (data->brush->ob_mode == OB_MODE_SCULPT) { - float test_radius = sqrtf(test.radius_squared); - /* Layer brush produces artifacts with normal radius. */ + float test_radius = sqrtf(normal_test.radius_squared); + /* Layer brush produces artifacts with normal and area radius. */ if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) { test_radius *= data->brush->normal_radius_factor; } - test.radius_squared = test_radius * test_radius; + normal_test.radius_squared = test_radius * test_radius; + } + + SculptBrushTest area_test; + SculptBrushTestFn sculpt_brush_area_test_sq_fn = sculpt_brush_test_init_with_falloff_shape( + ss, &area_test, data->brush->falloff_shape); + + if (data->brush->ob_mode == OB_MODE_SCULPT) { + float test_radius = sqrtf(area_test.radius_squared); + /* Layer brush produces artifacts with normal and area radius */ + if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) { + /* Enable area radius control only on Scrape for now */ + if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) && + data->brush->area_radius_factor > 0.0f) { + test_radius *= data->brush->area_radius_factor; + } + else { + test_radius *= data->brush->normal_radius_factor; + } + } + area_test.radius_squared = test_radius * test_radius; } /* When the mesh is edited we can't rely on original coords @@ -1493,22 +1515,26 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, }; float co[3]; - closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + closest_on_tri_to_point_v3(co, normal_test.location, UNPACK3(co_tri)); + + normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co); + area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co); - if (sculpt_brush_test_sq_fn(&test, co)) { + if (normal_test_r || area_test_r) { float no[3]; int flip_index; normal_tri_v3(no, UNPACK3(co_tri)); flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); - if (use_area_cos) { + if (use_area_cos && area_test_r) { add_v3_v3(anctd->area_cos[flip_index], co); + anctd->count_co[flip_index] += 1; } - if (use_area_nos) { + if (use_area_nos && normal_test_r) { add_v3_v3(anctd->area_nos[flip_index], no); + anctd->count_no[flip_index] += 1; } - anctd->area_count[flip_index] += 1; } } } @@ -1532,7 +1558,10 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, co = vd.co; } - if (sculpt_brush_test_sq_fn(&test, co)) { + normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co); + area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co); + + if (normal_test_r || area_test_r) { float no_buf[3]; const float *no; int flip_index; @@ -1555,13 +1584,14 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <= 0.0f); - if (use_area_cos) { + if (use_area_cos && area_test_r) { add_v3_v3(anctd->area_cos[flip_index], co); + anctd->count_co[flip_index] += 1; } - if (use_area_nos) { + if (use_area_nos && normal_test_r) { add_v3_v3(anctd->area_nos[flip_index], no); + anctd->count_no[flip_index] += 1; } - anctd->area_count[flip_index] += 1; } } BKE_pbvh_vertex_iter_end; @@ -1584,8 +1614,8 @@ static void calc_area_normal_and_center_reduce(const void *__restrict UNUSED(use add_v3_v3(join->area_nos[1], anctd->area_nos[1]); /* Weights. */ - join->area_count[0] += anctd->area_count[0]; - join->area_count[1] += anctd->area_count[1]; + add_v2_v2_int(join->count_no, anctd->count_no); + add_v2_v2_int(join->count_co, anctd->count_co); } static void calc_area_center( @@ -1607,7 +1637,7 @@ static void calc_area_center( .use_area_cos = true, }; - AreaNormalCenterTLSData anctd = {{{0}}}; + AreaNormalCenterTLSData anctd = {0}; PBVHParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode); @@ -1618,14 +1648,21 @@ static void calc_area_center( /* For flatten center. */ for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) { - if (anctd.area_count[n] != 0) { - mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.area_count[n]); + if (anctd.count_co[n] != 0) { + mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]); break; } } + if (n == 2) { zero_v3(r_area_co); } + + if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) { + if (ss->cache) { + copy_v3_v3(r_area_co, ss->cache->location); + } + } } static void calc_area_normal( @@ -1711,15 +1748,22 @@ static void calc_area_normal_and_center( /* For flatten center. */ for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) { - if (anctd.area_count[n] != 0) { - mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.area_count[n]); + if (anctd.count_co[n] != 0) { + mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]); break; } } + if (n == 2) { zero_v3(r_area_co); } + if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) { + if (ss->cache) { + copy_v3_v3(r_area_co, ss->cache->location); + } + } + /* For area normal. */ for (n = 0; n < ARRAY_SIZE(anctd.area_nos); n++) { if (normalize_v3_v3(r_area_no, anctd.area_nos[n]) != 0.0f) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 9d1795dec8f..0edac0f1b16 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -207,6 +207,13 @@ typedef struct SculptThreadedTaskData { bool use_area_cos; bool use_area_nos; + + /* 0=towards view, 1=flipped */ + float (*area_cos)[3]; + float (*area_nos)[3]; + int *count_no; + int *count_co; + bool any_vertex_sampled; float *prev_mask; diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h index eec154ea09d..03129bf6734 100644 --- a/source/blender/makesdna/DNA_brush_defaults.h +++ b/source/blender/makesdna/DNA_brush_defaults.h @@ -46,6 +46,7 @@ .topology_rake_factor = 0.0f, \ .crease_pinch_factor = 0.5f, \ .normal_radius_factor = 0.5f, \ + .area_radius_factor = 0.5f, \ .sculpt_plane = SCULPT_DISP_DIR_AREA, \ /* How far above or below the plane that is found by averaging the faces. */ \ .plane_offset = 0.0f, \ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index a9e15a5baf9..a5baa7a5c75 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -311,7 +311,7 @@ typedef struct Brush { char mask_tool; /** Active grease pencil tool. */ char gpencil_tool; - char _pad1[1]; + char _pad1[5]; float autosmooth_factor; @@ -320,6 +320,7 @@ typedef struct Brush { float crease_pinch_factor; float normal_radius_factor; + float area_radius_factor; float plane_trim; /** Affectable height of brush (layer height for layer tool, i.e.). */ diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 04b6ff55978..42c4e249aae 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1980,6 +1980,16 @@ static void rna_def_brush(BlenderRNA *brna) "used to sample the normal"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "area_radius_factor", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "area_radius_factor"); + RNA_def_property_range(prop, 0.0f, 2.0f); + RNA_def_property_ui_range(prop, 0.0f, 2.0f, 0.001, 3); + RNA_def_property_ui_text(prop, + "Area Radius", + "Ratio between the brush radius and the radius that is going to be " + "used to sample the area center"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "stencil_pos", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "stencil_pos"); RNA_def_property_array(prop, 2); |