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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2020-05-26 21:49:53 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-05-26 21:49:53 +0300
commit00674c12cc0f08254e5643ad18120b2e9e710a94 (patch)
tree6f28fd07543f92cbad4d11989fd48248c3132d48 /source/blender/editors/sculpt_paint
parenta2baf50242a315961fc7bc4d202a610442e813ec (diff)
parent18f33f293bfe08e87c50cad4a9d628592d7a3d15 (diff)
Merge branch 'blender-v2.83-release'
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c114
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c29
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c15
5 files changed, 117 insertions, 57 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 458c24e5194..723ac58bc6e 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -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 {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 855e7503e3b..9826cc9571c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -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);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 62a7f1925ab..6dac2b51645 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -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) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 9b13f6e6c24..e00555d93bd 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -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,
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index b5e2652df7c..f01800b2895 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -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];