[Bf-blender-cvs] [62ef59aa0cc] master: Add the ability to create internal springs to the cloth sim

Sebastian Parborg noreply at git.blender.org
Mon Dec 9 19:16:43 CET 2019


Commit: 62ef59aa0cca736b09192b67cc924180d9c2f9f9
Author: Sebastian Parborg
Date:   Mon Dec 9 19:10:55 2019 +0100
Branches: master
https://developer.blender.org/rB62ef59aa0cca736b09192b67cc924180d9c2f9f9

Add the ability to create internal springs to the cloth sim

This can be used to make closed surfaces behave more like a soft body.

Reviewed By: Jacques Lucke

Differential Revision: http://developer.blender.org/D5788

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

M	release/scripts/startup/bl_ui/properties_physics_cloth.py
M	source/blender/blenkernel/BKE_cloth.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/makesdna/DNA_cloth_types.h
M	source/blender/makesrna/intern/rna_cloth.c
M	source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index d5ac140dc98..cd7e99f255c 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -160,6 +160,46 @@ class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel):
         col = flow.column()
         col.prop(cloth, "bending_damping", text="Bending")
 
+class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel):
+    bl_label = "Internal Springs"
+    bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+    def draw_header(self, context):
+        cloth = context.cloth.settings
+
+        self.layout.active = cloth_panel_enabled(context.cloth)
+        self.layout.prop(cloth, "use_internal_springs", text="")
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        cloth = context.cloth.settings
+        md = context.cloth
+        ob = context.object
+
+        layout.active = cloth.use_internal_springs and cloth_panel_enabled(md)
+
+        flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
+
+        col = flow.column()
+        col.prop(cloth, "internal_spring_max_length", text="Max Spring Creation Length")
+        col = flow.column()
+        col.prop(cloth, "internal_spring_max_diversion", text="Max Creation Diversion")
+        col = flow.column()
+        col.prop(cloth, "internal_spring_normal_check", text="Check Surface Normals")
+        col = flow.column()
+        col.prop(cloth, "internal_tension_stiffness", text="Tension")
+        col = flow.column()
+        col.prop(cloth, "internal_compression_stiffness", text="Compression")
+
+        col = flow.column()
+        col.prop_search(cloth, "vertex_group_intern", ob, "vertex_groups", text="Vertex Group")
+        col = flow.column()
+        col.prop(cloth, "internal_tension_stiffness_max", text="Max Tension")
+        col = flow.column()
+        col.prop(cloth, "internal_compression_stiffness_max", text="Max Compression")
 
 class PHYSICS_PT_cloth_pressure(PhysicButtonsPanel, Panel):
     bl_label = "Pressure"
@@ -422,6 +462,7 @@ classes = (
     PHYSICS_PT_cloth_physical_properties,
     PHYSICS_PT_cloth_stiffness,
     PHYSICS_PT_cloth_damping,
+    PHYSICS_PT_cloth_internal_springs,
     PHYSICS_PT_cloth_pressure,
     PHYSICS_PT_cloth_cache,
     PHYSICS_PT_cloth_shape,
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index d59a81c1baf..17de53be42a 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -115,6 +115,7 @@ typedef struct ClothVertex {
   float shear_stiff;
   int spring_count;      /* how many springs attached? */
   float shrink_factor;   /* how much to shrink this cloth */
+  float internal_stiff;  /* internal spring stiffness scaling */
   float pressure_factor; /* how much pressure should affect this vertex */
 } ClothVertex;
 
@@ -198,8 +199,12 @@ typedef enum {
   CLOTH_SIMSETTINGS_FLAG_PRESSURE = (1 << 5),
   /** Use the user defined target volume. */
   CLOTH_SIMSETTINGS_FLAG_PRESSURE_VOL = (1 << 6),
+  /** True if internal spring generation is enabled. */
+  CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS = (1 << 7),
   /** DEPRECATED, for versioning only. */
   CLOTH_SIMSETTINGS_FLAG_SCALING = (1 << 8),
+  /** Require internal springs to be created between points with opposite normals. */
+  CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS_NORMAL = (1 << 9),
   /** Edit cache in edit-mode. */
   CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12),
   /** Don't allow spring compression. */
@@ -230,6 +235,7 @@ typedef enum {
   CLOTH_SPRING_TYPE_GOAL = (1 << 4),
   CLOTH_SPRING_TYPE_SEWING = (1 << 5),
   CLOTH_SPRING_TYPE_BENDING_HAIR = (1 << 6),
+  CLOTH_SPRING_TYPE_INTERNAL = (1 << 7),
 } CLOTH_SPRING_TYPES;
 
 /* SPRING FLAGS */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index d80fae29cc8..c26800aefba 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -31,6 +31,7 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_math.h"
+#include "BLI_rand.h"
 #include "BLI_edgehash.h"
 #include "BLI_linklist.h"
 
@@ -130,6 +131,16 @@ void cloth_init(ClothModifierData *clmd)
   clmd->sim_parms->eff_force_scale = 1000.0;
   clmd->sim_parms->eff_wind_scale = 250.0;
 
+  /* Internal spring settings */
+  clmd->sim_parms->internal_spring_max_length = 0.0f;
+  clmd->sim_parms->internal_spring_max_diversion = M_PI / 4.0f;
+  clmd->sim_parms->internal_tension = 15.0f;
+  clmd->sim_parms->max_internal_tension = 15.0f;
+  clmd->sim_parms->internal_compression = 15.0f;
+  clmd->sim_parms->max_internal_compression = 15.0f;
+  clmd->sim_parms->vgroup_intern = 0;
+  clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS_NORMAL;
+
   /* Pressure settings */
   clmd->sim_parms->uniform_pressure_force = 0.0f;
   clmd->sim_parms->target_volume = 0.0f;
@@ -654,7 +665,7 @@ int cloth_uses_vgroup(ClothModifierData *clmd)
            (clmd->coll_parms->vgroup_selfcol > 0)) ||
           (clmd->sim_parms->vgroup_pressure > 0) || (clmd->sim_parms->vgroup_struct > 0) ||
           (clmd->sim_parms->vgroup_bend > 0) || (clmd->sim_parms->vgroup_shrink > 0) ||
