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:
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c2711
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.c24
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c309
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c283
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c164
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c170
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c218
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c76
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c162
9 files changed, 2132 insertions, 1985 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 42dece9ddd5..d1028e5f542 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -391,13 +391,14 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) == face_set) {
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ if (abs(ss->face_sets[i]) != face_set) {
+ continue;
+ }
+ if (visible) {
+ ss->face_sets[i] = abs(ss->face_sets[i]);
+ }
+ else {
+ ss->face_sets[i] = -abs(ss->face_sets[i]);
}
}
break;
@@ -1057,12 +1058,13 @@ bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
char symm)
{
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- float location[3];
- flip_v3_v3(location, br_co, (char)i);
- if (len_squared_v3v3(location, vertex) < radius * radius) {
- return true;
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ float location[3];
+ flip_v3_v3(location, br_co, (char)i);
+ if (len_squared_v3v3(location, vertex) < radius * radius) {
+ return true;
}
}
return false;
@@ -1107,20 +1109,22 @@ void SCULPT_floodfill_add_initial_with_symmetry(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- v = index;
- }
- else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
- float location[3];
- flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ v = index;
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1131,20 +1135,22 @@ void SCULPT_floodfill_add_active(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- v = SCULPT_active_vertex_get(ss);
- }
- else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
- float location[3];
- flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ v = SCULPT_active_vertex_get(ss);
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1161,12 +1167,19 @@ void SCULPT_floodfill_execute(
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const int to_v = ni.index;
- if (!BLI_BITMAP_TEST(flood->visited_vertices, to_v) && SCULPT_vertex_visible_get(ss, to_v)) {
- BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
- if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
- BLI_gsqueue_push(flood->queue, &to_v);
- }
+ if (BLI_BITMAP_TEST(flood->visited_vertices, to_v)) {
+ continue;
+ }
+
+ if (!SCULPT_vertex_visible_get(ss, to_v)) {
+ continue;
+ }
+
+ BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
+
+ if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
+ BLI_gsqueue_push(flood->queue, &to_v);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -1466,40 +1479,42 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
unode = SCULPT_undo_get_node(data->nodes[n]);
}
- if (unode) {
- PBVHVertexIter vd;
- SculptOrigVertData orig_data;
+ if (!unode) {
+ return;
+ }
- SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
+ PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
- BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
- {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
- if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
- copy_v3_v3(vd.co, orig_data.co);
- if (vd.no) {
- copy_v3_v3_short(vd.no, orig_data.no);
- }
- else {
- normal_short_to_float_v3(vd.fno, orig_data.no);
- }
- }
- else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
- *vd.mask = orig_data.mask;
- }
- else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
- copy_v4_v4(vd.col, orig_data.col);
- }
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, orig_data.co);
+ if (vd.no) {
+ copy_v3_v3_short(vd.no, orig_data.no);
+ }
+ else {
+ normal_short_to_float_v3(vd.fno, orig_data.no);
}
}
- BKE_pbvh_vertex_iter_end;
+ else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = orig_data.mask;
+ }
+ else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
+ copy_v4_v4(vd.col, orig_data.col);
+ }
- BKE_pbvh_node_mark_update(data->nodes[n]);
+ 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 paint_mesh_restore_co(Sculpt *sd, Object *ob)
@@ -1545,11 +1560,15 @@ static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
* mesh parts could disappear from screen (sergey). */
SculptSession *ss = ob->sculpt;
- if (ss->cache) {
- if (!BLI_rcti_is_empty(&ss->cache->previous_r)) {
- BLI_rcti_union(rect, &ss->cache->previous_r);
- }
+ if (!ss->cache) {
+ return;
+ }
+
+ if (BLI_rcti_is_empty(&ss->cache->previous_r)) {
+ return;
}
+
+ BLI_rcti_union(rect, &ss->cache->previous_r);
}
/* Get a screen-space rectangle of the modified area. */
@@ -1651,28 +1670,30 @@ bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = sqrtf(distsq);
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = sqrtf(distsq);
+ return true;
}
bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
@@ -1689,14 +1710,16 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
closest_to_plane_normalized_v3(co_proj, test->plane_view, co);
float distsq = len_squared_v3v3(co_proj, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_cube(SculptBrushTest *test,
@@ -1724,25 +1747,26 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
const float constant_side = hardness * side;
const float falloff_side = roundness * side;
- if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
+ if (!(local_co[0] <= side && local_co[1] <= side && local_co[2] <= side)) {
+ /* Outside the square. */
+ return false;
+ }
+ if (min_ff(local_co[0], local_co[1]) > constant_side) {
/* Corner, distance to the center of the corner circle. */
- if (min_ff(local_co[0], local_co[1]) > constant_side) {
- float r_point[3];
- copy_v3_fl(r_point, constant_side);
- test->dist = len_v2v2(r_point, local_co) / falloff_side;
- return true;
- }
+ float r_point[3];
+ copy_v3_fl(r_point, constant_side);
+ test->dist = len_v2v2(r_point, local_co) / falloff_side;
+ return true;
+ }
+ if (max_ff(local_co[0], local_co[1]) > constant_side) {
/* Side, distance to the square XY axis. */
- if (max_ff(local_co[0], local_co[1]) > constant_side) {
- test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
- return true;
- }
- /* Inside the square, constant distance. */
- test->dist = 0.0f;
+ test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
return true;
}
- /* Outside the square. */
- return false;
+
+ /* Inside the square, constant distance. */
+ test->dist = 0.0f;
+ return true;
}
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
@@ -1777,21 +1801,21 @@ static float frontface(const Brush *br,
const short no[3],
const float fno[3])
{
- if (br->flag & BRUSH_FRONTFACE) {
- float dot;
+ if (!(br->flag & BRUSH_FRONTFACE)) {
+ return 1.0f;
+ }
- if (no) {
- float tmp[3];
+ float dot;
+ if (no) {
+ float tmp[3];
- normal_short_to_float_v3(tmp, no);
- dot = dot_v3v3(tmp, sculpt_normal);
- }
- else {
- dot = dot_v3v3(fno, sculpt_normal);
- }
- return dot > 0.0f ? dot : 0.0f;
+ normal_short_to_float_v3(tmp, no);
+ dot = dot_v3v3(tmp, sculpt_normal);
+ }
+ else {
+ dot = dot_v3v3(fno, sculpt_normal);
}
- return 1.0f;
+ return dot > 0.0f ? dot : 0.0f;
}
#if 0
@@ -1871,25 +1895,25 @@ static float calc_radial_symmetry_feather(Sculpt *sd,
static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
{
- if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
- float overlap;
- const int symm = cache->symmetry;
-
- overlap = 0.0f;
- for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
-
- overlap += calc_overlap(cache, i, 0, 0);
+ if (!(sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER)) {
+ return 1.0f;
+ }
+ float overlap;
+ const int symm = cache->symmetry;
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
- }
+ overlap = 0.0f;
+ for (int i = 0; i <= symm; i++) {
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
}
- return 1.0f / overlap;
+ overlap += calc_overlap(cache, i, 0, 0);
+
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
}
- return 1.0f;
+ return 1.0f / overlap;
}
/* -------------------------------------------------------------------- */
@@ -1991,35 +2015,37 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
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[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
- normal_tri_v3(no, UNPACK3(co_tri));
+ float no[3];
+ int flip_index;
- flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ normal_tri_v3(no, UNPACK3(co_tri));
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
+ flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
+ add_v3_v3(anctd->area_cos[flip_index], co);
+
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
}
@@ -2051,49 +2077,51 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
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[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
+
+ float no[3];
+ int flip_index;
- data->any_vertex_sampled = true;
+ data->any_vertex_sampled = true;
- if (use_original) {
- normal_short_to_float_v3(no, no_s);
+ if (use_original) {
+ normal_short_to_float_v3(no, no_s);
+ }
+ else {
+ if (vd.no) {
+ normal_short_to_float_v3(no, vd.no);
}
else {
- if (vd.no) {
- normal_short_to_float_v3(no, vd.no);
- }
- else {
- copy_v3_v3(no, vd.fno);
- }
+ copy_v3_v3(no, vd.fno);
}
+ }
- flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
- 0.0f);
+ flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
+ 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ add_v3_v3(anctd->area_cos[flip_index], co);
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2150,10 +2178,12 @@ static void calc_area_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); 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 (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2249,10 +2279,12 @@ static void calc_area_normal_and_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); 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 (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2892,26 +2924,27 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
- ss->cache->pressure;
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade =
+ bstrength *
+ SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
+ ss->cache->pressure;
- float avg[3], val[3];
+ float avg[3], val[3];
- SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
+ SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
- sub_v3_v3v3(val, avg, vd.co);
+ sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
+ SCULPT_clip(sd, ss, vd.co, val);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2964,21 +2997,23 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (bstrength > 0.0f) {
- (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
- }
- else {
- (*vd.mask) += fade * bstrength * (*vd.mask);
- }
- *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+ const float fade = SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (bstrength > 0.0f) {
+ (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
+ }
+ else {
+ (*vd.mask) += fade * bstrength * (*vd.mask);
+ }
+ *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
BKE_pbvh_vertex_iter_end;
}
@@ -3039,26 +3074,27 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- float limit_co[3];
- float disp[3];
- SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
- sub_v3_v3v3(disp, limit_co, vd.co);
- mul_v3_v3fl(proxy[vd.i], disp, fade);
+ float limit_co[3];
+ float disp[3];
+ SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
+ sub_v3_v3v3(disp, limit_co, vd.co);
+ mul_v3_v3fl(proxy[vd.i], disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3151,12 +3187,15 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
ss->cache->limit_surface_co[vd.index]);
const float *neighbor_limit_surface_disp = ss->cache->prev_displacement[ni.index];
normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float disp_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
- weights_accum += disp_interp;
+
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
+
+ const float disp_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
+ weights_accum += disp_interp;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -3246,23 +3285,24 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3325,23 +3365,24 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
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)) {
- /* Offset vertex. */
- const float fade = 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 (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = 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);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3407,52 +3448,53 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
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 = 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 current_disp[3];
- float current_disp_norm[3];
- float final_disp[3] = {0.0f, 0.0f, 0.0f};
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = 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 current_disp[3];
+ float current_disp_norm[3];
+ float final_disp[3] = {0.0f, 0.0f, 0.0f};
- switch (brush->slide_deform_type) {
- case BRUSH_SLIDE_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SLIDE_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SLIDE_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
+ switch (brush->slide_deform_type) {
+ case BRUSH_SLIDE_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SLIDE_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SLIDE_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
- madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
- }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
+ madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- mul_v3_v3fl(proxy[vd.i], final_disp, fade);
+ mul_v3_v3fl(proxy[vd.i], final_disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3482,16 +3524,17 @@ void SCULPT_relax_vertex(SculptSession *ss,
/* When the vertex to relax is boundary, use only connected boundary vertices for the average
* position. */
if (is_boundary) {
- if (SCULPT_vertex_is_boundary(ss, ni.index)) {
- add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
- avg_count++;
-
- /* Calculate a normal for the constraint plane using the edges of the boundary. */
- float to_neighbor[3];
- sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
- normalize_v3(to_neighbor);
- add_v3_v3(boundary_normal, to_neighbor);
+ if (!SCULPT_vertex_is_boundary(ss, ni.index)) {
+ continue;
}
+ add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
+ avg_count++;
+
+ /* Calculate a normal for the constraint plane using the edges of the boundary. */
+ float to_neighbor[3];
+ sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
+ normalize_v3(to_neighbor);
+ add_v3_v3(boundary_normal, to_neighbor);
}
else {
add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
@@ -3563,21 +3606,22 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
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 = 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);
-
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = 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);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3728,38 +3772,39 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val1[3];
- float val2[3];
-
- /* First we pinch. */
- sub_v3_v3v3(val1, test.location, vd.co);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val1[3];
+ float val2[3];
+
+ /* First we pinch. */
+ sub_v3_v3v3(val1, test.location, vd.co);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
+ }
- mul_v3_fl(val1, fade * flippedbstrength);
+ mul_v3_fl(val1, fade * flippedbstrength);
- sculpt_project_v3(spvc, val1, val1);
+ sculpt_project_v3(spvc, val1, val1);
- /* Then we draw. */
- mul_v3_v3fl(val2, offset, fade);
+ /* Then we draw. */
+ mul_v3_v3fl(val2, offset, fade);
- add_v3_v3v3(proxy[vd.i], val1, val2);
+ add_v3_v3v3(proxy[vd.i], val1, val2);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3845,40 +3890,41 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- /* Calculate displacement from the vertex to the brush center. */
- sub_v3_v3v3(disp_center, test.location, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ /* Calculate displacement from the vertex to the brush center. */
+ sub_v3_v3v3(disp_center, test.location, vd.co);
- /* Project the displacement into the X vector (aligned to the stroke). */
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ /* Project the displacement into the X vector (aligned to the stroke). */
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- /* Project the displacement into the Z vector (aligned to the surface normal). */
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ /* Project the displacement into the Z vector (aligned to the surface normal). */
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- /* Add the two projected vectors to calculate the final displacement.
- * The Y component is removed. */
- add_v3_v3v3(disp_center, x_disp, z_disp);
+ /* Add the two projected vectors to calculate the final displacement.
+ * The Y component is removed. */
+ add_v3_v3v3(disp_center, x_disp, z_disp);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
- }
- mul_v3_v3fl(proxy[vd.i], disp_center, fade);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
+ }
+ mul_v3_v3fl(proxy[vd.i], disp_center, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3961,33 +4007,34 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- 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_symmetry) < 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);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ 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_symmetry) < 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);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4149,13 +4196,14 @@ void SCULPT_flip_v3_by_symm_area(float v[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_v3(v, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_v3(v, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_v3(v, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_v3(v, symm_it);
}
}
}
@@ -4167,13 +4215,14 @@ void SCULPT_flip_quat_by_symm_area(float quat[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_qt(quat, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_qt(quat, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_qt(quat, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_qt(quat, symm_it);
}
}
}
@@ -4289,22 +4338,23 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4368,75 +4418,76 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (do_elastic || sculpt_brush_test_sq_fn(&test, vd.co)) {
+ if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- float fade;
- if (do_elastic) {
- fade = 1.0f;
- }
- else {
- fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- }
+ float fade;
+ if (do_elastic) {
+ fade = 1.0f;
+ }
+ else {
+ fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ }
- mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- /* Negative pinch will inflate, helps maintain volume. */
- if (do_pinch) {
- float delta_pinch_init[3], delta_pinch[3];
+ /* Negative pinch will inflate, helps maintain volume. */
+ if (do_pinch) {
+ float delta_pinch_init[3], delta_pinch[3];
- sub_v3_v3v3(delta_pinch, vd.co, test.location);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
- }
+ sub_v3_v3v3(delta_pinch, vd.co, test.location);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
+ }
- /* Important to calculate based on the grabbed location
- * (intentionally ignore fade here). */
- add_v3_v3(delta_pinch, grab_delta);
+ /* Important to calculate based on the grabbed location
+ * (intentionally ignore fade here). */
+ add_v3_v3(delta_pinch, grab_delta);
- sculpt_project_v3(spvc, delta_pinch, delta_pinch);
+ sculpt_project_v3(spvc, delta_pinch, delta_pinch);
- copy_v3_v3(delta_pinch_init, delta_pinch);
+ copy_v3_v3(delta_pinch_init, delta_pinch);
- float pinch_fade = pinch * fade;
- /* When reducing, scale reduction back by how close to the center we are,
- * so we don't pinch into nothingness. */
- if (pinch > 0.0f) {
- /* Square to have even less impact for close vertices. */
- pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
- }
- mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
- sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
- add_v3_v3(proxy[vd.i], delta_pinch);
+ float pinch_fade = pinch * fade;
+ /* When reducing, scale reduction back by how close to the center we are,
+ * so we don't pinch into nothingness. */
+ if (pinch > 0.0f) {
+ /* Square to have even less impact for close vertices. */
+ pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
}
+ mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
+ sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
+ add_v3_v3(proxy[vd.i], delta_pinch);
+ }
- if (do_rake_rotation) {
- float delta_rotate[3];
- sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
- add_v3_v3(proxy[vd.i], delta_rotate);
- }
+ if (do_rake_rotation) {
+ float delta_rotate[3];
+ sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
+ add_v3_v3(proxy[vd.i], delta_rotate);
+ }
- if (do_elastic) {
- float disp[3];
- BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
- mul_v3_fl(disp, bstrength * 20.0f);
- if (vd.mask) {
- mul_v3_fl(disp, 1.0f - *vd.mask);
- }
- mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
- copy_v3_v3(proxy[vd.i], disp);
+ if (do_elastic) {
+ float disp[3];
+ BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
+ mul_v3_fl(disp, bstrength * 20.0f);
+ if (vd.mask) {
+ mul_v3_fl(disp, 1.0f - *vd.mask);
}
+ mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
+ copy_v3_v3(proxy[vd.i], disp);
+ }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4507,22 +4558,23 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
{
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);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ 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);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4580,27 +4632,28 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- float vec[3], rot[3][3];
- 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);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ float vec[3], rot[3][3];
+ 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);
- sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
- axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
- mul_v3_m3v3(proxy[vd.i], rot, vec);
- add_v3_v3(proxy[vd.i], ss->cache->location);
- sub_v3_v3(proxy[vd.i], orig_data.co);
+ sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
+ axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
+ mul_v3_m3v3(proxy[vd.i], rot, vec);
+ add_v3_v3(proxy[vd.i], ss->cache->location);
+ sub_v3_v3(proxy[vd.i], orig_data.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4652,70 +4705,71 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- const int vi = vd.index;
- float *disp_factor;
- if (use_persistent_base) {
- disp_factor = &ss->persistent_base[vi].disp;
- }
- else {
- disp_factor = &ss->cache->layer_displacement_factor[vi];
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ const int vi = vd.index;
+ float *disp_factor;
+ if (use_persistent_base) {
+ disp_factor = &ss->persistent_base[vi].disp;
+ }
+ else {
+ disp_factor = &ss->cache->layer_displacement_factor[vi];
+ }
- /* When using persistent base, the layer brush (holding Control) invert mode resets the
- * height of the layer to 0. This makes possible to clean edges of previously added layers
- * on top of the base. */
- /* The main direction of the layers is inverted using the regular brush strength with the
- * brush direction property. */
- if (use_persistent_base && ss->cache->invert) {
- (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
- ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
- }
- else {
- (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
- }
- if (vd.mask) {
- const float clamp_mask = 1.0f - *vd.mask;
- *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
- }
- else {
- *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
- }
+ /* When using persistent base, the layer brush (holding Control) invert mode resets the
+ * height of the layer to 0. This makes possible to clean edges of previously added layers
+ * on top of the base. */
+ /* The main direction of the layers is inverted using the regular brush strength with the
+ * brush direction property. */
+ if (use_persistent_base && ss->cache->invert) {
+ (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
+ ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
+ }
+ else {
+ (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
+ }
+ if (vd.mask) {
+ const float clamp_mask = 1.0f - *vd.mask;
+ *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
+ }
+ else {
+ *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
+ }
- float final_co[3];
- float normal[3];
+ float final_co[3];
+ float normal[3];
- if (use_persistent_base) {
- SCULPT_vertex_persistent_normal_get(ss, vi, normal);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
- }
- else {
- normal_short_to_float_v3(normal, orig_data.no);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
- }
+ if (use_persistent_base) {
+ SCULPT_vertex_persistent_normal_get(ss, vi, normal);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
+ }
+ else {
+ normal_short_to_float_v3(normal, orig_data.no);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
+ }
- float vdisp[3];
- sub_v3_v3v3(vdisp, final_co, vd.co);
- mul_v3_fl(vdisp, fabsf(fade));
- add_v3_v3v3(final_co, vd.co, vdisp);
+ float vdisp[3];
+ sub_v3_v3v3(vdisp, final_co, vd.co);
+ mul_v3_fl(vdisp, fabsf(fade));
+ add_v3_v3v3(final_co, vd.co, vdisp);
- SCULPT_clip(sd, ss, vd.co, final_co);
+ SCULPT_clip(sd, ss, vd.co, final_co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4764,31 +4818,32 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val[3];
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val[3];
- if (vd.fno) {
- copy_v3_v3(val, vd.fno);
- }
- else {
- normal_short_to_float_v3(val, vd.no);
- }
+ if (vd.fno) {
+ copy_v3_v3(val, vd.fno);
+ }
+ else {
+ normal_short_to_float_v3(val, vd.no);
+ }
- mul_v3_fl(val, fade * ss->cache->radius);
- mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
+ mul_v3_fl(val, fade * ss->cache->radius);
+ mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4869,30 +4924,31 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float intr[3];
+ float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- sub_v3_v3v3(val, intr, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (SCULPT_plane_trim(ss->cache, brush, val)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
@@ -4975,16 +5031,17 @@ static void calc_clay_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
- float plane_dist_abs = fabsf(plane_dist);
- if (plane_dist > 0.0f) {
- csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
- }
- else {
- csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
- }
+ float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
+ float plane_dist_abs = fabsf(plane_dist);
+ if (plane_dist > 0.0f) {
+ csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
+ }
+ else {
+ csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
}
BKE_pbvh_vertex_iter_end;
}
@@ -5025,28 +5082,30 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ sub_v3_v3v3(val, intr, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5143,35 +5202,37 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
- if (plane_point_side_flip(vd.co, test.plane_tool, flip)) {
- float intr[3];
- float val[3];
+ if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
+ continue;
+ }
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!plane_point_side_flip(vd.co, test.plane_tool, flip)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
- const float fade = bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- ss->cache->radius * test.dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ ss->cache->radius * test.dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5295,33 +5356,37 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5390,33 +5455,37 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5501,38 +5570,39 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- mul_v3_m4v3(local_co, mat, vd.co);
- float intr[3], intr_tilt[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
-
- /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
- * coordinates. */
- /* We can also control the mix with a curve if it produces noticeable artifacts in the center
- * of the brush. */
- const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
- interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
- sub_v3_v3v3(val, intr_tilt, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ mul_v3_m4v3(local_co, mat, vd.co);
+ float intr[3], intr_tilt[3];
+ float val[3];
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
+ * coordinates. */
+ /* We can also control the mix with a curve if it produces noticeable artifacts in the center
+ * of the brush. */
+ const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
+ interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
+ sub_v3_v3v3(val, intr_tilt, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5656,22 +5726,23 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5766,49 +5837,51 @@ static void sculpt_topology_update(Sculpt *sd,
ob, sd, brush, use_original, radius_scale, &totnode);
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- PBVHTopologyUpdateMode mode = 0;
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
- if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
- if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
- mode |= PBVH_Subdivide;
- }
+ PBVHTopologyUpdateMode mode = 0;
+ float location[3];
- if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
- mode |= PBVH_Collapse;
- }
+ if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
+ if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
+ mode |= PBVH_Subdivide;
}
- for (n = 0; n < totnode; n++) {
- SCULPT_undo_push_node(ob,
- nodes[n],
- brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
- SCULPT_UNDO_COORDS);
- BKE_pbvh_node_mark_update(nodes[n]);
-
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_node_mark_topology_update(nodes[n]);
- BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
- }
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
+ mode |= PBVH_Collapse;
}
+ }
+
+ for (n = 0; n < totnode; n++) {
+ SCULPT_undo_push_node(ob,
+ nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
+ SCULPT_UNDO_COORDS);
+ BKE_pbvh_node_mark_update(nodes[n]);
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_bmesh_update_topology(ss->pbvh,
- mode,
- ss->cache->location,
- ss->cache->view_normal,
- ss->cache->radius,
- (brush->flag & BRUSH_FRONTFACE) != 0,
- (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
+ BKE_pbvh_node_mark_topology_update(nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
}
+ }
- MEM_SAFE_FREE(nodes);
-
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_update_topology(ss->pbvh,
+ mode,
+ ss->cache->location,
+ ss->cache->view_normal,
+ ss->cache->radius,
+ (brush->flag & BRUSH_FRONTFACE) != 0,
+ (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
}
+
+ MEM_SAFE_FREE(nodes);
+
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
}
static void do_brush_action_task_cb(void *__restrict userdata,
@@ -5914,202 +5987,199 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
}
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
+ float location[3];
- SculptThreadedTaskData task_data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
- if (sculpt_brush_needs_normal(ss, brush)) {
- update_sculpt_normal(sd, ob, nodes, totnode);
- }
+ if (sculpt_brush_needs_normal(ss, brush)) {
+ update_sculpt_normal(sd, ob, nodes, totnode);
+ }
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
- update_brush_local_mat(sd, ob);
- }
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
+ update_brush_local_mat(sd, ob);
+ }
- if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
- SCULPT_pose_brush_init(sd, ob, ss, brush);
- }
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ SCULPT_pose_brush_init(sd, ob, ss, brush);
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (!ss->cache->cloth_sim) {
- ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
- ss, 1.0f, 0.0f, 0.0f, false, true);
- SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
- }
- SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
- SCULPT_cloth_brush_ensure_nodes_constraints(
- sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (!ss->cache->cloth_sim) {
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
+ ss, 1.0f, 0.0f, 0.0f, false, true);
+ SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
+ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
+ SCULPT_cloth_brush_ensure_nodes_constraints(
+ sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ }
- bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
+ bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
- /* Apply one type of brush action. */
- switch (brush->sculpt_tool) {
- case SCULPT_TOOL_DRAW:
- do_draw_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMOOTH:
- if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
- SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
- }
- else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
- SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_CREASE:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BLOB:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PINCH:
- do_pinch_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_INFLATE:
- do_inflate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_GRAB:
- do_grab_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ROTATE:
- do_rotate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SNAKE_HOOK:
- do_snake_hook_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_NUDGE:
- do_nudge_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_THUMB:
- do_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_LAYER:
- do_layer_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FLATTEN:
- do_flatten_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY:
- do_clay_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_STRIPS:
- do_clay_strips_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_MULTIPLANE_SCRAPE:
- SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_THUMB:
- do_clay_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FILL:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- else {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_SCRAPE:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- else {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_MASK:
- do_mask_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_POSE:
- SCULPT_do_pose_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_SHARP:
- do_draw_sharp_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ELASTIC_DEFORM:
- do_elastic_deform_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SLIDE_RELAX:
- do_slide_relax_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BOUNDARY:
- SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLOTH:
- SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_FACE_SETS:
- SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_ERASER:
- do_displacement_eraser_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_SMEAR:
- do_displacement_smear_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PAINT:
- SCULPT_do_paint_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMEAR:
- SCULPT_do_smear_brush(sd, ob, nodes, totnode);
- break;
- }
-
- if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
- brush->autosmooth_factor > 0) {
- if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- SCULPT_smooth(sd,
- ob,
- nodes,
- totnode,
- brush->autosmooth_factor * (1.0f - ss->cache->pressure),
- false);
+ /* Apply one type of brush action. */
+ switch (brush->sculpt_tool) {
+ case SCULPT_TOOL_DRAW:
+ do_draw_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMOOTH:
+ if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
+ SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
+ }
+ else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
+ SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_CREASE:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BLOB:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PINCH:
+ do_pinch_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_INFLATE:
+ do_inflate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_GRAB:
+ do_grab_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ROTATE:
+ do_rotate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SNAKE_HOOK:
+ do_snake_hook_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_NUDGE:
+ do_nudge_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_THUMB:
+ do_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_LAYER:
+ do_layer_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FLATTEN:
+ do_flatten_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY:
+ do_clay_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_STRIPS:
+ do_clay_strips_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_MULTIPLANE_SCRAPE:
+ SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_THUMB:
+ do_clay_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FILL:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_scrape_brush(sd, ob, nodes, totnode);
}
else {
- SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
+ do_fill_brush(sd, ob, nodes, totnode);
}
- }
+ break;
+ case SCULPT_TOOL_SCRAPE:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_fill_brush(sd, ob, nodes, totnode);
+ }
+ else {
+ do_scrape_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_MASK:
+ do_mask_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_POSE:
+ SCULPT_do_pose_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_SHARP:
+ do_draw_sharp_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ELASTIC_DEFORM:
+ do_elastic_deform_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SLIDE_RELAX:
+ do_slide_relax_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BOUNDARY:
+ SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLOTH:
+ SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_FACE_SETS:
+ SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_ERASER:
+ do_displacement_eraser_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_SMEAR:
+ do_displacement_smear_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PAINT:
+ SCULPT_do_paint_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMEAR:
+ SCULPT_do_smear_brush(sd, ob, nodes, totnode);
+ break;
+ }
- if (sculpt_brush_use_topology_rake(ss, brush)) {
- bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
+ brush->autosmooth_factor > 0) {
+ if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
+ SCULPT_smooth(
+ sd, ob, nodes, totnode, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
}
-
- /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
- if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
- SCULPT_TOOL_CLOTH,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_BOUNDARY)) {
- do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ else {
+ SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
}
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
- SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
- SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
- }
+ if (sculpt_brush_use_topology_rake(ss, brush)) {
+ bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ }
+
+ /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
+ if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_BOUNDARY)) {
+ do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ }
+
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+ SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
+ SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
}
+ }
- MEM_SAFE_FREE(nodes);
+ MEM_SAFE_FREE(nodes);
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
- add_v3_v3(ups->average_stroke_accum, location);
- ups->average_stroke_counter++;
- /* Update last stroke position. */
- ups->last_stroke_valid = true;
- }
+ add_v3_v3(ups->average_stroke_accum, location);
+ ups->average_stroke_counter++;
+ /* Update last stroke position. */
+ ups->last_stroke_valid = true;
}
/* Flush displacement from deformed PBVH vertex to original mesh. */
@@ -6199,22 +6269,22 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHNode **nodes;
int totnode;
- BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
-
- /* First line is tools that don't support proxies. */
- if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
-
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
+ if (!ss->cache->supports_gravity && sculpt_tool_is_proxy_used(brush->sculpt_tool)) {
+ /* First line is tools that don't support proxies. */
+ return;
}
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
MEM_SAFE_FREE(nodes);
}
@@ -6235,12 +6305,14 @@ static void sculpt_update_keyblock(Object *ob)
vertCos = BKE_pbvh_vert_coords_alloc(ss->pbvh);
}
- if (vertCos) {
- SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+ if (!vertCos) {
+ return;
+ }
- if (vertCos != ss->orig_cos) {
- MEM_freeN(vertCos);
- }
+ SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+
+ if (vertCos != ss->orig_cos) {
+ MEM_freeN(vertCos);
}
}
@@ -6259,10 +6331,12 @@ static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata,
{
sculpt_flush_pbvhvert_deform(ob, &vd);
- if (vertCos) {
- int index = vd.vert_indices[vd.i];
- copy_v3_v3(vertCos[index], ss->orig_cos[index]);
+ if (!vertCos) {
+ continue;
}
+
+ int index = vd.vert_indices[vd.i];
+ copy_v3_v3(vertCos[index], ss->orig_cos[index]);
}
BKE_pbvh_vertex_iter_end;
}
@@ -6490,17 +6564,18 @@ static void do_symmetrical_brush_actions(Sculpt *sd,
/* `symm` is a bit combination of XYZ -
* 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
- cache->mirror_symmetry_pass = i;
- cache->radial_symmetry_pass = 0;
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ cache->mirror_symmetry_pass = i;
+ cache->radial_symmetry_pass = 0;
- SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
- do_tiled(sd, ob, brush, ups, action);
+ SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
+ do_tiled(sd, ob, brush, ups, action);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
- }
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
}
}
@@ -6668,22 +6743,25 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
- MirrorModifierData *mmd = (MirrorModifierData *)md;
-
- if (mmd->flag & MOD_MIR_CLIPPING) {
- /* Check each axis for mirroring. */
- for (int i = 0; i < 3; i++) {
- if (mmd->flag & (MOD_MIR_AXIS_X << i)) {
- /* Enable sculpt clipping. */
- ss->cache->flag |= CLIP_X << i;
-
- /* Update the clip tolerance. */
- if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
- ss->cache->clip_tolerance[i] = mmd->tolerance;
- }
- }
- }
+ if (!(md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime))) {
+ continue;
+ }
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
+
+ if (!(mmd->flag & MOD_MIR_CLIPPING)) {
+ continue;
+ }
+ /* Check each axis for mirroring. */
+ for (int i = 0; i < 3; i++) {
+ if (!(mmd->flag & (MOD_MIR_AXIS_X << i))) {
+ continue;
+ }
+ /* Enable sculpt clipping. */
+ ss->cache->flag |= CLIP_X << i;
+
+ /* Update the clip tolerance. */
+ if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
+ ss->cache->clip_tolerance[i] = mmd->tolerance;
}
}
}
@@ -6926,150 +7004,151 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
};
int tool = brush->sculpt_tool;
- if (ELEM(tool,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ELASTIC_DEFORM,
- SCULPT_TOOL_CLOTH,
- SCULPT_TOOL_NUDGE,
- SCULPT_TOOL_CLAY_STRIPS,
- SCULPT_TOOL_PINCH,
- SCULPT_TOOL_MULTIPLANE_SCRAPE,
- SCULPT_TOOL_CLAY_THUMB,
- SCULPT_TOOL_SNAKE_HOOK,
- SCULPT_TOOL_POSE,
- SCULPT_TOOL_BOUNDARY,
- SCULPT_TOOL_THUMB) ||
- sculpt_brush_use_topology_rake(ss, brush)) {
- float grab_location[3], imat[4][4], delta[3], loc[3];
+ if (!ELEM(tool,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_NUDGE,
+ SCULPT_TOOL_CLAY_STRIPS,
+ SCULPT_TOOL_PINCH,
+ SCULPT_TOOL_MULTIPLANE_SCRAPE,
+ SCULPT_TOOL_CLAY_THUMB,
+ SCULPT_TOOL_SNAKE_HOOK,
+ SCULPT_TOOL_POSE,
+ SCULPT_TOOL_BOUNDARY,
+ SCULPT_TOOL_THUMB) &&
+ !sculpt_brush_use_topology_rake(ss, brush)) {
+ return;
+ }
+ float grab_location[3], imat[4][4], delta[3], loc[3];
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->orig_grab_location,
- SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
- }
- else {
- copy_v3_v3(cache->orig_grab_location, cache->true_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->orig_grab_location,
+ SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
}
- else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
- (tool == SCULPT_TOOL_CLOTH &&
- brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
- add_v3_v3(cache->true_location, cache->grab_delta);
+ else {
+ copy_v3_v3(cache->orig_grab_location, cache->true_location);
}
+ }
+ else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
+ (tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
+ add_v3_v3(cache->true_location, cache->grab_delta);
+ }
- /* Compute 3d coordinate at same z from original location + mouse. */
- mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
- ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
+ /* Compute 3d coordinate at same z from original location + mouse. */
+ mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
+ ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
- /* Compute delta to move verts by. */
- if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- if (sculpt_needs_delta_from_anchored_origin(brush)) {
- sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, delta);
- add_v3_v3(cache->grab_delta, delta);
- }
- else if (sculpt_needs_delta_for_tip_orientation(brush)) {
- if (brush->flag & BRUSH_ANCHORED) {
- float orig[3];
- mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
- sub_v3_v3v3(cache->grab_delta, grab_location, orig);
- }
- else {
- sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
- }
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, cache->grab_delta);
+ /* Compute delta to move verts by. */
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ if (sculpt_needs_delta_from_anchored_origin(brush)) {
+ sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, delta);
+ add_v3_v3(cache->grab_delta, delta);
+ }
+ else if (sculpt_needs_delta_for_tip_orientation(brush)) {
+ if (brush->flag & BRUSH_ANCHORED) {
+ float orig[3];
+ mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
+ sub_v3_v3v3(cache->grab_delta, grab_location, orig);
}
else {
- /* Use for 'Brush.topology_rake_factor'. */
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, cache->grab_delta);
}
else {
- zero_v3(cache->grab_delta);
+ /* Use for 'Brush.topology_rake_factor'. */
+ sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ }
+ else {
+ zero_v3(cache->grab_delta);
+ }
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
- }
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
+ }
- copy_v3_v3(cache->old_grab_location, grab_location);
+ copy_v3_v3(cache->old_grab_location, grab_location);
- if (tool == SCULPT_TOOL_GRAB) {
- if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
- else {
- copy_v3_v3(cache->anchored_location, cache->true_location);
- }
+ if (tool == SCULPT_TOOL_GRAB) {
+ if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
}
- else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ else {
copy_v3_v3(cache->anchored_location, cache->true_location);
}
- else if (tool == SCULPT_TOOL_THUMB) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
+ }
+ else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ }
+ else if (tool == SCULPT_TOOL_THUMB) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
+ }
- if (sculpt_needs_delta_from_anchored_origin(brush)) {
- /* Location stays the same for finding vertices in brush radius. */
- copy_v3_v3(cache->true_location, cache->orig_grab_location);
+ if (sculpt_needs_delta_from_anchored_origin(brush)) {
+ /* Location stays the same for finding vertices in brush radius. */
+ copy_v3_v3(cache->true_location, cache->orig_grab_location);
- ups->draw_anchored = true;
- copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- ups->anchored_size = ups->pixel_radius;
- }
+ ups->draw_anchored = true;
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
+ ups->anchored_size = ups->pixel_radius;
+ }
- /* Handle 'rake' */
- cache->is_rake_rotation_valid = false;
+ /* Handle 'rake' */
+ cache->is_rake_rotation_valid = false;
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, grab_location);
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, grab_location);
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- copy_v3_v3(cache->rake_data.follow_co, grab_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ copy_v3_v3(cache->rake_data.follow_co, grab_location);
+ }
- if (sculpt_brush_needs_rake_rotation(brush)) {
- cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
+ if (!sculpt_brush_needs_rake_rotation(brush)) {
+ return;
+ }
+ cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
- if (!is_zero_v3(cache->grab_delta)) {
- const float eps = 0.00001f;
+ if (!is_zero_v3(cache->grab_delta)) {
+ const float eps = 0.00001f;
- float v1[3], v2[3];
+ float v1[3], v2[3];
- copy_v3_v3(v1, cache->rake_data.follow_co);
- copy_v3_v3(v2, cache->rake_data.follow_co);
- sub_v3_v3(v2, cache->grab_delta);
+ copy_v3_v3(v1, cache->rake_data.follow_co);
+ copy_v3_v3(v2, cache->rake_data.follow_co);
+ sub_v3_v3(v2, cache->grab_delta);
- sub_v3_v3(v1, grab_location);
- sub_v3_v3(v2, grab_location);
+ sub_v3_v3(v1, grab_location);
+ sub_v3_v3(v2, grab_location);
- if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) &&
- (len_squared_v3v3(v1, v2) > eps)) {
- const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
- const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
- 1.0f :
- sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
+ if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) && (len_squared_v3v3(v1, v2) > eps)) {
+ const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
+ const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
+ 1.0f :
+ sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
- float axis[3], angle;
- float tquat[4];
+ float axis[3], angle;
+ float tquat[4];
- rotation_between_vecs_to_quat(tquat, v1, v2);
+ rotation_between_vecs_to_quat(tquat, v1, v2);
- /* Use axis-angle to scale rotation since the factor may be above 1. */
- quat_to_axis_angle(axis, &angle, tquat);
- normalize_v3(axis);
+ /* Use axis-angle to scale rotation since the factor may be above 1. */
+ quat_to_axis_angle(axis, &angle, tquat);
+ normalize_v3(axis);
- angle *= brush->rake_factor * rake_fade;
- axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
- cache->is_rake_rotation_valid = true;
- }
- }
- sculpt_rake_data_update(&cache->rake_data, grab_location);
+ angle *= brush->rake_factor * rake_fade;
+ axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
+ cache->is_rake_rotation_valid = true;
}
}
+ sculpt_rake_data_update(&cache->rake_data, grab_location);
}
static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
@@ -7257,71 +7336,73 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptRaycastData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptRaycastData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_raycast(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->isect_precalc,
- &srd->depth,
- &srd->active_vertex_index,
- &srd->active_face_grid_index,
- srd->face_normal)) {
- srd->hit = true;
- *tmin = srd->depth;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_raycast(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->isect_precalc,
+ &srd->depth,
+ &srd->active_vertex_index,
+ &srd->active_face_grid_index,
+ srd->face_normal)) {
+ srd->hit = true;
+ *tmin = srd->depth;
+ }
}
static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptFindNearestToRayData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptFindNearestToRayData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->depth,
- &srd->dist_sq_to_ray)) {
- srd->hit = true;
- *tmin = srd->dist_sq_to_ray;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->depth,
+ &srd->dist_sq_to_ray)) {
+ srd->hit = true;
+ *tmin = srd->dist_sq_to_ray;
+ }
}
float SCULPT_raycast_init(ViewContext *vc,
@@ -7546,26 +7627,30 @@ bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mouse[2])
}
}
- if (!hit) {
- if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
- SculptFindNearestToRayData srd = {
- .original = original,
- .ss = ob->sculpt,
- .hit = false,
- .ray_start = ray_start,
- .ray_normal = ray_normal,
- .depth = FLT_MAX,
- .dist_sq_to_ray = FLT_MAX,
- };
- BKE_pbvh_find_nearest_to_ray(
- ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
- if (srd.hit) {
- hit = true;
- copy_v3_v3(out, ray_normal);
- mul_v3_fl(out, srd.depth);
- add_v3_v3(out, ray_start);
- }
- }
+ if (hit) {
+ return hit;
+ }
+
+ if (!ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
+ return hit;
+ }
+
+ SculptFindNearestToRayData srd = {
+ .original = original,
+ .ss = ob->sculpt,
+ .hit = false,
+ .ray_start = ray_start,
+ .ray_normal = ray_normal,
+ .depth = FLT_MAX,
+ .dist_sq_to_ray = FLT_MAX,
+ };
+ BKE_pbvh_find_nearest_to_ray(
+ ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
+ if (srd.hit) {
+ hit = true;
+ copy_v3_v3(out, ray_normal);
+ mul_v3_fl(out, srd.depth);
+ add_v3_v3(out, ray_start);
}
return hit;
@@ -7748,19 +7833,20 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
bScreen *screen = WM_window_get_active_screen(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
SpaceLink *sl = area->spacedata.first;
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- if (v3d != current_v3d) {
- need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
- }
+ if (sl->spacetype != SPACE_VIEW3D) {
+ continue;
+ }
+ View3D *v3d = (View3D *)sl;
+ if (v3d != current_v3d) {
+ need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
+ }
- /* Tag all 3D viewports for redraw now that we are done. Others
- * viewports did not get a full redraw, and anti-aliasing for the
- * current viewport was deactivated. */
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (region->regiontype == RGN_TYPE_WINDOW) {
- ED_region_tag_redraw(region);
- }
+ /* Tag all 3D viewports for redraw now that we are done. Others
+ * viewports did not get a full redraw, and anti-aliasing for the
+ * current viewport was deactivated. */
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ ED_region_tag_redraw(region);
}
}
}
@@ -7920,55 +8006,56 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
/* Finished. */
- if (ss->cache) {
- UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
- Brush *brush = BKE_paint_brush(&sd->paint);
- BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
- ups->draw_inverted = false;
+ if (!ss->cache) {
+ sculpt_brush_exit_tex(sd);
+ return;
+ }
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
+ ups->draw_inverted = false;
- SCULPT_stroke_modifiers_check(C, ob, brush);
+ SCULPT_stroke_modifiers_check(C, ob, brush);
- /* Alt-Smooth. */
- if (ss->cache->alt_smooth) {
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- brush->mask_tool = ss->cache->saved_mask_brush_tool;
- }
- else if (ELEM(brush->sculpt_tool,
- SCULPT_TOOL_SLIDE_RELAX,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_SMEAR)) {
- /* Do nothing. */
- }
- else {
- BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
- brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
- if (brush) {
- BKE_paint_brush_set(&sd->paint, brush);
- }
- }
+ /* Alt-Smooth. */
+ if (ss->cache->alt_smooth) {
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ brush->mask_tool = ss->cache->saved_mask_brush_tool;
}
-
- if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
- SCULPT_automasking_cache_free(ss->cache->automasking);
+ else if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_SLIDE_RELAX,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR)) {
+ /* Do nothing. */
}
+ else {
+ BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
+ brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
+ if (brush) {
+ BKE_paint_brush_set(&sd->paint, brush);
+ }
+ }
+ }
- BKE_pbvh_node_color_buffer_free(ss->pbvh);
- SCULPT_cache_free(ss->cache);
- ss->cache = NULL;
+ if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
+ SCULPT_automasking_cache_free(ss->cache->automasking);
+ }
- SCULPT_undo_push_end();
+ BKE_pbvh_node_color_buffer_free(ss->pbvh);
+ SCULPT_cache_free(ss->cache);
+ ss->cache = NULL;
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
- }
- else {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
- }
+ SCULPT_undo_push_end();
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+ }
+ else {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
}
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
sculpt_brush_exit_tex(sd);
}
@@ -8090,21 +8177,22 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
- if (ss) {
- SCULPT_vertex_random_access_ensure(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
+ if (!ss) {
+ return OPERATOR_FINISHED;
+ }
+ SCULPT_vertex_random_access_ensure(ss);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
- MEM_SAFE_FREE(ss->persistent_base);
+ MEM_SAFE_FREE(ss->persistent_base);
- const int totvert = SCULPT_vertex_count_get(ss);
- ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
- "layer persistent base");
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
+ "layer persistent base");
- for (int i = 0; i < totvert; i++) {
- copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
- SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
- ss->persistent_base[i].disp = 0.0f;
- }
+ for (int i = 0; i < totvert; i++) {
+ copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
+ ss->persistent_base[i].disp = 0.0f;
}
return OPERATOR_FINISHED;
@@ -8564,12 +8652,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
totpoints++;
ss->preview_vert_index_list[totpoints] = to_v;
totpoints++;
- if (!BLI_BITMAP_TEST(visited_vertices, to_v)) {
- BLI_BITMAP_ENABLE(visited_vertices, to_v);
- const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
- if (len_squared_v3v3(brush_co, co) < radius * radius) {
- BLI_gsqueue_push(not_visited_vertices, &to_v);
- }
+ if (BLI_BITMAP_TEST(visited_vertices, to_v)) {
+ continue;
+ }
+ BLI_BITMAP_ENABLE(visited_vertices, to_v);
+ const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
+ if (len_squared_v3v3(brush_co, co) < radius * radius) {
+ BLI_gsqueue_push(not_visited_vertices, &to_v);
}
}
}
@@ -9099,11 +9188,12 @@ static void do_mask_by_color_contiguous_update_nodes_cb(
const float current_mask = *vd.mask;
const float new_mask = data->mask_by_color_floodfill[vd.index];
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -9206,11 +9296,12 @@ static void do_mask_by_color_task_cb(void *__restrict userdata,
const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index bb68ec56b25..5f5fb51d75f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -298,24 +298,26 @@ float *SCULPT_boundary_automasking_init(Object *ob,
for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) {
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] == EDGE_DISTANCE_INF) {
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
- if (edge_distance[ni.index] == propagation_it) {
- edge_distance[i] = propagation_it + 1;
- }
+ if (edge_distance[i] != EDGE_DISTANCE_INF) {
+ continue;
+ }
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ if (edge_distance[ni.index] == propagation_it) {
+ edge_distance[i] = propagation_it + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] != EDGE_DISTANCE_INF) {
- const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
- const float edge_boundary_automask = pow2f(p);
- automask_factor[i] *= (1.0f - edge_boundary_automask);
+ if (edge_distance[i] == EDGE_DISTANCE_INF) {
+ continue;
}
+ const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
+ const float edge_boundary_automask = pow2f(p);
+ automask_factor[i] *= (1.0f - edge_boundary_automask);
}
MEM_SAFE_FREE(edge_distance);
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 0cfb6f17adb..fca19c04b98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -227,19 +227,19 @@ static bool boundary_floodfill_cb(
{
BoundaryFloodFillData *data = userdata;
SculptBoundary *boundary = data->boundary;
- if (SCULPT_vertex_is_boundary(ss, to_v)) {
- const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, to_v));
- const float distance_boundary_to_dst = boundary->distance ?
- boundary->distance[from_v] + edge_len :
- 0.0f;
- sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
- if (!is_duplicate) {
- sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
- }
- return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
+ if (!SCULPT_vertex_is_boundary(ss, to_v)) {
+ return false;
+ }
+ const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, to_v));
+ const float distance_boundary_to_dst = boundary->distance ?
+ boundary->distance[from_v] + edge_len :
+ 0.0f;
+ sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
+ if (!is_duplicate) {
+ sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
- return false;
+ return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
}
static void sculpt_boundary_indices_init(SculptSession *ss,
@@ -360,49 +360,50 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
- if (is_visible &&
- boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
- boundary->edit_info[ni.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
+ if (!is_visible ||
+ boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ continue;
+ }
+ boundary->edit_info[ni.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
- BLI_BITMAP_ENABLE(visited_vertices, ni.index);
+ BLI_BITMAP_ENABLE(visited_vertices, ni.index);
- if (ni.is_duplicate) {
- /* Grids duplicates handling. */
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps;
- }
- else {
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
-
- BLI_gsqueue_push(next_iteration, &ni.index);
-
- /* When copying the data to the neighbor for the next iteration, it has to be copied to
- * all its duplicates too. This is because it is not possible to know if the updated
- * neighbor or one if its uninitialized duplicates is going to come first in order to
- * copy the data in the from_v neighbor iterator. */
- if (has_duplicates) {
- SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
- if (ni_duplis.is_duplicate) {
- boundary->edit_info[ni_duplis.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
- boundary->edit_info[ni_duplis.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
- }
+ if (ni.is_duplicate) {
+ /* Grids duplicates handling. */
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps;
+ }
+ else {
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
+
+ BLI_gsqueue_push(next_iteration, &ni.index);
+
+ /* When copying the data to the neighbor for the next iteration, it has to be copied to
+ * all its duplicates too. This is because it is not possible to know if the updated
+ * neighbor or one if its uninitialized duplicates is going to come first in order to
+ * copy the data in the from_v neighbor iterator. */
+ if (has_duplicates) {
+ SculptVertexNeighborIter ni_duplis;
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
+ if (ni_duplis.is_duplicate) {
+ boundary->edit_info[ni_duplis.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
+ boundary->edit_info[ni_duplis.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
+ }
- /* Check the distance using the vertex that was propagated from the initial vertex that
- * was used to initialize the boundary. */
- if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
- boundary->pivot_vertex = ni.index;
- copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
- accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, ni.index));
- }
+ /* Check the distance using the vertex that was propagated from the initial vertex that
+ * was used to initialize the boundary. */
+ if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
+ boundary->pivot_vertex = ni.index;
+ copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
+ accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, ni.index));
}
}
}
@@ -552,28 +553,30 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
totvert, 3 * sizeof(float), "pivot positions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- float dir[3];
- float normal[3];
- SCULPT_vertex_normal_get(ss, i, normal);
- sub_v3_v3v3(dir,
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- cross_v3_v3v3(
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
- normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, i));
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
+ continue;
}
+ float dir[3];
+ float normal[3];
+ SCULPT_vertex_normal_get(ss, i, normal);
+ sub_v3_v3v3(dir,
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ cross_v3_v3v3(
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
+ normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, i));
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->bend.pivot_positions[i],
- boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->bend.pivot_positions[i],
+ boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
}
}
@@ -583,19 +586,20 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
}
+ sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->slide.directions[i],
- boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->slide.directions[i],
+ boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
@@ -662,24 +666,27 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float t_orig_co[3];
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->bend.pivot_rotation_axis[vd.index],
- angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
- add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float t_orig_co[3];
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->bend.pivot_rotation_axis[vd.index],
+ angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
+ add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -708,22 +715,25 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- boundary->slide.directions[vd.index],
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ boundary->slide.directions[vd.index],
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -752,24 +762,27 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float normal[3];
- normal_short_to_float_v3(normal, orig_data.no);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- normal,
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float normal[3];
+ normal_short_to_float_v3(normal, orig_data.no);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ normal,
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -796,21 +809,24 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- ss->cache->grab_delta_symmetry,
- boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ ss->cache->grab_delta_symmetry,
+ boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -845,24 +861,27 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float t_orig_co[3];
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->twist.rotation_axis,
- angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
- add_v3_v3(target_co, boundary->twist.pivot_position);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float t_orig_co[3];
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->twist.rotation_axis,
+ angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
+ add_v3_v3(target_co, boundary->twist.pivot_position);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index c97f31fa682..16d10f6d6bb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -540,97 +540,98 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
- if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
-
- float dist = sqrtf(test.dist);
+ if (!sculpt_brush_test_sq_fn(&test, current_vertex_location) && !use_falloff_plane) {
+ continue;
+ }
- if (use_falloff_plane) {
- dist = dist_to_plane_v3(current_vertex_location, deform_plane);
- }
+ float dist = sqrtf(test.dist);
- const float fade = sim_factor * bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- current_vertex_location,
- dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float brush_disp[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
+ if (use_falloff_plane) {
+ dist = dist_to_plane_v3(current_vertex_location, deform_plane);
+ }
- switch (brush->cloth_deform_type) {
- case BRUSH_CLOTH_DEFORM_DRAG:
- sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PUSH:
- /* Invert the fade to push inwards. */
- mul_v3_v3fl(force, offset, -fade);
- break;
- case BRUSH_CLOTH_DEFORM_GRAB:
- madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
- cloth_sim->init_pos[vd.index],
- ss->cache->grab_delta_symmetry,
- fade);
- if (use_falloff_plane) {
- cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
- }
- else {
- cloth_sim->deformation_strength[vd.index] = 1.0f;
- }
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
- copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
- madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
- cloth_sim->deformation_strength[vd.index] = fade;
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_POINT:
- if (use_falloff_plane) {
- float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
- copy_v3_v3(brush_disp, plane_normal);
- mul_v3_fl(brush_disp, -distance);
- }
- else {
- sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
- }
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
- normalize_v3(disp_center);
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- add_v3_v3v3(disp_center, x_disp, z_disp);
- mul_v3_v3fl(force, disp_center, fade);
- } break;
- case BRUSH_CLOTH_DEFORM_INFLATE:
- mul_v3_v3fl(force, normal, fade);
- break;
- case BRUSH_CLOTH_DEFORM_EXPAND:
- cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
- zero_v3(force);
- break;
- }
+ const float fade = sim_factor * bstrength *
+ SCULPT_brush_strength_factor(ss,
+ brush,
+ current_vertex_location,
+ dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float brush_disp[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
- cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
+ switch (brush->cloth_deform_type) {
+ case BRUSH_CLOTH_DEFORM_DRAG:
+ sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PUSH:
+ /* Invert the fade to push inwards. */
+ mul_v3_v3fl(force, offset, -fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_GRAB:
+ madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
+ cloth_sim->init_pos[vd.index],
+ ss->cache->grab_delta_symmetry,
+ fade);
+ if (use_falloff_plane) {
+ cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
+ }
+ else {
+ cloth_sim->deformation_strength[vd.index] = 1.0f;
+ }
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
+ copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
+ madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
+ cloth_sim->deformation_strength[vd.index] = fade;
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_POINT:
+ if (use_falloff_plane) {
+ float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
+ copy_v3_v3(brush_disp, plane_normal);
+ mul_v3_fl(brush_disp, -distance);
+ }
+ else {
+ sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
+ }
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
+ normalize_v3(disp_center);
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ add_v3_v3v3(disp_center, x_disp, z_disp);
+ mul_v3_v3fl(force, disp_center, fade);
+ } break;
+ case BRUSH_CLOTH_DEFORM_INFLATE:
+ mul_v3_v3fl(force, normal, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_EXPAND:
+ cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
+ zero_v3(force);
+ break;
}
+
+ cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
}
BKE_pbvh_vertex_iter_end;
}
@@ -644,17 +645,22 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
DEG_ITER_OBJECT_FLAG_DUPLI) {
CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
ob, eModifierType_Collision);
- if (cmd && cmd->bvhtree) {
- if (cache == NULL) {
- cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
- }
+ if (!cmd) {
+ continue;
+ }
- ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = ob;
- col->collmd = cmd;
- collision_move_object(cmd, 1.0, 0.0, true);
- BLI_addtail(cache, col);
+ if (!cmd->bvhtree) {
+ continue;
}
+ if (cache == NULL) {
+ cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+ }
+
+ ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ collision_move_object(cmd, 1.0, 0.0, true);
+ BLI_addtail(cache, col);
}
DEG_OBJECT_ITER_END;
return cache;
@@ -734,26 +740,27 @@ static void cloth_brush_solve_collision(Object *object,
&col,
raycast_flag);
- if (hit.index != -1) {
-
- float collision_disp[3];
- float movement_disp[3];
- mul_v3_v3fl(collision_disp, hit.no, 0.005f);
- sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
- float friction_plane[4];
- float pos_on_friction_plane[3];
- plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
- closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
- sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
-
- /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
- mul_v3_fl(movement_disp, 0.35f);
-
- copy_v3_v3(cloth_sim->pos[i], hit.co);
- add_v3_v3(cloth_sim->pos[i], movement_disp);
- add_v3_v3(cloth_sim->pos[i], collision_disp);
- mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
+ if (hit.index == -1) {
+ continue;
}
+
+ float collision_disp[3];
+ float movement_disp[3];
+ mul_v3_v3fl(collision_disp, hit.no, 0.005f);
+ sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
+ float friction_plane[4];
+ float pos_on_friction_plane[3];
+ plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
+ closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
+ sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
+
+ /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
+ mul_v3_fl(movement_disp, 0.35f);
+
+ copy_v3_v3(cloth_sim->pos[i], hit.co);
+ add_v3_v3(cloth_sim->pos[i], movement_disp);
+ add_v3_v3(cloth_sim->pos[i], collision_disp);
+ mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
}
}
@@ -784,38 +791,40 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
ss->cache ? cloth_brush_simulation_falloff_get(
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
1.0f;
- if (sim_factor > 0.0f) {
- int i = vd.index;
- float temp[3];
- copy_v3_v3(temp, cloth_sim->pos[i]);
+ if (sim_factor <= 0.0f) {
+ continue;
+ }
- mul_v3_fl(cloth_sim->acceleration[i], time_step);
+ int i = vd.index;
+ float temp[3];
+ copy_v3_v3(temp, cloth_sim->pos[i]);
- float pos_diff[3];
- sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
- mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
+ mul_v3_fl(cloth_sim->acceleration[i], time_step);
- const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
- SCULPT_automasking_factor_get(automasking, ss, vd.index);
+ float pos_diff[3];
+ sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
+ mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
- madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
- madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
+ const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
+ SCULPT_automasking_factor_get(automasking, ss, vd.index);
- if (cloth_sim->collider_list != NULL) {
- cloth_brush_solve_collision(data->ob, cloth_sim, i);
- }
+ madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
+ madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ if (cloth_sim->collider_list != NULL) {
+ cloth_brush_solve_collision(data->ob, cloth_sim, i);
+ }
- copy_v3_v3(cloth_sim->prev_pos[i], temp);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+ copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 20d8e136d12..df03d2adeaf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -148,40 +148,42 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
float poly_center[3];
BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center);
- if (sculpt_brush_test_sq_fn(&test, poly_center)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
- }
+ if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
+ ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
}
}
}
else if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (fade > 0.05f) {
- SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (fade > 0.05f) {
+ SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
}
}
}
@@ -214,23 +216,26 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (relax_face_sets != SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
+ continue;
+ }
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -582,44 +587,49 @@ static void sculpt_face_sets_init_flood_fill(Object *ob,
int next_face_set = 1;
for (int i = 0; i < totfaces; i++) {
- if (!BLI_BITMAP_TEST(visited_faces, i)) {
- GSQueue *queue;
- queue = BLI_gsqueue_new(sizeof(int));
-
- face_sets[i] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, i);
- BLI_gsqueue_push(queue, &i);
-
- while (!BLI_gsqueue_is_empty(queue)) {
- int from_f;
- BLI_gsqueue_pop(queue, &from_f);
-
- BMFace *f, *f_neighbor;
- BMEdge *ed;
- BMIter iter_a, iter_b;
-
- f = BM_face_at_index(bm, from_f);
-
- BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
- BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
- if (f_neighbor != f) {
- int neighbor_face_index = BM_elem_index_get(f_neighbor);
- if (!BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
- if (test(bm, f, ed, f_neighbor, threshold)) {
- face_sets[neighbor_face_index] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
- BLI_gsqueue_push(queue, &neighbor_face_index);
- }
- }
- }
+ if (BLI_BITMAP_TEST(visited_faces, i)) {
+ continue;
+ }
+ GSQueue *queue;
+ queue = BLI_gsqueue_new(sizeof(int));
+
+ face_sets[i] = next_face_set;
+ BLI_BITMAP_ENABLE(visited_faces, i);
+ BLI_gsqueue_push(queue, &i);
+
+ while (!BLI_gsqueue_is_empty(queue)) {
+ int from_f;
+ BLI_gsqueue_pop(queue, &from_f);
+
+ BMFace *f, *f_neighbor;
+ BMEdge *ed;
+ BMIter iter_a, iter_b;
+
+ f = BM_face_at_index(bm, from_f);
+
+ BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
+ BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
+ if (f_neighbor == f) {
+ continue;
}
+ int neighbor_face_index = BM_elem_index_get(f_neighbor);
+ if (BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
+ continue;
+ }
+ if (!test(bm, f, ed, f_neighbor, threshold)) {
+ continue;
+ }
+
+ face_sets[neighbor_face_index] = next_face_set;
+ BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
+ BLI_gsqueue_push(queue, &neighbor_face_index);
}
}
+ }
- next_face_set += 1;
+ next_face_set += 1;
- BLI_gsqueue_free(queue);
- }
+ BLI_gsqueue_free(queue);
}
MEM_SAFE_FREE(visited_faces);
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index e47a94dff90..cfc31e1dcdd 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -88,38 +88,39 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
- mul_v3_m4v3(local_co, mat, vd.co);
- /* Use the brush falloff to weight the sampled normals. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Sample the normal and area of the +X and -X axis individually. */
- if (local_co[0] > 0.0f) {
- madd_v3_v3fl(mssd->area_nos[0], normal, fade);
- add_v3_v3(mssd->area_cos[0], vd.co);
- mssd->area_count[0]++;
- }
- else {
- madd_v3_v3fl(mssd->area_nos[1], normal, fade);
- add_v3_v3(mssd->area_cos[1], vd.co);
- mssd->area_count[1]++;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
+ mul_v3_m4v3(local_co, mat, vd.co);
+ /* Use the brush falloff to weight the sampled normals. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Sample the normal and area of the +X and -X axis individually. */
+ if (local_co[0] > 0.0f) {
+ madd_v3_v3fl(mssd->area_nos[0], normal, fade);
+ add_v3_v3(mssd->area_cos[0], vd.co);
+ mssd->area_count[0]++;
+ }
+ else {
+ madd_v3_v3fl(mssd->area_nos[1], normal, fade);
+ add_v3_v3(mssd->area_cos[1], vd.co);
+ mssd->area_count[1]++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -168,56 +169,61 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- bool deform = false;
-
- mul_v3_m4v3(local_co, mat, vd.co);
-
- if (local_co[0] > 0.0f) {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
- }
- else {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
- }
-
- if (angle < 0.0f) {
- deform = true;
- }
-
- if (deform) {
- float intr[3];
- float val[3];
-
- if (local_co[0] > 0.0f) {
- closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
- }
- else {
- closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
- }
-
- sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
- /* This produces a not round brush tip. */
- local_co[1] *= 2.0f;
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- len_v3(local_co),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ float local_co[3];
+ bool deform = false;
+
+ mul_v3_m4v3(local_co, mat, vd.co);
+
+ if (local_co[0] > 0.0f) {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
+ }
+ else {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
+ }
+
+ if (angle < 0.0f) {
+ deform = true;
+ }
+
+ if (!deform) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+
+ if (local_co[0] > 0.0f) {
+ closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
+ }
+ else {
+ closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
+ }
+
+ sub_v3_v3v3(val, intr, vd.co);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
+ /* This produces a not round brush tip. */
+ local_co[1] *= 2.0f;
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ len_v3(local_co),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 39320f3f558..5fdf8415f28 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -87,24 +87,25 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float smooth_color[4];
- SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
- blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float smooth_color[4];
+ SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
+ blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -153,46 +154,49 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
distance_to_stroke_location = sqrtf(test.dist);
}
- if (affect_vertex) {
- float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- distance_to_stroke_location,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Density. */
- float noise = 1.0f;
- const float density = ss->cache->paint_brush.density;
- if (density < 1.0f) {
- const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
- if (hash_noise > density) {
- noise = density * hash_noise;
- fade = fade * noise;
- }
+ if (!affect_vertex) {
+ continue;
+ }
+
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ distance_to_stroke_location,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Density. */
+ float noise = 1.0f;
+ const float density = ss->cache->paint_brush.density;
+ if (density < 1.0f) {
+ const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
+ if (hash_noise > density) {
+ noise = density * hash_noise;
+ fade = fade * noise;
}
+ }
- /* Brush paint color, brush test falloff and flow. */
- float paint_color[4];
- float wet_mix_color[4];
- float buffer_color[4];
+ /* Brush paint color, brush test falloff and flow. */
+ float paint_color[4];
+ float wet_mix_color[4];
+ float buffer_color[4];
- mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
- mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
- /* Interpolate with the wet_mix color for wet paint mixing. */
- blend_color_interpolate_float(
- paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
- blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
+ /* Interpolate with the wet_mix color for wet paint mixing. */
+ blend_color_interpolate_float(
+ paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
+ blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
- /* Final mix over the original color using brush alpha. */
- mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+ /* Final mix over the original color using brush alpha. */
+ mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+
+ IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- }
CLAMP4(vd.col, 0.0f, 1.0f);
if (vd.mvert) {
@@ -225,10 +229,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- add_v4_v4(swptd->color, vd.col);
- swptd->tot_samples++;
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
}
+
+ add_v4_v4(swptd->color, vd.col);
+ swptd->tot_samples++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -380,59 +386,61 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float current_disp[3];
- float current_disp_norm[3];
- float interp_color[4];
- copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
-
- switch (brush->smear_deform_type) {
- case BRUSH_SMEAR_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SMEAR_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SMEAR_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- const float *neighbor_color = ss->cache->prev_colors[ni.index];
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float color_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- float color_mix[4];
- copy_v4_v4(color_mix, neighbor_color);
- mul_v4_fl(color_mix, color_interp * fade);
- blend_color_mix_float(interp_color, interp_color, color_mix);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float current_disp[3];
+ float current_disp_norm[3];
+ float interp_color[4];
+ copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
+
+ switch (brush->smear_deform_type) {
+ case BRUSH_SMEAR_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SMEAR_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SMEAR_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ const float *neighbor_color = ss->cache->prev_colors[ni.index];
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ const float color_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ float color_mix[4];
+ copy_v4_v4(color_mix, neighbor_color);
+ mul_v4_fl(color_mix, color_interp * fade);
+ blend_color_mix_float(interp_color, interp_color, color_mix);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
+ blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index f9ccbbb849c..a85f805894b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -490,50 +490,52 @@ static bool pose_face_sets_floodfill_cb(
is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
}
- if (is_vertex_valid) {
-
- if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
- data->pose_factor[index] = 1.0f;
- BLI_BITMAP_ENABLE(data->is_weighted, index);
- visit_next = true;
- }
-
- /* Fallback origin accumulation. */
- if (symmetry_check) {
- add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
- data->fallback_count++;
- }
-
- if (symmetry_check && !SCULPT_vertex_has_unique_face_set(ss, index)) {
+ if (!is_vertex_valid) {
+ return visit_next;
+ }
- /* We only add coordinates for calculating the origin when it is possible to go from this
- * vertex to another vertex in a valid face set for the next iteration. */
- bool count_as_boundary = false;
+ if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
+ data->pose_factor[index] = 1.0f;
+ BLI_BITMAP_ENABLE(data->is_weighted, index);
+ visit_next = true;
+ }
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
- int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+ /* Fallback origin accumulation. */
+ if (symmetry_check) {
+ add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
+ data->fallback_count++;
+ }
- /* Check if we can get a valid face set for the next iteration from this neighbor. */
- if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
- !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
- if (!data->next_face_set_found) {
- data->next_face_set = next_face_set_candidate;
- data->next_vertex = ni.index;
- data->next_face_set_found = true;
- }
- count_as_boundary = true;
- }
- }
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) {
+ return visit_next;
+ }
- /* Origin accumulation. */
- if (count_as_boundary) {
- add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
- data->tot_co++;
+ /* We only add coordinates for calculating the origin when it is possible to go from this
+ * vertex to another vertex in a valid face set for the next iteration. */
+ bool count_as_boundary = false;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+
+ /* Check if we can get a valid face set for the next iteration from this neighbor. */
+ if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
+ !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
+ if (!data->next_face_set_found) {
+ data->next_face_set = next_face_set_candidate;
+ data->next_vertex = ni.index;
+ data->next_face_set_found = true;
}
+ count_as_boundary = true;
}
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ /* Origin accumulation. */
+ if (count_as_boundary) {
+ add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
+ data->tot_co++;
+ }
return visit_next;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 87ee7480c92..4c0795eb0f7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -231,24 +231,26 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
- SCULPT_clip(sd, ss, vd.co, disp);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
+ SCULPT_clip(sd, ss, vd.co, disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -312,33 +314,34 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(
- ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
- vd.index,
- thread_id);
- if (smooth_mask) {
- float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
- val *= fade * bstrength;
- *vd.mask += val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
- }
- else {
- float avg[3], val[3];
- SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
- sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
- }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(
+ ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+ vd.index,
+ thread_id);
+ if (smooth_mask) {
+ float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
+ }
+ else {
+ float avg[3], val[3];
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
+ sub_v3_v3v3(val, avg, vd.co);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
+ SCULPT_clip(sd, ss, vd.co, val);
+ }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -473,32 +476,28 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
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, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- SCULPT_surface_smooth_laplacian_step(ss,
- disp,
- vd.co,
- ss->cache->surface_smooth_laplacian_disp,
- vd.index,
- orig_data.co,
- alpha);
- madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ SCULPT_surface_smooth_laplacian_step(
+ ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, orig_data.co, alpha);
+ madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BKE_pbvh_vertex_iter_end;
}
+ BKE_pbvh_vertex_iter_end;
}
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
@@ -519,19 +518,20 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- SCULPT_surface_smooth_displace_step(
- ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
}
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ SCULPT_surface_smooth_displace_step(
+ ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
}
BKE_pbvh_vertex_iter_end;
}