Merge branch 'blender-v2.83-release'

This commit is contained in:
Pablo Dobarro 2020-05-26 20:49:53 +02:00
commit 00674c12cc
5 changed files with 117 additions and 57 deletions

View File

@ -230,8 +230,7 @@ static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
SCULPT_TOOL_THUMB)) {
return false;
}
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
else if (SCULPT_is_cloth_deform_brush(brush)) {
return false;
}
else {

View File

@ -156,9 +156,16 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
normal_short_to_float_v3(no, ss->mvert[index].no);
return;
case PBVH_FACES: {
if (ss->shapekey_active || ss->deform_modifiers_active) {
const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh);
normal_short_to_float_v3(no, mverts[index].no);
}
else {
normal_short_to_float_v3(no, ss->mvert[index].no);
}
break;
}
case PBVH_BMESH:
copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
break;
@ -2084,9 +2091,13 @@ static float brush_strength(const Sculpt *sd,
case SCULPT_TOOL_LAYER:
return alpha * flip * pressure * overlap * feather;
case SCULPT_TOOL_CLOTH:
/* Expand is more sensible to strength as it keeps expanding the cloth when sculpting over
* the same vertices. */
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_EXPAND) {
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
/* Grab deform uses the same falloff as a regular grab brush. */
return root_alpha * feather;
}
else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_EXPAND) {
/* Expand is more sensible to strength as it keeps expanding the cloth when sculpting over
* the same vertices. */
return 0.1f * alpha * flip * pressure * overlap * feather;
}
else {
@ -6208,6 +6219,34 @@ static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, flo
}
}
/* In these brushes the grab delta is calculated always from the initial stroke location, which is
* generally used to create grab deformations. */
static bool sculpt_needs_delta_from_anchored_origin(Brush *brush)
{
return ELEM(brush->sculpt_tool,
SCULPT_TOOL_GRAB,
SCULPT_TOOL_POSE,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_ELASTIC_DEFORM) ||
SCULPT_is_cloth_deform_brush(brush);
}
/* In these brushes the grab delta is calculated from the previous stroke location, which is used
* to calculate to orientate the brush tip and deformation towards the stroke direction. */
static bool sculpt_needs_delta_for_tip_orientation(Brush *brush)
{
if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
return !SCULPT_is_cloth_deform_brush(brush);
}
return ELEM(brush->sculpt_tool,
SCULPT_TOOL_CLAY_STRIPS,
SCULPT_TOOL_PINCH,
SCULPT_TOOL_MULTIPLANE_SCRAPE,
SCULPT_TOOL_CLAY_THUMB,
SCULPT_TOOL_NUDGE,
SCULPT_TOOL_SNAKE_HOOK);
}
static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Brush *brush)
{
SculptSession *ss = ob->sculpt;
@ -6251,38 +6290,27 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
/* Compute delta to move verts by. */
if (!cache->first_time) {
switch (tool) {
case SCULPT_TOOL_GRAB:
case SCULPT_TOOL_POSE:
case SCULPT_TOOL_THUMB:
case SCULPT_TOOL_ELASTIC_DEFORM:
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);
break;
case SCULPT_TOOL_CLAY_STRIPS:
case SCULPT_TOOL_PINCH:
case SCULPT_TOOL_CLOTH:
case SCULPT_TOOL_MULTIPLANE_SCRAPE:
case SCULPT_TOOL_CLAY_THUMB:
case SCULPT_TOOL_NUDGE:
case SCULPT_TOOL_SNAKE_HOOK:
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);
break;
default:
/* Use for 'Brush.topology_rake_factor'. */
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);
break;
}
invert_m4_m4(imat, ob->obmat);
mul_mat3_m4_v3(imat, cache->grab_delta);
}
else {
/* Use for 'Brush.topology_rake_factor'. */
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
}
else {
@ -6303,18 +6331,14 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
copy_v3_v3(cache->anchored_location, cache->true_location);
}
}
else if (tool == SCULPT_TOOL_ELASTIC_DEFORM) {
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 (ELEM(tool,
SCULPT_TOOL_GRAB,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_ELASTIC_DEFORM,
SCULPT_TOOL_POSE)) {
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);
@ -6385,9 +6409,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
if (cache->first_time ||
!((brush->flag & BRUSH_ANCHORED) || (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) ||
(brush->sculpt_tool == SCULPT_TOOL_ROTATE) ||
(brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB))) {
(brush->sculpt_tool == SCULPT_TOOL_ROTATE) || SCULPT_is_cloth_deform_brush(brush))) {
RNA_float_get_array(ptr, "location", cache->true_location);
}

View File