-          (clmd->sim_parms->vgroup_mass > 0));
+          (clmd->sim_parms->vgroup_intern > 0) || (clmd->sim_parms->vgroup_mass > 0));
 }
 
 /**
@@ -729,8 +740,14 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
             verts->shrink_factor = dvert->dw[j].weight;
           }
 
+          if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_intern - 1)) {
+            /* Used to define the stiffness weight on the internal spring connected to this vertex.
+             */
+            verts->internal_stiff = dvert->dw[j].weight;
+          }
+
           if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_pressure - 1)) {
-            /* Used to define how much the pressure settings should affect the given vertex */
+            /* Used to define how much the pressure settings should affect the given vertex. */
             verts->pressure_factor = dvert->dw[j].weight;
           }
         }
@@ -1144,6 +1161,11 @@ static void cloth_update_springs(ClothModifierData *clmd)
                                cloth->verts[spring->ij].bend_stiff) /
                               2.0f;
     }
+    else if (spring->type & CLOTH_SPRING_TYPE_INTERNAL) {
+      spring->lin_stiffness = (cloth->verts[spring->kl].internal_stiff +
+                               cloth->verts[spring->ij].internal_stiff) /
+                              2.0f;
+    }
     else if (spring->type == CLOTH_SPRING_TYPE_BENDING_HAIR) {
       ClothVertex *v1 = &cloth->verts[spring->ij];
       ClothVertex *v2 = &cloth->verts[spring->kl];
@@ -1208,8 +1230,8 @@ static void cloth_update_spring_lengths(ClothModifierData *clmd, Mesh *mesh)
     ClothSpring *spring = search->link;
 
     if (spring->type != CLOTH_SPRING_TYPE_SEWING) {
-      if (spring->type &
-          (CLOTH_SPRING_TYPE_STRUCTURAL | CLOTH_SPRING_TYPE_SHEAR | CLOTH_SPRING_TYPE_BENDING)) {
+      if (spring->type & (CLOTH_SPRING_TYPE_STRUCTURAL | CLOTH_SPRING_TYPE_SHEAR |
+                          CLOTH_SPRING_TYPE_BENDING | CLOTH_SPRING_TYPE_INTERNAL)) {
         shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
       }
       else {
@@ -1385,6 +1407,85 @@ BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop
   return true;
 }
 
+static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
+                                               unsigned int v_idx,
+                                               RNG *rng,
+                                               float max_length,
+                                               float max_diversion,
+                                               bool check_normal,
+                                               unsigned int *r_tar_v_idx)
+{
+  float co[3], no[3], new_co[3];
+  float radius;
+
+  copy_v3_v3(co, treedata->vert[v_idx].co);
+  normal_short_to_float_v3(no, treedata->vert[v_idx].no);
+  negate_v3(no);
+
+  float vec_len = sin(max_diversion);
+  float offset[3];
+
+  offset[0] = 0.5f - BLI_rng_get_float(rng);
+  offset[1] = 0.5f - BLI_rng_get_float(rng);
+  offset[2] = 0.5f - BLI_rng_get_float(rng);
+
+  normalize_v3(offset);
+  mul_v3_fl(offset, vec_len);
+  add_v3_v3(no, offset);
+  normalize_v3(no);
+
+  /* Nudge the start point so we do not hit it with the ray. */
+  copy_v3_v3(new_co, no);
+  mul_v3_fl(new_co, FLT_EPSILON);
+  add_v3_v3(new_co, co);
+
+  radius = 0.0f;
+  if (max_length == 0.0f) {
+    max_length = FLT_MAX;
+  }
+
+  BVHTreeRayHit rayhit = {0};
+  rayhit.index = -1;
+  rayhit.dist = max_length;
+
+  BLI_bvhtree_ray_cast(
+      treedata->tree, new_co, no, radius, &rayhit, treedata->raycast_callback, treedata);
+
+  unsigned int vert_idx = -1;
+  const MLoop *mloop = treedata->loop;
+  const MLoopTri *lt = NULL;
+
+  if (rayhit.index != -1 && rayhit.dist <= max_length) {
+    if (check_normal && dot_v3v3(rayhit.no, no) < 0.0f) {
+      /* We hit a point that points in the same direction as our starting point. */
+      return false;
+    }
+
+    float min_len = FLT_MAX;
+    lt = &treedata->looptri[rayhit.index];
+
+    for (int i = 0; i < 3; i++) {
+      unsigned int tmp_vert_idx = mloop[lt->tri[i]].v;
+      if (tmp_vert_idx == v_idx) {
+        /* We managed to hit ourselves. */
+        return false;
+      }
+
+      float len = len_v3v3(co, rayhit.co);
+      if (len < min_len) {
+        min_len = len;
+        vert_idx = tmp_vert_idx;
+      }
+    }
+
+    *r_tar_v_idx = vert_idx;
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
 static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
 {
   Cloth *cloth = clmd->clothObject;
@@ -1431,6 +1532,69 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
     }
   }

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list