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:
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c2711
1 files changed, 1401 insertions, 1310 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;