Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2019-12-17 01:16:21 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-02-11 22:48:01 +0300
commitdf45257ec53c795081e65a35784bd89ac8c3e83d (patch)
tree524ce372deed454123d0ea2cbd4505d264019b32 /source/blender/editors/sculpt_paint
parent6ee6a42d10e3c1c0868d1f038401d525264a7e24 (diff)
Sculpt: Split normal radius and area radius
This enables an extra layer of control in the sculpt brushes. For now it is enabled only in Scrape, but it should work in all brushes (like normal radius). In the future it may also be enabled in other brushes. You can tweak in this property in the scrape brush to achieve a much better behavior when working on curve surfaces and control how much volume you want to trim. In most cases, it also fixes the bug where the brush keeps trimming in the same area without disabling accumulate. It should be possible to fix some other artifacts in other brushes by tweaking this default property. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D5993
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c90
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h7
2 files changed, 74 insertions, 23 deletions
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;