@ -212,8 +212,9 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
const float *grab_delta = data->grab_delta;
float(*imat)[4] = data->mat;
const bool use_falloff_plane = brush->cloth_force_falloff_type ==
BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
const bool use_falloff_plane = !SCULPT_is_cloth_deform_brush(brush) &&
brush->cloth_force_falloff_type ==
BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
PBVHVertexIter vd;
const float bstrength = ss->cache->bstrength;
@ -246,14 +247,29 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
gravity, ss->cache->gravity_direction, -ss->cache->radius * data->sd->gravity_factor);
}
/* Original data for deform brushes. */
SculptOrigVertData orig_data;
if (SCULPT_is_cloth_deform_brush(brush)) {
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
}
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
float force[3];
const float sim_factor = cloth_brush_simulation_falloff_get(
brush, ss->cache->radius, ss->cache->initial_location, cloth_sim->init_pos[vd.index]);
float current_vertex_location[3];
if (SCULPT_is_cloth_deform_brush(brush)) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
copy_v3_v3(current_vertex_location, orig_data.co);
}
else {
copy_v3_v3(current_vertex_location, vd.co);
}
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
if (sculpt_brush_test_sq_fn(&test, vd.co) || use_falloff_plane) {
if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
float dist = sqrtf(test.dist);
@ -264,7 +280,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
const float fade = sim_factor * bstrength *
SCULPT_brush_strength_factor(ss,
brush,
vd.co,
current_vertex_location,
dist,
vd.no,
vd.fno,
@ -293,7 +309,10 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
mul_v3_v3fl(force, offset, -fade);
break;
case BRUSH_CLOTH_DEFORM_GRAB:
mul_v3_v3fl(force, grab_delta, fade);
/* Grab writes the positions in the simulation directly without applying forces. */
madd_v3_v3v3fl(
cloth_sim->pos[vd.index], orig_data.co, ss->cache->grab_delta_symmetry, fade);
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
if (use_falloff_plane) {

View File

@ -120,7 +120,7 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss,
SCULPT_vertex_neighbors_get(ss, v_index, false, &neighbor_iterator); \
for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \
neighbor_iterator.i++) { \
neighbor_iterator.index = ni.neighbors[ni.i];
neighbor_iterator.index = neighbor_iterator.neighbors[neighbor_iterator.i];
/* Iterate over neighboring and duplicate vertices (for PBVH_GRIDS). Duplicates come
* first since they are nearest for floodfill. */
@ -128,8 +128,8 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss,
SCULPT_vertex_neighbors_get(ss, v_index, true, &neighbor_iterator); \
for (neighbor_iterator.i = neighbor_iterator.size - 1; neighbor_iterator.i >= 0; \
neighbor_iterator.i--) { \
neighbor_iterator.index = ni.neighbors[ni.i]; \
neighbor_iterator.is_duplicate = (ni.i >= \
neighbor_iterator.index = neighbor_iterator.neighbors[neighbor_iterator.i]; \
neighbor_iterator.is_duplicate = (neighbor_iterator.i >= \
neighbor_iterator.size - neighbor_iterator.num_duplicates);
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator) \
@ -333,6 +333,13 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
struct SculptSession *ss,
const float outline_col[3],
float outline_alpha);
BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
{
return brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB;
}
/* Pose Brush. */
void SCULPT_do_pose_brush(struct Sculpt *sd,
struct Object *ob,

View File

@ -393,6 +393,10 @@ typedef struct PoseFloodFillData {
bool is_first_iteration;
/* In topology mode this stores the furthest point from the stroke origin for cases when a pose
* origin based on the brush radius can't be set. */
float fallback_floodfill_origin[3];
/* Fallback origin. If we can't find any face set to continue, use the position of all vertices
* that have the current face set. */
float fallback_origin[3];
@ -403,12 +407,17 @@ static bool pose_topology_floodfill_cb(
SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
{
PoseFloodFillData *data = userdata;
const float *co = SCULPT_vertex_co_get(ss, to_v);
if (data->pose_factor) {
data->pose_factor[to_v] = 1.0f;
}
const float *co = SCULPT_vertex_co_get(ss, to_v);
if (len_squared_v3v3(data->pose_initial_co, data->fallback_floodfill_origin) <
len_squared_v3v3(data->pose_initial_co, co)) {
copy_v3_v3(data->fallback_floodfill_origin, co);
}
if (sculpt_pose_brush_is_vertex_inside_brush_radius(
co, data->pose_initial_co, data->radius, data->symm)) {
return true;
@ -547,12 +556,16 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
};
zero_v3(fdata.pose_origin);
copy_v3_v3(fdata.pose_initial_co, initial_location);
copy_v3_v3(fdata.fallback_floodfill_origin, initial_location);
SCULPT_floodfill_execute(ss, &flood, pose_topology_floodfill_cb, &fdata);
SCULPT_floodfill_free(&flood);
if (fdata.tot_co > 0) {
mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co);
}
else {
copy_v3_v3(fdata.pose_origin, fdata.fallback_floodfill_origin);
}
/* Offset the pose origin. */
float pose_d[3];