[Bf-blender-cvs] [c2f0522760b] master: Sculpt: Enable Cloth Simulation Target for Pose and Boundary

Pablo Dobarro noreply at git.blender.org
Tue Aug 18 17:16:56 CEST 2020


Commit: c2f0522760b24b746b1f1686f91198c643b6b4c2
Author: Pablo Dobarro
Date:   Tue Aug 18 15:11:51 2020 +0200
Branches: master
https://developer.blender.org/rBc2f0522760b24b746b1f1686f91198c643b6b4c2

Sculpt: Enable Cloth Simulation Target for Pose and Boundary

This adds a new brush property called "Deformation Target" which
controls how the brush deformations is going to affect the mesh data. By
default is set to Geometry, which makes the brushes displace the
vertices. When set to Cloth Simulation, the deformation of the brush is
applied to the cloth solver constraints, so the simulation is
responsible to apply the final deformation. This allows to add cloth
simulation effects to other sculpt tools with minor modifications to their
code.

This patch enables Cloth Simulation deformation target for Pose and
Boundary brushes, which are tools that are already designed to work in
low poly counts and produce large deformations. This allows creating the
most common cloth effects, like bending and compressing folds, without
relying on collisions.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8578

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_cloth.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_pose.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 5f15fa00562..a20de3e29db 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -640,6 +640,8 @@ def brush_settings(layout, context, brush, popover=False):
             layout.separator()
 
         elif sculpt_tool == 'POSE':
+            layout.separator()
+            layout.prop(brush, "deform_target")
             layout.separator()
             layout.prop(brush, "pose_deform_type")
             layout.prop(brush, "pose_origin_type")
@@ -721,6 +723,8 @@ def brush_settings(layout, context, brush, popover=False):
             col.prop(brush, "smear_deform_type")
 
         elif sculpt_tool == 'BOUNDARY':
+            layout.prop(brush, "deform_target")
+            layout.separator()
             col = layout.column()
             col.prop(brush, "boundary_deform_type")
             col.prop(brush, "boundary_falloff_type")
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5d09109c506..e1c1b8ee5fb 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -275,6 +275,19 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3])
   SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal);
 }
 
+float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
+                                                const int deform_target,
+                                                PBVHVertexIter *iter)
+{
+  switch (deform_target) {
+    case BRUSH_DEFORM_TARGET_GEOMETRY:
+      return iter->co;
+    case BRUSH_DEFORM_TARGET_CLOTH_SIM:
+      return ss->cache->cloth_sim->deformation_pos[iter->index];
+  }
+  return iter->co;
+}
+
 /* Sculpt Face Sets and Visibility. */
 
 int SCULPT_active_face_set_get(SculptSession *ss)
@@ -5690,6 +5703,16 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       SCULPT_pose_brush_init(sd, ob, ss, brush);
     }
 
+    if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+      if (!ss->cache->cloth_sim) {
+        ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(ss, brush, 1.0f, 0.0f, false);
+        SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
+        SCULPT_cloth_brush_build_nodes_constraints(
+            sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+      }
+      SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
+    }
+
     bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
 
     /* Apply one type of brush action. */
@@ -5828,6 +5851,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
     }
 
+    if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+      if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+        SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
+      }
+    }
+
     MEM_SAFE_FREE(nodes);
 
     /* Update average stroke position. */
@@ -7308,7 +7337,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
     need_mask = true;
   }
 
-  if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+  if (brush->sculpt_tool == SCULPT_TOOL_CLOTH ||
+      brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
     need_mask = true;
   }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index a188d6a678c..5e01e034715 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -633,6 +633,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
   const int symm_area = ss->cache->mirror_symmetry_pass;
   SculptBoundary *boundary = ss->cache->boundaries[symm_area];
   const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  const Brush *brush = data->brush;
 
   const float strength = ss->cache->bstrength;
 
@@ -657,12 +658,13 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
               orig_data.co, boundary->initial_vertex_position, symm)) {
         const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
         float t_orig_co[3];
+        float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
         sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
-        rotate_v3_v3v3fl(vd.co,
+        rotate_v3_v3v3fl(target_co,
                          t_orig_co,
                          boundary->bend.pivot_rotation_axis[vd.index],
                          angle * boundary->edit_info[vd.index].strength_factor * mask);
-        add_v3_v3(vd.co, boundary->bend.pivot_positions[vd.index]);
+        add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
       }
     }
 
@@ -682,6 +684,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
   const int symm_area = ss->cache->mirror_symmetry_pass;
   SculptBoundary *boundary = ss->cache->boundaries[symm_area];
   const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  const Brush *brush = data->brush;
 
   const float strength = ss->cache->bstrength;
 
@@ -699,7 +702,8 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
       if (SCULPT_check_vertex_pivot_symmetry(
               orig_data.co, boundary->initial_vertex_position, symm)) {
         const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
-        madd_v3_v3v3fl(vd.co,
+        float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+        madd_v3_v3v3fl(target_co,
                        orig_data.co,
                        boundary->slide.directions[vd.index],
                        boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
@@ -722,6 +726,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
   const int symm_area = ss->cache->mirror_symmetry_pass;
   SculptBoundary *boundary = ss->cache->boundaries[symm_area];
   const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  const Brush *brush = data->brush;
 
   const float strength = ss->cache->bstrength;
 
@@ -741,7 +746,8 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
         const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
         float normal[3];
         normal_short_to_float_v3(normal, orig_data.no);
-        madd_v3_v3v3fl(vd.co,
+        float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+        madd_v3_v3v3fl(target_co,
                        orig_data.co,
                        normal,
                        boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
@@ -764,6 +770,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
   const int symm_area = ss->cache->mirror_symmetry_pass;
   SculptBoundary *boundary = ss->cache->boundaries[symm_area];
   const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  const Brush *brush = data->brush;
 
   const float strength = ss->cache->bstrength;
 
@@ -779,7 +786,8 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
       if (SCULPT_check_vertex_pivot_symmetry(
               orig_data.co, boundary->initial_vertex_position, symm)) {
         const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
-        madd_v3_v3v3fl(vd.co,
+        float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+        madd_v3_v3v3fl(target_co,
                        orig_data.co,
                        ss->cache->grab_delta_symmetry,
                        boundary->edit_info[vd.index].strength_factor * mask * strength);
@@ -802,6 +810,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
   const int symm_area = ss->cache->mirror_symmetry_pass;
   SculptBoundary *boundary = ss->cache->boundaries[symm_area];
   const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  const Brush *brush = data->brush;
 
   const float strength = ss->cache->bstrength;
 
@@ -826,12 +835,13 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
               orig_data.co, boundary->initial_vertex_position, symm)) {
         const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
         float t_orig_co[3];
+        float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
         sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
-        rotate_v3_v3v3fl(vd.co,
+        rotate_v3_v3v3fl(target_co,
                          t_orig_co,
                          boundary->twist.rotation_axis,
                          angle * mask * boundary->edit_info[vd.index].strength_factor);
-        add_v3_v3(vd.co, boundary->twist.pivot_position);
+        add_v3_v3(target_co, boundary->twist.pivot_position);
       }
     }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index acfa04022cb..ea94398ee5d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -134,6 +134,7 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush,
 #define CLOTH_SIMULATION_ITERATIONS 5
 #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
 #define CLOTH_SIMULATION_TIME_STEP 0.01f
+#define CLOTH_DEFORMATION_TARGET_STRENGTH 0.35f
 
 static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim,
                                                   const int v1,
@@ -297,9 +298,22 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
       }
     }
 
-    if (cloth_is_deform_brush && l

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list