From 5f63344e849ea6435bfd2de5584389cd18b22aa6 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Wed, 20 May 2020 21:11:35 +0200 Subject: Fix PBVH API returning wrong normal when using shape keys and modifiers The implementation of this function should match the one in SCULPT_vertex_co_get. This does not solve the issue when sculpting with modifiers active but I think this code is wrong Reviewed By: sergey, brecht Differential Revision: https://developer.blender.org/D7805 --- source/blender/editors/sculpt_paint/sculpt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d2dda1be1e7..8443608cfa5 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; -- cgit v1.2.3 From 18f33f293bfe08e87c50cad4a9d628592d7a3d15 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Tue, 19 May 2020 00:00:21 +0200 Subject: Fix Cloth Brush grab deformation mode The grab mode was not correctly implemented, so the way it was working was confusing for users. - Grab delta was calculated in increments from the last stroke position, so it did not match the behavior of a grab brush. I refactored the grab delta calculation to make this change more explicit. - Grab displacement was not calculated from the original coordinates - Grab was using an incorrect strength Grab is now setting the position of the affected vertices directly and the constraints solve the rest of the cloth. I also tried to implement an alternative version based on applying forces to move the vertices to the grab position, but I think this is more controllable and the grab falloff can be adjusted by tweaking the simulation falloff. Reviewed By: sergey Differential Revision: https://developer.blender.org/D7756 --- source/blender/editors/sculpt_paint/sculpt.c | 101 +++++++++++++++------------ 1 file changed, 58 insertions(+), 43 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8443608cfa5..c42170695c2 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2091,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 { @@ -6199,6 +6203,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; @@ -6242,38 +6274,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 { @@ -6294,18 +6315,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); @@ -6376,9 +6393,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); } -- cgit v1.2.3