[Bf-blender-cvs] [5775efba2f3] sculpt-dev: Sculpt: Elastic Transform

Pablo Dobarro noreply at git.blender.org
Wed Dec 16 21:36:53 CET 2020


Commit: 5775efba2f32afa0d2f79b6890caeb35c24ad48f
Author: Pablo Dobarro
Date:   Tue Dec 15 21:38:07 2020 +0100
Branches: sculpt-dev
https://developer.blender.org/rB5775efba2f32afa0d2f79b6890caeb35c24ad48f

Sculpt: Elastic Transform

===================================================================

M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_transform.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_sculpt_paint.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 507a9d0c036..c107f67dd29 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -266,9 +266,15 @@ class _defs_annotate:
 
 class _defs_transform:
 
+    def draw_transform_sculpt_tool_settings(context, layout):
+        if context.mode != 'SCULPT':
+            return
+        layout.prop(context.tool_settings.sculpt, "transform_mode")
+
     @ToolDef.from_fn
     def translate():
         def draw_settings(context, layout, _tool):
+            _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
             _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
         return dict(
             idname="builtin.move",
@@ -284,6 +290,7 @@ class _defs_transform:
     @ToolDef.from_fn
     def rotate():
         def draw_settings(context, layout, _tool):
+            _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
             _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2)
         return dict(
             idname="builtin.rotate",
@@ -299,6 +306,7 @@ class _defs_transform:
     @ToolDef.from_fn
     def scale():
         def draw_settings(context, layout, _tool):
+            _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
             _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3)
         return dict(
             idname="builtin.scale",
@@ -354,6 +362,7 @@ class _defs_transform:
                 props = tool.gizmo_group_properties("VIEW3D_GGT_xform_gizmo")
                 layout.prop(props, "drag_action")
 
+            _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
             _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
 
         return dict(
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 37ac2015992..70779882dc5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -6177,15 +6177,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata,
   SculptSession *ss = data->ob->sculpt;
   Sculpt *sd = data->sd;
   Object *ob = data->ob;
-
-  /* These brushes start from original coordinates. */
-  const bool use_orco = ELEM(data->brush->sculpt_tool,
-                             SCULPT_TOOL_GRAB,
-                             SCULPT_TOOL_ROTATE,
-                             SCULPT_TOOL_THUMB,
-                             SCULPT_TOOL_ELASTIC_DEFORM,
-                             SCULPT_TOOL_BOUNDARY,
-                             SCULPT_TOOL_POSE);
+  const bool use_orco = data->use_proxies_orco;
 
   PBVHVertexIter vd;
   PBVHProxyNode *proxies;
@@ -6240,11 +6232,20 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
 
   /* First line is tools that don't support proxies. */
   if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
+    const bool use_orco = ELEM(brush->sculpt_tool,
+                               SCULPT_TOOL_GRAB,
+                               SCULPT_TOOL_ROTATE,
+                               SCULPT_TOOL_THUMB,
+                               SCULPT_TOOL_ELASTIC_DEFORM,
+                               SCULPT_TOOL_BOUNDARY,
+                               SCULPT_TOOL_POSE);
+
     SculptThreadedTaskData data = {
         .sd = sd,
         .ob = ob,
         .brush = brush,
         .nodes = nodes,
+        .use_proxies_orco = use_orco,
     };
 
     TaskParallelSettings settings;
@@ -6255,6 +6256,27 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
   MEM_SAFE_FREE(nodes);
 }
 
+void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob)
+{
+  SculptSession *ss = ob->sculpt;
+  PBVHNode **nodes;
+  int totnode;
+
+  BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .nodes = nodes,
+      .use_proxies_orco = false,
+  };
+
+  TaskParallelSettings settings;
+  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+  BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
+
+  MEM_SAFE_FREE(nodes);
+}
+
 /**
  * Copy the modified vertices from the #PBVH to the active key.
  */
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index b0a208446ad..df722bf0617 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -706,6 +706,10 @@ typedef struct SculptThreadedTaskData {
   float (*mat)[4];
   float (*vertCos)[3];
 
+  /* When true, the displacement stored in the proxies will be aplied to the original coordinates
+   * instead of to the current coordinates. */
+  bool use_proxies_orco;
+
   /* X and Z vectors aligned to the stroke direction for operations where perpendicular vectors to
    * the stroke direction are needed. */
   float (*stroke_xz)[3];
@@ -749,6 +753,9 @@ typedef struct SculptThreadedTaskData {
   bool mask_expand_create_face_set;
 
   float transform_mats[8][4][4];
+  float elastic_transform_mat[4][4];
+  float elastic_transform_pivot[3];
+  float elastic_transform_radius;
 
   /* Boundary brush */
   float boundary_deform_strength;
@@ -833,6 +840,8 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3]);
 bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v);
 bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v);
 
