Cleanup: Unindent if statements in sculpt tools code

This removes indentations from if statements by converting them to early
returns and continue.
Most of the code of brushes and tools has loops with a full indented
body inside of an if, which was also copied into some of the new tools.

Reviewed By: JacquesLucke

Differential Revision: https://developer.blender.org/D10333
This commit is contained in:
Pablo Dobarro 2021-02-10 01:38:28 +01:00
parent 54cbfeedd7
commit 4818ed1c76
9 changed files with 2151 additions and 2004 deletions

File diff suppressed because it is too large Load Diff

View File

@ -298,24 +298,26 @@ float *SCULPT_boundary_automasking_init(Object *ob,
for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) {
for (int i = 0; i < totvert; i++) {
if (edge_distance[i] == EDGE_DISTANCE_INF) {
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
if (edge_distance[ni.index] == propagation_it) {
edge_distance[i] = propagation_it + 1;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (edge_distance[i] != EDGE_DISTANCE_INF) {
continue;
}
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
if (edge_distance[ni.index] == propagation_it) {
edge_distance[i] = propagation_it + 1;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
for (int i = 0; i < totvert; i++) {
if (edge_distance[i] != EDGE_DISTANCE_INF) {
const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
const float edge_boundary_automask = pow2f(p);
automask_factor[i] *= (1.0f - edge_boundary_automask);
if (edge_distance[i] == EDGE_DISTANCE_INF) {
continue;
}
const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
const float edge_boundary_automask = pow2f(p);
automask_factor[i] *= (1.0f - edge_boundary_automask);
}
MEM_SAFE_FREE(edge_distance);

View File

@ -227,19 +227,19 @@ static bool boundary_floodfill_cb(
{
BoundaryFloodFillData *data = userdata;
SculptBoundary *boundary = data->boundary;
if (SCULPT_vertex_is_boundary(ss, to_v)) {
const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, to_v));
const float distance_boundary_to_dst = boundary->distance ?
boundary->distance[from_v] + edge_len :
0.0f;
sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
if (!is_duplicate) {
sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
if (!SCULPT_vertex_is_boundary(ss, to_v)) {
return false;
}
return false;
const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, to_v));
const float distance_boundary_to_dst = boundary->distance ?
boundary->distance[from_v] + edge_len :
0.0f;
sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
if (!is_duplicate) {
sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
}
static void sculpt_boundary_indices_init(SculptSession *ss,
@ -360,49 +360,50 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
if (is_visible &&
boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
boundary->edit_info[ni.index].original_vertex =
boundary->edit_info[from_v].original_vertex;
if (!is_visible ||
boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) {
continue;
}
boundary->edit_info[ni.index].original_vertex =
boundary->edit_info[from_v].original_vertex;
BLI_BITMAP_ENABLE(visited_vertices, ni.index);
BLI_BITMAP_ENABLE(visited_vertices, ni.index);
if (ni.is_duplicate) {
/* Grids duplicates handling. */
boundary->edit_info[ni.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps;
}
else {
boundary->edit_info[ni.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps + 1;
if (ni.is_duplicate) {
/* Grids duplicates handling. */
boundary->edit_info[ni.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps;
}
else {
boundary->edit_info[ni.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps + 1;
BLI_gsqueue_push(next_iteration, &ni.index);
BLI_gsqueue_push(next_iteration, &ni.index);
/* When copying the data to the neighbor for the next iteration, it has to be copied to
* all its duplicates too. This is because it is not possible to know if the updated
* neighbor or one if its uninitialized duplicates is going to come first in order to
* copy the data in the from_v neighbor iterator. */
if (has_duplicates) {
SculptVertexNeighborIter ni_duplis;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
if (ni_duplis.is_duplicate) {
boundary->edit_info[ni_duplis.index].original_vertex =
boundary->edit_info[from_v].original_vertex;
boundary->edit_info[ni_duplis.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps + 1;
}
/* When copying the data to the neighbor for the next iteration, it has to be copied to
* all its duplicates too. This is because it is not possible to know if the updated
* neighbor or one if its uninitialized duplicates is going to come first in order to
* copy the data in the from_v neighbor iterator. */
if (has_duplicates) {
SculptVertexNeighborIter ni_duplis;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
if (ni_duplis.is_duplicate) {
boundary->edit_info[ni_duplis.index].original_vertex =
boundary->edit_info[from_v].original_vertex;
boundary->edit_info[ni_duplis.index].num_propagation_steps =
boundary->edit_info[from_v].num_propagation_steps + 1;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
/* Check the distance using the vertex that was propagated from the initial vertex that
* was used to initialize the boundary. */
if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
boundary->pivot_vertex = ni.index;
copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, ni.index));
}
/* Check the distance using the vertex that was propagated from the initial vertex that
* was used to initialize the boundary. */
if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
boundary->pivot_vertex = ni.index;
copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, ni.index));
}
}
}
@ -552,28 +553,30 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
totvert, 3 * sizeof(float), "pivot positions");
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
float dir[3];
float normal[3];
SCULPT_vertex_normal_get(ss, i, normal);
sub_v3_v3v3(dir,
SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
cross_v3_v3v3(
boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
SCULPT_vertex_co_get(ss, i));
if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
continue;
}
float dir[3];
float normal[3];
SCULPT_vertex_normal_get(ss, i, normal);
sub_v3_v3v3(dir,
SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
cross_v3_v3v3(
boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
SCULPT_vertex_co_get(ss, i));
}
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
copy_v3_v3(boundary->bend.pivot_positions[i],
boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
continue;
}
copy_v3_v3(boundary->bend.pivot_positions[i],
boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
}
}
@ -583,19 +586,20 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
}
sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
copy_v3_v3(boundary->slide.directions[i],
boundary->slide.directions[boundary->edit_info[i].original_vertex]);
if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
continue;
}
copy_v3_v3(boundary->slide.directions[i],
boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
@ -662,24 +666,27 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
rotate_v3_v3v3fl(target_co,
t_orig_co,
boundary->bend.pivot_rotation_axis[vd.index],
angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
}
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
rotate_v3_v3v3fl(target_co,
t_orig_co,
boundary->bend.pivot_rotation_axis[vd.index],
angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@ -708,22 +715,25 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
boundary->slide.directions[vd.index],
boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
strength);
}
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
boundary->slide.directions[vd.index],
boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
strength);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@ -752,24 +762,27 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float normal[3];
normal_short_to_float_v3(normal, orig_data.no);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
normal,
boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
strength);
}
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float normal[3];
normal_short_to_float_v3(normal, orig_data.no);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
normal,
boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
strength);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@ -796,21 +809,24 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
ss->cache->grab_delta_symmetry,
boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
}
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
ss->cache->grab_delta_symmetry,
boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@ -845,24 +861,27 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
rotate_v3_v3v3fl(target_co,
t_orig_co,
boundary->twist.rotation_axis,
angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
add_v3_v3(target_co, boundary->twist.pivot_position);
}
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
rotate_v3_v3v3fl(target_co,
t_orig_co,
boundary->twist.rotation_axis,
angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
add_v3_v3(target_co, boundary->twist.pivot_position);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}

View File

@ -540,97 +540,98 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
float dist = sqrtf(test.dist);
if (use_falloff_plane) {
dist = dist_to_plane_v3(current_vertex_location, deform_plane);
}
const float fade = sim_factor * bstrength *
SCULPT_brush_strength_factor(ss,
brush,
current_vertex_location,
dist,
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float brush_disp[3];
float normal[3];
if (vd.no) {
normal_short_to_float_v3(normal, vd.no);
}
else {
copy_v3_v3(normal, vd.fno);
}
switch (brush->cloth_deform_type) {
case BRUSH_CLOTH_DEFORM_DRAG:
sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
normalize_v3(brush_disp);
mul_v3_v3fl(force, brush_disp, fade);
break;
case BRUSH_CLOTH_DEFORM_PUSH:
/* Invert the fade to push inwards. */
mul_v3_v3fl(force, offset, -fade);
break;
case BRUSH_CLOTH_DEFORM_GRAB:
madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
cloth_sim->init_pos[vd.index],
ss->cache->grab_delta_symmetry,
fade);
if (use_falloff_plane) {
cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
}
else {
cloth_sim->deformation_strength[vd.index] = 1.0f;
}
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
cloth_sim->deformation_strength[vd.index] = fade;
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
if (use_falloff_plane) {
float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
copy_v3_v3(brush_disp, plane_normal);
mul_v3_fl(brush_disp, -distance);
}
else {
sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
}
normalize_v3(brush_disp);
mul_v3_v3fl(force, brush_disp, fade);
break;
case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
float disp_center[3];
float x_disp[3];
float z_disp[3];
sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
normalize_v3(disp_center);
mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
add_v3_v3v3(disp_center, x_disp, z_disp);
mul_v3_v3fl(force, disp_center, fade);
} break;
case BRUSH_CLOTH_DEFORM_INFLATE:
mul_v3_v3fl(force, normal, fade);
break;
case BRUSH_CLOTH_DEFORM_EXPAND:
cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
zero_v3(force);
break;
}
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
if (!sculpt_brush_test_sq_fn(&test, current_vertex_location) && !use_falloff_plane) {
continue;
}
float dist = sqrtf(test.dist);
if (use_falloff_plane) {
dist = dist_to_plane_v3(current_vertex_location, deform_plane);
}
const float fade = sim_factor * bstrength *
SCULPT_brush_strength_factor(ss,
brush,
current_vertex_location,
dist,
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float brush_disp[3];
float normal[3];
if (vd.no) {
normal_short_to_float_v3(normal, vd.no);
}
else {
copy_v3_v3(normal, vd.fno);
}
switch (brush->cloth_deform_type) {
case BRUSH_CLOTH_DEFORM_DRAG:
sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
normalize_v3(brush_disp);
mul_v3_v3fl(force, brush_disp, fade);
break;
case BRUSH_CLOTH_DEFORM_PUSH:
/* Invert the fade to push inwards. */
mul_v3_v3fl(force, offset, -fade);
break;
case BRUSH_CLOTH_DEFORM_GRAB:
madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
cloth_sim->init_pos[vd.index],
ss->cache->grab_delta_symmetry,
fade);
if (use_falloff_plane) {
cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
}
else {
cloth_sim->deformation_strength[vd.index] = 1.0f;
}
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
cloth_sim->deformation_strength[vd.index] = fade;
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
if (use_falloff_plane) {
float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
copy_v3_v3(brush_disp, plane_normal);
mul_v3_fl(brush_disp, -distance);
}
else {
sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
}
normalize_v3(brush_disp);
mul_v3_v3fl(force, brush_disp, fade);
break;
case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
float disp_center[3];
float x_disp[3];
float z_disp[3];
sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
normalize_v3(disp_center);
mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
add_v3_v3v3(disp_center, x_disp, z_disp);
mul_v3_v3fl(force, disp_center, fade);
} break;
case BRUSH_CLOTH_DEFORM_INFLATE:
mul_v3_v3fl(force, normal, fade);
break;
case BRUSH_CLOTH_DEFORM_EXPAND:
cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
zero_v3(force);
break;
}
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
}
BKE_pbvh_vertex_iter_end;
}
@ -644,17 +645,22 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
DEG_ITER_OBJECT_FLAG_DUPLI) {
CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
ob, eModifierType_Collision);
if (cmd && cmd->bvhtree) {
if (cache == NULL) {
cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
}
ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
col->ob = ob;
col->collmd = cmd;
collision_move_object(cmd, 1.0, 0.0, true);
BLI_addtail(cache, col);
if (!cmd) {
continue;
}
if (!cmd->bvhtree) {
continue;
}
if (cache == NULL) {
cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
}
ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
col->ob = ob;
col->collmd = cmd;
collision_move_object(cmd, 1.0, 0.0, true);
BLI_addtail(cache, col);
}
DEG_OBJECT_ITER_END;
return cache;
@ -734,26 +740,27 @@ static void cloth_brush_solve_collision(Object *object,
&col,
raycast_flag);
if (hit.index != -1) {
float collision_disp[3];
float movement_disp[3];
mul_v3_v3fl(collision_disp, hit.no, 0.005f);
sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
float friction_plane[4];
float pos_on_friction_plane[3];
plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
/* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
mul_v3_fl(movement_disp, 0.35f);
copy_v3_v3(cloth_sim->pos[i], hit.co);
add_v3_v3(cloth_sim->pos[i], movement_disp);
add_v3_v3(cloth_sim->pos[i], collision_disp);
mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
if (hit.index == -1) {
continue;
}
float collision_disp[3];
float movement_disp[3];
mul_v3_v3fl(collision_disp, hit.no, 0.005f);
sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
float friction_plane[4];
float pos_on_friction_plane[3];
plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
/* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
mul_v3_fl(movement_disp, 0.35f);
copy_v3_v3(cloth_sim->pos[i], hit.co);
add_v3_v3(cloth_sim->pos[i], movement_disp);
add_v3_v3(cloth_sim->pos[i], collision_disp);
mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
}
}
@ -784,38 +791,40 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
ss->cache ? cloth_brush_simulation_falloff_get(
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
1.0f;
if (sim_factor > 0.0f) {
int i = vd.index;
float temp[3];
copy_v3_v3(temp, cloth_sim->pos[i]);
if (sim_factor <= 0.0f) {
continue;
}
mul_v3_fl(cloth_sim->acceleration[i], time_step);
int i = vd.index;
float temp[3];
copy_v3_v3(temp, cloth_sim->pos[i]);
float pos_diff[3];
sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
mul_v3_fl(cloth_sim->acceleration[i], time_step);
const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
SCULPT_automasking_factor_get(automasking, ss, vd.index);
float pos_diff[3];
sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
SCULPT_automasking_factor_get(automasking, ss, vd.index);
if (cloth_sim->collider_list != NULL) {
cloth_brush_solve_collision(data->ob, cloth_sim, i);
}
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
if (cloth_sim->collider_list != NULL) {
cloth_brush_solve_collision(data->ob, cloth_sim, i);
}
copy_v3_v3(cloth_sim->prev_pos[i], temp);
copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
copy_v3_v3(cloth_sim->prev_pos[i], temp);
copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;

View File

@ -148,40 +148,42 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
float poly_center[3];
BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center);
if (sculpt_brush_test_sq_fn(&test, poly_center)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
}
if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
}
}
}
else if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (fade > 0.05f) {
SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
}
if (fade > 0.05f) {
SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
}
}
}
@ -214,23 +216,26 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
if (relax_face_sets != SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
continue;
}
SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@ -582,44 +587,49 @@ static void sculpt_face_sets_init_flood_fill(Object *ob,
int next_face_set = 1;
for (int i = 0; i < totfaces; i++) {
if (!BLI_BITMAP_TEST(visited_faces, i)) {
GSQueue *queue;
queue = BLI_gsqueue_new(sizeof(int));
if (BLI_BITMAP_TEST(visited_faces, i)) {
continue;
}
GSQueue *queue;
queue = BLI_gsqueue_new(sizeof(int));
face_sets[i] = next_face_set;
BLI_BITMAP_ENABLE(visited_faces, i);
BLI_gsqueue_push(queue, &i);
face_sets[i] = next_face_set;
BLI_BITMAP_ENABLE(visited_faces, i);
BLI_gsqueue_push(queue, &i);
while (!BLI_gsqueue_is_empty(queue)) {
int from_f;
BLI_gsqueue_pop(queue, &from_f);
while (!BLI_gsqueue_is_empty(queue)) {
int from_f;
BLI_gsqueue_pop(queue, &from_f);
BMFace *f, *f_neighbor;
BMEdge *ed;
BMIter iter_a, iter_b;
BMFace *f, *f_neighbor;
BMEdge *ed;
BMIter iter_a, iter_b;
f = BM_face_at_index(bm, from_f);
f = BM_face_at_index(bm, from_f);
BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
if (f_neighbor != f) {
int neighbor_face_index = BM_elem_index_get(f_neighbor);
if (!BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
if (test(bm, f, ed, f_neighbor, threshold)) {
face_sets[neighbor_face_index] = next_face_set;
BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
BLI_gsqueue_push(queue, &neighbor_face_index);
}
}
}
BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
if (f_neighbor == f) {
continue;
}
int neighbor_face_index = BM_elem_index_get(f_neighbor);
if (BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
continue;
}
if (!test(bm, f, ed, f_neighbor, threshold)) {
continue;
}
face_sets[neighbor_face_index] = next_face_set;
BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
BLI_gsqueue_push(queue, &neighbor_face_index);
}
}
next_face_set += 1;
BLI_gsqueue_free(queue);
}
next_face_set += 1;
BLI_gsqueue_free(queue);
}
MEM_SAFE_FREE(visited_faces);

View File

@ -88,38 +88,39 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
float local_co[3];
float normal[3];
if (vd.no) {
normal_short_to_float_v3(normal, vd.no);
}
else {
copy_v3_v3(normal, vd.fno);
}
mul_v3_m4v3(local_co, mat, vd.co);
/* Use the brush falloff to weight the sampled normals. */
const float fade = SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
float local_co[3];
float normal[3];
if (vd.no) {
normal_short_to_float_v3(normal, vd.no);
}
else {
copy_v3_v3(normal, vd.fno);
}
mul_v3_m4v3(local_co, mat, vd.co);
/* Use the brush falloff to weight the sampled normals. */
const float fade = SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
/* Sample the normal and area of the +X and -X axis individually. */
if (local_co[0] > 0.0f) {
madd_v3_v3fl(mssd->area_nos[0], normal, fade);
add_v3_v3(mssd->area_cos[0], vd.co);
mssd->area_count[0]++;
}
else {
madd_v3_v3fl(mssd->area_nos[1], normal, fade);
add_v3_v3(mssd->area_cos[1], vd.co);
mssd->area_count[1]++;
}
/* Sample the normal and area of the +X and -X axis individually. */
if (local_co[0] > 0.0f) {
madd_v3_v3fl(mssd->area_nos[0], normal, fade);
add_v3_v3(mssd->area_cos[0], vd.co);
mssd->area_count[0]++;
}
else {
madd_v3_v3fl(mssd->area_nos[1], normal, fade);
add_v3_v3(mssd->area_cos[1], vd.co);
mssd->area_count[1]++;
}
BKE_pbvh_vertex_iter_end;
}
@ -168,56 +169,61 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
float local_co[3];
bool deform = false;
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
mul_v3_m4v3(local_co, mat, vd.co);
float local_co[3];
bool deform = false;
if (local_co[0] > 0.0f) {
deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
}
else {
deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
}
mul_v3_m4v3(local_co, mat, vd.co);
if (angle < 0.0f) {
deform = true;
}
if (local_co[0] > 0.0f) {
deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
}
else {
deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
}
if (deform) {
float intr[3];
float val[3];
if (angle < 0.0f) {
deform = true;
}
if (local_co[0] > 0.0f) {
closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
}
else {
closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
}
if (!deform) {
continue;
}
sub_v3_v3v3(val, intr, vd.co);
if (SCULPT_plane_trim(ss->cache, brush, val)) {
/* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
/* This produces a not round brush tip. */
local_co[1] *= 2.0f;
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
len_v3(local_co),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float intr[3];
float val[3];
mul_v3_v3fl(proxy[vd.i], val, fade);
if (local_co[0] > 0.0f) {
closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
}
else {
closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
sub_v3_v3v3(val, intr, vd.co);
if (!SCULPT_plane_trim(ss->cache, brush, val)) {
continue;
}
/* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
/* This produces a not round brush tip. */
local_co[1] *= 2.0f;
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
len_v3(local_co),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
mul_v3_v3fl(proxy[vd.i], val, fade);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;

View File

@ -87,24 +87,25 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@ -153,46 +154,49 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
distance_to_stroke_location = sqrtf(test.dist);
}
if (affect_vertex) {
float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
distance_to_stroke_location,
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
/* Density. */
float noise = 1.0f;
const float density = ss->cache->paint_brush.density;
if (density < 1.0f) {
const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
if (hash_noise > density) {
noise = density * hash_noise;
fade = fade * noise;
}
}
/* Brush paint color, brush test falloff and flow. */
float paint_color[4];
float wet_mix_color[4];
float buffer_color[4];
mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
/* Interpolate with the wet_mix color for wet paint mixing. */
blend_color_interpolate_float(
paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
/* Final mix over the original color using brush alpha. */
mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
if (!affect_vertex) {
continue;
}
float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
distance_to_stroke_location,
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
/* Density. */
float noise = 1.0f;
const float density = ss->cache->paint_brush.density;
if (density < 1.0f) {
const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
if (hash_noise > density) {
noise = density * hash_noise;
fade = fade * noise;
}
}
/* Brush paint color, brush test falloff and flow. */
float paint_color[4];
float wet_mix_color[4];
float buffer_color[4];
mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
/* Interpolate with the wet_mix color for wet paint mixing. */
blend_color_interpolate_float(
paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
/* Final mix over the original color using brush alpha. */
mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
CLAMP4(vd.col, 0.0f, 1.0f);
if (vd.mvert) {
@ -225,10 +229,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
add_v4_v4(swptd->color, vd.col);
swptd->tot_samples++;
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
add_v4_v4(swptd->color, vd.col);
swptd->tot_samples++;
}
BKE_pbvh_vertex_iter_end;
}
@ -380,59 +386,61 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float current_disp[3];
float current_disp_norm[3];
float interp_color[4];
copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
float current_disp[3];
float current_disp_norm[3];
float interp_color[4];
copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
switch (brush->smear_deform_type) {
case BRUSH_SMEAR_DEFORM_DRAG:
sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
break;
case BRUSH_SMEAR_DEFORM_PINCH:
sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
break;
case BRUSH_SMEAR_DEFORM_EXPAND:
sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
break;
switch (brush->smear_deform_type) {
case BRUSH_SMEAR_DEFORM_DRAG:
sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
break;
case BRUSH_SMEAR_DEFORM_PINCH:
sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
break;
case BRUSH_SMEAR_DEFORM_EXPAND:
sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
break;
}
normalize_v3_v3(current_disp_norm, current_disp);
mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vertex_disp[3];
float vertex_disp_norm[3];
sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
const float *neighbor_color = ss->cache->prev_colors[ni.index];
normalize_v3_v3(vertex_disp_norm, vertex_disp);
if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
continue;
}
normalize_v3_v3(current_disp_norm, current_disp);
mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
const float color_interp = clamp_f(
-dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
float color_mix[4];
copy_v4_v4(color_mix, neighbor_color);
mul_v4_fl(color_mix, color_interp * fade);
blend_color_mix_float(interp_color, interp_color, color_mix);
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vertex_disp[3];
float vertex_disp_norm[3];
sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
const float *neighbor_color = ss->cache->prev_colors[ni.index];
normalize_v3_v3(vertex_disp_norm, vertex_disp);
if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
const float color_interp = clamp_f(
-dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
float color_mix[4];
copy_v4_v4(color_mix, neighbor_color);
mul_v4_fl(color_mix, color_interp * fade);
blend_color_mix_float(interp_color, interp_color, color_mix);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;

View File

@ -490,50 +490,52 @@ static bool pose_face_sets_floodfill_cb(
is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
}
if (is_vertex_valid) {
if (!is_vertex_valid) {
return visit_next;
}
if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
data->pose_factor[index] = 1.0f;
BLI_BITMAP_ENABLE(data->is_weighted, index);
visit_next = true;
}
if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
data->pose_factor[index] = 1.0f;
BLI_BITMAP_ENABLE(data->is_weighted, index);
visit_next = true;
}
/* Fallback origin accumulation. */
if (symmetry_check) {
add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
data->fallback_count++;
}
/* Fallback origin accumulation. */
if (symmetry_check) {
add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
data->fallback_count++;
}
if (symmetry_check && !SCULPT_vertex_has_unique_face_set(ss, index)) {
if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) {
return visit_next;
}
/* We only add coordinates for calculating the origin when it is possible to go from this
* vertex to another vertex in a valid face set for the next iteration. */
bool count_as_boundary = false;
/* We only add coordinates for calculating the origin when it is possible to go from this
* vertex to another vertex in a valid face set for the next iteration. */
bool count_as_boundary = false;
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
/* Check if we can get a valid face set for the next iteration from this neighbor. */
if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
!BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
if (!data->next_face_set_found) {
data->next_face_set = next_face_set_candidate;
data->next_vertex = ni.index;
data->next_face_set_found = true;
}
count_as_boundary = true;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
/* Origin accumulation. */
if (count_as_boundary) {
add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
data->tot_co++;
/* Check if we can get a valid face set for the next iteration from this neighbor. */
if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
!BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
if (!data->next_face_set_found) {
data->next_face_set = next_face_set_candidate;
data->next_vertex = ni.index;
data->next_face_set_found = true;
}
count_as_boundary = true;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
/* Origin accumulation. */
if (count_as_boundary) {
add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
data->tot_co++;
}
return visit_next;
}

View File

@ -231,24 +231,26 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
float disp[3];
madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
SCULPT_clip(sd, ss, vd.co, disp);
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;
}
float disp[3];
madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
SCULPT_clip(sd, ss, vd.co, disp);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@ -312,33 +314,34 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(
ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
vd.index,
thread_id);
if (smooth_mask) {
float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
val *= fade * bstrength;
*vd.mask += val;
CLAMP(*vd.mask, 0.0f, 1.0f);
}
else {
float avg[3], val[3];
SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
sub_v3_v3v3(val, avg, vd.co);
madd_v3_v3v3fl(val, vd.co, val, fade);
SCULPT_clip(sd, ss, vd.co, val);
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(
ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
vd.index,
thread_id);
if (smooth_mask) {
float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
val *= fade * bstrength;
*vd.mask += val;
CLAMP(*vd.mask, 0.0f, 1.0f);
}
else {
float avg[3], val[3];
SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
sub_v3_v3v3(val, avg, vd.co);
madd_v3_v3v3fl(val, vd.co, val, fade);
SCULPT_clip(sd, ss, vd.co, val);
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@ -473,32 +476,28 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float disp[3];
SCULPT_surface_smooth_laplacian_step(ss,
disp,
vd.co,
ss->cache->surface_smooth_laplacian_disp,
vd.index,
orig_data.co,
alpha);
madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
float disp[3];
SCULPT_surface_smooth_laplacian_step(
ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, orig_data.co, alpha);
madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
BKE_pbvh_vertex_iter_end;
}
BKE_pbvh_vertex_iter_end;
}
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
@ -519,19 +518,20 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
SCULPT_surface_smooth_displace_step(
ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
sqrtf(test.dist),
vd.no,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.index,
thread_id);
SCULPT_surface_smooth_displace_step(
ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
}
BKE_pbvh_vertex_iter_end;
}