Sculpt: pinch/inflate support for snake-hook
authorCampbell Barton <ideasman42@gmail.com>
Thu, 21 Jan 2016 10:06:49 +0000 (21:06 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 21 Jan 2016 10:28:24 +0000 (21:28 +1100)
Snake-hook tended to loose volume along the stroke,
now with pinch > 0.5 its possible to sculpt shapes without loosing volume.

source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesrna/intern/rna_brush.c

index 587f33468a611df065173501768c7add0a09014e..73f829ada7194c309f8f96decb5d2d141680a97c 100644 (file)
@@ -2278,6 +2278,7 @@ static void do_snake_hook_brush_task_cb_ex(
        SculptThreadedTaskData *data = userdata;
        SculptSession *ss = data->ob->sculpt;
        Brush *brush = data->brush;
+       SculptProjectVector *spvc = data->spvc;
        const float *grab_delta = data->grab_delta;
 
        PBVHVertexIter vd;
@@ -2285,6 +2286,9 @@ static void do_snake_hook_brush_task_cb_ex(
        float (*proxy)[3];
        const float bstrength = ss->cache->bstrength;
        const bool do_rake_rotation = ss->cache->is_rake_rotation_valid;
+       const bool do_pinch = (brush->crease_pinch_factor != 0.5f);
+       const float pinch = do_pinch ?
+               (2.0f * (0.5f - brush->crease_pinch_factor) * (len_v3(grab_delta) / ss->cache->radius)) : 0.0f;
 
        proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
 
@@ -2298,6 +2302,31 @@ static void do_snake_hook_brush_task_cb_ex(
 
                        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];
+
+                               sub_v3_v3v3(delta_pinch, vd.co, test.location);
+
+                               /* 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);
+
+                               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);
+                       }
+
                        if (do_rake_rotation) {
                                float delta_rotate[3];
                                sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
@@ -2319,6 +2348,8 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
        float grab_delta[3];
        float len;
 
+       SculptProjectVector spvc;
+
        copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
 
        len = len_v3(grab_delta);
@@ -2332,9 +2363,14 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
                add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm);
        }
 
+       /* optionally pinch while painting */
+       if (brush->crease_pinch_factor != 0.5f) {
+               sculpt_project_v3_cache_init(&spvc, grab_delta);
+       }
+
        SculptThreadedTaskData data = {
            .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
-           .grab_delta = grab_delta,
+           .spvc = &spvc, .grab_delta = grab_delta,
        };
 
        BLI_task_parallel_range_ex(
index 9822b9f4a98f80e4c0bba9e2520febea1c503a8c..e3733ff2850c224324c403397b6e536b3b053dd9 100644 (file)
@@ -178,7 +178,7 @@ static int rna_SculptToolCapabilities_has_persistence_get(PointerRNA *ptr)
 static int rna_SculptToolCapabilities_has_pinch_factor_get(PointerRNA *ptr)
 {
        Brush *br = (Brush *)ptr->data;
-       return ELEM(br->sculpt_tool, SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE);
+       return ELEM(br->sculpt_tool, SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE, SCULPT_TOOL_SNAKE_HOOK);
 }
 
 static int rna_SculptToolCapabilities_has_plane_offset_get(PointerRNA *ptr)