+void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob);
+
 SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
                                                             SculptBrushTest *test,
                                                             char falloff_shape);
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index f74d59e1987..4b7639bdeb3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -32,6 +32,7 @@
 
 #include "BKE_brush.h"
 #include "BKE_context.h"
+#include "BKE_kelvinlet.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_object.h"
@@ -83,7 +84,12 @@ void ED_sculpt_init_transform(struct bContext *C)
   SCULPT_vertex_random_access_ensure(ss);
   SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
 
-  ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_ORIGINAL;
+  if (sd->transform_mode == SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC) {
+    ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL;
+  }
+  else {
+    ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_ORIGINAL;
+  }
 }
 
 static void sculpt_transform_matrices_init(SculptSession *ss,
@@ -123,13 +129,13 @@ static void sculpt_transform_matrices_init(SculptSession *ss,
 
     /* Translation matrix. */
     sub_v3_v3v3(d_t, ss->pivot_pos, start_pivot_pos);
-    SCULPT_flip_v3_by_symm_area(d_t, symm, v_symm, ss->init_pivot_pos);
+    SCULPT_flip_v3_by_symm_area(d_t, symm, v_symm, start_pivot_pos);
     translate_m4(t_mat, d_t[0], d_t[1], d_t[2]);
 
     /* Rotation matrix. */
     sub_qt_qtqt(d_r, ss->pivot_rot, start_pivot_rot);
     normalize_qt(d_r);
-    SCULPT_flip_quat_by_symm_area(d_r, symm, v_symm, ss->init_pivot_pos);
+    SCULPT_flip_quat_by_symm_area(d_r, symm, v_symm, start_pivot_pos);
     quat_to_mat4(r_mat, d_r);
 
     /* Scale matrix. */
@@ -220,6 +226,94 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
       0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings);
 }
 
+static void sculpt_elastic_transform_task_cb(void *__restrict userdata,
+                                             const int i,
+                                             const TaskParallelTLS *__restrict UNUSED(tls))
+{
+
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  PBVHNode *node = data->nodes[i];
+
+  float(*proxy)[3] = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[i])->co;
+
+  SculptOrigVertData orig_data;
+  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i]);
+
+  KelvinletParams params;
+  /* TODO(pablodp606): These parameters can be exposed if needed as transform strength and volume
+   * preservation like in the elastic deform brushes. Setting them to the same default as elastic
+   * deform triscale grab because they work well in most cases. */
+  const float force = 1.0f;
+  const float shear_modulus = 1.0f;
+  const float poisson_ratio = 0.4f;
+  BKE_kelvinlet_init_params(
+      &params, data->elastic_transform_radius, force, shear_modulus, poisson_ratio);
+
+  SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
+
+  PBVHVertexIter vd;
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+  {
+    SCULPT_orig_vert_data_update(&orig_data, &vd);
+    float transformed_co[3], orig_co[3], disp[3];
+    const float fade = vd.mask ? *vd.mask : 0.0f;
+    copy_v3_v3(orig_co, orig_data.co);
+
+    copy_v3_v3(transformed_co, vd.co);
+    mul_m4_v3(data->elastic_transform_mat, transformed_co);
+    sub_v3_v3v3(disp, transformed_co, vd.co);
+
+    float final_disp[3];
+    BKE_kelvinlet_grab_triscale(final_disp, &params, vd.co, data->elastic_transform_pivot, disp);
+    mul_v3_fl(final_disp, 20.0f * (1.0f - fade));
+
+    copy_v3_v3(proxy[vd.i], final_disp);
+
+    if (vd.mvert) {
+      vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+
+  BKE_pbvh_node_mark_update(node);
+}
+
+static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float transform_radius)
+{
+  BLI_assert(ss->filter_cache->transform_displacement_mode ==
+             SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL);
+
+  SculptSession *ss = ob->sculpt;
+  const char symm = SCULPT_mesh_sy

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list